Files
Aivanov_scan_ogc/README.md
Dom 2ceb3c4916 docs: README avec installation Linux/macOS et référence des répertoires
Guide de démarrage pour un nouveau collaborateur :
- Prérequis système (Python 3.10+, poppler, GPU ≥ 8 Go VRAM)
- Installation (Debian/Ubuntu et macOS) et venv Python
- Commandes principales : pipeline.cli, ui_overlay Streamlit,
  annotate_validation, tests, reconstruction ATIH
- Structure des répertoires (ce qui est dans git vs ignoré)
- Schéma d'architecture et format du JSON produit
- État actuel chiffré + limites connues + pistes suite

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 15:11:49 +02:00

215 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Aivanov_scan_ogc
Pipeline d'extraction structurée des **fiches OGC** (contrôles T2A/PMSI de l'Assurance
Maladie) à partir de PDFs scannés. Produit un JSON par dossier + validation automatique
des codes médicaux contre les référentiels ATIH 2018.
---
## Architecture en une page
```
PDF scanné (6 pages)
┌───────────────┐ pipeline/ingest.py
│ ingest │ → PNG 300 dpi, cache par hash SHA256
└───────┬───────┘
┌───────────────┐ pipeline/classify.py
│ routing │ → type de page (recueil, concertation_1/2, preuves…)
└───────┬───────┘ → vérif 1 seule page (ordre standard OGC respecté)
┌───────────────┐ pipeline/ocr_qwen.py — Qwen2.5-VL-3B (VLM local ~7 Go VRAM)
│ extraction │ + pipeline/prompts.py — JSON schemas par type de page
│ OCR + JSON │ + pipeline/checkboxes.py — densité pixels pour Accord/Désaccord
└───────┬───────┘ (les VLM testés n'arrivent pas à lire les cases à cocher)
┌───────────────┐ pipeline/validation.py + pipeline/referentials.py
│ validation │ → lookup ATIH (CIM-10, CCAM, GHM, GHS 2018 en SQLite local)
│ ATIH │ → suggestion Levenshtein ≤ 1 en cas de code invalide
└───────┬───────┘ → cross-check GHM ↔ GHS
┌───────────────┐ pipeline/persist.py — JSON annoté + metadata
│ output JSON │ pipeline/ui_overlay.py — Streamlit review/annotation
└───────────────┘
```
## Prérequis
- **Python 3.10 3.12**
- **Linux ou macOS** (testé sur Linux + RTX 5070, et macOS Apple Silicon)
- **GPU** : une carte CUDA avec **≥ 8 Go VRAM** (Qwen2.5-VL-3B en bfloat16 tient en 7 Go).
Sur Apple Silicon, MPS fonctionne mais n'a pas été validé ici.
- **poppler** pour `pdf2image`
- **git**, **curl**
### Installation des deps système
**Linux (Debian/Ubuntu) :**
```bash
sudo apt update
sudo apt install -y python3.12 python3.12-venv python3-pip poppler-utils git curl
```
**macOS :**
```bash
brew install python@3.12 poppler git
```
## Installation du projet
```bash
git clone http://localhost:3100/Dom/Aivanov_scan_ogc.git
cd Aivanov_scan_ogc
python3.12 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
# Deps principales (GPU)
pip install "torch>=2.6" torchvision --index-url https://download.pytorch.org/whl/cu128
pip install transformers "accelerate>=1.0" qwen-vl-utils
pip install pdf2image Pillow openpyxl numpy
# UI + tests
pip install streamlit pytest
```
> **Note VRAM** : si la carte fait < 8 Go, réduire `max_pixels` dans
> `pipeline/ocr_qwen.py` (`max_pixels=1280 * 28 * 28` → `640 * 28 * 28`).
> Si pas de GPU du tout, le modèle tournera sur CPU mais **très lentement**
> (≈ 5-10 min par page au lieu de 3 s).
## Données d'entrée
Déposer les PDFs à extraire dans un répertoire, par exemple `2018 CARC/` à la racine.
Le nom est libre, mais les fichiers doivent suivre le modèle `OGC <N>.pdf` (ex.
`OGC 7.pdf`). Le répertoire de données **n'est pas dans le dépôt** (voir
`.gitignore`) — c'est à chacun de récupérer ses scans.
## Utilisation
### 1. Extraire un ou plusieurs dossiers
```bash
# Un PDF
python -m pipeline.cli "2018 CARC/OGC 7.pdf"
# Tout un répertoire
python -m pipeline.cli "2018 CARC" --out output/v2
```
Sortie : `output/v2/<nom>.json` avec la structure :
```json
{
"fichier": "OGC 7",
"pdf_hash": "…",
"pages": [ { "page": 1, "type": "recueil", "elapsed_s": 6.3, }, ],
"extraction": {
"recueil": { "etablissement": "…", "ghm_etab": "21M162", ,
"_validation": { "summary": {}, "cross_checks": {} } },
"concertation_2": { "ghs_initial": "…", "decision": "…", "_validation": },
"concertation_1": { "argumentaire": "…", "date_concertation": "…" },
"preuves": { "date": "…", "pieces": [] }
},
"_meta": { "pipeline_version": "v1", "ocr_model": "…", "generated_at": "…" }
}
```
Temps attendu : ~35 s / dossier (6 pages).
### 2. Interface de review & annotation
```bash
streamlit run pipeline/ui_overlay.py
```
Ouvre **http://localhost:8501**. Sélectionner un dossier dans la sidebar ; pour chaque
page, l'image est affichée à gauche et les champs extraits (éditables) à droite. Les
codes médicaux sont annotés d'un badge ATIH (🟢 valide / 🟡 invalide mais suggestion /
🔴 invalide). Les corrections sont sauvegardées dans `gold/<nom>.json`.
### 3. Validation ATIH sur les JSONs existants
```bash
python annotate_validation.py # annote output/v2/*.json et produit validation_report.md
```
Rapport produit : `validation_report.md` avec taux de validité par champ, suggestions de
correction OCR, incohérences GHM↔GHS.
### 4. Tests
```bash
pytest tests/ # 11 tests unitaires sur les référentiels ATIH
```
### 5. Reconstruction de la base ATIH (si besoin)
La base SQLite `referentials/atih_2018.sqlite` est déjà incluse dans le dépôt, donc
aucune action n'est normalement requise. Si les sources changent :
```bash
python -m pipeline.referentials --build # relit referentials/sources/ → SQLite
python -m pipeline.referentials --stats # affiche le nombre de codes par table
python -m pipeline.referentials --test # self-test rapide
```
## Structure des répertoires
| Chemin | Contenu | Dans git ? |
|---|---|---|
| `pipeline/` | Code de production (modules OCR, validation, UI) | ✅ |
| `pipeline/ui_overlay.py` | Interface Streamlit | ✅ |
| `referentials/sources/` | Données ATIH brutes (XLSX, XML ClaML, ~8 Mo) | ✅ |
| `referentials/atih_2018.sqlite` | Base SQLite générée (3 Mo) | ✅ |
| `tests/` | Tests unitaires | ✅ |
| `output/` | Sorties legacy (pipeline V0 `extract_ogc.py`) | ✅ |
| `output/v2/` | Sorties pipeline V2 (JSONs annotés ATIH, 18 dossiers) | ✅ |
| `scratch/` | Scripts exploratoires (choix d'OCR) + README | ✅ |
| `bench_v2_report.md` | Comparaison V2 vs legacy | ✅ |
| `validation_report.md` | Rapport validation ATIH | ✅ |
| **`2018 CARC/`** | **PDFs scannés** — à fournir, **ignoré par git** | ❌ |
| `.cache/images/` | Cache PDF → PNG (reconstructible, gitignoré) | ❌ |
| `gold/` | Annotations manuelles (créé au besoin via l'UI) | ❌ |
| `.venv/` | Environnement Python virtuel | ❌ |
| `extract_ogc.py` | Pipeline legacy docTR+VLM (conservé pour comparaison) | ✅ |
| `generate_pdf.py` | Reconstruction de PDFs propres depuis JSON (legacy) | ✅ |
## État du pipeline (au 2026-04-24)
**Qualité mesurée sur 18 dossiers** (validation ATIH, fix `*`/`+N` appliqué) :
| Champ | Validité |
|---|---:|
| ghm_etab / ghs_etab / ghm_reco / ghs_reco | 94 % |
| codage_etab.dp | 94 % |
| codage_etab.das / codage_reco.das | 100 % |
| codage_etab.dr | 79 % (suffixes PMSI) |
| accord_desaccord (checkboxes) | 17/17 sur échantillon vérifié |
**Limites connues** (cf. `bench_v2_report.md`) :
- `codage_reco.*` sous-extrait (27 % de couverture, mais 100 % de validité quand
extrait) — la colonne « Recodage » du tableau n'est pas lue systématiquement.
- `praticien_conseil` halluciné (biais fréquentiel « DR VIGNAU »).
- Pages manuscrites (p3 et parfois p6) : hors scope actuel.
**Pistes pour la suite** :
1. Prompt explicite colonne Recodage, ou crop demi-page droite en second passage.
2. Anti-hallucination praticien_conseil (consigne stricte + crop bas de page).
3. Passage de `ghs_injustifie` dans `checkboxes.py` (comme Accord/Désaccord).
4. Annotation manuelle d'un gold set de 5-10 dossiers via l'UI pour mesurer chaque
itération contre une vérité auditée (et pas seulement contre le legacy qui contient
lui-même des erreurs).
## Références
- **Modèle OCR** : [Qwen/Qwen2.5-VL-3B-Instruct](https://huggingface.co/Qwen/Qwen2.5-VL-3B-Instruct)
- **Référentiels ATIH** : CIM-10 FR à usage PMSI, CCAM descriptive, Manuel des GHM, Tarifs MCO
([atih.sante.fr](https://www.atih.sante.fr))
- **Licence** : interne, projet non redistribué