Remplacer GPT par un modèle open-source auto-hébergé : retour d'expérience avec l'extraction documentaire

En bref : migration réelle d'une stack d'extraction documentaire d'Azure (Document Intelligence + GPT-4o) vers un SLM open-source auto-hébergé sur un seul GPU. Résultat : qualité équivalente au cloud, traitement plus rapide, et jusqu'à 20× moins cher à l'échelle — sans qu'aucune donnée sensible ne quitte l'infrastructure. Pertinent dès quelques milliers de pages/mois, sous contrainte de souveraineté ou de rate limits.
L'extraction documentaire fait partie des tâches de l'IA générative que l'on peut facilement traiter avec les modèles propriétaires en API comme GPT, Claude et Gemini. Ces modèles sont rapides à intégrer, performants, et simples à opérer. Mais leur utilisation se heurte vite à la conjonction de plusieurs contraintes : la souveraineté des données, le coût facturé au token qui grimpe avec le volume, les rate limits qui plafonnent le débit, la modération qui bloque parfois des requêtes légitimes, et la dépendance à un fournisseur.
Or les performances des SLM open-source (small language models) atteignent aujourd'hui le niveau des grands modèles propriétaires sur les tâches classiques (OCR, segmentation, extraction structurée). Chez Galadrim, agence tech & IA française, nous avons mené cette migration pour un client soumis à de fortes contraintes de souveraineté. Cet article en détaille le retour d'expérience pas à pas : choix du modèle et du GPU, mise en production, garde-fous, et méthode d'évaluation pour valider qu'on ne perd rien en qualité.

Le contexte : pourquoi une API propriétaire ne tenait plus

Le projet est une application métier construite sur-mesure pour un bureau d'expertises médicales dont les clients sont des assureurs santé en Suisse. Un utilisateur y dépose un dossier PDF composite, souvent 50 à 500 pages, qui rassemble des pièces hétérogènes : rapports, formulaires, courriers, ordonnances, factures. L'application découpe ce PDF en sous-documents distincts, en extrait la date et le titre, produit un résumé, et sélectionne les pièces utiles au traitement.
En interne, ce pipeline enchaîne 7 étapes :
  • rendu des pages en images,
  • OCR,
  • segmentation (poser les frontières entre sous-documents),
  • fusion des blocs,
  • extraction des dates,
  • extraction du contenu (titre + résumé + sélection),
  • et déduplication.
La segmentation est l'étape pivot. Si on coupe mal, tout le reste est biaisé : un rapport éclaté en plusieurs morceaux fait exploser les dates extraites et fausse la sélection. C'est donc l'étape sur laquelle on a concentré nos tests en premier.
La protection des données privées a été au coeur des contraintes de développement du projet en raison des données sensibles traitées et régulées par la LPD suisse (Loi fédérale sur la protection des données), équivalent de la réglementation européenne. Plusieurs clients de la solution souhaitaient aller au-delà des garanties contractuelles fournies par Azure en Suisse en termes de souveraineté de la donnée.
À cette contrainte réglementaire, s'ajoutaient déjà un coût facturé au token qui croît avec le volume, et une dépendance à des fournisseurs hors de notre contrôle. Le client a donc demandé, en amont, une infrastructure 100 % suisse, sans tiers extra-européen dans la boucle. C'est le déclencheur de la migration.

Choisir son SLM : multimodalité et budget VRAM

Migrer vers de l'auto-hébergé GPU engage un coût d'infrastructure et une complexité opérationnelle et soulève principalement les questions suivantes : quelle infrastructure choisir pour l'inférence, en particulier la mémoire vive du GPU (VRAM) et quel modèle choisir pour chaque tâche (nombre de paramètres, quantification etc.) ?

Le LLM pour les tâches d'extraction et de synthèse

L'entrée de l'étape de segmentation est composée d'images de pages. Il faut donc un modèle multimodal, à fenêtre de contexte large, qui tienne sur un seul GPU.
ModèleParams actifsVRAM Q5MultimodalChoix
Llama 3.1 70B70B~50 GBpas de vision
Mistral Large 2 123B123B> 80 GBinfaisable single-GPU
Qwen2.5-VL 32B32B~22 GBcorrect mais lent
Qwen3.6-35B-A3B (MoE)3B actifs / 35B~28 GBretenu
Pixtral 12B12B~10 GBécart de qualité
Tableau 1 — Choix du modèle multimodal (splitter) : Un seul GPU 48 Go, vision requise pour lire les pages.

