OCR в 2026 году: классические пайплайны, VLMs и Document AI

Автоматический перевод Эта статья была автоматически переведена с оригинальной английской версии.

Обновление статьи

Изначально опубликовано 4 марта 2026 года. Проверено и обновлено 6 сентября 2026 года. В обновлении добавлены новые кандидаты среди OCR- и vision-моделей, ссылки на бенчмарки и рекомендации по интерпретации результатов извлечения данных из документов.

Рейтинги OCR расходятся, потому что проверяют разные документы, форматы вывода и джаджей. Версионная таблица бенчмарка OmniDocBench и актуальные пользовательские оценки OCR Arena могут давать разный порядок моделей; их баллы нельзя напрямую сравнивать, но само расхождение полезно. Для продакшн-выбора нужны документы и метрики из реального workload.

Vision-language models (VLMs) умеют работать с layout, рукописным текстом, таблицами и повреждёнными изображениями, на которых обычный пайплайн распознавания текста даёт сбой. Классические движки по-прежнему конкурентоспособны на чистой печати, особенно когда важны латентность на CPU и стоимость эксплуатации. Приведённый ниже устаревший срез включает PaddleOCR-VL 1.6 и dots.mocr — с разными компромиссами по железу, приватности и формату вывода. Перед актуальным выбором проверьте каждый проект.

Репозиторий к статье: The OCR Gauntlet содержит три учебных ноутбука и пять скачанных примеров. Это smoke demo, а не подтверждённый рейтинг движков. В проверенной версии Docling-метки ненадёжно выбирают заявленный пайплайн, ссылки на эталонные данные для распознавания чеков включают ключи аннотаций, ошибки исчезают из средних значений, а запрос к Gemini использует gemini-2.5-flash, хотя в ноутбуке он обозначен как Gemini 3 Flash. Его ANLS для страницы целиком и сценарии стоимости также требуют отдельной интерпретации. Перед использованием результатов для выбора модели эти дефекты реализации необходимо исправить.

Компактную версию для выбора модели см. в статье Best OCR Models in 2026: Classical OCR, PaddleOCR-VL, VLMs.

Теперь OCR определяет качество downstream-систем

OCR давно используется в архивах, почтовых системах, инструментах доступности и системах управления документами. RAG и документные агенты сделали его режимы отказа заметными для более широкой группы инженеров: downstream-модель не может восстановить текст или структуру таблицы, которые были потеряны при извлечении.

Как OCR вписывается в современный AI-стек: документы проходят через OCR в RAG-пайплайны, AI-агентов и корпоративных ассистентовКак OCR вписывается в современный AI-стек: документы проходят через OCR в RAG-пайплайны, AI-агентов и корпоративных ассистентов

Качество retrieval в вашей RAG-системе ограничено качеством OCR. Если при извлечении таблица искажена, дата распознана неверно или абзац пропущен, последующие изменения чанкинга и эмбеддингов не смогут восстановить утраченную информацию. Такие ошибки могут скрыть пункт договора, изменить итоговую сумму в счёте или испортить медицинскую запись.

Поэтому OCR — часть инфраструктуры retrieval и агентов наряду с парсингом, чанкингом, эмбеддингами и индексацией. Его ошибки нужно оценивать отдельно, а не поглощать одним сквозным score.

Что означает OCR в эпоху foundation models

OCR преобразует текст на изображении в машиночитаемые символы. Document AI — более широкая система, включающая анализ layout, разбор таблиц и формул, извлечение полей, семантический ризонинг, provenance и валидацию. В некоторых статьях для end-to-end моделей, объединяющих несколько этих этапов, используется термин «OCR-2.0», но он не должен стирать различие между распознаванием и пониманием документов.

Сравнение модульного пайплайна OCR-1.0 (детекция, распознавание, постобработка) с end-to-end VLM-пайплайном, который может объединять детекцию и распознаваниеСравнение модульного пайплайна OCR-1.0 (детекция, распознавание, постобработка) с end-to-end VLM-пайплайном, который может объединять детекцию и распознавание

Классический OCR-пайплайн состоит из трёх основных этапов:

  1. Детекция текста: поиск областей, содержащих текст (например, CRAFT, DBNet).
  2. Распознавание текста: преобразование найденных областей в последовательности символов (например, CRNN).
  3. Постобработка: проверка орфографии и коррекция языковой моделью.

