Accueil
» Domaines
»
Comment automatiser l'extraction de données PDF à l'aide de modèles d'IA locaux sans API cloud
Comment automatiser l'extraction de données PDF à l'aide de modèles d'IA locaux sans API cloud
Le flux de travail d'extraction PDF locale le plus fiable est généralement un pipeline, et non une simple invite d'IA : commencez par récupérer un texte et une mise en page fiables du PDF, demandez ensuite à un modèle local de mapper ce contenu vers un schéma strict, et enfin validez les champs avant de les enregistrer. Envoyer chaque page de PDF directement à un modèle de vision peut fonctionner, mais c'est souvent plus lent, plus gourmand en ressources matérielles et plus difficile à auditer que d'utiliser le texte natif du PDF ou l'OCR lorsque ceux-ci sont suffisants.
Cette distinction est importante si votre objectif est « aucune API cloud ». Vous pouvez toujours utiliser une API locale sur votre propre machine—par exemple, le point de terminaison HTTP d'Ollama sur localhost—sans envoyer le contenu des documents à un service hébergé. Ollama déclare que les invites et les réponses ne sont pas renvoyées à Ollama lorsque les modèles s'exécutent localement, et il fournit un mode local uniquement qui désactive les fonctionnalités cloud. Docling désactive également les services distants par défaut, bien que les fichiers de modèle puissent encore devoir être téléchargés lors de la configuration, sauf si vous les préchargez pour une utilisation hors ligne.
La pile technologique appropriée dépend du PDF. Les factures nées numériques avec du texte sélectionnable nécessitent une approche différente des reçus scannés, des tableaux financiers complexes ou des formulaires riches en images. Ce guide compare ces options et propose un modèle d'automatisation en quatre étapes que vous pouvez adapter aux factures, contrats, bons de commande, formulaires de demande, rapports et autres documents récurrents.
Recommandation rapide : choisissez le pipeline selon le type de document
Type de PDF
Pipeline local pratique
Principal avantage
Principal compromis
PDF né numérique avec texte sélectionnable propre
PyMuPDF → LLM texte local → validation JSON
Rapide et relativement léger en ressources matérielles
L'extraction brute peut perdre l'ordre de lecture ou les relations de tableau
PDF scanné avec des pages simples
OCRmyPDF/Tesseract → PyMuPDF → LLM texte local
Transforme les images de page en texte recherchable avant l'extraction par IA
Les erreurs d'OCR deviennent des erreurs d'entrée du modèle
PDF mixte avec texte, scans et tableaux
Docling ou OCRmyPDF en mode skip/redo → LLM local
Meilleur contrôle sur le contenu mixte et la structure du document
Plus de dépendances et de temps de traitement
Formulaires riches en mise en page, tableaux, diagrammes ou pages visuellement significatives
Pipeline local Docling ou modèle de vision local → sortie structurée
Préserve davantage le contexte visuel/de mise en page
Nécessite généralement plus de calculs et une validation plus robuste
Il n'y a pas de gagnant universel. Si vos documents sont prévisibles et contiennent du texte intégré, un analyseur syntaxique associé à un petit modèle de langage local peut surpasser un flux de travail de vision beaucoup plus volumineux en termes de coût, de vitesse et de reproductibilité. Si la position du texte fait partie du sens—par exemple, un tableau avec des cellules fusionnées ou un formulaire où les étiquettes et les valeurs sont spatialement associées—le traitement conscient de la mise en page devient plus précieux.
Étape 1 : Classifiez le PDF avant de choisir l'OCR ou l'IA
Commencez par déterminer si le document contient déjà du texte utilisable. Né numérique signifie que le PDF a été généré par un logiciel et contient généralement des objets texte qui peuvent être sélectionnés et copiés. Un PDF scanné peut ne contenir que des images de page, de sorte qu'un analyseur de texte normal renvoie peu ou pas de contenu.
La documentation officielle de PyMuPDF montre l'extraction directe de texte avec page.get_text(). Un test local minimal ressemble à ceci :
import pymupdf
def extract_native_text(pdf_path: str) -> str:
pages = []
with pymupdf.open(pdf_path) as doc:
for page in doc:
pages.append(page.get_text())
return "\f".join(pages)
text = extract_native_text("invoice.pdf")
print(text[:1000])
Voir les bases officielles de PyMuPDF. PyMuPDF avertit également que le texte PDF brut peut ne pas apparaître dans l'ordre de lecture naturel et peut contenir des sauts de ligne inattendus. C'est une limitation de l'analyseur, pas nécessairement un problème d'IA.
Meilleure adéquation : factures, relevés, rapports et formulaires où la copie/le collage de texte fonctionne déjà et où les champs sont faciles à identifier à partir des étiquettes proches.
Attention : une page peut contenir une minuscule couche de texte ainsi qu'une grande image scannée. Vérifier simplement si « du texte existe » n'est donc pas un détecteur de scan parfait. Pour l'automatisation en production, inspectez des documents représentatifs plutôt que de vous fier à un seul seuil de nombre de caractères universel.
Action : prenez 20 à 50 PDF représentatifs et classez-les en groupes nés numériques, scannés, mixtes et riches en mise en page. Votre pipeline doit router selon le comportement du document, et non seulement selon l'extension de fichier.
Illustration générée par IA de l'étape d'entrée PDF. C'est une image de flux de travail conceptuel, et non une capture d'écran d'une application PDF spécifique ou d'un résultat de benchmark.
Étape 2 : Extrayez le texte localement—ou utilisez l'OCR uniquement si nécessaire
Option A : PyMuPDF pour les PDF numériques propres
Si la couche de texte est fiable, l'extraction directe est normalement la route la plus simple. Elle évite la latence de l'OCR et évite d'introduire des erreurs de caractères OCR dans un texte déjà correctement encodé. Pour les documents longs, vous pouvez conserver les séparateurs de page et traiter des groupes de pages ou des sections logiques plutôt que de passer l'ensemble du document au modèle en une seule fois.
Compromis : le texte brut est bon marché et rapide, mais les tableaux, les pages multi-colonnes, les en-têtes, les pieds de page et l'ordre de lecture peuvent nécessiter un traitement supplémentaire. Si ces relations sont importantes pour les champs cibles, passez à une représentation consciente de la mise en page plutôt que d'empiler des instructions d'invite sur un texte source pauvre.
Option B : OCRmyPDF plus Tesseract pour les pages scannées
Tesseract est un moteur OCR open source. Son manuel d'utilisateur actuel documente la série 5.x et la prise en charge de nombreuses langues via des fichiers de données entraînés séparés. OCRmyPDF enveloppe l'OCR autour du traitement spécifique aux PDF afin que les pages scannées puissent acquérir une couche de texte recherchable.
Pour un document mixte où certaines pages contiennent déjà du texte, les versions actuelles d'OCRmyPDF prennent en charge un mode skip :
ocrmypdf --mode skip input.pdf searchable.pdf
La documentation avancée officielle d'OCRmyPDF explique que --mode skip laisse les pages avec du texte existant intactes et effectue l'OCR sur les pages qui en ont besoin. La même documentation décrit redo pour remplacer l'OCR antérieur détecté et force pour rasteriser et effectuer l'OCR de tout le contenu. Utilisez force avec prudence car la rasterisation peut supprimer les avantages vectoriels et aplatir le contenu interactif.
Pour l'installation de Tesseract, les langues et le comportement en ligne de commande, utilisez le manuel d'utilisateur officiel de Tesseract. La langue de l'OCR est importante : si vos factures contiennent de l'anglais et de l'allemand, par exemple, installez et configurez les données linguistiques appropriées plutôt que de supposer que le modèle anglais par défaut gérera les deux également bien.
Option C : Docling lorsque la structure est importante
Docling est conçu pour la conversion de documents avec des options de mise en page, de tableau, d'OCR et de traitement local de vision-langage. Sa documentation de projet répertorie la compréhension avancée des PDF, la structure des tableaux, l'OCR et les sorties JSON/Markdown sans perte, avec une exécution locale destinée aux flux de travail sensibles et isolés (air-gapped).
Une conversion Python de base peut être aussi petite que :
Voir le démarrage rapide officiel de Docling. Docling prend également en charge les pipelines VLM locaux et plusieurs backends OCR. Ses options avancées expliquent que les appels de services distants nécessitent un opt-in explicite, tandis que les artefacts de modèle peuvent être préchargés pour une utilisation hors ligne.
Meilleure adéquation : tableaux complexes, titres, rapports multi-colonnes, scans mixtes, ou cas où vous souhaitez une représentation de document réutilisable au lieu d'un simple vidage de texte brut.
Compromis : le pipeline est plus lourd qu'un simple analyseur de PDF. Utilisez-le parce que la structure supplémentaire améliore votre précision d'extraction—et non simplement parce qu'il possède plus de composants.
Action : choisissez la méthode d'extraction la plus légère qui préserve les informations dont votre schéma cible a besoin. N'effectuez pas d'OCR sur du texte intégré propre, et ne jetez pas la mise en page lorsque la mise en page détermine le sens.
Illustration générée par IA du choix de l'OCR pour les scans et de l'extraction directe pour les PDF nés numériques. Elle représente le concept de décision plutôt qu'une interface réelle d'application OCR.
Étape 3 : Mappez le contenu récupéré vers un schéma strict avec un modèle local
Une fois que vous avez un contenu source fiable, utilisez le modèle local pour ce qu'il fait bien : le mapping sémantique. Au lieu de demander « Extrayez tout de cette facture », définissez les champs dont vous avez réellement besoin.
Par exemple :
from pydantic import BaseModel
from typing import Optional
class LineItem(BaseModel):
description: str
quantity: Optional[float]
unit_price: Optional[float]
amount: Optional[float]
class Invoice(BaseModel):
invoice_number: Optional[str]
invoice_date: Optional[str]
vendor_name: Optional[str]
currency: Optional[str]
subtotal: Optional[float]
tax: Optional[float]
total: Optional[float]
items: list[LineItem]
La documentation actuelle des sorties structurées d'Ollama prend en charge le passage d'un JSON Schema via le champ format et la validation de la réponse avec Pydantic. Un appel local peut ressembler à ceci :
from ollama import chat
schema = Invoice.model_json_schema()
prompt = f"""
Extract the invoice into the supplied schema.
Rules:
- Use only information present in the source.
- Use null when a field is not found.
- Do not infer missing invoice numbers, dates, tax, or totals.
- Preserve line items individually.
SOURCE:
{text}
"""
response = chat(
model="gpt-oss",
messages=[{"role": "user", "content": prompt}],
format=schema,
options={"temperature": 0},
)
invoice = Invoice.model_validate_json(response.message.content)
Le nom du modèle ci-dessus est un exemple tiré de la propre documentation des sorties structurées d'Ollama, et non une affirmation selon laquelle il s'agit du meilleur modèle pour chaque tâche d'extraction. Un modèle plus petit peut être adéquat pour des factures répétitives avec des étiquettes claires ; un modèle plus puissant peut aider avec des contrats ambigus ou des mises en page incohérentes, mais nécessitera généralement plus de mémoire et de temps de traitement.
Modèle de texte ou modèle de vision ?
Utilisez un modèle de texte lorsque la sortie de l'analyseur/OCR préserve déjà les relations de champs dont vous avez besoin. Utilisez un modèle local capable de vision lorsque la position visuelle est essentielle ou que la conversion de texte perd constamment la structure. La documentation officielle de Vision d'Ollama prend en charge les entrées d'images pour les modèles de vision locaux, et sa fonction de sortie structurée peut être combinée avec des modèles capables de vision.
Cependant, le rendu de chaque page en image modifie le compromis :
plus de pixels doivent être traités ;
les pages haute résolution consomment plus de calculs et de mémoire ;
le regroupement de pages devient important pour les PDF longs ;
les modèles visuels peuvent toujours inventer un champ ou mal lire un nombre ;
vous avez besoin d'un moyen de tracer les valeurs extraites jusqu'à une page ou une région source.
Action : commencez par le texte de l'analyseur/OCR plus un LLM local contraint par un schéma. N'escaladez que les types de pages difficiles vers un VLM local au lieu de payer le coût de la vision pour chaque page.
Illustration générée par IA de l'étape du modèle local. Elle ne représente pas un écran réel d'Ollama et n'implique pas qu'un modèle local peut extraire chaque champ sans validation.
Étape 4 : Validez avant d'écrire du JSON, CSV, Excel ou une base de données
Un JSON valide selon le schéma n'est pas automatiquement factuellement correct. Un modèle peut produire des champs valides avec des valeurs erronées. La dernière étape doit donc utiliser des vérifications déterministes chaque fois que possible.
Pour une facture, les vérifications utiles incluent :
Champs d'identité requis : le numéro de facture ou le nom du fournisseur doit être présent si votre flux de travail en a besoin.
Analyse de date : analysez les dates avec une politique fixe plutôt que de faire confiance à des chaînes ambiguës telles que 03/04/26.
Arithmétique : comparez la somme des montants des lignes avec le sous-total du document dans une tolérance définie.
Totaux : vérifiez si le sous-total plus la taxe et les autres frais sont cohérents avec le total.
Devise : ne supposez pas USD parce que le document est en anglais.
Provenance : stockez le nom du fichier source, le numéro de page, l'horodatage d'extraction et éventuellement un hachage du PDF original.
File d'attente de revue : routez les cas manquants, conflictuels ou de faible confiance pour une revue humaine au lieu de remplir silencieusement des valeurs.
Une structure de lot de base peut séparer l'extraction de la validation :
from pathlib import Path
import json
for pdf_path in Path("inbox").glob("*.pdf"):
source_text = extract_native_text(str(pdf_path))
# If text is unusable, run your OCR or Docling branch here.
record = extract_with_local_model(source_text)
errors = validate_record(record)
if errors:
save_for_review(pdf_path, record, errors)
else:
output = Path("processed") / f"{pdf_path.stem}.json"
output.write_text(
json.dumps(record, ensure_ascii=False, indent=2),
encoding="utf-8"
)
Les fonctions d'aide sont intentionnellement laissées spécifiques à l'application car les règles de validation diffèrent considérablement entre les factures, les contrats, les formulaires fiscaux, les rapports de laboratoire et les bons de commande. Un validateur universel créerait une fausse confiance.
Si vous avez besoin de CSV ou d'Excel, aplatissez uniquement les champs qui appartiennent réellement aux lignes et aux colonnes. Pour les documents avec des lignes répétées, il est souvent plus propre de créer une table au niveau du document et une seconde table de lignes liées par un ID de document plutôt que de forcer chaque champ dans une seule ligne de feuille de calcul large.
Action : définissez les règles de validation avant de traiter des milliers de fichiers. Testez contre un ensemble d'échantillons étiquetés et enregistrez la précision au niveau du champ, et non seulement « documents traités avec succès ».
Illustration générée par IA des cibles d'exportation locales telles que Excel, CSV et JSON. C'est un point de terminaison conceptuel, et non la preuve que chaque PDF peut être converti sans revue.
Une architecture entièrement locale pratique
Pour de nombreux petits et moyens travaux d'automatisation, cette division des responsabilités est plus facile à maintenir qu'un modèle tout-en-un :
Cette conception vous permet de permuter les composants indépendamment. Si la qualité de l'OCR est faible, améliorez la couche OCR sans réentraîner le LLM. Si le modèle local est trop lent, utilisez-en un plus petit sans changer l'analyseur de PDF. Si les factures d'un fournisseur nécessitent un traitement spécial des tableaux, routez uniquement ces fichiers via Docling ou une branche de vision.
Ollama vs. llama.cpp vs. Docling VLM : quel runtime local devriez-vous choisir ?
Option
Utilisez-le lorsque
Force
Compromis
Ollama
Vous souhaitez l'API de modèle local la plus simple et une sortie contrainte par schéma
API localhost simple, JSON structuré, prise en charge de la vision pour les modèles compatibles
L'abstraction vous donne moins de contrôle sur le runtime de bas niveau qu'un moteur d'inférence nu
llama.cpp
Vous souhaitez un contrôle direct GGUF, un déploiement en ligne de commande ou un serveur local léger
CLI/serveur local et génération contrainte par grammaire/schéma JSON
Plus de détails sur le modèle/runtime sont à votre charge
Docling VLM
Votre principal défi est la conversion de la mise en page du document plutôt que l'extraction générale de type chat
Pipeline VLM local axé sur les documents avec des sorties de type Markdown/HTML/DocTags
Mieux considéré comme un composant de conversion de document, et non comme un remplacement pour chaque étape d'extraction de règles métier
Le dépôt officiel de llama.cpp documente un llama-server local et la génération contrainte par grammaire ; le code du serveur actuel accepte également les contraintes de schéma JSON. La documentation des modèles de vision de Docling répertorie les options VLM locales pour la conversion de documents.
Ne sélectionnez pas un runtime uniquement sur la base d'un classement de modèles. Pour l'extraction de PDF, les mesures pratiques sont la précision des champs, le débit par document, l'utilisation de la mémoire sur votre machine, le taux d'échec sur vos mises en page, la complexité de démarrage et la facilité avec laquelle vous pouvez inspecter les résultats erronés.
Comment garder le pipeline véritablement local
« Aucune API cloud » devrait être une propriété de déploiement que vous pouvez vérifier, et non simplement une étiquette marketing.
Ollama
La FAQ officielle d'Ollama indique que les invites et les réponses locales ne sont pas renvoyées à Ollama. Elle documente également un paramètre de désactivation du cloud :
OLLAMA_NO_CLOUD=1
ou le paramètre de serveur équivalent disable_ollama_cloud. L'API locale d'Ollama s'exécute sur http://localhost:11434 et ne nécessite pas d'authentification pour l'accès local, selon sa documentation d'authentification.
Rappelez-vous qu'un service lié à localhost est différent d'un service exposé à votre LAN. Si vous modifiez son adresse de liaison ou le placez derrière un autre serveur, vous êtes responsable du contrôle d'accès.
Docling
Docling garde l'utilisation des services distants désactivée par défaut. Sa documentation distingue également la confidentialité du traitement de l'acquisition des modèles : les modèles peuvent être récupérés lors de la première utilisation sauf si vous les pré-téléchargez. Pour un système isolé (air-gapped), utilisez docling-tools models download sur une machine de staging connectée ou pré-positionnez autrement les artefacts de modèle approuvés, puis pointez l'environnement hors ligne vers ce répertoire d'artefacts local.
Action : avant de traiter des documents sensibles, bloquez l'accès réseau sortant au niveau du système d'exploitation ou du réseau et exécutez un test tout en surveillant les connexions. Les paramètres de l'application sont utiles, mais les contrôles réseau vous donnent une couche de vérification indépendante.
Ce que l'IA locale ne résout pas
L'exécution locale améliore les options de contrôle des données, mais ne rend pas automatiquement l'extraction correcte, conforme ou sécurisée. Les fichiers locaux peuvent toujours fuiter via les journaux de débogage, les répertoires temporaires, les sauvegardes, les dossiers partagés, les services trop permissifs ou les exports copiés. Un modèle local peut également halluciner des valeurs exactement comme un modèle hébergé.
N'utilisez pas le modèle comme seul vérificateur pour les champs à fort impact tels que les numéros de compte bancaire, les instructions de paiement, les dates de contrat, les valeurs médicales ou les identifiants réglementaires. Pour ceux-ci, comparez avec le texte source, appliquez une validation déterministe et exigez une revue humaine lorsque la confiance est insuffisante.
Comment tester avant d'automatiser un dossier entier
Construisez un petit ensemble d'évaluation étiqueté contenant les cas que vous recevez réellement :
PDF numérique propre ;
scan basse résolution ;
page pivotée ou inclinée ;
facture multi-pages ;
tableau s'étendant sur plusieurs pages ;
champs optionnels manquants ;
formats de date et de nombre différents ;
au moins un document délibérément difficile.
Pour chaque champ cible, comparez la valeur extraite avec la vérité terrain. Mesurez la correspondance exacte pour les identifiants, la tolérance numérique pour les montants et la précision au niveau de la ligne pour les lignes de détail. Enregistrez également le temps de traitement et le pourcentage de documents envoyés à la revue manuelle.
Si un chemin plus simple PyMuPDF-plus-LLM atteint votre précision requise, gardez-le. Si les scans sont la principale cause d'échec, améliorez l'OCR. Si les relations de tableaux sont le problème, testez Docling. Si les champs positionnés visuellement restent difficiles, routez ce sous-ensemble via un modèle de vision local. Cette escalade par étapes vous donne généralement un meilleur contrôle sur la vitesse et l'utilisation du matériel que d'appliquer le modèle le plus lourd à chaque page.
En résumé
Un bon système local d'extraction de PDF sépare la lecture de document de l'extraction sémantique. Utilisez PyMuPDF lorsque le PDF contient déjà du bon texte ; OCRmyPDF/Tesseract lorsque la page est scannée ; Docling lorsque la structure et les tableaux sont importants ; et un modèle local Ollama ou llama.cpp lorsque vous avez besoin d'un mapping flexible vers un schéma métier. Utilisez la vision locale uniquement là où la mise en page visuelle ajoute des informations que le pipeline de texte ne peut pas préserver de manière fiable.
La dernière exigence est la validation. Le JSON Schema peut contraindre la forme d'une réponse de modèle, mais il ne peut pas prouver que le montant, la date, le nom ou le numéro de compte correspond à la source. Si vous concevez le pipeline de manière à ce que les documents incertains soient visibles et révisables, vous pouvez automatiser une grande partie de l'extraction de données PDF sans confier les documents à une API cloud—et sans prétendre que l'IA locale supprime le besoin de contrôle qualité.