OCR w 2026 roku: klasyczne pipeline’y, VLM-y i Document AI
Tłumaczenie automatyczne Ten artykuł został automatycznie przetłumaczony z angielskiego oryginału.
Aktualizacja artykułu
Pierwotnie opublikowano 4 marca 2026 roku. Zrecenzowano i zaktualizowano 6 września 2026 roku. Aktualizacja obejmuje nowszych kandydatów w dziedzinie OCR i modeli wizyjnych, odnośniki do benchmarków oraz wskazówki dotyczące interpretacji wyników ekstrakcji dokumentów.
Rankingi OCR są rozbieżne, ponieważ testują różne dokumenty, dane wyjściowe i metody oceny. Tabela wersjonowanego benchmarku OmniDocBench oraz bieżące głosy preferencji w OCR Arena mogą prowadzić do innych kolejności; wyników tych nie można bezpośrednio porównywać, ale sama rozbieżność jest użyteczna. Wybór rozwiązania produkcyjnego wymaga dokumentów i metryk pochodzących z rzeczywistego workloadu.
Modele vision-language (VLM) radzą sobie z układem, odręcznym pismem, tabelami i obrazami o obniżonej jakości, które mogą złamać zwykły pipeline rozpoznawania tekstu. Tradycyjne silniki pozostają konkurencyjne w przypadku czystego druku, szczególnie gdy znaczenie mają opóźnienia na CPU i koszt operacyjny. Poniższy stan snapshotu obejmuje PaddleOCR-VL 1.6 oraz dots.mocr, oferujące różne kompromisy w zakresie sprzętu, prywatności i danych wyjściowych. Przed podjęciem aktualnej decyzji sprawdź każdy projekt.
Repozytorium towarzyszące: The OCR Gauntlet zawiera trzy notebooki instruktażowe i pięć pobranych próbek. To demonstracja typu smoke test, a nie zweryfikowany ranking silników. W analizowanej wersji Docling etykiety nie wybierają niezawodnie reklamowanego pipeline’u, odwołania do adnotacji występują w przykładach rozpoznawania paragonów, błędy znikają ze średnich, a żądanie Gemini używa
gemini-2.5-flash, mimo że notebook opisuje je jako Gemini 3 Flash. Wyniki ANLS dla całych stron oraz scenariusze kosztowe również wymagają osobnej interpretacji. Te błędy implementacyjne trzeba naprawić przed wykorzystaniem wyników do wyboru modelu.
Skróconą wersję dotyczącą wyboru modeli znajdziesz w Najlepsze modele OCR w 2026 roku: klasyczny OCR, PaddleOCR-VL, VLM-y.
OCR wyznacza dziś jakość kolejnych etapów
OCR od dawna zasila archiwa, systemy pocztowe, narzędzia dostępności i systemy zarządzania dokumentami. RAG i agenci dokumentowi uwidoczniły jego tryby awarii szerszej grupie inżynierów: model działający downstream nie odzyska tekstu ani struktury tabeli, które zostały odrzucone podczas ekstrakcji.
Jakość wyszukiwania w systemie RAG jest ograniczona jakością OCR. Jeśli ekstrakcja zniekształci tabelę, błędnie odczyta datę albo pominie akapit, późniejsze zmiany chunkingu i embeddingów nie odzyskają brakujących informacji. Takie błędy mogą ukryć klauzulę umowy, zmienić sumę na fakturze albo uszkodzić dokumentację medyczną.
OCR jest więc częścią infrastruktury wyszukiwania i agentów, podobnie jak parsowanie, chunking, embedding i indeksowanie. Jego błędy wymagają osobnej ewaluacji, zamiast wchłaniania ich do jednego wyniku end-to-end.
Co oznacza OCR w epoce foundation models
OCR konwertuje tekst z obrazu na znaki możliwe do odczytu maszynowego. Document AI to szerszy system obejmujący analizę układu, parsowanie tabel i wzorów, ekstrakcję pól, rozumowanie semantyczne, proweniencję i walidację. W niektórych publikacjach określenie „OCR-2.0” odnosi się do modeli end-to-end łączących kilka z tych etapów, ale etykieta ta nie powinna zacierać różnicy między rozpoznawaniem a rozumieniem dokumentu.
Tradycyjny pipeline OCR składa się z trzech głównych etapów:
- Detekcja tekstu: lokalizacja obszarów zawierających tekst (np. CRAFT, DBNet).
- Rozpoznawanie tekstu: konwersja wykrytych obszarów na sekwencje znaków (np. CRNN).
- Post-processing: sprawdzanie pisowni i korekta z użyciem modelu językowego.
Takie podejście dobrze działa w przypadku czystych dokumentów, ale błędy detekcji, rozpoznawania i post-processingu mogą się kumulować. Mierz zarówno dokładność znakową, jak i dokładność pól downstream, aby czytelna strona nie ukrywała błędnej sumy lub identyfikatora.
Niektóre ścieżki end-to-end VLM łączą większą część tego pipeline’u w encoderze wizyjnym i decoderze językowym. Modele takie jak GOT-OCR 2.0 mogą generować jednocześnie tekst i strukturę, a ogólne VLM-y mogą także mapować pola do żądanego schematu. Kompromisy zależą od workloadu i obejmują opóźnienia, koszt GPU lub API oraz ryzyko wiarygodnie brzmiącego tekstu, którego nie ma na obrazie.
Praktyczne zastrzeżenie: model działający wyłącznie na obrazie potrzebuje zrasteryzowanych stron, podczas gdy usługa przyjmująca PDF może wewnętrznie obsługiwać konwersję. Prostowanie, skalowanie i czyszczenie obrazu to eksperymenty zależne od pipeline’u, a nie obowiązkowe usprawnienia. AWS Textract zaleca zachowanie obsługiwanych danych wejściowych zamiast ich bezkrytycznej konwersji lub zmniejszania rozdzielczości. Parsowanie i walidacja danych wyjściowych nadal należą do aplikacji.
Co mierzą benchmarki OCR, a czego nie mierzą
Poniższe zbiory danych pokazują, jak zadania OCR prowadzą do różnych metryk. Rozmiary zbiorów i metryki opisują wskazaną wersję datasetu; w przypadku wyników modeli korzystaj z aktualnego leaderboardu danego projektu.
| Dataset | Rok | Rozmiar testu | Języki | Główna metryka |
|---|---|---|---|---|
| FUNSD | 2019 | 50 dokumentów | angielski | F1 |
| SROIE | 2019 | 400 obrazów testowych | angielski | F1 |
| CORD | 2019 | 100 paragonów | indonezyjski | F1 |
| IAM | 1999 | Zależny od podziału | angielski | CER |
| OCRBench v2 | 2024 | 10 000 par QA | EN + CN | wynik /100 |
| OmniDocBench v1.6 | 2026 | 1651 stron | EN + CN | złożona |
Liczba linii w IAM zależy od wybranego podziału według autora i protokołu rozpoznawania; nie przyjęto jednej liczby linii testowych.
Różnica między benchmarkiem a areną
Rankingi automatycznych benchmarków mogą być sprzeczne z preferencjami ludzi, ponieważ różnią się rozkładem danych wejściowych i kryteriami oceny.
W OCR Arena użytkownicy w ciemno głosują na wyniki w pojedynkach head-to-head. Bieżąca kolejność zmienia się wraz z napływem nowych pojedynków, więc nie jest odtwarzalnym historycznym snapshotem benchmarku. Wersjonowana tabela OmniDocBench przedstawiona dalej w artykule odpowiada na inne pytanie, wykorzystując metryki datasetu. Nie łącz tych dwóch leaderboardów w jeden wynik.
Prawdopodobne czynniki obejmują zestaw dokumentów, format danych wyjściowych, zakres języków i kryteria oceny. Opublikowane liczby są przydatne do wstępnej selekcji, ale ostateczny wybór wymaga wydzielonego zbioru danych z docelowego workloadu.
Tradycyjne silniki OCR nadal mają znaczenie
Jeśli tradycyjne silniki są gorsze w przypadku złożonych danych, po co ich używać? Ponieważ są szybkie i tanie dla czystych, ustrukturyzowanych danych.
Tradycyjne silniki są użytecznymi baseline’ami, ponieważ mogą działać lokalnie na CPU. Ich opóźnienie i dokładność zależą od wybranego modelu, rozdzielczości strony, języka, preprocessingu i sprzętu, dlatego należy je benchmarkować na tych samych opisanych stronach, które służą do ewaluacji VLM-ów.
| Silnik | Sposób wdrożenia | Przydatny baseline dla |
|---|---|---|
| Tesseract 5.5 | Lokalny CPU | Czysty druk i ustalone systemy pisma |
| EasyOCR | Lokalny PyTorch na CPU lub GPU | Prototypy i tekst sceniczny |
| PaddleOCR 3.x | Lokalny CPU, GPU i warianty mobilne | Wielojęzyczny OCR i toolchainy wdrożeniowe |
Tesseract dla czystego druku
Tesseract (v5.5.x, Apache 2.0) to dojrzały silnik działający głównie na CPU, wyposażony w ponad 100 pakietów językowych. Dokładność dla czystego druku może być wysoka po odpowiednim rasteryzowaniu i preprocessingu, ale odręczne pismo, tekst sceniczny i złożone układy wymagają osobnych testów. Jego główną zaletą jest niewielkie lokalne wdrożenie na CPU. Eksperymentalna obsługa OpenCL nie potwierdza ogólnej przewagi wydajnościowej.
EasyOCR
EasyOCR łączy detektor CRAFT z recognizerem CRNN. Przy pełnej akceleracji GPU w PyTorch jest szybką opcją do szybkiego prototypowania i tekstu scenicznego.
Snippet wymaga pip install easyocr, PyTorch, pobranych wag modelu EasyOCR oraz lokalnego receipt.jpg. Został sprawdzony składniowo, ale nie był wykonywany przez markdownowy runner repozytorium.
import easyocr
# Three lines for complete OCR
reader = easyocr.Reader(["en"])
result = reader.readtext("receipt.jpg")
# Returns: [(bbox, text, confidence), ...]
PaddleOCR 3
PaddleOCR 3 zawiera utrzymywane pipeline’y OCR, parsowania dokumentów i wdrożeń. Aktualny quick start korzysta z API predict() oraz jawnych ustawień orientacji. Przypnij pakiet paddleocr i wybrany pipeline, ponieważ przykłady z wersji 2.x używające .ocr(..., cls=True) nie odpowiadają API wersji 3.x.
Snippet wymaga pip install "paddleocr>=3,<4", zgodnego runtime’u PaddlePaddle, pobranych wag modelu oraz lokalnego receipt.jpg. Został sprawdzony składniowo, ale nie był wykonywany przez markdownowy runner repozytorium.
from paddleocr import PaddleOCR
ocr = PaddleOCR(
use_doc_orientation_classify=False,
use_doc_unwarping=False,
use_textline_orientation=False,
)
for result in ocr.predict("receipt.jpg"):
result.print()
result.save_to_json("output")
Wyspecjalizowane i ogólne opcje VLM
Krzywe paragony, przekrzywione etykiety produktów, odręczne pismo i gęste układy to obszary, w których wyspecjalizowane lub ogólne VLM-y stają się warte testowania w porównaniu z tradycyjnymi silnikami.
Fala wyspecjalizowanego OCR
Lista modeli w tej sekcji została sprawdzona 6 września 2026 roku. Nie jest to aktualny ranking. Wyspecjalizowane modele do parsowania dokumentów opublikowane w latach 2024–2026 obejmują:
- PaddleOCR-VL 1.6: Dwustopniowy pipeline, który wykonuje analizę układu, a następnie wykorzystuje komponent VLM o rozmiarze 0.9B na wykrytych obszarach. PaddleOCR raportuje obsługę 109 języków i wynik 96.3 w OmniDocBench v1.6; wynik dostawcy należy wiązać z nazwanym pipeline’em i wersją benchmarku.
- dots.mocr (3B): Zmiana marki dots.ocr-1.5 z marca 2026 roku. Model parsuje tekst i ustrukturyzowane grafiki, w tym wariant ukierunkowany na SVG. Oryginalny dots.ocr pozostaje osobnym modelem z 2025 roku.
- GOT-OCR 2.0: Ujednolicony model z 580 mln parametrów, który generuje zwykły tekst oraz sformatowane dane wyjściowe, takie jak Markdown i LaTeX. Oficjalne repozytorium nie publikuje minimalnej wartości VRAM, dlatego zmierz szczytowe zużycie pamięci przy użyciu wybranego runtime’u, precyzji, rozmiaru obrazu i limitu danych wyjściowych.
- DeepSeek-OCR2: Checkpoint opisany w oficjalnym repozytorium w dniu snapshotu, będący następcą oryginalnego modelu DeepSeek-OCR klasy 3B, który wprowadził „kontekstową kompresję optyczną”. Wyniki przepustowości dla obu generacji traktuj jako zależne od sprzętu i datasetu.
- Mistral OCR 4.1 (
mistral-ocr-4-1): Karta modelu datuje wydanie na 16 lipca 2026 roku; changelog odnotowuje ogólną dostępność 31 sierpnia. Model dodaje confidence dla bloków obok ramek akapitów i etykiet strukturalnych. Przed automatyczną akceptacją skalibruj confidence względem poprawności pól. Identyfikator OCR 3 w repozytorium towarzyszącym jest historycznym kontekstem wykonania, a nie aktualnym kandydatem ani ceną. Do porównań przypnij jawną wersję; aliaslatestmoże się zmieniać. - Granite-Docling 258M: Generuje DocTags, które można konwertować do ustrukturyzowanego
DoclingDocument. Pipeline VLM Docling musi zostać wybrany jawnie; domyślny konwerter nie jest dowodem, że uruchomiono ten model. - MinerU i olmOCR: Kandydaci odpowiednio do ustrukturyzowanej konwersji i linearyzacji dokumentów. Sprawdź ich kompletne pipeline’y oraz licencje wybranych modeli. Warunki licencyjne modelu MinerU dodają ograniczenia do bazowej licencji Apache 2.0, więc sama licencja biblioteki nie rozstrzyga praw do wdrożenia.
Frontier VLMs
Ogólne VLM-y są kolejną opcją, gdy zadanie łączy ekstrakcję z rozumowaniem wizualnym lub semantycznym. Kandydatów tych sprawdzono 6 września 2026 roku i wykorzystano w poniższym przykładzie gatewaya. To lista startowa, a nie ranking OCR:
- Gemini 3.8 Flash (Google): Ogólnie dostępny multimodalny model z obsługą obrazów i ustrukturyzowanych danych wyjściowych. Rozpoczynając nowe porównanie, użyj stabilnego ID zamiast starszego przykładu Gemini 3 Flash Preview.
- Claude Sonnet 5 (Anthropic): Nowsza generacja Sonnet do porównań hostowanych. Sprawdź wierność transkrypcji i ekstrakcji pól na własnych dokumentach; ulepszenia ogólnego rozumowania nie potwierdzają dokładności OCR.
- Qwen3.8-27B (Alibaba): Otwarty wagowo vision-language model, który można testować przez gateway lub hostować samodzielnie. Rozmiar 27B oznacza inny wybór wdrożeniowy niż wcześniejszy Qwen3-VL 8B, który pozostaje użytecznym mniejszym baseline’em przy ograniczonej pamięci.
Nowsze wydanie zasługuje na miejsce w zbiorze testowym, ale nie na automatyczny awans do produkcji. Porównuj poprawność pól, abstencję, opóźnienie i koszt każdego zaakceptowanego dokumentu przy tym samym protokole.
Mierz opóźnienie według poziomu
Mierz opóźnienie na stronę przy rzeczywistej rozdzielczości, rozmiarze batcha, sprzęcie lub regionie dostawcy oraz długości danych wyjściowych. Uwzględniaj preprocessing i retry w całkowitym czasie; pomiar samego modelu nie pozwala wycenić poprawnie przetworzonej strony.
Metryki: mierz to, co ma znaczenie
Wybierz metrykę odpowiednią dla typu danych wyjściowych:
- CER i WER dla zwykłego tekstu. Character i Word Error Rate zależą od decyzji dotyczących normalizacji, takich jak wielkość liter, białe znaki i interpunkcja, dlatego przed porównaniem modeli ustal protokół porównawczy.
- Field exact match i Field F1 dla formularzy i paragonów. Exact match jest binarny dla pojedynczego pola; jego wskaźnik to odsetek ocenianych pól, które przeszły test. Osobno raportuj poprawność wszystkich pól na poziomie dokumentu. W przypadku Field F1 zdefiniuj dopasowanie klucz/wartość, normalizację, pola zduplikowane i brakujące oraz sposób agregacji; poprawna kwota przypisana do niewłaściwego wiersza jest błędem.
- TEDS dla tabel. Tree-Edit-Distance-based Similarity porównuje przewidywane i referencyjne drzewa HTML, wykrywając błędy struktury i zawartości komórek, które CER może ukryć.
- Porównanie kolejności czytania, gdy odbiorca potrzebuje jednej sekwencji liniowej. Porównuj bezpośrednio uporządkowane bloki lub spany albo użyj metryki uwzględniającej kolejność; OmniDocBench ocenia kolejność czytania osobno. Poprawne znaki i komórki tabeli nie gwarantują właściwej kolejności na stronie wielokolumnowej.
- ANLS dla document VQA. Average Normalized Levenshtein Similarity ocenia odpowiedzi względem zaakceptowanych referencji. Oryginalna definicja ST-VQA przypisuje
1 − normalized_distancetylko wtedy, gdy odległość jest ściśle mniejsza niż 0,5; w przeciwnym razie wynik wynosi zero. Wykorzystywany jest najlepszy wynik spośród zaakceptowanych referencji, a następnie obliczana jest średnia po pytaniach. DocVQA wykorzystuje ANLS. Przy odtwarzaniu wyniku przypnij normalizację wielkości liter, białych znaków i odległości używaną przez ewaluator. Repozytorium towarzyszące ocenia natomiast ciągi dla całych stron i uwzględnia granicę 0,5, dlatego jego wariant nie jest protokołem benchmarku.
CER/WER zliczają podstawienia, usunięcia i wstawienia podzielone przez liczbę znaków lub słów w referencji. Mogą przekroczyć jeden, gdy dominują wstawienia. Określ, czy agregacja sumuje błędy korpusu i długości referencji, czy uśrednia wyniki dokumentów. Zachowuj stronę, blok, bounding box, oryginalny tekst i historię normalizacji, aby błędne pole można było prześledzić do obrazu.
W implementacjach: jiwer obsługuje CER/WER od ręki, a implementacje TEDS znajdują się w repozytorium OmniDocBench.
Testowanie VLM-ów z OpenRouter
OpenRouter udostępnia zgodny z OpenAI gateway do modeli wielu dostawców. ID modeli i obsługiwane funkcje żądań zmieniają się, dlatego przed uruchomieniem przykładu zweryfikuj je w aktualnym katalogu gatewaya.
Snippet wymaga pip install openai, OPENROUTER_API_KEY, dostępu do sieci, lokalnego receipt.jpg oraz ID modeli nadal obsługiwanych przez OpenRouter. Został sprawdzony składniowo, ale nie był wykonywany przez markdownowy runner repozytorium.
import base64
import os
from openai import OpenAI
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)
def extract_text(image_path: str, model: str) -> str:
with open(image_path, "rb") as f:
image_b64 = base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model=model,
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Extract all text from this image, preserving layout as markdown."},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_b64}"}},
],
}],
max_tokens=4096,
)
choice = response.choices[0]
if choice.finish_reason != "stop":
raise RuntimeError(f"{model} did not finish: {choice.finish_reason}")
if not choice.message.content:
raise RuntimeError(f"{model} returned no text (finish_reason={choice.finish_reason})")
return choice.message.content
# Compare models by changing one string
models = [
"google/gemini-3.8-flash",
"anthropic/claude-sonnet-5",
"qwen/qwen3.8-27b",
]
for model in models:
print(f"\n--- {model} ---\n{extract_text('receipt.jpg', model)[:200]}...")
Katalog modeli OpenRouter wymieniał google/gemini-3.8-flash, anthropic/claude-sonnet-5 i qwen/qwen3.8-27b z obsługą wejścia obrazowego i parametrów ustrukturyzowanych danych wyjściowych 6 września 2026 roku. Obsługa w katalogu nie dowodzi, że dokładnie to żądanie powiedzie się w każdym routowanym endpoincie; na potrzeby tej aktualizacji nie wykonano płatnej inferencji.
W przypadku ustrukturyzowanej ekstrakcji użyj response_format z JSON Schema, gdy wybrany model i gateway to obsługują. Może to zapewnić parsowalność odpowiedzi, ale nie waliduje wyekstrahowanych wartości względem obrazu. W OpenRouter provider.require_parameters powoduje niepowodzenie żądania, gdy żaden routowany endpoint nie obsługuje wszystkich żądanych parametrów, zamiast przełączać się na endpoint, który nie może honorować schematu. Poniższy blok powtarza konfigurację, aby był czytelny niezależnie. Nadal wymaga pip install openai, OPENROUTER_API_KEY, dostępu do sieci, lokalnego receipt.jpg oraz modelu obsługującego JSON Schema; runner repozytorium jedynie sprawdza go składniowo.
import base64
import json
import os
from openai import OpenAI
with open("receipt.jpg", "rb") as f:
image_b64 = base64.b64encode(f.read()).decode()
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)
response = client.chat.completions.create(
model="google/gemini-3.8-flash",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Extract only visible receipt fields. Copy amounts as source strings. Use null for absent or unreadable values; do not infer them. Use null for an unreadable item list, and [] only when no items are present."},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_b64}"}},
],
}],
max_tokens=4096,
response_format={
"type": "json_schema",
"json_schema": {
"name": "receipt",
"strict": True,
"schema": {
"type": "object",
"properties": {
"vendor": {"type": ["string", "null"]},
"date": {"type": ["string", "null"]},
"items": {
"type": ["array", "null"],
"items": {
"type": "object",
"properties": {
"description": {"type": ["string", "null"]},
"amount": {"type": ["string", "null"]},
},
"required": ["description", "amount"],
"additionalProperties": False,
},
},
"total": {"type": ["string", "null"]},
},
"required": ["vendor", "date", "items", "total"],
"additionalProperties": False,
},
},
},
extra_body={"provider": {"require_parameters": True}},
)
def completed_text(response, label: str) -> str:
choice = response.choices[0]
if choice.finish_reason != "stop":
raise RuntimeError(f"{label} did not finish: {choice.finish_reason}")
if not choice.message.content:
raise RuntimeError(
f"{label} returned no text (finish_reason={choice.finish_reason})"
)
return choice.message.content
receipt = json.loads(completed_text(response, "receipt extraction"))
Zachowuj skopiowane ciągi kwot obok znormalizowanych wartości. Pieniądze parsuj downstream z użyciem arytmetyki dziesiętnej lub całkowitoliczbowej w najmniejszych jednostkach, przy jawnie określonej walucie i lokalizacji; poprawność schematu nie waliduje sumy płatności. Krytyczne pola o wartości null kieruj do weryfikacji.
Wyniki benchmarków: co naprawdę pokazują liczby
Poniższa tabela to jeden wersjonowany snapshot: OmniDocBench v1.6_full, oficjalny README w commicie 09ba2b606662695b16aafe5f5e36b7ef020e11a8, opublikowany 10 kwietnia 2026 roku i dostępny 9 sierpnia 2026 roku. Wszystkie cztery wiersze pochodzą z tej przypiętej tabeli. Tabela nie łączy wartości z wcześniejszych tabel w publikacjach ani z innych leaderboardów.
| Model | Rozmiar | Overall ↑ | Text Edit ↓ | Table TEDS ↑ |
|---|---|---|---|---|
| PaddleOCR-VL-1.5 | 0.9B | 94.93 | 0.038 | 91.67 |
| GLM-OCR | 0.9B | 95.22 | 0.044 | 92.83 |
| Gemini 3 Flash | — | 92.62 | 0.066 | 89.29 |
| dots.ocr | 3B | 90.77 | 0.048 | 87.18 |
Wniosek jest ograniczony do tej wersji OmniDocBench: sam rozmiar modelu nie przewiduje wyniku parsowania dokumentów. OmniDocBench odnotował następnie wersję v1.7 i integrację z EvalScope. Zmiany w dopasowaniu predykcji do referencji mogą zmienić wyniki nawet przy identycznych danych wyjściowych modelu. Zachowaj powyższe historyczne wiersze; nowe uruchomienia porównuj wyłącznie przy użyciu jednego przypiętego ewaluatora. Wynik złożony obejmuje odległość edycji tekstu, TEDS dla tabel i CDM dla wzorów; kolejność czytania wymaga osobnego wyniku.
Repozytorium towarzyszące oblicza przykładowe metryki na pięciu próbkach. Przed interpretacją któregokolwiek wiersza jako dowodu porównawczego zweryfikuj tożsamość pipeline’u, referencje rozpoznawania, sposób uwzględniania błędów, nazwy modeli, protokół metryki i założenia kosztowe.
Wdrażanie OCR na produkcji
Warstwowa architektura może oddzielać preprocessing na CPU od inferencji na GPU lub przez API oraz rezerwować kosztowniejsze ścieżki dla dokumentów, które ich wymagają.
Uwaga dotycząca orkiestracji: Narzędzia takie jak Docling mogą koordynować konwersję i przetwarzanie batchowe. Polityka retry nadal należy do otaczającej aplikacji lub usługi, a routing nadal wymaga własnych etykiet jakości i progów.
Warstwowy wzorzec fallbacku
Zacznij od najtańszej ścieżki spełniającej cel jakościowy, a następnie skalibruj routing na opisanych stronach:
- Sprawdź osadzony tekst (Tier 0). W przypadku PDF-ów sprawdź warstwę tekstową za pomocą
PyMuPDFlubpdfplumberprzed rasteryzacją, ale zweryfikuj, czy warstwa jest kompletna i ma poprawną kolejność. - Spróbuj użyć szybkiego modelu. Wykorzystaj tradycyjny silnik dla klas dokumentów, w których osiąga docelową jakość.
- Oceń skalibrowaną confidence. Połącz confidence modelu z klasą dokumentu, krytycznością pola i regułami walidacji.
- Przejdź do silniejszego modelu. Kieruj niepewne strony do wyspecjalizowanego lub ogólnego VLM-u.
- Przekaż awarie wysokiego ryzyka człowiekowi. Weryfikacja człowieka to osobny poziom dla wartości, w przypadku których koszt błędu przewyższa korzyść z automatyzacji.
Uwaga dotycząca confidence: Surowe prawdopodobieństwa znaków nie są automatycznie skalibrowane względem poprawności pól. Poniższa funkcja ważona powierzchnią jest baseline’em do agregacji na poziomie strony, a nie uniwersalnym routerem. Skalibruj ją względem opisanych stron i nadaj krytycznym polom własne reguły, ponieważ średnia dla strony może ukryć błędny identyfikator lub sumę.
def area_weighted_confidence(page):
"""Compute area-weighted confidence from one PaddleOCR 3.x result."""
total_area, weighted_sum = 0, 0
for (x_min, y_min, x_max, y_max), score in zip(
page["rec_boxes"], page["rec_scores"]
):
width = int(x_max) - int(x_min)
height = int(y_max) - int(y_min)
area = width * height
weighted_sum += score * area
total_area += area
return weighted_sum / total_area if total_area > 0 else 0
assert area_weighted_confidence({
"rec_boxes": [[0, 0, 300, 300]], "rec_scores": [0.5]
}) == 0.5
Dla każdej planowanej pary silnik/dokument zachowuj wynik ze statusem success, error lub skipped. Wyniki nieudane, puste i ucięte pozostają w mianowniku próby przetworzenia dokumentu, wraz z poniesionym kosztem. Raportuj completion rate, błędy krytycznych pól wśród automatycznych akceptacji, udział dokumentów skierowanych do weryfikacji, p50/p95 opóźnienia end-to-end oraz koszt każdego pomyślnie przetworzonego dokumentu. Obiekty konwerterów wykorzystuj ponownie dla pomiarów rozgrzanego systemu, a inicjalizację rejestruj osobno.
Analiza kosztów przy dużej skali
Nie istnieje uniwersalny próg break-even zależny od liczby stron, który rozstrzygałby między API a self-hostingiem. Zbuduj porównanie na podstawie tego samego workloadu:
| Składnik kosztu | Ścieżka API | Ścieżka self-hosted |
|---|---|---|
| Inferencja | Aktualna cena za stronę lub token | Godziny GPU przy zmierzonej liczbie stron na godzinę |
| Bezczynna przepustowość | Zwykle uwzględniona po stronie dostawcy | Wykorzystanie i zapas przepustowości |
| Inżynieria | Integracja i monitoring dostawcy | Wdrożenie, aktualizacje, obserwowalność i dyżury |
| Obsługa danych | Transfer, retencja i warunki regionalne | Pamięć masowa, sieć i mechanizmy zgodności |
| Błędy jakościowe | Retry i weryfikacja człowieka | Retry i weryfikacja człowieka |
Użyj wspólnego wzoru: monthly pages × cost per successful page + review cost + fixed operating cost. „Pomyślnie przetworzona strona” musi spełniać te same kryteria tekstu, tabel i pól na obu ścieżkach. Ceny dostawców i wynajem GPU zmieniają się zbyt szybko, aby umieszczać je w trwałej estymacji zakupowej.
Obsługa błędów: problem halucynacji
Błędy VLM-ów mogą być kontekstowo wiarygodne, ale faktycznie niepoprawne. Suma na paragonie „$42.50” może stać się „$45.20”: składniowo poprawna, ale niewykrywalna przez spell-checker.
Przykład syntetycznej awarii: VLM ekstrahuje trzy pozycje z paragonu i podaną sumę, które są ze sobą zgodne, ale jedna cyfra różni się od tej na obrazie. Wewnętrzna arytmetyka przechodzi, mimo że ekstrakcja jest błędna. Dlatego walidacja wymaga etykiet powiązanych z obrazem lub niezależnej ścieżki weryfikacji, a nie wyłącznie testów spójności.
Kilka praktycznych sposobów ograniczania ryzyka:
- Uzgadnianie arytmetyczne. Gdy schemat je udostępnia, zweryfikuj
subtotal + tax + fees + shipping - discounts, w granicach tolerancji zaokrągleń danej waluty, względem podanej sumy. Brakujące składniki lub niezgodności kieruj do weryfikacji. - Kontrole sanityczne oparte na regexach dla dat (bez miesiąca 13), numerów telefonów (poprawna liczba cyfr) i formatów walut.
- Weryfikacja między modelami. Przepuść krytyczne pola przez dwa różne modele i oznacz rozbieżności.
- Niezależna kontrola OCR. Uruchom drugą ścieżkę ekstrakcji dla krytycznych wartości i oznacz rozbieżności. Zgodność zwiększa confidence tylko wtedy, gdy obie ścieżki mają wystarczająco różne tryby awarii; nie jest dowodem poprawności.
Najważniejsze wnioski
- Dopasuj poziom modelu do opisanej klasy dokumentów. Tradycyjne silniki mogą wystarczyć dla czystego tekstu; wyspecjalizowane i ogólne VLM-y powinny uzasadnić dodatkowy koszt na trudniejszych stronach.
- Nie łącz nieporównywalnych leaderboardów. Metryki OmniDocBench i preferencje OCR Arena odpowiadają na różne pytania.
- Kalibruj routing. Progi confidence, klasy dokumentów, krytyczność pól i polityka weryfikacji człowieka powinny być częścią jednej ewaluacji.
- Waliduj wiarygodnie wyglądające dane wyjściowe. Zgodność ze schematem i wewnętrzna arytmetyka nie dowodzą, że dana wartość występuje na obrazie.
- Wyceniaj pomyślnie przetworzone strony. Porównując API z self-hostingiem, uwzględnij retry, weryfikację, koszty stałe operacyjne i kontrole jakości.
Preprocessing i detekcja nadal mają znaczenie, ale produkcyjny OCR wymaga dziś również routingu, ewaluacji dopasowanej do zadania i ochrony przed wiarygodnie wyglądającymi błędami ekstrakcji.
Referencje
- OCR Arena Leaderboard — crowdsourcingowe pojedynki modeli head-to-head
- Repozytorium The OCR Gauntlet — wykonywalne notebooki do porównywania silników OCR, inspekcji danych wyjściowych Docling i szacowania kosztów
- OmniDocBench — ewaluacja end-to-end parsowania dokumentów
- dots.ocr — około 3B parametrów łącznie, w tym model językowy 1.7B
- PaddleOCR — tradycyjny toolkit OCR i modele
- OpenRouter — ujednolicony gateway dostępu do modeli na potrzeby testów A/B