На чистых документах это работает хорошо, но ошибки детекции, распознавания и постобработки могут накапливаться. Измеряйте и точность символов, и точность downstream-полей, чтобы читаемая страница не скрывала неверную сумму или идентификатор.

Некоторые end-to-end VLM-пайплайны объединяют больше этапов в vision encoder и language decoder. Модели вроде GOT-OCR 2.0 могут одновременно выдавать текст и структуру, а general-purpose VLM — сопоставлять поля с заданной схемой. Компромиссы зависят от workload: латентность, стоимость GPU или API и риск получить правдоподобный текст, которого нет на изображении.

Практическая оговорка: image-only модели требуют растеризованных страниц, а сервис, принимающий PDF, может выполнять конвертацию внутри себя. Deskewing, ресайз и очистка — это специфичные для пайплайна эксперименты, а не обязательные улучшения. AWS Textract рекомендует сохранять поддерживаемые входные данные, а не без разбора конвертировать или уменьшать их. Парсинг и валидация вывода по-прежнему относятся к ответственности приложения.

Что измеряют OCR-бенчмарки и что они упускают

Следующие датасеты показывают, как разные OCR-задачи приводят к разным метрикам. Размеры датасетов и метрики относятся к указанной версии датасета; оценки моделей проверяйте в актуальном leaderboard каждого проекта.

ДатасетГодРазмер тестаЯзыкиОсновная метрика
FUNSD201950 документовАнглийскийF1
SROIE2019400 тестовых изображенийАнглийскийF1
CORD2019100 чековИндонезийскийF1
IAM1999Зависит от splitАнглийскийCER
OCRBench v2202410 000 пар QAEN + CNScore /100
OmniDocBench v1.620261 651 страницаEN + CNComposite

Число строк в IAM зависит от выбранного split по авторам и протокола распознавания; здесь не предполагается одно фиксированное число тестовых строк.

Разрыв между «бенчмарком» и «ареной»

Автоматические рейтинги бенчмарков могут расходиться с пользовательскими предпочтениями, поскольку отличаются распределение входных данных и критерии оценки.

В OCR Arena пользователи вслепую голосуют за результаты очных сравнений. Её актуальный порядок меняется по мере появления новых сравнений, поэтому это не воспроизводимый исторический срез бенчмарка. Версионная таблица OmniDocBench далее в статье отвечает на другой вопрос с помощью метрик датасета. Не объединяйте эти два leaderboard в один score.

Вероятные причины расхождений включают состав документов, формат вывода, языковое покрытие и критерии джаджей. Опубликованные числа полезны для первичного отбора, но финальный выбор требует отложенного набора из целевого workload.

Классические OCR-движки: они всё ещё актуальны

Если классические движки хуже работают на сложных данных, зачем их использовать? Потому что на чистых структурированных данных они быстрые и дешёвые.

Классические движки полезны как baseline, поскольку могут работать локально на CPU. Их латентность и точность зависят от выбранной модели, разрешения страницы, языка, препроцессинга и железа, поэтому сравнивайте их на тех же размеченных страницах, что и VLM.

ДвижокДеплойПодходящий baseline для
Tesseract 5.5Локальный CPUЧистого печатного текста и распространённых письменностей
EasyOCRЛокальный PyTorch на CPU или GPUПрототипов и scene text
PaddleOCR 3.xЛокальный CPU, GPU и мобильные вариантыМультиязычного OCR и deployment toolchains

Tesseract для чистой печати

Tesseract (v5.5.x, Apache 2.0) — зрелый, преимущественно CPU-движок со 100+ языковыми пакетами. Точность на чистой печати может быть высокой после корректной растеризации и препроцессинга, но рукописный текст, scene text и сложные layout требуют отдельного тестирования. Главное преимущество — небольшой локальный деплой на CPU. Экспериментальная поддержка OpenCL не доказывает общего преимущества по производительности.

EasyOCR

EasyOCR объединяет детектор CRAFT и распознаватель CRNN. При полной GPU-акселерации через PyTorch это быстрый вариант для быстрого прототипирования и scene text.

Сниппет требует pip install easyocr, PyTorch, скачанных весов модели EasyOCR и локального receipt.jpg. Он проверен на синтаксис, но не выполнялся Markdown-раннером репозитория.

import easyocr

# Three lines for complete OCR
reader = easyocr.Reader(["en"])
result = reader.readtext("receipt.jpg")
# Returns: [(bbox, text, confidence), ...]

