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>
This commit is contained in:
214
README.md
Normal file
214
README.md
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
# 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é
|
||||||
Reference in New Issue
Block a user