On a retenu un Mixture-of-Experts (Qwen3.6-35B-A3B) : il n'active que 3 milliards de paramètres par token généré tout en disposant de la connaissance d'un modèle à 35 milliards de paramètres. On obtient donc le débit d'un petit modèle avec la qualité d'un gros. Sur notre tâche, il est au niveau de GPT-4o en segmentation et extraction de dates.

L'OCR

GLM-OCR est spécialisé OCR (pas généraliste) et lit bien les écritures manuscrites. C'est un point critique sur les formulaires où l'information utile est souvent une mention manuscrite.
ModèleQualité petit texteVitesseChoix
Azure Document Intelligenceréférence1-2 s/pcloud
Tesseract / PaddleOCRdégradée sur tampons/écriture< 1 s/pinsuffisant
Qwen2.5-VL OCR-modebonne8-10 s/plent
GLM-OCR (THUDM)≈ Azure DI1-2 s/pretenu
Tableau 2 — Choix du moteur OCR : Qualité proche d'Azure, sans le cloud.

Quantization : c'est avant tout une question de budget VRAM

Faire cohabiter deux modèles sur 48 GB est surtout un problème d'enveloppe mémoire. On a comparé plusieurs niveaux de quantization et retenu, pour notre cas et notre VRAM, du Q5_K_M pour le LLM et du Q8_0 pour l'OCR : c'est le point où la qualité reste indistingable du FP16 sur nos tâches tout en laissant assez de marge pour faire tourner plusieurs requêtes LLM concurrentes. Le bon niveau dépend du modèle, de la tâche et du GPU. Le Q4 dégradait l'extraction structurée et l'OCR des petits chiffres ; le FP16 ne rentrait tout simplement pas.
2026-06-16T15:00:06.207744image/svg+xmlMatplotlib v3.10.8, https://matplotlib.org/01020283848LLMQwen3.6-35B-A3B · Q5_K_M28 GoOCRGLM-OCR · Q8_010 GoMarge anti-OOMtampon de contexte10 GoVRAM (Go) · NVIDIA L40S 48 Go
Figure 1 — Les deux modèles cohabitent sur un seul GPU 48 Go : ~38 Go alloués, ~10 Go conservés en marge pour absorber les pics de contexte.

Deux enseignements tirés de la mise en production des SLM

Couper le « thinking mode » : structurer la tâche plutôt que laisser le modèle réfléchir

Par défaut, le modèle émet plusieurs milliers de tokens de raisonnement () avant de produire son JSON. Sur une tâche à sortie structurée, ce raisonnement est du temps perdu : sur un batch de 10 pages, on passe de ~20 s à ~3 s en le désactivant, un gain × 5 à × 10.
Au-delà du flag : sur les tâches structurées, la qualité vient moins du raisonnement libre que de bien définir et structurer la tâche dans le prompt système. Et quand la qualité de sortie est critique, on remplace le raisonnement implicite par un dispositif explicite et contrôlé, typiquement plusieurs passes en réseau adversarial de LLM-as-a-judge pour durcir et valider le système de prompt. On garde le raisonnement uniquement là où il aide réellement (ici, la déduplication).

Toujours tester ses garde-fous : les modèles open-source hallucinent

Un SLM auto-hébergé n'a pas le filet de sécurité d'un fournisseur. Il faut construire ses propres garde-fous, et les tester en conditions réelles pour trouver les bonnes solutions.
Garde-fouDéclenchementEffet
Détection de boucle OCRSortie anormalement longue ou répétition phrase-levelSauvegarde le préfixe valide, retry, fallback
Fallback per-pageLe parsing d'un batch OCR échoueRe-OCR page par page
Fallback LLM sur OCR loopBoucle OCR + retry échouéBascule sur le LLM vision pour cette page
Retry exponentielErreur HTTP / timeoutRécupère les transients réseau ou saturation
Boundary resolverLe splitter hésite entre 2 frontièresRéinjecte le contexte limitrophe pour trancher
Tableau 3 — Garde-fous du pipeline auto-hébergé : sans filet fournisseur, tout est géré côté pipeline.
Dans la pratique, ces garde-fous récupèrent la quasi-totalité des incidents : sur nos lots, environ 1 % des pages partent en boucle d'hallucination, et 100 % sont récupérées via sauvegarde du préfixe valide + fallback. L'objectif est de la détecter et d'avoir un plan B systématique.