PaddleOCR 3

PaddleOCR 3 объединяет поддерживаемые OCR-, document-parsing- и deployment-пайплайны. В текущем quick start используется API predict() и явные настройки ориентации. Зафиксируйте пакет paddleocr и выбранный pipeline, поскольку примеры для 2.x с .ocr(..., cls=True) не соответствуют API 3.x.

Сниппет требует pip install "paddleocr>=3,<4", совместимый рантайм PaddlePaddle, скачанные веса модели и локальный receipt.jpg. Он проверен на синтаксис, но не выполнялся Markdown-раннером репозитория.

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")

Специализированные и general-purpose VLM

Сравнение трёх семейств OCR-деплоя по широте задач; режимы деплоя перечислены отдельно, поскольку любое семейство может работать локально, в self-hosted-режиме или через hosted APIСравнение трёх семейств OCR-деплоя по широте задач; режимы деплоя перечислены отдельно, поскольку любое семейство может работать локально, в self-hosted-режиме или через hosted API

Искривлённые чеки, перекошенные этикетки товаров, рукописный текст и плотные layout — это случаи, в которых специализированные или general-purpose VLM стоит сравнить с классическими движками.

Волна специализированных OCR-моделей

Список моделей в этом разделе проверен 6 сентября 2026 года. Это не актуальный рейтинг. Среди специализированных моделей для разбора документов, опубликованных в 2024–2026 годах:

  • PaddleOCR-VL 1.6: Двухэтапный pipeline, который сначала выполняет анализ layout, а затем использует компонент VLM на 0.9B параметров для найденных областей. PaddleOCR заявляет поддержку 109 языков и результат 96.3 на OmniDocBench v1.6; результат поставщика необходимо связывать с указанным pipeline и версией бенчмарка.
  • dots.mocr (3B): Ребрендинг dots.ocr-1.5 от марта 2026 года, который разбирает текст и структурированную графику, включая вариант, ориентированный на SVG. Исходная dots.ocr остаётся отдельной моделью 2025 года.
  • GOT-OCR 2.0: Унифицированная модель на 580M параметров, выдающая обычный текст и форматированный вывод, например Markdown и LaTeX. В официальном репозитории не указано минимальное значение VRAM, поэтому пиковое потребление памяти нужно измерять с выбранными рантаймом, точностью, размером изображения и лимитом вывода.
  • DeepSeek-OCR2: Чекпоинт, описанный в официальном репозитории на дату среза; он следует за исходной моделью DeepSeek-OCR класса 3B, представившей «contextual optical compression». Показатели throughput для любого из поколений следует считать зависящими от железа и датасета.
  • Mistral OCR 4.1 (mistral-ocr-4-1): В model card дата релиза указана как 16 июля 2026 года; changelog фиксирует general availability 31 августа. Модель добавляет confidence для блоков наряду с боксами абзацев и структурными метками. Перед автоматическим принятием откалибруйте confidence относительно корректности полей. Упоминание OCR 3 в companion — исторический контекст выполнения, а не текущий кандидат или его цена. Для сравнений зафиксируйте явную версию; alias latest может измениться.
  • Granite-Docling 258M: Выдаёт DocTags, которые можно преобразовать в структурированный DoclingDocument. VLM-пайплайн Docling необходимо выбирать явно; конвертер по умолчанию не доказывает, что была запущена именно эта модель.
  • MinerU и olmOCR: Кандидаты соответственно для структурированной конвертации и линеаризации документов. Изучите их полные пайплайны и лицензии выбранных моделей. Условия использования моделей MinerU добавляют ограничения к базе Apache 2.0, поэтому одна лишь лицензия библиотеки не определяет права на деплой.

Frontier VLM

General-purpose VLM — ещё один вариант, когда задача сочетает извлечение данных с визуальным или семантическим ризонингом. Эти кандидаты проверены 6 сентября 2026 года и используются в примере gateway ниже. Это исходный shortlist, а не OCR-рейтинг:

  • Gemini 3.8 Flash (Google): Мультимодальная модель с image input и structured outputs, доступная в general availability. При начале нового сравнения используйте её стабильный ID вместо устаревшего примера Gemini 3 Flash Preview.
  • Claude Sonnet 5 (Anthropic): Новое поколение Sonnet для hosted-сравнения. Проверьте точность транскрипции и извлечения полей на собственных документах; улучшение общего ризонинга не доказывает точность OCR.
  • Qwen3.8-27B (Alibaba): Vision-language model с открытыми весами, которую можно тестировать через gateway или разместить самостоятельно. Размер 27B делает её иным вариантом деплоя по сравнению с более ранней Qwen3-VL 8B, которая остаётся полезным небольшим baseline при ограниченной памяти.

