Acasă
» domenii
»
Cum să automatizezi extragerea datelor din PDF-uri folosind modele AI locale fără API cloud
Cum să automatizezi extragerea datelor din PDF-uri folosind modele AI locale fără API cloud
Cel mai fiabil workflow local de extragere a datelor din PDF este de obicei un pipeline, nu un singur prompt AI: mai întâi recuperează textul și layout-ul de încredere din PDF, apoi cere unui model local să mapeze acel conținut într-o schemă strictă și, în final, validează câmpurile înainte de a le salva. Trimiterea fiecărei pagini PDF direct către un model de viziune poate funcționa, dar este adesea mai lentă, mai intensă din punct de vedere hardware și mai greu de auditat decât utilizarea textului nativ PDF sau a OCR atunci când acestea sunt suficiente.
Această distincție este importantă dacă obiectivul tău este „fără API cloud”. Poți folosi în continuare un API local pe propriul tău calculator—de exemplu, endpoint-ul HTTP al Ollama pe localhost—fără a trimite conținutul documentelor către un serviciu găzduit. Ollama declară că prompturile și răspunsurile nu sunt trimise înapoi către Ollama atunci când modelele rulează local și oferă un mod exclusiv local care dezactivează funcțiile cloud. Docling, de asemenea, menține serviciile de la distanță dezactivate implicit, deși fișierele de model pot necesita încă descărcarea în timpul configurării, dacă nu le preiați pentru utilizare offline.
Stack-ul potrivit depinde de PDF. Facturile generate digital cu text selectabil necesită o abordare diferită față de chitanțele scanate, tabelele financiare complicate sau formularele pline de imagini. Acest ghid compară acele opțiuni și oferă un model de automatizare în patru etape pe care îl poți adapta pentru facturi, contracte, comenzi de cumpărare, formulare de aplicare, rapoarte și alte documente recurente.
Recomandare rapidă: alege pipeline-ul în funcție de tipul de document
Tip PDF
Pipeline local practic
Avantaj principal
Compromis principal
PDF generat digital cu text selectabil curat
PyMuPDF → LLM text local → validare JSON
Rapid și relativ ușor pentru hardware
Extragerea simplă poate pierde ordinea de citire sau relațiile din tabele
PDF scanat cu pagini simple
OCRmyPDF/Tesseract → PyMuPDF → LLM text local
Transformă imaginile paginilor în text căutabil înainte de extragerea AI
Erorile OCR devin erori de intrare pentru model
PDF mixt cu text, scanări și tabele
Docling sau OCRmyPDF în modul skip/redo → LLM local
Control mai bun asupra conținutului mixt și a structurii documentului
Mai multe dependențe și timp de procesare
Formulare cu layout complex, tabele, diagrame sau pagini semnificative vizual
Pipeline local Docling sau model local de viziune → ieșire structurată
Păstrează mai mult context vizual/de layout
Necesită de obicei mai multă putere de calcul și validare mai riguroasă
Nu există un câștigător universal. Dacă documentele tale sunt previzibile și conțin text încorporat, un parser plus un mic model de limbaj local poate depăși un workflow de viziune mult mai mare în ceea ce privește costul, viteza și reproductibilitatea. Dacă poziția textului face parte din sens—de exemplu, un tabel cu celule unite sau un formular unde etichetele și valorile sunt asociate spațial—procesarea conștientă de layout devine mai valoroasă.
Pasul 1: Clasifică PDF-ul înainte de a alege OCR sau AI
Începe prin a determina dacă documentul conține deja text utilizabil. Generat digital înseamnă că PDF-ul a fost generat din software și conține de obicei obiecte de text care pot fi selectate și copiate. Un PDF scanat poate conține doar imagini ale paginilor, astfel încât un parser de text normal returnează puțin sau nimic.
Documentația oficială PyMuPDF arată extragerea directă a textului cu page.get_text(). Un test local minim arată astfel:
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])
Vezi bazele oficiale PyMuPDF. PyMuPDF avertizează, de asemenea, că textul PDF simplu poate să nu apară în ordinea naturală de citire și poate conține întreruperi de linie neașteptate. Aceasta este o limitare a parserului, nu neapărat o problemă de AI.
Cel mai potrivit pentru: facturi, extrase de cont, rapoarte și formulare unde copierea/lipirea textului funcționează deja și câmpurile sunt ușor de identificat din etichetele din apropiere.
Atenție la: o pagină poate conține un strat de text foarte mic plus o imagine scanată mare. Simplul control al existenței „unui text” nu este, prin urmare, un detector perfect de scanare. Pentru automatizare în producție, inspectează documente reprezentative în loc să te bazezi pe un singur prag universal de număr de caractere.
Acțiune: ia 20–50 de PDF-uri reprezentative și clasifică-le în grupuri generate digital, scanate, mixte și cu layout complex. Pipeline-ul tău ar trebui să direcționeze în funcție de comportamentul documentului, nu doar de extensia fișierului.
Ilustrație generată de AI a etapei de intrare PDF. Este o imagine conceptuală a workflow-ului, nu o captură de ecran a unei aplicații PDF specifice sau un rezultat de benchmark.
Pasul 2: Extrage textul local—sau folosește OCR doar când ai nevoie
Opțiunea A: PyMuPDF pentru PDF-uri digitale curate
Dacă stratul de text este fiabil, extragerea directă este în mod normal cea mai simplă cale. Aceasta evită latența OCR și evită introducerea erorilor de caractere OCR în textul care a fost deja codat corect. Pentru documente lungi, poți păstra separatorii de pagină și procesa grupuri de pagini sau secțiuni logice în loc să trimiți întregul document modelului deodată.
Compromis: textul simplu este ieftin și rapid, dar tabelele, paginile cu mai multe coloane, antetele, subsolurile și ordinea de citire pot necesita gestionare suplimentară. Dacă acele relații contează pentru câmpurile țintă, treci la o reprezentare conștientă de layout în loc să adaugi instrucțiuni de prompt pe un text sursă slab.
Opțiunea B: OCRmyPDF plus Tesseract pentru pagini scanate
Tesseract este un motor OCR open-source. Manualul său actual pentru utilizatori documentează seria 5.x și suportul pentru multe limbi prin fișiere separate de date antrenate. OCRmyPDF împachetează OCR-ul în jurul procesării specifice PDF-urilor, astfel încât paginile scanate să poată obține un strat de text căutabil.
Pentru un document mixt unde unele pagini conțin deja text, versiunile curente OCRmyPDF suportă un mod skip:
ocrmypdf --mode skip input.pdf searchable.pdf
Documentația avansată oficială OCRmyPDF explică faptul că --mode skip lasă paginile cu text existent neatinsă și aplică OCR paginilor care au nevoie de el. Aceeași documentație descrie redo pentru înlocuirea OCR-ului anterior detectat și force pentru rasterizarea și OCR-ul întregului conținut. Folosește force cu precauție deoarece rasterizarea poate elimina avantajele vectoriale și poate aplana conținutul interactiv.
Pentru instalarea Tesseract, limbi și comportamentul liniei de comandă, folosește manualul oficial al utilizatorului Tesseract. Limba OCR contează: dacă facturile tale conțin engleză și germană, de exemplu, instalează și configurează datele lingvistice corespunzătoare în loc să presupui că modelul implicit în engleză le va gestiona pe ambele la fel de bine.
Opțiunea C: Docling când structura contează
Docling este conceput pentru conversia documentelor cu opțiuni de layout, tabele, OCR și procesare locală de viziune-limbaj. Documentația proiectului listează înțelegerea avansată a PDF-urilor, structura tabelelor, OCR-ul și ieșirile pierdute de tip JSON/Markdown, cu execuție locală destinată workflow-urilor sensibile și izolate (air-gapped).
Vezi ghidul de pornire rapidă oficial Docling. Docling suportă, de asemenea, pipeline-uri VLM locale și mai multe backend-uri OCR. Opțiunile avansate explică faptul că apelurile către servicii de la distanță necesită opt-in explicit, în timp ce artefactele de model pot fi preluare pentru utilizare offline.
Cel mai potrivit pentru: tabele complexe, titluri, rapoarte cu mai multe coloane, scanări mixte sau cazuri în care dorești o reprezentare reutilizabilă a documentului în loc de un dump de text simplu.
Compromis: pipeline-ul este mai greu decât un simplu parser PDF. Folosește-l pentru că structura suplimentară îți îmbunătățește acuratețea extragerii—nu doar pentru că are mai multe componente.
Acțiune: alege cea mai ușoară metodă de extragere care păstrează informațiile de care are nevoie schema ta țintă. Nu aplica OCR pe text încorporat curat și nu arunca layout-ul când layout-ul determină sensul.
Ilustrație generată de AI a alegerii OCR pentru scanări și a extragerii directe pentru PDF-uri generate digital. Reprezintă conceptul decizional, nu interfața unei aplicații OCR reale.
Pasul 3: Mapează conținutul recuperat într-o schemă strictă cu un model local
Odată ce ai conținut sursă de încredere, folosește modelul local pentru ceea ce este bun: maparea semantică. În loc să întrebi „Extrage totul din această factură”, definește câmpurile de care ai nevoie efectiv.
De exemplu:
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]
Documentația actuală a ieșirilor structurate Ollama suportă trecerea unui JSON Schema prin câmpul format și validarea răspunsului cu Pydantic. Un apel local poate arăta astfel:
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)
Aceasta urmează modelul din documentația oficială Structured Outputs a Ollama, care recomandă scheme reutilizabile și o temperatură scăzută, cum ar fi zero, pentru completări structurate mai deterministe.
Numele modelului de mai sus este un exemplu din documentația proprie a Ollama pentru ieșiri structurate, nu o afirmație că este cel mai bun model pentru orice job de extragere. Un model mai mic poate fi adecvat pentru facturi repetitive cu etichete clare; un model mai puternic poate ajuta la contracte ambigue sau layout-uri inconsistente, dar va necesita în general mai multă memorie și timp de procesare.
Model de text sau model de viziune?
Folosește un model de text când ieșirea parserului/OCR păstrează deja relațiile de câmp de care ai nevoie. Folosește un model local capabil de viziune când poziția vizuală este esențială sau conversia de text pierde constant structura. Documentația oficială Vision a Ollama suportă intrări de imagine pentru modele locale de viziune, iar funcția de ieșire structurată poate fi combinată cu modele capabile de viziune.
Cu toate acestea, randarea fiecărei pagini ca imagine schimbă compromisul:
mai mulți pixeli trebuie procesați;
paginile de înaltă rezoluție consumă mai multă putere de calcul și memorie;
batching-ul paginilor devine important pentru PDF-uri lungi;
modelele vizuale pot inventa în continuare un câmp sau pot citi greșit un număr;
ai nevoie de o modalitate de a urmări valorile extrase înapoi la o pagină sau o regiune sursă.
Acțiune: începe cu textul parserului/OCR plus un LLM local constrâns de schemă. Escaladează doar tipurile de pagini dificile către un VLM local în loc să plătești costul viziunii pentru fiecare pagină.
Ilustrație generată de AI a etapei modelului local. Nu reprezintă un ecran Ollama real și nu implică faptul că un model local poate extrage fiecare câmp fără validare.
Pasul 4: Validează înainte de a scrie JSON, CSV, Excel sau o bază de date
Un JSON valid din punct de vedere al schemei nu este automat corect din punct de vedere factual. Un model poate produce câmpuri valide cu valori greșite. Ultima etapă ar trebui, prin urmare, să folosească verificări deterministe oriunde este posibil.
Pentru o factură, verificările utile includ:
Câmpuri de identitate obligatorii: numărul facturii sau numele furnizorului trebuie să fie prezente dacă workflow-ul tău le necesită.
Analiza datei: analizează datele cu o politică fixă în loc să te încrezi în șiruri ambigue cum ar fi 03/04/26.
Arithmetică: compară suma valorilor liniilor de articol cu subtotalul documentului în cadrul unei toleranțe definite.
Totaluri: verifică dacă subtotalul plus taxele și alte taxe este consistent cu totalul.
Moneda: nu presupune USD doar pentru că documentul este în engleză.
Proveniența: stochează numele fișierului sursă, numărul paginii, marcajul temporal al extragerii și opțional un hash al PDF-ului original.
Coadă de revizuire: direcționează cazurile lipsă, conflictuale sau cu încredere scăzută pentru revizuire umană în loc să completezi valorile în tăcere.
O structură de batch de bază poate separa extragerea de validare:
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"
)
Funcțiile helper sunt lăsate intenționat specifice aplicației deoarece regulile de validare diferă dramatic între facturi, contracte, formulare fiscale, rapoarte de laborator și comenzi de cumpărare. Un validator universal ar crea o încredere falsă.
Dacă ai nevoie de CSV sau Excel, aplatizează doar câmpurile care aparțin efectiv rândurilor și coloanelor. Pentru documente cu linii de articol repetate, este adesea mai curat să creezi un tabel la nivel de document și un al doilea tabel de linii de articol legate printr-un ID de document, în loc să forțezi fiecare câmp într-un rând lat de foaie de calcul.
Acțiune: definește regulile de validare înainte de a procesa mii de fișiere. Testează față de un set de eșantion etichetat și înregistrează acuratețea la nivel de câmp, nu doar „documente procesate cu succes”.
Ilustrație generată de AI a țintelor de export local cum ar fi Excel, CSV și JSON. Este un endpoint conceptual, nu o dovadă că fiecare PDF poate fi convertit fără revizuire.
O arhitectură practică complet locală
Pentru multe joburi de automatizare mici și medii, această divizare a responsabilităților este mai ușor de întreținut decât un model all-in-one:
Această design îți permite să schimbi componentele independent. Dacă calitatea OCR este slabă, îmbunătățește stratul OCR fără a reantrena LLM-ul. Dacă modelul local este prea lent, folosește unul mai mic fără a schimba parserul PDF. Dacă facturile unui anumit furnizor necesită gestionare specială a tabelelor, direcționează doar acele fișiere prin Docling sau o ramură de viziune.
Ollama vs. llama.cpp vs. Docling VLM: ce runtime local ar trebui să alegi?
Opțiune
Folosește-l când
Punct forte
Compromis
Ollama
Vrei cea mai ușoară API de model local și ieșire constrânsă de schemă
API localhost simplu, JSON structurat, suport viziune pentru modele compatibile
Abstracția îți oferă mai puțin control la nivel de runtime decât un motor de inferență gol
llama.cpp
Vrei control direct GGUF, deploy pe linia de comandă sau un server local ușor
CLI/server local și generare constrânsă de gramatică/JSON-schema
Mai multe detalii de model/runtime sunt responsabilitatea ta
Docling VLM
Provocarea ta principală este conversia layout-ului documentului, nu extragerea generală de tip chat
Pipeline VLM local axat pe documente cu ieșiri de tip Markdown/HTML/DocTags
Gândește-l mai degrabă ca o componentă de conversie a documentelor, nu ca un înlocuitor pentru fiecare pas de extragere a regulilor de afaceri
Nu selecta un runtime bazat doar pe un leaderboard de modele. Pentru extragerea PDF, măsurile practice sunt acuratețea câmpurilor, throughput-ul per document, utilizarea memoriei pe mașina ta, rata de eșec pe layout-urile tale, complexitatea pornirii și cât de ușor poți inspecta rezultatele greșite.
Cum să menții pipeline-ul cu adevărat local
„Fără API cloud” ar trebui să fie o proprietate de deployment pe care o poți verifica, nu doar o etichetă de marketing.
Ollama
FAQ-ul oficial Ollama spune că prompturile și răspunsurile locale nu sunt trimise înapoi către Ollama. Documentează, de asemenea, o setare de dezactivare a cloud-ului:
OLLAMA_NO_CLOUD=1
sau setarea echivalentă a serverului disable_ollama_cloud. API-ul local Ollama rulează la http://localhost:11434 și nu necesită autentificare pentru acces local, conform documentației de autentificare.
Ține minte că un serviciu legat de localhost este diferit de unul expus către LAN-ul tău. Dacă schimbi adresa de legare sau îl plasezi în spatele unui alt server, ești responsabil pentru controlul accesului.
Docling
Docling menține utilizarea serviciilor de la distanță dezactivată implicit. Documentația sa distinge, de asemenea, confidențialitatea procesării de achiziția modelului: modelele pot fi preluare la prima utilizare dacă nu le pre-descarci. Pentru un sistem izolat (air-gapped), folosește docling-tools models download pe o mașină de staging conectată sau pre-stochează artefactele de model aprobate, apoi îndreaptă mediul offline către acel director local de artefacte.
Acțiune: înainte de a procesa documente sensibile, blochează accesul la rețea la ieșire la nivelul sistemului de operare sau al rețelei și rulează un test în timp ce monitorizezi conexiunile. Setările aplicației sunt utile, dar controalele de rețea îți oferă un strat de verificare independent.
Ce nu rezolvă AI-ul local
Rularea locală îmbunătățește opțiunile de control al datelor, dar nu face automat extragerea corectă, conformă sau securizată. Fișierele locale se pot scurge în continuare prin loguri de debug, directoare temporare, backup-uri, foldere partajate, servicii prea permisive sau exporturi copiate. Un model local poate, de asemenea, să halucineze valori exact ca un model găzduit.
Nu folosi modelul ca singurul verifier pentru câmpuri cu impact mare cum ar fi numerele de cont bancar, instrucțiunile de plată, datele contractuale, valorile medicale sau identificatorii reglementați. Pentru acelea, compară cu textul sursă, aplică validare deterministă și cere revizuire umană când încrederea este insuficientă.
Cum să testezi înainte de a automatiza un întreg folder
Construiește un mic set de evaluare etichetat care conține cazurile pe care le primești efectiv:
PDF digital curat;
scanare de rezoluție scăzută;
pagină rotită sau înclinată;
factură cu mai multe pagini;
tabel care se întinde pe pagini;
câmpuri opționale lipsă;
formate diferite de dată și număr;
cel puțin un document deliberat dificil.
Pentru fiecare câmp țintă, compară valoarea extrasă cu adevărul de bază (ground truth). Măsoară potrivirea exactă pentru identificatori, toleranța numerică pentru sume și acuratețea la nivel de rând pentru liniile de articol. Înregistrează, de asemenea, timpul de procesare și procentul de documente trimise pentru revizuire manuală.
Dacă o cale mai simplă PyMuPDF-plus-LLM atinge acuratețea necesară, păstreaz-o. Dacă scanările sunt eșecul principal, îmbunătățește OCR-ul. Dacă relațiile din tabele sunt problema, testează Docling. Dacă câmpurile poziționate vizual rămân dificile, direcționează acea submulțime printr-un model local de viziune. Această escaladare treptată îți oferă de obicei un control mai bun asupra vitezei și utilizării hardware decât aplicarea celui mai greu model pe fiecare pagină.
Concluzie
Un bun sistem local de extragere PDF separă citirea documentului de extragerea semantică. Folosește PyMuPDF când PDF-ul conține deja text bun; OCRmyPDF/Tesseract când pagina este scanată; Docling când structura și tabelele contează; și un model local Ollama sau llama.cpp când ai nevoie de mapare flexibilă într-o schemă de afaceri. Folosește viziunea locală doar unde layout-ul vizual adaugă informații pe care pipeline-ul de text nu le poate păstra în mod fiabil.
Cerința finală este validarea. JSON Schema poate constrânge forma unui răspuns al modelului, dar nu poate dovedi că suma, data, numele sau numărul de cont se potrivesc cu sursa. Dacă proiectezi pipeline-ul astfel încât documentele incerte să fie vizibile și revizuite, poți automatiza o mare parte din extragerea datelor PDF fără a preda documentele unui API cloud—și fără a pretinde că AI-ul local elimină necesitatea controlului calității.