Strona główna
» Domeny
»
Jak zautomatyzować ekstrakcję danych z plików PDF przy użyciu lokalnych modeli AI bez chmurowego API
Jak zautomatyzować ekstrakcję danych z plików PDF przy użyciu lokalnych modeli AI bez chmurowego API
Najbardziej niezawodny lokalny workflow ekstrakcji danych z PDF to zazwyczaj potok, a nie pojedynczy prompt AI: najpierw odzyskaj wiarygodny tekst i układ z pliku PDF, następnie poproś lokalny model o zmapowanie tej zawartości do ścisłego schematu, a na końcu zwaliduj pola przed ich zapisaniem. Wysyłanie każdej strony PDF bezpośrednio do modelu wizyjnego może działać, ale często jest wolniejsze, bardziej wymagające sprzętowo i trudniejsze do audytu niż korzystanie z natywnego tekstu PDF lub OCR, gdy są one wystarczające.
To rozróżnienie ma znaczenie, jeśli Twoim celem jest „brak chmurowego API”. Nadal możesz korzystać z lokalnego API na własnej maszynie – na przykład z punktu końcowego HTTP Ollama na localhost – bez wysyłania zawartości dokumentów do usługi hostowanej. Ollama oświadcza, że prompty i odpowiedzi nie są wysyłane z powrotem do Ollama, gdy modele działają lokalnie, i udostępnia tryb tylko lokalny, który wyłącza funkcje chmurowe. Docling również domyślnie wyłącza usługi zdalne, choć pliki modeli mogą nadal wymagać pobrania podczas konfiguracji, chyba że pobierzesz je z wyprzedzeniem do użytku offline.
Właściwy stos technologiczny zależy od pliku PDF. Faktury urodzone w formie cyfrowej z zaznaczalnym tekstem wymagają innego podejścia niż skanowane paragony, skomplikowane tabele finansowe czy formularze z dużą ilością obrazów. Ten przewodnik porównuje te opcje i przedstawia czterostopniowy wzorzec automatyzacji, który można dostosować do faktur, umów, zamówień, formularzy aplikacyjnych, raportów i innych powtarzalnych dokumentów.
Szybka rekomendacja: wybierz potok w zależności od typu dokumentu
Typ PDF
Praktyczny lokalny potok
Główna zaleta
Główny kompromis
PDF urodzony w formie cyfrowej z czystym, zaznaczalnym tekstem
PyMuPDF → lokalny LLM tekstowy → walidacja JSON
Szybki i względnie lekki dla sprzętu
Zwykła ekstrakcja może utracić kolejność czytania lub relacje tabelaryczne
Zamienia obrazy stron na przeszukiwalny tekst przed ekstrakcją AI
Błędy OCR stają się błędami wejściowymi modelu
Mieszany PDF z tekstem, skanami i tabelami
Docling lub OCRmyPDF w trybie skip/redo → lokalny LLM
Lepsza kontrola nad mieszaną zawartością i strukturą dokumentu
Więcej zależności i czasu przetwarzania
Formularze, tabele, diagramy lub strony o znaczeniu wizualnym z dużym naciskiem na układ
Lokalny potok Docling lub lokalny model wizyjny → wynik strukturalny
Zachowuje więcej kontekstu wizualnego/układu
Zazwyczaj wymaga większej mocy obliczeniowej i silniejszej walidacji
Nie ma uniwersalnego zwycięzcy. Jeśli Twoje dokumenty są przewidywalne i zawierają osadzony tekst, parser plus mały lokalny model językowy może przewyższać znacznie większy workflow wizyjny pod względem kosztów, prędkości i powtarzalności. Jeśli pozycja tekstu jest częścią znaczenia – na przykład tabela z scalonymi komórkami lub formularz, w którym etykiety i wartości są sparowane przestrzennie – przetwarzanie uwzględniające układ staje się bardziej wartościowe.
Krok 1: Klasyfikuj PDF przed wyborem OCR lub AI
Zacznij od ustalenia, czy dokument zawiera już użyteczny tekst. Urodzony w formie cyfrowej oznacza, że PDF został wygenerowany przez oprogramowanie i zazwyczaj zawiera obiekty tekstowe, które można zaznaczyć i skopiować. Skanowany PDF może zawierać tylko obrazy stron, więc zwykły parser tekstu zwróci niewiele lub nic.
Oficjalna dokumentacja PyMuPDF pokazuje bezpośrednią ekstrakcję tekstu za pomocą page.get_text(). Minimalny lokalny test wygląda następująco:
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])
Zobacz oficjalne podstawy PyMuPDF. PyMuPDF ostrzega również, że zwykły tekst PDF może nie pojawiać się w naturalnej kolejności czytania i może zawierać nieoczekiwane podziały linii. Jest to ograniczenie parsera, a niekoniecznie problem AI.
Najlepsze zastosowanie: faktury, wyciągi, raporty i formularze, w których kopiowanie/wklejanie tekstu już działa, a pola są łatwe do zidentyfikowania na podstawie pobliskich etykiet.
Uwaga: strona może zawierać bardzo małą warstwę tekstową plus duży skanowany obraz. Samo sprawdzenie, czy „jakiś tekst istnieje”, nie jest więc idealnym detektorem skanów. Do automatyzacji produkcyjnej sprawdzaj reprezentatywne dokumenty, zamiast polegać na jednym uniwersalnym progu liczby znaków.
Działanie: weź 20–50 reprezentatywnych plików PDF i sklasyfikuj je w grupy: urodzone w formie cyfrowej, skanowane, mieszane i z dużym naciskiem na układ. Twój potok powinien kierować ruchem w zależności od zachowania dokumentu, a nie tylko rozszerzenia pliku.
Ilustracja wygenerowana przez AI etapu wejścia PDF. Jest to koncepcyjny obraz workflow, a nie zrzut ekranu konkretnej aplikacji PDF ani wynik benchmarku.
Krok 2: Ekstrahuj tekst lokalnie – lub używaj OCR tylko wtedy, gdy jest to konieczne
Opcja A: PyMuPDF dla czystych cyfrowych PDF
Jeśli warstwa tekstowa jest niezawodna, bezpośrednia ekstrakcja jest zazwyczaj najprostszą drogą. Unikasz opóźnień OCR i unikasz wprowadzania błędów znaków OCR do tekstu, który był już poprawnie zakodowany. Dla długich dokumentów możesz zachować separatory stron i przetwarzać grupy stron lub logiczne sekcje, zamiast przekazywać cały dokument do modelu naraz.
Kompromis: zwykły tekst jest tani i szybki, ale tabele, strony wielokolumnowe, nagłówki, stopki i kolejność czytania mogą wymagać dodatkowej obsługi. Jeśli te relacje mają znaczenie dla docelowych pól, przejdź do reprezentacji uwzględniającej układ, zamiast nakładać instrukcje promptu na słaby tekst źródłowy.
Opcja B: OCRmyPDF plus Tesseract dla skanowanych stron
Tesseract to silnik OCR open-source. Jego obecny podręcznik użytkownika dokumentuje serię 5.x i obsługę wielu języków poprzez oddzielne pliki danych treningowych. OCRmyPDF opakowuje OCR wokół przetwarzania specyficznego dla PDF, aby skanowane strony mogły zyskać przeszukiwalną warstwę tekstową.
Dla dokumentu mieszanego, w którym niektóre strony zawierają już tekst, obecne wersje OCRmyPDF obsługują tryb skip:
ocrmypdf --mode skip input.pdf searchable.pdf
Oficjalna zaawansowana dokumentacja OCRmyPDF wyjaśnia, że --mode skip pozostawia strony z istniejącym tekstem bez zmian i wykonuje OCR tylko dla stron, które tego wymagają. Ta sama dokumentacja opisuje redo do zastępowania wykrytego wcześniejszego OCR oraz force do rasteryzacji i OCR wszystkich treści. Używaj force ostrożnie, ponieważ rasteryzacja może odrzucić zalety wektorowe i spłaszczyć interaktywną zawartość.
W przypadku instalacji Tesseract, języków i zachowania wiersza poleceń, użyj oficjalnego podręcznika użytkownika Tesseract. Język OCR ma znaczenie: jeśli Twoje faktury zawierają angielski i niemiecki, na przykład, zainstaluj i skonfiguruj odpowiednie dane językowe, zamiast zakładać, że domyślny model angielski poradzi sobie z oboma równie dobrze.
Opcja C: Docling, gdy struktura ma znaczenie
Docling jest zaprojektowany do konwersji dokumentów z opcjami układu, tabel, OCR i lokalnego przetwarzania wizualno-językowego. Dokumentacja projektu wymienia zaawansowane rozumienie PDF, strukturę tabel, OCR i bezstratne wyjścia w stylu JSON/Markdown, z lokalnym wykonaniem przeznaczonym dla wrażliwych i izolowanych (air-gapped) workflow.
Podstawowa konwersja w Pythonie może być tak mała jak:
Zobacz oficjalny szybki start Docling. Docling obsługuje również lokalne potoki VLM i kilka backendów OCR. Jego zaawansowane opcje wyjaśniają, że wywołania usług zdalnych wymagają wyraźnej zgody, podczas gdy artefakty modeli można pobrać z wyprzedzeniem do użytku offline.
Najlepsze zastosowanie: złożone tabele, nagłówki, raporty wielokolumnowe, mieszane skany lub przypadki, w których chcesz użytecznej reprezentacji dokumentu zamiast zwykłego zrzutu tekstu.
Kompromis: potok jest cięższy niż prosty parser PDF. Używaj go, ponieważ dodatkowa struktura poprawia dokładność ekstrakcji – a nie tylko dlatego, że ma więcej komponentów.
Działanie: wybierz najlżejszą metodę ekstrakcji, która zachowuje informacje potrzebne Twojemu docelowemu schematowi. Nie rób OCR czystego osadzonego tekstu i nie wyrzucaj układu, gdy układ determinuje znaczenie.
Ilustracja wygenerowana przez AI wyboru OCR dla skanów i bezpośredniej ekstrakcji dla PDF urodzonych w formie cyfrowej. Reprezentuje koncepcję decyzji, a nie interfejs rzeczywistej aplikacji OCR.
Krok 3: Zmapuj odzyskaną zawartość do ścisłego schematu za pomocą lokalnego modelu
Gdy masz wiarygodną zawartość źródłową, użyj lokalnego modelu do tego, w czym jest dobry: mapowania semantycznego. Zamiast pytać: „Wyekstrahuj wszystko z tej faktury”, zdefiniuj pola, których naprawdę potrzebujesz.
Na przykład:
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]
Obecna dokumentacja strukturalnych wyników Ollama obsługuje przekazywanie schematu JSON przez pole format i walidację odpowiedzi za pomocą Pydantic. Lokalny wywołanie może wyglądać tak:
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)
To podąża za wzorcem w oficjalnej dokumentacji Structured Outputs Ollama, która zaleca używanie powtarzalnych schematów i niskiej temperatury, takiej jak zero, dla bardziej deterministycznych uzupełnień strukturalnych.
Nazwa modelu powyżej jest przykładem z własnej dokumentacji strukturalnych wyników Ollama, a nie twierdzeniem, że jest to najlepszy model do każdego zadania ekstrakcji. Mniejszy model może być wystarczający dla powtarzalnych faktur z jasnymi etykietami; silniejszy model może pomóc w niejednoznacznych umowach lub niespójnych układach, ale zazwyczaj będzie wymagał więcej pamięci i czasu przetwarzania.
Model tekstowy czy wizyjny?
Używaj modelu tekstowego, gdy wyjście parsera/OCR już zachowuje relacje pól, których potrzebujesz. Używaj lokalnego modelu zdolnego do widzenia, gdy pozycja wizualna jest kluczowa lub konwersja tekstu konsekwentnie traci strukturę. Oficjalna dokumentacja Vision Ollama obsługuje wejścia obrazowe dla lokalnych modeli wizyjnych, a jego funkcja strukturalnych wyników może być łączona z modelami zdolnymi do widzenia.
Jednak renderowanie każdej strony na obraz zmienia kompromis:
trzeba przetworzyć więcej pikseli;
strony o wysokiej rozdzielczości zużywają więcej mocy obliczeniowej i pamięci;
partycjonowanie stron staje się ważne dla długich PDF;
modele wizualne nadal mogą wymyślić pole lub źle odczytać liczbę;
potrzebujesz sposobu na prześledzenie wyekstrahowanych wartości do strony lub regionu źródłowego.
Działanie: zacznij od tekstu parsera/OCR plus lokalny LLM ograniczony schematem. Eskaluj tylko trudne typy stron do lokalnego VLM, zamiast płacić koszt wizji za każdą stronę.
Ilustracja wygenerowana przez AI etapu modelu lokalnego. Nie przedstawia rzeczywistego ekranu Ollama ani nie sugeruje, że model lokalny może wyekstrahować każde pole bez walidacji.
Krok 4: Waliduj przed zapisem do JSON, CSV, Excel lub bazy danych
Poprawny schematowo JSON nie jest automatycznie poprawny faktycznie. Model może wyprodukować poprawne pola z błędnymi wartościami. Ostatni etap powinien zatem wykorzystywać deterministyczne kontrole, gdzie to możliwe.
Dla faktury przydatne kontrole obejmują:
Wymagane pola identyfikacyjne: numer faktury lub nazwa dostawcy muszą być obecne, jeśli Twój workflow tego wymaga.
Analiza dat: parsuj daty ze stałą polityką, zamiast ufać niejednoznacznym ciągom, takim jak 03/04/26.
Arytmetyka: porównaj sumę kwot pozycji z sumą częściową dokumentu w ramach zdefiniowanej tolerancji.
Sumy: zweryfikuj, czy suma częściowa plus podatek i inne opłaty są zgodne z sumą całkowitą.
Waluta: nie zakładaj USD tylko dlatego, że dokument jest w języku angielskim.
Pochodzenie: przechowuj nazwę pliku źródłowego, numer strony, znacznik czasu ekstrakcji i opcjonalnie hash oryginalnego PDF.
Kolejka przeglądowa: kieruj przypadki brakujące, sprzeczne lub o niskiej pewności do przeglądu ludzkiego, zamiast cicho wypełniać wartości.
Podstawowa struktura wsadowa może oddzielić ekstrakcję od walidacji:
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"
)
Funkcje pomocnicze są celowo pozostawione specyficzne dla aplikacji, ponieważ reguły walidacji różnią się dramatycznie między fakturami, umowami, formularzami podatkowymi, raportami laboratoryjnymi i zamówieniami. Uniwersalny walidator stworzyłby fałszywe poczucie bezpieczeństwa.
Jeśli potrzebujesz CSV lub Excela, spłaszczaj tylko te pola, które naprawdę należą do wierszy i kolumn. Dla dokumentów z powtarzającymi się pozycjami często czyściej jest utworzyć jedną tabelę na poziomie dokumentu i drugą tabelę pozycji połączoną identyfikatorem dokumentu, zamiast wymuszać każde pole w jednym szerokim wierszu arkusza kalkulacyjnego.
Działanie: zdefiniuj reguły walidacji przed przetwarzaniem tysięcy plików. Testuj na oznakowanym zestawie próbek i rejestruj dokładność na poziomie pola, a nie tylko „dokumenty przetworzone pomyślnie”.
Ilustracja wygenerowana przez AI lokalnych celów eksportu, takich jak Excel, CSV i JSON. Jest to koncepcyjny punkt końcowy, a nie dowód, że każdy PDF można przekonwertować bez przeglądu.
Praktyczna w pełni lokalna architektura
Dla wielu małych i średnich zadań automatyzacji ten podział odpowiedzialności jest łatwiejszy w utrzymaniu niż model all-in-one:
Ten projekt pozwala wymieniać komponenty niezależnie. Jeśli jakość OCR jest słaba, popraw warstwę OCR bez ponownego trenowania LLM. Jeśli lokalny model jest zbyt wolny, użyj mniejszego bez zmiany parsera PDF. Jeśli faktury jednego dostawcy wymagają specjalnej obsługi tabel, kieruj tylko te pliki przez Docling lub gałąź wizyjną.
Ollama vs. llama.cpp vs. Docling VLM: który lokalny runtime wybrać?
Opcja
Używaj, gdy
Mocna strona
Kompromis
Ollama
Chcesz najłatwiejsze lokalne API modelu i wynik ograniczony schematem
Proste API localhost, strukturalny JSON, obsługa wizji dla kompatybilnych modeli
Abstrakcja daje mniej kontroli nad niskopoziomowym runtime niż goły silnik inferencyjny
llama.cpp
Chcesz bezpośredniej kontroli GGUF, wdrożenia wiersza poleceń lub lekkiego lokalnego serwera
Lokalny CLI/serwer i generowanie ograniczone gramatyką/schematem JSON
Więcej szczegółów modelu/runtime jest Twoją odpowiedzialnością
Docling VLM
Głównym wyzwaniem jest konwersja układu dokumentu, a nie ogólna ekstrakcja w stylu czatu
Dokumentowo-zorientowany lokalny potok VLM z wyjściami w stylu Markdown/HTML/DocTags
Najlepiej myśleć o tym jako o komponencie konwersji dokumentów, a nie zamienniku każdego kroku ekstrakcji reguł biznesowych
Oficjalne repozytorium llama.cpp dokumentuje lokalny llama-server i generowanie ograniczone gramatyką; obecny kod serwera akceptuje również ograniczenia schematu JSON. Dokumentacja Vision Models Docling wymienia opcje lokalnych VLM do konwersji dokumentów.
Nie wybieraj runtime tylko na podstawie rankingu modeli. Dla ekstrakcji z PDF praktyczne miary to dokładność pól, przepustowość na dokument, zużycie pamięci na Twojej maszynie, wskaźnik awarii na Twoich układach, złożoność uruchomienia i łatwość inspekcji błędnych wyników.
Jak utrzymać potok naprawdę lokalny
„Brak chmurowego API” powinno być właściwością wdrożenia, którą można zweryfikować, a nie tylko etykietą marketingową.
Ollama
Oficjalne FAQ Ollama mówi, że lokalne prompty i odpowiedzi nie są wysyłane z powrotem do Ollama. Dokumentuje również ustawienie wyłączenia chmury:
OLLAMA_NO_CLOUD=1
lub równoważne ustawienie serwera disable_ollama_cloud. Lokalny API Ollama działa pod adresem http://localhost:11434 i nie wymaga uwierzytelniania dla dostępu lokalnego, zgodnie z jego dokumentacją uwierzytelniania.
Pamiętaj, że usługa związana z localhost jest różna od tej wystawionej na Twoją sieć LAN. Jeśli zmienisz jej adres bind lub umieścisz za innym serwerem, jesteś odpowiedzialny za kontrolę dostępu.
Docling
Docling utrzymuje użycie usług zdalnych wyłączone domyślnie. Jego dokumentacja rozróżnia również prywatność przetwarzania od pozyskiwania modeli: modele mogą być pobierane przy pierwszym użyciu, chyba że pobierzesz je z wyprzedzeniem. Dla systemu izolowanego (air-gapped) użyj docling-tools models download na podłączonej maszynie stagingowej lub inaczej wstępnie umieść zatwierdzone artefakty modeli, a następnie wskaż środowisku offline ten lokalny katalog artefaktów.
Działanie: przed przetwarzaniem wrażliwych dokumentów zablokuj dostęp do sieci wychodzącej na poziomie systemu operacyjnego lub sieci i uruchom test, monitorując połączenia. Ustawienia aplikacji są przydatne, ale kontrole sieciowe dają niezależną warstwę weryfikacji.
Czego lokalne AI nie rozwiązuje
Uruchamianie lokalnie poprawia opcje kontroli danych, ale nie czyni automatycznie ekstrakcji poprawną, zgodną z przepisami ani bezpieczną. Lokalne pliki nadal mogą wyciekać przez logi debugowania, katalogi tymczasowe, kopie zapasowe, udostępnione foldery, zbyt liberalne usługi lub skopiowane eksporty. Lokalny model może również halucynować wartości dokładnie tak samo jak model hostowany.
Nie używaj modelu jako jedynego weryfikatora dla pól o wysokim wpływie, takich jak numery kont bankowych, instrukcje płatności, daty umów, wartości medyczne lub identyfikatory regulacyjne. Dla nich porównuj z tekstem źródłowym, stosuj walidację deterministyczną i wymagaj przeglądu ludzkiego, gdy pewność jest niewystarczająca.
Jak testować przed automatyzacją całego folderu
Zbuduj mały oznakowany zestaw ewaluacyjny zawierający przypadki, które faktycznie otrzymujesz:
czysty cyfrowy PDF;
skan o niskiej rozdzielczości;
obrócona lub pochylona strona;
wielostronicowa faktura;
tabela rozciągająca się na strony;
brakujące pola opcjonalne;
różne formaty dat i liczb;
przynajmniej jeden celowo trudny dokument.
Dla każdego docelowego pola porównaj wyekstrahowaną wartość z prawdą podstawową (ground truth). Mierz dokładne dopasowanie dla identyfikatorów, tolerancję numeryczną dla kwot i dokładność na poziomie wiersza dla pozycji. Rejestruj również czas przetwarzania i procent dokumentów wysłanych do ręcznego przeglądu.
Jeśli prostsza ścieżka PyMuPDF-plus-LLM osiąga wymaganą dokładność, trzymaj się jej. Jeśli skany są główną przyczyną awarii, popraw OCR. Jeśli relacje tabelaryczne są problemem, przetestuj Docling. Jeśli pola pozycjonowane wizualnie pozostają trudne, kieruj ten podzbiór przez lokalny model wizyjny. Ta stopniowa eskalacja zazwyczaj daje lepszą kontrolę nad prędkością i użyciem sprzętu niż stosowanie najcięższego modelu do każdej strony.
Podsumowanie
Dobry lokalny system ekstrakcji PDF oddziela czytanie dokumentu od ekstrakcji semantycznej. Używaj PyMuPDF, gdy PDF zawiera już dobry tekst; OCRmyPDF/Tesseract, gdy strona jest skanowana; Docling, gdy struktura i tabele mają znaczenie; oraz lokalnego modelu Ollama lub llama.cpp, gdy potrzebujesz elastycznego mapowania do schematu biznesowego. Używaj lokalnej wizji tylko tam, gdzie układ wizualny dodaje informacje, których potok tekstowy nie może wiarygodnie zachować.
Ostatnim wymogiem jest walidacja. Schemat JSON może ograniczyć kształt odpowiedzi modelu, ale nie może udowodnić, że kwota, data, nazwa lub numer konta pasują do źródła. Jeśli zaprojektujesz potok tak, aby niepewne dokumenty były widoczne i możliwe do przeglądu, możesz zautomatyzować dużą część ekstrakcji danych z PDF bez przekazywania dokumentów do chmurowego API – i bez udawania, że lokalne AI eliminuje potrzebę kontroli jakości.