Новый релиз даёт модели место в тестовом наборе, но не автоматический допуск в продакшен. При одном протоколе сравнивайте корректность полей, abstention, латентность и стоимость одного принятого документа.

Измеряйте латентность по tier

Измеряйте латентность страницы при фактических разрешении, batch size, железе или регионе провайдера и длине вывода. Учитывайте препроцессинг и ретраи в общей длительности; время только модели не отражает стоимость успешно обработанной страницы.

Метрики: измеряйте то, что действительно важно

Выбирайте метрику, соответствующую типу вывода:

  • CER и WER для обычного текста. Character и Word Error Rate зависят от правил нормализации — регистра, пробелов и пунктуации, — поэтому перед сравнением моделей зафиксируйте протокол.
  • Field exact match и Field F1 для форм и чеков. Exact match бинарен для одного поля; его значение — доля проверенных полей, прошедших проверку. Отдельно отчитывайтесь о корректности всех полей на уровне документа. Для Field F1 определите сопоставление key/value, нормализацию, дубликаты и пропущенные поля, а также агрегацию; правильная сумма, сопоставленная не той строке, является ошибкой.
  • TEDS для таблиц. Tree-Edit-Distance-based Similarity сравнивает предсказанные и эталонные HTML-деревья, выявляя структурные ошибки и ошибки в содержимом ячеек, которые CER скрывает.
  • Сравнение порядка чтения, когда потребителю нужна одна линейная последовательность. Сравнивайте упорядоченные блоки или спаны напрямую либо используйте метрику, учитывающую порядок; OmniDocBench оценивает порядок чтения отдельно. Корректные символы и ячейки таблицы не доказывают правильный порядок на много-колоночной странице.
  • ANLS для document VQA. Average Normalized Levenshtein Similarity оценивает ответы относительно допустимых эталонов. В исходном определении ST-VQA значение 1 − normalized_distance присваивается только при расстоянии строго меньше 0.5, в противном случае используется ноль; берётся лучший score среди допустимых эталонов, после чего значения усредняются по вопросам. DocVQA использует ANLS. При воспроизведении score зафиксируйте регистр, пробелы и нормализацию расстояния в evaluator. В companion вместо этого оцениваются строки целой страницы и включается граница 0.5, поэтому его вариант не соответствует протоколу бенчмарка.

CER/WER считают замены, удаления и вставки, делённые на число эталонных символов или слов. При большом числе вставок они могут превышать единицу. Укажите, агрегируются ли ошибки и длины эталона по всему корпусу или усредняются document-level scores. Сохраняйте страницу, блок, bounding box, исходный текст и историю нормализации, чтобы неправильное поле можно было отследить до изображения.

Для реализации: jiwer из коробки поддерживает CER/WER, а реализации TEDS находятся в репозитории OmniDocBench.

Тестирование VLM через OpenRouter

OpenRouter предоставляет OpenAI-compatible gateway к моделям нескольких провайдеров. ID моделей и поддерживаемые возможности запросов меняются, поэтому перед запуском примера проверьте их по актуальному каталогу gateway.

Сниппет требует pip install openai, OPENROUTER_API_KEY, доступ в сеть, локальный receipt.jpg и ID моделей, которые по-прежнему поддерживаются OpenRouter. Он проверен на синтаксис, но не выполнялся Markdown-раннером репозитория.

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]}...")

В каталоге моделей OpenRouter на 6 сентября 2026 года для google/gemini-3.8-flash, anthropic/claude-sonnet-5 и qwen/qwen3.8-27b были указаны image input и параметры structured outputs. Поддержка в каталоге не доказывает, что именно этот запрос сработает на каждой маршрутизируемой endpoint; в рамках этого обновления платный инференс не выполнялся.