Mesurer pour décider : comment on a validé qu'on ne perdait rien

Le risque numéro un d'une migration comme celle-ci, c'est de dégrader silencieusement la qualité. On a donc construit un harness d'évaluation qui compare chaque sortie du modèle local à une référence, sur un jeu de dossiers représentatifs annotés (plusieurs centaines de sous-documents).
Quelle référence ? La cible, c'est l'extraction faite en amont par GPT-4o (la stack de prod historique), consolidée par annotation. Point important : cette référence n'est pas une vérité absolue. Il subsiste des incertitudes métier et il arrive que le LLM-as-a-judge estime que le découpage ou l'extraction du modèle local sont meilleurs que la référence. Autrement dit, une partie des « écarts » mesurés ne sont pas des régressions mais des désaccords légitimes, ce qui plafonne mécaniquement les scores bruts vers le bas.
Séparer le mécanique du sémantique. Tout ce qui est comparable mécaniquement (frontières, dates, sélection, hallucinations) est calculé en Python pur, alignement par overlap de pages, F1, ce qui rend ces KPIs reproductibles bit-à-bit entre deux runs. Mais certains critères ne se réduisent pas à un exact-match : « Rapport médical Dr Martin » et « Rapport initial — Jean MARTIN » désignent le même document. Pour ces cas, un LLM-as-a-judge rend un verdict structuré ok | partial | ko + une raison courte. Seule cette couche dépend d'un LLM, donc elle reste auditable indépendamment.
KPIDéfinitionCible
Cut F1 (tol ±1)Précision/rappel des frontières de découpe≥ 90 %
Date exact rate% de dates prédites exactes≥ 80 %
is_selected F1Sélection des pièces utiles≥ 90 %
Hallucination rate% de documents prédits sans correspondance≤ 2 %
Title verdictQualité du titre, jugée par LLM≥ 95 % ok
Tableau 4 — KPIs et cibles métier : séparer le mécanique du sémantique.
Astuce : le LLM-as-a-judge comme annotateur quand on n'a pas de golden set. Construire une ground truth à la main coûte cher. Avec les modèles actuels (on utilise aujourd'hui Claude Code avec Opus 4.8, ou Codex avec GPT-5.5), un LLM-as-a-judge fait un annotateur de départ étonnamment fiable : il pré-annote, on relit, et on itère. C'est un excellent moyen d'amorcer un jeu d'évaluation à moindre coût.
⚠️ Sur des données sensibles, anonymisez d'abord. Dès qu'on envoie des contenus à un LLM-as-a-judge ou à un modèle d'annotation — a fortiori via une API externe — il faut anonymiser en amont (caviardage des identités, identifiants). Sinon, on réintroduit par la petite porte exactement la fuite de données qu'on cherchait à éliminer en migrant on-premise. D'où l'importance d'un set de base anonymisé.
(Note transverse) Pour itérer vite, c'est un agent de code qui pilote la chaîne d'évaluation : il lance les pipelines, déclenche les passes de jugement, agrège les bilans et régénère un comparatif cross-runs — sans intervention manuelle. Un bon exemple d'usage d'agents de code pour accélérer une boucle de R&D.

Résultats : qualité, vitesse, coût

La qualité au rendez-vous

