Des rapports de laboratoire scannés aux données structurées : compromis dans l’architecture OCR
Comment une startup de santé à budget limité peut évaluer les bibliothèques OCR, les API Google Cloud et un LLM de vision auto-hébergé pour transformer des scans médicaux en JSON structuré.
Sources: How We Chose Our OCR Architecture for a Medical Reports Pipeline (Part 1 of 2)
Transformer une photo d’une impression de laboratoire en une ligne indiquant « Hémoglobine, 13,2, g/dL, référence 12,0–15,5 » semble être un problème d’OCR, mais la reconnaissance de texte brut n’est que la première étape. Le véritable défi consiste à extraire du sens d’une scan approximative de manière économique, fiable et sans divulguer les données des patients. Cette présentation décrit les choix architecturaux sous-jacents à un tel pipeline d’extraction pour un MVP de rapports médicaux, afin que vous puissiez réutiliser cette logique lorsque vous rencontrerez un problème similaux de compréhension de documents avec un budget limité.
Le critère qui guide tout
Imaginez un produit de santé en phase initiale. Les patients téléchargent un rapport médical numérisé, que ce soit en PDF ou en photo prise avec leur téléphone d’une feuille de laboratoire imprimée. Le système doit le convertir en dossiers médicaux structurés que le patient et son médecin puissent consulter, ainsi que des données exploitables par des analyses ultérieures basées sur l’IA. Chaque dossier nécessite quatre éléments : le nom du paramètre, sa valeur mesurée, l’unité de mesure et la plage de référence.
Ce dernier point est essentiel. Un outil qui restitue simplement un bloc de caractères reconnus ne répond pas à cette exigence par lui-même. Il reste encore nécessaire de déterminer quel chiffre correspond à quel test, quelle chaîne de caractères représente une unité et quelles sont les valeurs normales pour un couple de chiffres. Chaque décision concerne donc l’endroit où se situe cette étape de « compréhension » et son coût.
Les contraintes étaient typiques pour un MVP : une petite équipe, un budget d’infrastructure limité, et un volume initial prévu d’environ 500 rapports téléchargés par jour, ce qui correspond à roughly 30 000 pages par mois.
Décision 1 : Choix du langage de développement
L’avantage de l’écosystème Python est réel
Si l’on part de la question « quel langage dispose des meilleures outils d’OCR et d’apprentissage automatique ? », Python l’emporte sans grande discussion. Des moteurs open source matures tels que PaddleOCR et EasyOCR sont conçus pour Python, OpenCV dispose de bindings de premier ordre pour ce langage, et la plupart des exemples de vision par ordinateur prévoient son utilisation. Un pipeline d’OCR développé à partir de zéro commencerait naturellement en Python.
Il est également utile d’être honnête quant à ce qui n’est pas un facteur de différenciation. L’API Vision de Google faisait partie des options payantes à l’étude, et Google publie des bibliothèques clients pour Python ainsi que pour Go. La disponibilité des SDK ne favorisait donc aucune de ces langages.
Pourquoi Go a quand même gagné
Les facteurs décisifs concernaient le système environnant plutôt que l’OCR lui-même. Le reste du pipeline asynchrone était déjà conçu pour fonctionner avec un processus en Go : il consomme les tâches depuis Redis Streams, télécharge les fichiers uploadés depuis le stockage Cloudflare R2 et enregistre les résultats dans Postgres. Écrire l’étape d’extraction en Python aurait signifié de devoir gérer deux environnements de exécution distincts, avec des déploiements, une gestion des dépendances et des outils d’observation séparés, pour une seule fonctionnalité. De plus, l’ingénieur chargé de son développement était le plus productif en Go pour ce type de service d’infrastructure.
Leçon générale : la langue disposant du catalogue de bibliothèques le plus complet n’est pas automatiquement celle qui convient. Si l’étape d’extraction peut se réduire à l’appel d’un modèle via HTTP (ce qui est le cas dans cette conception), il vaut souvent mieux conserver un seul environnement de exécution pour toute la couche de travail plutôt que de privilégier une profondeur de bibliothèques que l’on n’utilisera presque pas.
Décision 2 : API cloud contre hébergement propre, coûts élevés
L’équipe a comparé quatre options compte tenu d’un volume prévu de 30 000 pages par mois. Les chiffres ci-dessous correspondent aux estimations faites au moment de l’évaluation ; les prix des services cloud varient, il est donc conseillé de consulter les listes de prix actuelles avant de s’y fier.
- Google Cloud Vision avec
DOCUMENT_TEXT_DETECTION. Il restitue du texte brut accompagné de coordonnées, sans champs structurés. Au prix d’environ 1,50 $ pour 1 000 pages, cela représente roughly 45 $ par mois.
Interpréter correctement les chiffres
L’API Vision semble bon marché, mais elle résout un problème différent. Elle indique que les caractères « 13,2 » apparaissent à certaines coordonnées ; elle ignore complètement qu’il s’agit d’une valeur de glycémie. Vous devrez néanmoins créer vous-même toute la couche de parsing, ce qui fait que son prix n’est pas comparable à celui des solutions qui renvoient des données structurées.
Document AI fournit bien une structure, mais un coût mensuel d’environ 1 000 à 2 000 dollars représente une dépense variable élevée pour un produit qui n’a pas encore généré de revenus.
Gemini Flash est le concurrent véritablement intéressant. Le tarif basé sur les tokens pour les pages scannées se situe dans la même fourchette que celui du self-hosting, et vous évitez d’avoir à gérer une infrastructure GPU. Alors pourquoi ne pas le choisir ?
Pourquoi le self-hosting reste préférable
Trois arguments ont influencé la décision :
- Plafond de coût. Un nœud dédié coûte le même prix que ce soit pour traiter 5 000 ou 50 000 pages. Une API à tarification par utilisation ne comporte pas de plafond : une augmentation soudaine du trafic, des tentatives répétées ou une importation en masse se reflètent directement sur la facture.
- Isolement des données. Les rapports médicaux contiennent des informations de santé protégées. En effectuant l’extraction au sein du réseau privé de l’équipe, les documents des patients ne sont jamais envoyés à une API tierce à chaque téléchargement, ce qui évite toute problématique liée au respect des réglementations et aux audits fournisseurs, domaines pour lesquels une équipe MVP dispose de peu de ressources.
- Aucune quota externe ni latence. Il n’y a pas de limites de vitesse, de niveaux de concurrence ni d’intermédiaires réseau supplémentaires sur le parcours critique.
En conséquence, les options Google Cloud et Vertex AI ont été abandonnées au profit d’une solution entièrement auto-hébergée.
Il est utile de considérer également l’autre aspect. Le coût d’un serveur fixe n’est prévisible que jusqu’à la capacité de traitement d’une seule machine ; au-delà, vous devez acquérir plus de matériel et gérer vous-même la planification des capacités ainsi que le temps de disponibilité. L’hébergement auto-géré ne supprime pas non plus les obligations de conformité, car vous restez responsable du stockage, du contrôle d’accès et de l’audit de ces données. Pour une charge de travail modeste et stable avec des données sensibles, l’hébergement auto-géré est généralement préférable ; pour un volume en forte croissance avec une équipe dépourvue de capacités opérationnelles, une API gérée peut être le meilleur choix.
Décision 3 : Éviter les bibliothèques OCR traditionnelles
Les moteurs open source tels que PaddleOCR et Docling sont capables de le faire, mais leurs résultats sont conçus pour l’affichage. Le contenu est généralement encadré dans des balises de mise en page ou formaté en Markdown afin d’être bien affiché dans une interface utilisateur ou un document HTML. Cela est idéal lorsque quelqu’un va lire le résultat, mais gênant lorsque du code a besoin d’extraire « Hémoglobine : 13,2 g/dL » sous forme de champ propre.
Compléter cette lacune constitue à lui seul un projet. Il faudrait extraire des valeurs de la structure des balises, procéder à de nombreuses tentatives et erreurs pour gérer les différents laboratoires et formats de rapports, et il est probable d’ajouter des étapes de prétraitement ou de post-traitement avec OpenCV pour les tableaux et les régions que le moteur n’a pas segmentés correctement. Tout cela s’ajoute au travail déjà requis pour intégrer et héberger le moteur d’OCR. Pour un MVP, il s’agit d’une charge de travail importante pour quelque chose qui relève de l’infrastructure plutôt que du produit lui-même.
Une mise en garde mérite d’être soulignée : cette évaluation reflète l’appréciation de l’équipe, et non un jugement définitif sur ces outils. Les ingénieurs ayant une expérience plus approfondie avec PaddleOCR ou Docling connaissent peut-être des méthodes plus rapides pour obtenir des champs propres à partir de leurs sorties structurées, et comme ces projets évoluent rapidement, il est utile de vérifier à nouveau leurs formats de sortie actuels.
Décision 4 : Un modèle de langage visuel auto-hébergé, adapté au budget
Extraction du sens plutôt que des caractères
L’alternative à « OCR, puis création d’un analyseur pour les résultats de l’OCR » consiste à faire effectuer ces deux étapes en même temps par un modèle de langage capable de comprendre l’image. L’OCR classique reconnaît les caractères. Un modèle de langage visuel, doté d’une instruction bien structurée, peut examiner la page scannée et retourner directement les champs paramètre, valeur et unité, en évitant l’étape intermédiaire de traitement de Markdown annoté.
Ici, la capacité visuelle est essentielle, et non une mise à niveau optionnelle. Un modèle ne contenant que du texte ne peut pas aider avec une image scannée, car il n’y a pas encore de texte à analyser. Le modèle doit donc lire les pixels lui-même.
Cette approche présente ses propres risques, et il est judicieux de planifier des mesures pour y faire face dès le premier jour. Les modèles de langage peuvent interpréter incorrectement les chiffres ou générer des valeurs plausibles qui ne figurent pas sur la page ; en particulier, les modèles plus petits ne restituent pas toujours exactement la structure JSON demandée. Pour les données de santé, cela justifie une analyse défensive de la réponse du modèle, une validation des valeurs par rapport aux types et plages attendus, ainsi qu’un moyen permettant aux utilisateurs ou aux cliniciens de consulter et de corriger le document source.
Choisir un modèle que vous pouvez réellement exécuter
Le choix du modèle a suivi la même logique budgétaire. Les modèles plus gros de Qwen capables de gérer des images sont performants, mais héberger un tel modèle nécessite plus de VRAM et de puissance de calcul que ce qui était raisonnable pour l’infrastructure pour laquelle l’équipe dépensait de l’argent provenant du budget MVP. Le choix s’est porté sur MiniCPM-V : un modèle bien plus petit que Ollama peut exécuter sur du matériel peu coûteux sans difficulté, tout en étant suffisamment performant pour une extraction structurée des images de rapports de laboratoire.
Si vous reproduisez cette étude, testez les modèles candidats sur un échantillon représentatif de vos documents réels, y compris des photos floues prises avec un téléphone et des agencements de laboratoire atypiques, plutôt que de vous fier uniquement aux classements. Le meilleur modèle en théorie est inutile si vous n’avez pas les moyens de le faire fonctionner.
Ce dont l’implémentation a besoin ensuite
L’architecture présentée ci-dessus définit ce qui est exécuté ; le pipeline de production doit encore gérer comment. Les étapes suivantes consistent à convertir les PDF en images que le modèle peut lire, à structurer la requête et l’instruction de l’API Ollama, à parser le JSON de manière prudente lorsque un petit modèle s’écarte du format requis, ainsi qu’à utiliser Redis Streams dans le processus Go afin que les rapports soient traités de manière fiable à mesure que le volume augmente.
Points clés
- Définissez la sortie souhaitée (ici : nom, valeur, unité, plage de référence) avant de comparer les outils ; le texte OCR brut et les données structurées sont des produits distincts avec des prix différents.
- Choisissez le langage du processus pour l’ensemble du système, et non celui qui dispose de la bibliothèque la plus riche pour un seul composant.
- Comparez les options cloud en fonction d’une sortie équivalente, puis évaluez les plafonds de coût, l’isolation des données et les quotas en plus du prix affiché.