Для структурированного извлечения используйте response_format с JSON schema, если выбранная модель и gateway это поддерживают. Это может сделать ответ парсибельным, но не проверяет извлечённые значения по изображению. В OpenRouter provider.require_parameters приводит к ошибке, если ни одна маршрутизируемая endpoint не поддерживает все запрошенные параметры, вместо fallback на endpoint, которая не может применить схему. Следующий блок повторяет настройку, чтобы его можно было читать независимо. Он также требует pip install openai, OPENROUTER_API_KEY, доступа в сеть, локального receipt.jpg и модели с поддержкой JSON Schema; раннер репозитория только проверяет его на синтаксис.

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"))

Храните исходные строки с суммами вместе с нормализованными значениями. Выполняйте downstream-парсинг денежных значений с помощью decimal или целочисленной арифметики в минимальных единицах при явно заданных валюте и локали; валидность схемы не подтверждает корректность итоговой суммы. Критические поля со значением null направляйте на проверку.

Результаты бенчмарка: что на самом деле показывают числа

Таблица ниже — один версионный срез: OmniDocBench v1.6_full, официальный README на коммите 09ba2b606662695b16aafe5f5e36b7ef020e11a8, опубликован 10 апреля 2026 года и проверен 9 августа 2026 года. Все четыре строки взяты из этой зафиксированной таблицы. Значения из более ранних таблиц статей и других leaderboard не смешиваются.

МодельРазмерOverall ↑Text Edit ↓Table TEDS ↑
PaddleOCR-VL-1.50.9B94.930.03891.67
GLM-OCR0.9B95.220.04492.83
Gemini 3 Flash92.620.06689.29
dots.ocr3B90.770.04887.18

Вывод ограничен этой версией OmniDocBench: размер модели сам по себе не предсказывает score разбора документов. В OmniDocBench позднее появились v1.7 и интеграция с EvalScope. Изменения в сопоставлении prediction/reference могут изменить score даже при идентичном выводе модели. Сохраняйте приведённые выше исторические строки; новые запуски сравнивайте только с одним зафиксированным evaluator. Composite включает text edit distance, table TEDS и formula CDM; порядок чтения требует отдельного результата.

Companion вычисляет иллюстративные метрики на пяти примерах. Перед интерпретацией любой строки как сравнительного доказательства проверьте идентичность пайплайна, references для распознавания, учёт ошибок, названия моделей, протокол метрик и допущения по стоимости.

Деплой OCR в продакшен

Многоуровневая архитектура позволяет отделить CPU-препроцессинг от GPU- или API-инференса и резервировать дорогие пути для документов, которым они действительно нужны.

Многоуровневая продакшн-архитектура: для PDF сначала проверяется встроенный текстовый слой, а изображения и документы, не прошедшие проверку текста, проходят препроцессинг и последовательно более мощные OCR-пути перед постобработкой и проверкой человекомМногоуровневая продакшн-архитектура: для PDF сначала проверяется встроенный текстовый слой, а изображения и документы, не прошедшие проверку текста, проходят препроцессинг и последовательно более мощные OCR-пути перед постобработкой и проверкой человеком

Об оркестрации: такие инструменты, как Docling, могут координировать конвертацию и пакетную обработку. Политика ретраев по-прежнему относится к окружающему приложению или сервису, а для роутинга нужны собственные quality labels и thresholds.

Паттерн многоуровневого fallback

Начинайте с самого дешёвого пути, который достигает целевого качества, а затем калибруйте роутинг на размеченных страницах:

  1. Проверьте наличие встроенного текста (Tier 0). Для PDF изучите текстовый слой с помощью PyMuPDF или pdfplumber до растеризации, но убедитесь, что слой полный и имеет корректный порядок.
  2. Попробуйте быструю модель. Используйте классический движок для классов документов, на которых он достигает целевого качества.
  3. Оцените откалиброванную уверенность. Объединяйте confidence модели с классом документа, критичностью поля и правилами валидации.
  4. Переключитесь на более сильную модель. Направляйте неуверенные страницы специализированной или general-purpose VLM.
  5. Передайте высокорисковые ошибки человеку. Проверка человеком — отдельный tier для значений, стоимость ошибки в которых выше выгоды автоматизации.

Об уверенности: исходные вероятности символов не являются автоматически откалиброванной оценкой корректности поля. Приведённая ниже функция с учётом площади — baseline для агрегации на уровне страницы, а не универсальный роутер. Калибруйте её на размеченных страницах и задавайте отдельные правила для критических полей, поскольку средняя оценка страницы может скрыть неправильный ID или сумму.

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

