Le Défi : Extraire du JSON depuis des PDF Financiers
Relevés bancaires, avis d'imposition, taxes foncières, tableaux d'amortissement, cartes d'identité... Autant de documents financiers qu'il faut traiter manuellement au quotidien. L'objectif de ce projet R&D : automatiser l'extraction de données structurées (JSON) à partir de ces documents, en utilisant exclusivement des modèles open-source auto-hébergés.
Le principe : un OCR (reconnaissance optique de caractères) lit le document pixel par pixel pour en extraire le texte, puis un LLM (grand modèle de langage, le même type de technologie que ChatGPT) structure ce texte en données exploitables. Le tout tourne sur GPU cloud, sans envoyer vos documents à un service tiers.
Après plusieurs semaines de tests intensifs, nous avons convergé vers une architecture hybride qui atteint 100% de précision sur les données financières. Voici le parcours complet, des premières tentatives aux résultats finaux.
Pourquoi ne pas Utiliser les Solutions Existantes ?
La question est légitime. Des solutions d'OCR et d'extraction existent depuis longtemps — Tesseract (open-source, Google), AWS Textract, Google Document AI, ou encore Azure AI Document Intelligence. Pourquoi développer notre propre pipeline ?
Les OCR classiques comme Tesseract ou EasyOCR fonctionnent bien sur du texte imprimé propre, mais peinent dès qu'il s'agit de comprendre la structure d'un document complexe : colonnes débit/crédit, tableaux multi-pages, en-têtes hiérarchiques. Ils extraient du texte, pas de la donnée structurée.
Les solutions cloud (Textract, Document AI) sont plus performantes sur la structuration, mais posent d'autres problèmes : confidentialité des données (vos relevés bancaires transitent par des serveurs tiers), coûts récurrents qui grimpent vite avec le volume, et dépendance à un fournisseur qui peut modifier ses tarifs ou son API à tout moment.
Notre approche combine le meilleur des deux mondes : la puissance des modèles de dernière génération (Chandra-OCR, Gemma 4) avec un hébergement 100% maîtrisé. Les documents ne quittent jamais votre infrastructure, le coût est fixe et prévisible, et vous gardez le contrôle total sur le pipeline.
Phase 1 : pdfplumber + LLM Texte
La première approche était intuitive : extraire le texte des PDF avec pdfplumber (tables, layout), puis envoyer ce texte brut au LLM pour le structurer en JSON.
Les problèmes rencontrés
Très vite, les limites sont apparues :
L'encodage PDF produit des chaînes illisibles type "RELEVEDEVOTRECOMPTECOURANT" ou "PAIEMENTCARTE1234MAGASIN". Impossible pour le LLM de les interpréter correctement.
pdfplumber fusionne les cellules multi-lignes, rendant l'output illisible. Les transactions coupées entre deux pages créent des lignes "orphelines" fantômes.
Chaque banque structure ses relevés différemment. Ce qui fonctionne pour l'une échoue pour l'autre : mise en page des colonnes, gestion des multi-lignes, distinction entre tables de transactions et tables de frais...
Malgré de nombreux correctifs spécifiques, chaque nouveau format bancaire révélait de nouveaux cas de figure. La solution restait trop fragile et dépendante du format source : ce qui fonctionnait pour une banque échouait pour une autre. Il fallait une approche universelle.
Phase 2 : Mode Vision Direct
Les modèles Qwen 3.5 étant nativement multimodaux, l'idée était tentante : envoyer directement les pages PDF converties en images JPEG au LLM, sans passer par l'extraction de texte.
Le problème des tokens
Une page à 150 DPI consomme environ 9 000 tokens (et non 1 260 comme estimé initialement). À 300 DPI, 3 pages représentent ~108k tokens, bien au-delà du contexte de 32k. Même à 150 DPI, 3 pages occupent ~27k tokens, laissant très peu de place pour le prompt et la réponse.
Mais le vrai problème est ailleurs : le modèle fait des erreurs sur les montants des transactions (hallucinations visuelles). Pour des documents financiers où chaque centime compte, c'est rédhibitoire.
Conclusion : le mode vision fonctionne, mais n'est pas assez fiable pour les données financières. Il faut un OCR spécialisé.
Phase 3 : L'Architecture Hybride OCR + LLM
L'idée gagnante : combiner un modèle OCR spécialisé pour extraire le texte avec une précision parfaite, puis un LLM pour structurer ce texte en JSON. Cette approche élimine tous les problèmes des phases précédentes :
- Plus de dépendance à pdfplumber et ses limitations d'encodage
- Plus d'hallucinations visuelles du mode vision
- Solution universelle : fonctionne quel que soit le type de document ou la banque
Chandra-OCR-2 : Le Moteur OCR
Chandra-OCR-2 (datalab-to/chandra-ocr-2) est un modèle OCR basé sur l'architecture Qwen 3.5 VL. Avec seulement 5.3 milliards de paramètres, il offre une qualité d'extraction remarquable sur les documents numériques.
Qualité OCR sur 9 Relevés Bancaires (34 pages)
Le résultat est sans appel : zéro erreur sur les données financières, soit environ 200 transactions vérifiées une par une. Les seules imprécisions concernent des typos mineures dans du texte "boilerplate" (URL, références alphanumériques longues).
| Relevé | Montants | Soldes | IBAN/BIC | Problèmes |
|---|---|---|---|---|
| Banque A - Relevé 1 | 100% | OK | OK | "ASSURANCCE" au lieu de "ASSURANCE" |
| Banque A - Relevé 2 | 100% | OK | OK | Aucun |
| Banque A - Relevé 3 | 100% | OK | OK | URL typo mineure |
| Banque B - Relevé 1 | 100% | OK | OK | 1 char masqué en moins |
| Banque B - Relevé 2 | 100% | OK | OK | 1 zéro en trop sur réf longue |
| Banque B - Relevé 3 | 100% | OK | OK | 1-2 chars sur réfs longues |
Et sur les Autres Types de Documents ?
Nous avons ensuite testé sur 12 documents variés couvrant un large spectre de cas d'usage :
| Document | Type | Qualité | Notes |
|---|---|---|---|
| Liasse fiscale (12 pages) | Formulaires fiscaux | Bon | 1 chiffre tronqué sur identifiant |
| Avis d'imposition (x2) | Avis IR | Excellent | Aucun problème |
| Taxe foncière | Taxe foncière | Très bon | 1 char sur un prénom |
| Échéancier prêt (183 lignes) | Amortissement | Parfait | Aucun problème |
| Portefeuille PEA | Synthèse titres | Excellent | Aucun problème |
| Relevé assurance vie / PER | Relevé de situation | Excellent | Aucun problème |
| Attestation INPI | Attestation RNE | Excellent | Aucun problème |
| Carte d'identité (scan) | CNI | Bon | Zone MRZ partiellement malformée |
| Passeport (photo) | Photo smartphone | Moyen à bon | Variable selon angle/reflets |
Constat : sur les PDF numériques (relevés, avis d'imposition, échéanciers), la qualité est excellente à parfaite. Les scans propres fonctionnent très bien également. Seules les photos de pièces d'identité prises au smartphone montrent des limites, principalement dues aux reflets, à l'angle de prise de vue et au flou.
Le LLM : Gemma 4 vs Qwen 3.5
Une fois le texte extrait par Chandra-OCR, il faut un LLM capable de le structurer en JSON propre. Deux candidats de dernière génération ont été mis en compétition sur nos 18 documents (dont 338 transactions bancaires) :
- Architecture : Transformer hybride (sliding + full attention), multimodal texte/image/vidéo
- Quantization : NVFP4 — FP4 sur les poids et activations, optimisée par NVIDIA. Seulement ~0.5% de dégradation par rapport au BF16 original
- VRAM : ~31 Go pour les poids, jusqu'à 90 Go avec le KV cache selon le contexte
- Contexte : 256K tokens (testé à 65K pour nos documents)
- Architecture : Dense hybride (Gated DeltaNet + Gated Attention), 64 couches, multimodal
- Quantization : FP8 (E4M3) — précision intermédiaire entre FP16 et FP4, bonne fidélité avec réduction de VRAM
- VRAM : ~31 Go pour les poids
- Contexte : 262K tokens (testé à 32K). Nécessite de désactiver le mode "thinking" pour éviter du chain-of-thought parasite
Gemma 4 est la dernière génération de Google (2025), spécifiquement optimisé par NVIDIA pour l'inférence en FP4 — un format de quantization agressif qui divise par 4 l'empreinte mémoire avec une dégradation quasi imperceptible. Qwen 3.5 est le dernier modèle dense d'Alibaba, réputé pour son excellence en multilingue et en raisonnement structuré.
En benchmarks publics (MMLU, HumanEval), les deux modèles sont proches. Mais sur notre tâche très spécifique — extraire fidèlement des données financières en JSON sans hallucination — les différences sont notables :
| Critère | Gemma 4 31B (NVFP4) | Qwen 3.5 27B (FP8) |
|---|---|---|
| Montants | 338/338 (100%) | 338/338 (100%) |
| Soldes | 9/9 | 8/9 |
| IBAN | 9/9 | 8/9 (1 tronqué à 26 chars) |
| Vitesse | ~30 t/s | ~33 t/s |
| Temps (18 fichiers) | 182s | 142s |
| Fiabilité métadonnées | Meilleure | Bonne |
Gemma 4 NVFP4 l'emporte : plus fiable sur les métadonnées (soldes, IBAN) avec une vitesse acceptable. Sur une tâche d'extraction structurée qui demande rigueur et fidélité plutôt que créativité, Gemma 4 se montre plus conservateur — et c'est exactement ce qu'on attend. Qwen 3.5, malgré une vitesse de génération légèrement supérieure, commet des erreurs ponctuelles : un solde confondu avec un total de crédits, un IBAN tronqué d'un caractère.
Point notable : les deux modèles oublient systématiquement le BIC dans le JSON de sortie, bien qu'il soit présent dans l'OCR. Un simple ajout du champ au schéma du prompt suffit à corriger ce comportement — preuve que le prompt engineering reste déterminant, même avec des modèles de cette envergure.
Benchmarks GPU : La Course au Débit
Les performances OCR varient considérablement selon le GPU utilisé. La bande passante mémoire HBM3 du H100 (3.35 TB/s) fait une différence nette face au RTX PRO 6000 (~1 TB/s).
| GPU | Config | Débit OCR | Temps (73 pages) |
|---|---|---|---|
| RTX PRO 6000 (22% VRAM) | Partage avec LLM | 0.26 p/s | 333s |
| RTX PRO 6000 (90% VRAM) | Chandra seul | 0.70 p/s | 104s |
| 2x RTX PRO 6000 (TP=2) | Tensor parallel | 0.88 p/s | 83s |
| H100 NVL (90% VRAM) | Chandra seul | 1.23 p/s | 59s |
Observation intéressante : le tensor parallel (TP=2) sur 2 GPU n'apporte que +25% de débit au lieu du doublement théorique. Comment l'expliquer ?
L'hypothèse la plus probable est la bande passante inter-GPU. Les RTX PRO 6000 communiquent entre elles via PCIe Gen5, soit environ 64 Go/s. À titre de comparaison, les H100 utilisent NVLink avec une bande passante de 900 Go/s — 14 fois plus. Pour un modèle de seulement 5.3B paramètres comme Chandra-OCR, le temps de synchronisation des tenseurs entre GPU via PCIe domine largement le gain du parallélisme.
Dans ce cas de figure, le data parallel (2 instances indépendantes du même modèle, chacune sur son GPU) serait bien plus pertinent : chaque GPU traite ses propres pages en totale autonomie, sans synchronisation. Le gain serait alors quasi linéaire.
Infrastructure : vLLM sur GPU Cloud
Tout le pipeline tourne sur vLLM 0.19, un serveur d'inférence compatible avec l'API OpenAI. La configuration optimale utilise 2 GPU :
- Modèle : Chandra-OCR-2
- Port : 8081
- VRAM : 20% (~20 Go)
- Concurrence : 64 séquences
- Modèle : Gemma 4 31B NVFP4
- Port : 8082
- VRAM : 90% (~88 Go)
- Contexte : 65 000 tokens
Pièges CUDA 13
Certaines images cloud récentes embarquent CUDA 13, alors que vLLM est compilé pour CUDA 12. Le fix : pip install nvidia-cuda-runtime-cu12. Attention, un simple symlink entre les versions ne fonctionne pas (les symbols de version sont incompatibles).
Prompt Engineering : Les Règles Apprises
Le prompt système est le coeur du pipeline. Il a été construit progressivement, erreur après erreur — chaque règle correspond à un bug réel rencontré en production. Au final, il contient une vingtaine de directives étiquetées "TOLÉRANCE ZÉRO" sur les champs les plus sensibles.
Stratégie de croisement des sources
Le LLM reçoit deux sources d'information pour chaque document : le texte OCR (fiable pour les chiffres et les montants) et les images originales (fiables pour la structure visuelle, les colonnes, les en-têtes). Le prompt lui impose de croiser systématiquement ces deux sources : en cas de doute sur un montant, c'est l'OCR qui fait foi ; pour comprendre la mise en page (colonnes débit/crédit, sections), ce sont les images.
Les règles métier critiques
Le nom de la banque est celui de l'établissement émetteur du relevé, visible dans l'en-tête ou le logo. Un nom de banque qui apparaît dans une transaction (ex. : retrait DAB chez un concurrent) ne désigne pas la banque du compte. Cette confusion est arrivée dès les premiers tests.
Les identifiants créancier SEPA (ICS) et les références uniques de mandat (RUM) commencent aussi par "FR..." et ressemblent à des IBAN. Le prompt impose une validation stricte : un IBAN français fait exactement 27 caractères sans espaces, et se trouve en en-tête ou pied de page — jamais dans les détails d'un prélèvement.
Le solde d'ouverture est le solde à la date indiquée, pas le premier montant visible. Et le solde de clôture n'est pas le total des crédits ou débits de la période. Sans cette distinction explicite dans le prompt, le LLM confond systématiquement les deux.
Le LLM doit analyser les en-têtes de colonnes pour déterminer le signe de chaque montant (négatif pour les débits, positif pour les crédits). Les sous-totaux ("TOTAL DES OPERATIONS", "Sous-total...") doivent être ignorés. Tous les montants sont en float avec point décimal, toutes les dates en ISO 8601.
Les libellés de transactions peuvent s'étaler sur plusieurs lignes. Le prompt impose de les concaténer avec un séparateur, sans jamais inclure le montant dans le libellé. Et surtout : interdiction formelle d'inventer une information absente du document. Si un champ n'est pas visible, il reste vide.
Les leçons du terrain
Ce prompt illustre une réalité du travail avec les LLM : les benchmarks généraux ne prédisent pas la performance sur une tâche spécifique. Un modèle excellent en MMLU peut confondre un solde avec un total de crédits. La différence se fait dans la précision du prompt — et dans le nombre d'itérations qu'on est prêt à investir.
L'usage de marqueurs d'emphase comme "TRÈS CRITIQUE" dans le prompt système n'est pas anecdotique : ces marqueurs pondèrent l'attention du modèle vers les champs les plus sensibles. En pratique, les erreurs sur les IBAN ont disparu après l'ajout de cette emphase.
Résultats Finaux
| Étape | Temps (18 fichiers) |
|---|---|
| pdf2img (conversion) | ~5s |
| OCR (Chandra, pipeliné) | ~75s |
| LLM (Gemma 4, extraction) | ~175s |
| Total pipeline | ~250s (4 min 10s) |
Coûts d'Infrastructure
Sur les plateformes de location GPU cloud, le coût est très raisonnable : environ $1.50 à $2.00/h pour 2x RTX PRO 6000 Blackwell (98 Go chacun), ou ~$1.62/h pour un H100 NVL.
Exemple de Sortie JSON
Voici un extrait anonymisé du JSON produit par le pipeline à partir d'un relevé bancaire :
{
"bank_information": {
"bank_name": "Banque Exemple",
"iban": "FR76XXXXXXXXXXXXXXXXXXXXX"
},
"statement_period": {
"start_date": "2026-01-01",
"end_date": "2026-01-31"
},
"balances": {
"opening_balance": 3245.67,
"closing_balance": 2891.43
},
"transactions": [
{
"operation_date": "2026-01-03",
"value_date": "2026-01-03",
"raw_description": "PAIEMENT CB 0301 SUPERMARCHE",
"amount": -87.54
},
{
"operation_date": "2026-01-05",
"value_date": "2026-01-05",
"raw_description": "VIR SEPA EMPLOYEUR SAS - SALAIRE JANVIER",
"amount": 2450.00
}
]
}Pistes d'Amélioration
- Stripper le HTML OCR avant envoi au LLM pour réduire les tokens de ~40% (les tags
data-bboxsont inutiles pour l'extraction) - Prompts par type de document : adapter le prompt selon qu'il s'agisse d'une CNI, d'un tableau d'amortissement ou d'une liasse fiscale
- Post-processing : valider les IBAN (27 chars FR), vérifier la chaîne de soldes, implémenter des checksums
- Data parallel OCR : 2 instances Chandra indépendantes pour doubler le throughput
- Batch processing : pour de gros volumes (100+ fichiers), le round-robin multi-endpoint devient pertinent
Conclusion
Ce pipeline hybride démontre qu'il est tout à fait possible de construire une solution d'extraction documentaire fiable à 100% sur les données financières, en utilisant exclusivement des modèles open-source auto-hébergés.
La clé du succès réside dans la séparation des responsabilités : un OCR spécialisé (Chandra) pour la lecture pixel-parfaite, et un LLM (Gemma 4) pour l'intelligence de structuration. Cette architecture est universelle — elle ne dépend ni de la banque, ni du type de document.
Avec un coût d'infrastructure modeste (~$2/h sur GPU cloud) et des performances de 4 minutes pour 18 documents, cette solution est déployable en production dès aujourd'hui pour automatiser le traitement de documents financiers à grande échelle.
— Laurent Lefèvre