KPIScore (local)Verdict
Cut F1 (tol ±1)89,8 %au niveau cible
Date exact rate81,3 %
is_selected F185,1 %
Hallucination rate0,4 %quasi nulle
Title verdict ok68 % ok / 25 % partiel / 6 % ko
Tableau 5 — Résultats du SLM local vs cibles : tous les indicateurs au niveau attendu.
2026-06-16T15:00:06.628664image/svg+xmlMatplotlib v3.10.8, https://matplotlib.org/020406080100Score (%)Titres jugés « ok » + partielsSélection des pièces (F1)Dates exactesCut F1 (segmentation)94 %85 %81 %90 %trait foncé = cible métierHallucinations0,4 %
Figure 2 — Le SLM local atteint ou approche les cibles métier sur tous les KPIs, avec un taux d'hallucination quasi nul (0,4 %).
Sur un dossier représentatif, la segmentation atteint un Cut F1 de 98 % : les frontières prédites coïncident presque toutes avec les frontières de référence, avec seulement deux sur-découpages mineurs sur 48.
2026-06-16T15:00:07.020616image/svg+xmlMatplotlib v3.10.8, https://matplotlib.org/01020304050607080Transition entre pages (frontière de sous-document)RéférencePréditsur-coupesur-coupeRéférence · 46Prédit · 48
Figure 3 — Frontières de référence et prédites sur un dossier de 79 pages. 46 des 48 frontières prédites sont exactes ; les deux sur-coupes entourées sont les seuls écarts.

La vitesse : plus rapide que le cloud

Mesure directe sur un même dossier de 530 pages :
Azure (DI + GPT-4o)Local (GPU L40S)Ratio
Temps wall-clock45 min30 min× 1,5 plus rapide
Coût du run$8.70~$0.45 (estimé sur le coût horaire)× ~20 moins cher
Tableau 6 — Azure vs local sur un même dossier de 530 pages.
Le coût local n'est pas nul : il s'estime en rapportant le temps machine au coût horaire du GPU (~$0.90/h). Un run de 30 min revient donc à ~$0.45 de compute, contre $8.70 facturés par le cloud sur le même dossier.
2026-06-16T15:00:07.403389image/svg+xmlMatplotlib v3.10.8, https://matplotlib.org/0102030405060Part du temps de traitement (%)DUPLICATESCONTENTSPLITDATES< 1 %· MinHash + LLM8 %· titre + résumé42 %· segmentation par batch50 %· 1 appel LLM / sous-docDATES + SPLIT92 %du temps total
Figure 4 — DATES et SPLIT concentrent 92 % du temps de traitement : ce sont les deux postes à paralléliser en priorité.
À noter, une limite : un seul GPU ne tient pas une énorme charge parallèle : on plafonne autour de ~15 pages/min en charge maximale. C'est parfait pour du traitement asynchrone à volume modéré, moins adapté à un pic temps-réel massif.

Le coût : le vrai argument à l'échelle

C'est sur le coût que le gain est le plus net. Le GPU coûte un montant fixe (~$0.90/h, soit ~$650/mois en 24/24), indépendant du volume. Le cloud, lui, facture chaque page.
MétriqueAzureLocal (GPU 24/24)
Coût marginal / dossier (530 p)$8.70~$0.45 (en on-demand)
Coût fixe / mois0 (pay-as-you-go)~$650
Seuil de rentabilitédès ~75 gros dossiers / mois
Tableau 7 — Coût — Azure vs GPU local 24/24.

En mode 24/24, le coût marginal d'un dossier supplémentaire tend vers zéro (la machine tourne de toute façon). Au-delà du seuil, tout volume supplémentaire est traité à coût marginal quasi nul côté infra IA, et l'écart se creuse linéairement.
2026-06-16T15:00:07.844251image/svg+xmlMatplotlib v3.10.8, https://matplotlib.org/050100150200250300350400Volume mensuel (gros dossiers de ~530 pages)$0$500$1 000$1 500$2 000$2 500$3 000Coût mensuel ($)API cloud (au token)GPU on-premise 24/24 (coût fixe)Seuil de rentabilité~75 gros dossiers / mois
Figure 5 — Le coût cloud croît avec le volume ; le GPU on-premise reste fixe. Au-delà de ~75 gros dossiers/mois, l'écart se creuse en faveur de l'on-premise.

Quand basculer vers un SLM on-premise