Для каждой запланированной пары «движок/документ» сохраняйте результат со статусом success, error или skipped. Ошибочные, пустые и усечённые ответы должны оставаться в знаменателе попыток обработки вместе с потраченной стоимостью. Отчитывайтесь о completion rate, ошибках критических полей среди автоматически принятых результатов, доле ручной проверки, end-to-end латентности p50/p95 и стоимости успешно обработанного документа. Для измерений в тёплом режиме переиспользуйте converter objects, а инициализацию записывайте отдельно.

Анализ стоимости в масштабе

Универсальной точки безубыточности по объёму страниц между API и self-hosting не существует. Стройте сравнение на одном и том же workload:

Компонент стоимостиAPI-путьSelf-hosted-путь
ИнференсТекущая стоимость страницы или токенаGPU-часы при измеренной производительности в страницах/час
Простаивающая ёмкостьОбычно поглощается провайдеромУтилизация и запас ёмкости
ИнжинирингИнтеграция и мониторинг провайдераДеплой, обновления, observability и on-call
Работа с даннымиПередача, хранение и условия регионаХранилище, сеть и compliance-контроли
Ошибки качестваРетраи и ручная проверкаРетраи и ручная проверка

Используйте общую формулу: monthly pages × cost per successful page + review cost + fixed operating cost. «Успешная страница» должна соответствовать одним и тем же критериям по тексту, таблицам и полям в обоих вариантах. Цены провайдеров и аренда GPU меняются слишком быстро, чтобы включать их в долгосрочную оценку закупки.

Обработка ошибок: проблема галлюцинаций

Ошибки VLM могут быть контекстно правдоподобными, но фактически неверными. Итоговая сумма чека “$42.50” может превратиться в “$45.20”: синтаксически корректное значение, незаметное для spell-checker.

Синтетический пример ошибки: VLM извлекает три позиции чека и указанную итоговую сумму, которые согласуются между собой, но одна цифра отличается от изображения. Внутренняя арифметика проходит проверку, хотя извлечение ошибочно. Поэтому валидации нужны labels, grounded в изображении, или независимый путь проверки, а не только проверки согласованности.

Несколько практических мер:

  • Арифметическая сверка. Если схема их предоставляет, проверьте subtotal + tax + fees + shipping - discounts с учётом допустимого округления валюты относительно указанной суммы. Отправляйте на проверку отсутствующие компоненты и несоответствия.
  • Sanity checks с помощью regex для дат (без месяца 13), телефонных номеров (правильное количество цифр) и форматов валют.
  • Кросс-модельная проверка. Прогоняйте критические поля через две разные модели и отмечайте расхождения.
  • Независимая OCR-проверка. Выполняйте второй путь извлечения для критических значений и отмечайте расхождения. Совпадение повышает уверенность только тогда, когда два пути имеют достаточно разные режимы отказа; это не доказательство корректности.

Ключевые выводы

  1. Сопоставляйте tier модели с размеченным классом документов. Для чистого текста может быть достаточно классических движков; специализированные и general-purpose VLM должны оправдать дополнительные затраты на более сложных страницах.
  2. Не объединяйте несопоставимые leaderboard. Метрики OmniDocBench и предпочтения OCR Arena отвечают на разные вопросы.
  3. Калибруйте роутинг. Пороговые значения confidence, классы документов, критичность полей и политика ручной проверки должны оцениваться вместе.
  4. Валидируйте правдоподобный вывод. Соответствие схеме и внутренняя арифметика не доказывают, что значение присутствует на изображении.
  5. Считайте стоимость успешных страниц. При сравнении API и self-hosting учитывайте ретраи, ручную проверку, фиксированные операционные расходы и проверки качества.

Препроцессинг и детекция по-прежнему важны, но продакшн-OCR теперь также требует роутинга, task-specific evaluation и защиты от правдоподобных ошибок извлечения.

Источники

  • OCR Arena Leaderboard — краудсорсинговые очные сравнения моделей
  • Репозиторий The OCR Gauntlet — запускаемые ноутбуки для сравнения OCR-движков, проверки вывода Docling и оценки стоимости
  • OmniDocBench — eval end-to-end разбора документов
  • dots.ocr — около 3B общих параметров, включая языковую модель на 1.7B
  • PaddleOCR — классический OCR toolkit и модели
  • OpenRouter — единый gateway для A/B-тестирования моделей