Cette migration n'est pas un dogme. Voici le cadre de décision qu'on en retire.
Basculez vers un SLM auto-hébergé quand :
  • vous avez une contrainte de souveraineté / conformité forte (données sensibles, secteur réglementé) ;
  • votre volume dépasse le seuil de rentabilité (typiquement quelques dizaines à centaines de dossiers/mois) ;
  • vous vous heurtez régulièrement aux rate limits des API : auto-héberger, c'est reprendre la main sur son throughput au lieu de subir les quotas du fournisseur ;
  • votre cas d'usage est « classique » (OCR, segmentation, extraction structurée, classification), là où les SLM ont rattrapé les gros modèles ;
  • votre charge est asynchrone et tolère une latence de l'ordre de la minute.

Ce qu'on a appris en chemin

  1. La quantization est un arbitrage local, pas une recette : le bon niveau dépend du modèle, de la tâche et de votre VRAM.
  2. MoE = qualité d'un gros modèle au débit d'un petit : un excellent profil pour de l'auto-hébergé.
  3. Structurez la tâche plutôt que de laisser le modèle raisonner librement : prompt système soigné, et passes adversariales de LLM-as-a-judge quand la qualité est critique.
  4. Testez vos garde-fous en conditions réelles : les modèles open-source hallucinent, l'enjeu est de détecter et de récupérer, pas de viser le zéro défaut illusoire.
  5. Séparez l'évaluation mécanique (reproductible) du jugement sémantique (LLM) pour des KPIs auditables — et anonymisez avant tout passage par un juge externe.

Conclusion

Sur ce traitement documentaire, un SLM open-source en architecture MoE associé à un OCR spécialisé, sur un seul GPU à ~$650/mois, atteint la qualité du cloud, va plus vite, coûte jusqu'à 20 fois moins cher à l'échelle, et garde les données sensibles dans le périmètre. L'open-source ne remplace pas tout : il s'agit de choisir le bon modèle pour le bon usage. Pour les tâches classiques, à volume, sous contrainte de souveraineté ou de rate limits, les SLM sont prêts.
Par Maceo Duriez, Ingénieur IA chez Galadrim. Retour d'expérience issu d'un projet client réel.

FAQ

Un SLM open-source peut-il égaler GPT-4o sur l'extraction documentaire ?

Oui, sur les tâches classiques (OCR, segmentation, extraction structurée). Sur ce projet, le modèle MoE local atteint le niveau de GPT-4o en segmentation et extraction de dates. Les API propriétaires gardent l'avantage sur le raisonnement avancé et les tâches agentiques complexes.

À partir de quel volume l'auto-hébergement devient-il rentable ?

Typiquement quelques dizaines à centaines de dossiers/mois. Le GPU coûte un montant fixe (~650 $/mois en 24/24) ; au-delà du seuil de rentabilité (~3000 pages/mois ici), chaque dossier supplémentaire est traité à coût marginal quasi nul, là où le cloud facture chaque page.

Combien coûte le traitement d'un dossier en local vs cloud ?

Sur un même dossier de 530 pages : ~0,45 $ de compute en local (30 min à ~0,90 $/h de GPU) contre 8,70 $ (environ 16cts/pages) facturés par le cloud.

Quand rester sur une API propriétaire plutôt qu'un SLM on-premise ?

Quand le volume est faible, que vous avez besoin du raisonnement le plus avancé, que vous devez encaisser des pics de charge massifs sans provisionner d'infra, ou que la donnée n'a aucune contrainte de localisation.
Vous souhaitez être accompagné pour lancer votre projet digital ?
Déposez votre projet dès maintenant
Article presentation image
Comment des couleurs dans un terminal peuvent vous compromettre
Imaginez la scène : vous lancez un outil CLI pour diagnostiquer un serveur en prod. Il affiche des informations sur un process ...
Molly Allerhand
Molly Allerhand
Développeuse full-stack @ Galadrim
Article presentation image
Comment maximiser l’efficacité d’un Web Application Firewall (WAF) ?
Le Web Application Firewall (WAF) est un de ces outils dont on parle souvent, mais qu’on exploite rarement à son plein potentiel. ...
Molly Allerhand
Molly Allerhand
Développeuse full-stack @ Galadrim
Article presentation image
Certifier l’intégrité d’un flux de logs en continu, un enjeu de sécurité crucial
Dans la plupart des systèmes modernes, conserver un journal de logs permet de retracer les actions effectuées et de comprendre ...
Molly Allerhand
Molly Allerhand
Développeuse full-stack @ Galadrim