Donut

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

Рабочий процесс строится вокруг изображения и короткого task prompt. Визуальный кодировщик анализирует всю страницу, текстовый декодер формирует ответ токен за токеном, а служебные маркеры задают требуемую операцию: разбор чека, классификацию, чтение текста либо вопрос к документу. Поэтому один и тот же механизм можно обучить разным схемам данных, не собирая отдельную цепочку из распознавания строк, координат и правил постобработки.

Для быстрого испытания предусмотрен демонстрационный экран Gradio: слева загружается изображение, для DocVQA ниже вводится вопрос, справа появляется структурированный результат. В производственном сценарии те же действия выполняются из Python, где можно заранее нормализовать страницы PDF, запускать пакетную обработку, проверять JSON по схеме и отправлять подтверждённые значения в базу данных.

Скачать Donut

Оценка 9.7 Рекомендуем
  • Редактирование PDF
  • Русский интерфейс
  • Просто новичкам
Скачать бесплатно на Windows
Лучшая альтернатива
Donut
Оценка 8.5
  • Нет PDF-интерфейса
  • Нужна настройка Python
  • Обучение требует GPU
Скачать Donut
Загрузка начнётся после нажатия

Что происходит между изображением и JSON

Donut рассматривает документ не как набор уже найденных строк, а как единую визуальную сцену. Изображение разбивается на участки, преобразуется кодировщиком Swin Transformer в последовательность признаков, а декодер на основе BART использует эти признаки вместе с начальным запросом. Результат похож на текст с открывающими и закрывающими маркерами полей. Встроенный преобразователь разворачивает такую последовательность в словари, списки и строки, поэтому на выходе удобно получить не просто расшифровку страницы, а объект с именами полей, значениями и вложенными группами.

Схема Donut: изображение и запрос преобразуются в последовательность и JSON

Практическое следствие этой архитектуры состоит в том, что порядок и названия выходных полей задаются обучающей разметкой. Если в примерах чеков использовались ключи menu, subtotal и total, модель будет стараться формировать именно такую структуру. Если требуется российская схема с полями продавец, ИНН, дата, позиции и итог, эти ключи нужно последовательно использовать в собственном наборе данных и добавить соответствующие служебные токены. Простая замена названий после обучения не меняет того, чему научился декодер.

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

Демонстрационный экран и первый прогон

В демонстрации для разбора чеков основная область разделена на загрузчик изображения и панель результата. После выбора файла миниатюра появляется слева; кнопка Submit запускает обработку, а справа выводится многострочный JSON-подобный объект. Кнопка Clear очищает текущий пример. Этот экран подходит для проверки совместимости контрольной точки с несколькими документами, но не заменяет очередь заданий, журнал ошибок и проверку обязательных полей.

Демонстрация вопроса к документу с полем question и ответом

Режим DocVQA добавляет поле question. Вопрос должен быть конкретным и относиться к информации, видимой на странице: название, дата, сумма, номер, адрес или подпись. Слишком общий запрос заставляет декодер выбирать ответ без достаточного контекста, а вопрос на другом языке может не совпасть с распределением данных, на которых обучена выбранная контрольная точка. Для повторяемых результатов формулировку и регистр служебных маркеров фиксируют в коде.

Первый тест лучше выполнять на изображении из той же предметной области, что и модель. Контрольная точка для CORD ожидает чек и вложенные позиции меню, DocVQA — пару вопрос–ответ, RVL-CDIP — класс страницы. Если подать договор модели чеков, она не переключится автоматически на извлечение сторон и дат: она попытается заполнить знакомую ей схему и может сгенерировать правдоподобные, но неверные поля.

Как выглядит интерфейс разбора чека

На экране CORD слева виден загруженный чек, справа — древовидная структура с массивом позиций и блоками итогов. Значения количества, названия и цены не выводятся в отдельные карточки; они появляются как результат генерации. Поэтому оператору важно сравнивать не только отдельные цифры, но и целостность структуры: закрыты ли списки, не повторилась ли позиция, присутствуют ли subtotal и total, правильно ли разделены цена и количество.

Экран разбора чека: изображение слева и структурированный результат справа

При ручной проверке полезно начинать с итоговой суммы и числа товарных строк. Если они совпали, затем сверяют налог, скидку, наличные и сдачу. Такое направление проверки быстро выявляет усечение последовательности: при слишком малой максимальной длине начало JSON может быть правильным, а последние поля исчезнут. Увеличивать лимит следует умеренно, потому что длинная генерация расходует больше памяти и времени и повышает вероятность повторов.

Для интеграции интерфейс не требуется: изображение передаётся непосредственно процессору, а предсказание декодируется в строку и преобразуется в объект. Однако демонстрация остаётся полезной диагностикой. Она позволяет отделить проблему модели от ошибки вашего API, сериализации или подготовки файлов: если один и тот же кадр корректно разбирается в Gradio и неверно в собственном коде, проверять нужно prompt, размер изображения, токенизатор и параметры generate.

Как подготовить страницы PDF

Donut принимает изображение страницы, поэтому PDF перед обработкой переводят в растровые кадры. Для одностраничного скана достаточно сохранить страницу в PNG или JPEG. Для многостраничного документа создают отдельный файл на каждую страницу, сохраняют исходный порядок и связывают результаты идентификатором документа. Векторный текст внутри PDF не передаётся модели напрямую: она анализирует визуальный рендер так же, как фотографию или скан.

Пример сложного входного изображения чека с замятиями и слабым контрастом

Разрешение выбирают по самому мелкому значимому шрифту. Слишком низкое DPI превращает тонкие цифры в похожие пятна; чрезмерное разрешение увеличивает время растрирования и всё равно будет приведено процессором к размеру, заданному конфигурацией модели. Практичный подход — отрендерить несколько сложных страниц с разными настройками, оценить читаемость мелких реквизитов и закрепить минимальный режим, при котором символы остаются различимыми.

Перед растрированием следует учитывать поворот страницы, CropBox и MediaBox. Если документ хранит поворот в метаданных, а конвертер его игнорирует, модель получит боковой текст. Если на странице широкие поля или метки сканера, они займут часть доступного изображения и уменьшат полезный шрифт после масштабирования. Поля можно обрезать только по устойчивому правилу: агрессивный кроп способен удалить номер, печать или итог, расположенные возле края.

Выбор контрольной точки под задачу

Базовая контрольная точка содержит общее предварительное обучение, но не знает вашу итоговую схему. Для готового сценария выбирают вариант, дообученный на соответствующей задаче: CORD для чеков, RVL-CDIP для классификации, DocVQA для вопросов к документам, отдельный вариант для китайских железнодорожных билетов. Название задачи в модели важнее внешнего сходства документа: два чека из разных стран могут иметь несовместимые поля и словарь.

При выборе сравнивают четыре характеристики: формат ответа, языки обучающих примеров, тип изображения и размер входа. Формат ответа определяет, что можно получить без дополнительного обучения. Языки влияют на распознавание букв и типографику. Тип изображения показывает, видел ли модель фотографии с перспективой или только ровные сканы. Размер входа определяет, насколько мелкий текст сохранится после подготовки пикселей.

Контрольную точку нельзя оценивать по одному удачному примеру. Соберите небольшой закрытый набор из разных поставщиков, камер, уровней контраста и длины документов. Зафиксируйте ожидаемый JSON и прогоните все варианты одинаковыми параметрами. Такая матрица сразу показывает, где готовая модель пригодна как прототип, а где требуется собственное дообучение или отдельная маршрутизация по типам страниц.

Извлечение позиций, итогов и реквизитов

Для чеков удобна вложенная структура: массив позиций содержит название, количество, цену и при необходимости единицу измерения; отдельные блоки хранят промежуточный итог, скидку, налог, способ оплаты и общий итог. Donut генерирует поля в последовательности, поэтому стабильный порядок ключей в обучающей разметке упрощает обучение и последующее сравнение. Случайное чередование одинаковых полей повышает вариативность ответа без практической пользы.

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

Реквизиты продавца лучше хранить независимо от товарных строк. Название организации, адрес, налоговый номер и дата часто находятся в шапке, где шрифт и выравнивание отличаются от таблицы. Если часть реквизитов отсутствует на документе, в эталонной разметке используют единый подход — пропуск ключа либо пустое значение. Смешивание этих вариантов затрудняет проверку и заставляет модель угадывать, должна ли она генерировать отсутствующее поле.

Вопросы к документу через DocVQA

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

Тестовый рукописный документ для вопросно-ответного режима

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

Наличие нескольких допустимых формулировок ответа отражается в gt_parses. Например, полное название и сокращение могут считаться правильными кандидатами. Во время подготовки данных важно не превращать разные фактические ответы в эквивалентные: если в документе указаны две даты, вопрос должен уточнять, нужна дата выставления, оплаты или доставки. Чем точнее семантика вопроса, тем легче модели и валидатору.

Классификация входящих документов

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

Набор классов должен отражать последующее действие. Категории документ А и документ Б бесполезны, если обе обрабатываются одинаково. Наоборот, визуально похожие страницы стоит разделить, когда для них нужны разные схемы данных или сроки. Для многостраничных файлов дополнительно решают, классифицируется каждая страница или документ целиком; Donut видит один кадр, поэтому итоговый класс файла обычно агрегируют из классов страниц.

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

Псевдочтение текста и предварительное обучение

Задача pseudo text reading формирует объект с полем text_sequence. Она нужна не для воспроизведения координат каждой строки, а для обучения модели сопоставлять визуальные символы с последовательностью текста. В официальной структуре это один из вариантов общей JSON-задачи, поэтому подготовка данных остаётся совместимой с классификацией и извлечением.

Примеры синтетических документов для предварительного обучения

SynthDoG создаёт синтетические страницы с текстом, фонами и разметкой. Такие примеры полезны, когда реальных документов мало или нельзя свободно распространять, но они не заменяют финальную выборку из настоящих сканов. Синтетический генератор должен воспроизводить язык, шрифты, длину строк, расположение блоков, шум и артефакты вашего канала; иначе модель выучит аккуратную искусственную типографику и растеряется на мятых чеках и тенях.

Для русского проекта важно добавить кириллические шрифты и тексты, проверять корректность кодировки и не полагаться только на официальные синтетические языки. Полезно смешивать короткие реквизиты, длинные наименования, числа с запятыми, даты, валютные обозначения и налоговые идентификаторы. После предварительного чтения модель всё равно дообучают на целевой JSON-схеме, потому что простая расшифровка не учит, какое значение относится к какому ключу.

Task prompt и специальные токены

Начальный prompt сообщает декодеру, какую последовательность строить. Для разборов часто применяется маркер вида , для вопросов — конструкция с отдельными маркерами вопроса и ответа. Точное написание, регистр и порядок должны совпадать с обучением. Невидимая на первый взгляд разница между токеном, добавленным в словарь, и обычной строкой способна полностью изменить результат.

При собственной схеме ключи JSON превращаются в служебные маркеры. Функция преобразования обычно открывает поле токеном , записывает значение и закрывает . Вложенный объект раскрывается рекурсивно, список повторяет группу элементов, а специальные значения вроде yes/no могут иметь отдельные токены. Если имя ключа содержит пробелы или нестабильные символы, лучше заранее привести его к однозначному техническому виду.

После добавления токенов размер словаря декодера должен быть синхронизирован с моделью. Иначе новые идентификаторы не получат весов или возникнет ошибка размеров. При загрузке контрольной точки для инференса используют тот же токенизатор, что при обучении. Сохранение только весов без конфигурации, словаря и processor создаёт трудноуловимые расхождения даже при одинаковом коде генерации.

Из последовательности в проверяемый JSON

Сырой ответ содержит токены начала и конца, маркеры неизвестных символов и служебные границы полей. Перед разбором удаляют начало последовательности, padding и конец, затем вызывают преобразование token2json. Получившийся объект следует считать предложением модели, а не гарантированно корректной записью. Его проверяют по JSON Schema или программным правилам до сохранения.

Валидатор контролирует типы и обязательность: сумма должна быть числом после нормализации, дата — допустимой датой, массив позиций — списком объектов, код валюты — значением из разрешённого набора. Преобразование денежных строк выполняют отдельно, потому что в документах встречаются пробелы, точки, запятые и символы валют. Автоматическая замена всех разделителей без учёта локали может превратить 1 234,50 в другое число.

Полезно хранить три уровня результата: исходную сгенерированную строку, разобранный объект и нормализованную бизнес-запись. Тогда при споре можно понять, ошибка возникла в генерации, token2json или последующей очистке. Для аудита также сохраняют идентификатор контрольной точки, параметры генерации, хеш исходного изображения и список сработавших правил.

Структура набора данных

Официальный формат разделяет данные на train, validation и test. В каждой папке находятся изображения и metadata.jsonl. Каждая строка JSON Lines связывает относительный file_name с полем ground_truth, причём ground_truth хранит сериализованную JSON-строку. Внутри неё располагается gt_parse для одного эталона либо gt_parses для нескольких допустимых вариантов.

Разделение выполняют по источнику документа, а не случайно по кадрам. Если фотографии одного и того же шаблона попали и в обучение, и в тест, метрика будет завышена: модель узнает расположение, фон и типографику. Для чеков разумно разделять по магазинам или сериям шаблонов, для счетов — по поставщикам, для форм — по редакциям бланка.

Пути в metadata.jsonl проверяют отдельным скриптом до обучения. Он должен открыть каждое изображение, преобразовать его в RGB, распарсить вложенную строку ground_truth и убедиться, что указан ровно один ожидаемый корневой ключ. Ошибка кавычек или переносов в одной строке способна остановить загрузку далеко после старта, поэтому предварительная проверка экономит время на дорогом GPU.

Как проектировать эталонную схему

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

Ключи выбирают один раз. Пара invoice_date в части примеров и date в других создаёт две конкурирующие команды. Значения приводят только там, где нормализация не уничтожает видимую информацию: дату можно хранить в едином формате, но исходную строку иногда полезно сохранить отдельно. Для сумм решают, включается ли знак валюты, разделитель тысяч и налог.

Вложенность отражает естественную структуру. Табличные позиции удобно хранить списком объектов, адрес — объектом с компонентами только при наличии надёжной разметки, а одиночные реквизиты — строками. Глубоко вложенный JSON удлиняет последовательность и усложняет обучение; если дочерние поля не нужны downstream-системе, лучше не добавлять их ради формальной полноты.

Подготовка изображений

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

Автоповорот выполняют до processor. Ориентацию можно определить по метаданным камеры, простому классификатору угла или нескольким тестовым прогоном. Перспективу фотографии исправляют только при надёжном обнаружении четырёх углов; ошибочная геометрическая коррекция растягивает символы и ухудшает чтение. Тени и неравномерное освещение лучше уменьшать мягкой нормализацией, не превращая серый мелкий текст в белый фон.

JPEG подходит для обычных фотографий, но многократное пересохранение создаёт артефакты вокруг букв. Для промежуточных страниц PDF предпочтителен PNG. Альфа-канал перед подачей убирают, прозрачность сводят на белый фон. Чёрный фон вокруг прозрачного скана меняет визуальное распределение и может занять значительную часть кадра.

Запуск обучения

Официальный сценарий получает YAML-конфигурацию, имя предварительно обученной модели, список наборов данных и идентификатор эксперимента. Конфигурация задаёт размер входа, максимальную длину ответа, число эпох, learning rate, batch size, число workers, warmup и расположение результатов. Перед длинным запуском полезно выполнить несколько шагов на малой выборке и убедиться, что loss уменьшается, контрольные изображения открываются и пример декодируется.

Команда имеет следующий общий вид:

python train.py --config config/train_cord.yaml   --pretrained_model_name_or_path naver-clova-ix/donut-base   --dataset_name_or_paths '["my_dataset"]'   --exp_version receipt_ru

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

Официальный пример обучения CORD рассчитан на мощный графический ускоритель. На более скромной карте уменьшают batch size и используют накопление градиента, но итоговая динамика может отличаться. Смешанная точность экономит память, однако её поддержка зависит от устройства и версий компонентов. Первые эксперименты лучше проводить с небольшим числом образцов, сохраняя воспроизводимые параметры и seed.

Наблюдение за обучением

Главный сигнал — не минимальный train loss, а качество на validation. Если обучающая ошибка падает, а edit distance на проверке перестаёт улучшаться, модель запоминает шаблоны. Сравнивайте предсказания на фиксированном наборе сложных страниц после каждой контрольной точки: числовая метрика может не показать, что модель стала чаще пропускать редкое, но критичное поле.

Панель с loss, edit distance и использованием GPU при обучении Donut

В журнале полезно отслеживать learning rate, время шага, загрузку GPU, выделенную память и долю пропущенных примеров. Резкие пики loss иногда связаны с очень длинной последовательностью или повреждённым изображением. Вместо немедленного удаления такого примера проверьте разметку: длинный реальный чек может быть именно тем случаем, который система обязана выдерживать.

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

Проверка Tree Edit Distance и F1

Для структурированных ответов используется Tree Edit Distance: JSON представляется деревом, и метрика оценивает, насколько предсказанная структура отличается от эталона. Она чувствительна не только к тексту, но и к расположению ключей, списков и вложенных объектов. Это лучше простой посимвольной точности, когда одна пропущенная скобка иначе сдвинула бы всё сравнение.

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

Кроме общей метрики рассчитывают точность критичных полей: итоговая сумма, дата, номер документа, налоговый идентификатор. Для массивов позиций отдельно измеряют полноту строк и точность значений. Итоговый порог запуска в производство выбирают по стоимости ошибок: пропущенный комментарий и неверная сумма имеют разный риск, даже если одинаково влияют на усреднённый F1.

Инференс через DonutModel

Базовый вызов состоит из загрузки изображения, подготовки pixel values, формирования task prompt и генерации последовательности. Устройство выбирают явно, модель переводят в режим eval, а вычисления выполняют без градиентов. Начальный идентификатор prompt передают как decoder_input_ids; параметры bad_words_ids и early_stopping помогают исключить нежелательные токены и завершить ответ.

После generate последовательность декодируют с сохранением специальных маркеров, удаляют стартовый и конечный токены, затем передают в token2json. Если декодировать с skip_special_tokens=True слишком рано, границы полей исчезнут и структуру будет невозможно восстановить. Это частая причина результата, который выглядит как плоский текст вместо словаря.

Для повторяемости фиксируют max_length, число лучей и остальные параметры. Beam search иногда улучшает короткие ответы, но повышает время и память. Для длинного структурированного JSON жадная генерация часто проще для диагностики. Любое изменение стратегии проверяют на закрытом наборе, потому что более красивый текст не обязательно означает более точные поля.

Работа через Transformers

В Transformers модель доступна через AutoProcessor и классы image-to-text. Процессор объединяет подготовку пикселей и токенизатор, а контрольные точки из организации разработчика содержат конфигурацию нужного размера. Пример для DocVQA должен использовать модель, дообученную именно на вопросах, и передавать вопрос в ожидаемом формате.

Высокоуровневый pipeline удобен для короткого прототипа, однако его интерфейс меняется между крупными выпусками Transformers. Если готовый pipeline сообщает о несовместимом типе модели, используйте прямую загрузку processor и модели по официальному примеру документации. Такой код длиннее, зато вы контролируете prompt, устройство, тип чисел и post-processing.

При миграции окружения сначала сохраните небольшой регрессионный набор и ожидаемые ответы. Обновляйте PyTorch, Transformers, timm и Lightning не все одновременно. После каждого шага запускайте тесты. Совпадение импортов ещё не гарантирует одинаковое поведение: могла измениться обработка размера, генерация, токенизация либо значение параметра по умолчанию.

Пакетная обработка

Пакет строят из изображений одинакового подготовленного размера. Processor формирует тензор pixel_values, который можно передать одной генерации. Однако ответы имеют разную длину, поэтому экономия зависит от документов. Очень длинный чек способен задерживать весь batch; в очереди полезно группировать страницы по предполагаемой сложности или соотношению сторон.

Для многостраничных PDF каждая страница получает document_id и page_number. После инференса результаты сортируют, затем объединяют по правилам задачи. Классификацию можно выполнить первым дешёвым проходом, чтобы пропускать пустые страницы и направлять счета, чеки и письма к разным контрольным точкам. Ошибки одной страницы не должны отменять весь документ: статус сохраняют отдельно.

Очередь ограничивает число одновременных запросов, чтобы не получить out-of-memory. Перед каждым batch оценивают суммарное число пикселей и максимальную длину. При падении воркера задание возвращают с идентификатором попытки, но не запускают бесконечный повтор: повреждённое изображение следует отправить в карантин после заданного числа неудач.

Скорость, память и выбор устройства

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

На GPU инференс заметно практичнее, особенно для больших страниц. На CPU тест возможен, но длительная генерация и обучение становятся медленными; некоторые режимы низкой точности на процессоре не ускоряют вычисления. Официальное изменение, удалившее принудительный bfloat16 для CPU, подчёркивает необходимость выбирать dtype по устройству, а не копировать параметры графического ускорителя.

Перед масштабированием измеряют медиану и высокие процентили времени, а не только лучший пример. Включают загрузку изображения, растрирование PDF, перенос тензора и post-processing. Часто узким местом становится не сама модель, а последовательная конвертация больших PDF или скачивание контрольных точек при каждом старте контейнера. Веса кэшируют заранее и прогревают воркер тестовым кадром.

Русский язык и смешанные документы

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

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

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

Таблицы, формы и сложная компоновка

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

Объединённые ячейки, многоуровневые заголовки и продолжение таблицы на следующей странице требуют явной схемы. Модель видит одну страницу и не знает, что строка продолжается, если это не отражено в данных и логике объединения. Удобно извлекать строки постранично, сохранять признак заголовка и затем связывать их по номеру документа, повторяющимся колонкам и последовательности страниц.

Формы с галочками и печатями можно обрабатывать, если они представлены в обучающих примерах и имеют однозначные значения. Не стоит ожидать, что модель автоматически поймёт любой рукописный знак. Для критичных отметок добавляют отдельные проверки изображения или требуют ручного подтверждения, особенно когда слабая галочка похожа на шум сканера.

Контроль качества результатов

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

Сопоставление фотографии чека и сгенерированного структурированного ответа

Для каждого поля задают уровень доверия. Donut не всегда возвращает готовую калиброванную вероятность на уровне ключа, но можно использовать оценки токенов, повторный прогон, согласованность правил и сравнение нескольких вариантов. Чувствительные поля отправляют оператору при любом конфликте. Интерфейс проверки должен показывать исходную страницу рядом с полями, иначе человек тратит время на поиск места.

Регрессионный набор пополняют ошибками из эксплуатации. Документы с тенями, новым шаблоном, длинным чеком или редким символом не удаляют после исправления; их добавляют в тест и при достаточном объёме — в следующую обучающую выборку. Так качество оценивается на реальных сбоях, а не только на первоначально удобных примерах.

Конфиденциальность и хранение

При обработке финансовых и персональных документов определите, где хранятся изображения, веса и журналы. Контрольные точки можно заранее разместить в закрытом хранилище и запускать без повторной загрузки. В логах не следует печатать полный JSON и путь с персональными данными; достаточно идентификатора задания, статуса и технической ошибки.

Временные страницы PDF удаляют после успешной обработки или по короткому сроку хранения. Хеш файла помогает находить повторную отправку без сохранения лишней копии. Доступ операторов разделяют по ролям, а экспорт результатов журналируют. Модель не заменяет правила защиты данных: она видит все пиксели переданного документа.

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

Ошибки установки и зависимостей

Если импорт завершается ошибкой, сначала создайте чистое окружение Python и установите компоненты по совместимому набору. Donut связан с PyTorch, Transformers, timm, PyTorch Lightning, SentencePiece и Pillow; слишком новые или слишком старые сочетания могут менять API. Записывайте вывод pip freeze для рабочего окружения и переносите его как единое целое.

Ошибка при загрузке tokenizer часто указывает на отсутствующий SentencePiece либо повреждённый кэш. Удалять весь кэш без разбора необязательно: найдите каталог конкретной контрольной точки, проверьте полноту файлов и повторите загрузку. В закрытой сети убедитесь, что конфигурация, веса, tokenizer и processor скопированы вместе и путь указывает на корневой каталог.

Несовпадение аргументов Lightning или Trainer обычно появляется после крупного обновления. Сверяйте код с API выбранного окружения, а не случайным фрагментом из другого периода. Исправление одного имени параметра может быть недостаточно, если изменился формат checkpoint. Безопаснее начать с официального рабочего примера и постепенно переносить собственные изменения.

Ошибки CUDA и памяти

Сообщение CUDA out of memory устраняют уменьшением batch size, размера входа или длины генерации, но каждое изменение влияет на задачу. Сначала убедитесь, что на устройстве не остались процессы предыдущих запусков. Затем протестируйте один пример, включите накопление градиента для обучения и только после этого уменьшайте разрешение, контролируя мелкий текст.

Несовместимость CUDA, драйвера и сборки PyTorch проявляется ещё до модели. Проверьте, видит ли PyTorch устройство и выполняется ли простая операция с тензором. Не устанавливайте случайные пакеты поверх рабочего окружения. Для контейнера закрепите базовый образ и драйверную матрицу, чтобы обновление хоста не меняло среду незаметно.

NaN в loss может быть связан с переполнением смешанной точности, ошибочной разметкой или экстремально длинным примером. Отключите mixed precision на коротком диагностическом запуске, найдите первый проблемный batch и откройте его данные. Простое пропускание всех NaN скрывает дефект и может оставить систематическую дыру в обучении.

Почему ответ обрывается или повторяется

Обрезанный JSON чаще всего означает, что max_length меньше длины требуемой последовательности. Измерьте токенизированные эталоны и выберите лимит с запасом для верхнего процентиля. Единичные аномально длинные документы можно обрабатывать отдельным маршрутом, чтобы не увеличивать стоимость каждого запроса.

Повторение одного поля или товарной строки возникает при неуверенной генерации, длинном контексте или несогласованной разметке. Проверьте, что closing-токены присутствуют в обучающих строках, списки сериализуются одинаково, а eos_token_id задан правильно. Ограничители повторов применяйте осторожно: одинаковые реальные позиции действительно могут встречаться дважды.

Если token2json возвращает пустой объект, вы могли удалить специальные токены при decode либо использовать токенизатор от другой модели. Выведите сырую последовательность и идентификаторы первых токенов. Наличие обычного читаемого текста без указывает на неправильный prompt или контрольную точку, а набор неизвестных токенов — на рассогласование словаря.

Почему поля выглядят правдоподобно, но неверны

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

Первое действие — проверить, соответствует ли документ области контрольной точки. Затем откройте подготовленный тензор или сохранённое после resize изображение: мелкий текст мог стать нечитаемым ещё до модели. Сравните результат на оригинальном и более аккуратно выровненном кадре, не меняя одновременно prompt и генерацию.

Если ошибка повторяется на одном поставщике, добавьте его документы в отдельную оценочную группу. Возможно, нужен fine-tuning на новом шаблоне либо маршрутизация. Не подменяйте систематическую проблему словарём замен, который исправляет конкретные названия: он не поможет новым строкам и может испортить корректный результат.

Когда OCR-free подход даёт преимущество

Единая модель уменьшает число независимых этапов. Нет отдельного OCR, который сначала ошибается в строках и координатах, а затем передаёт ошибку классификатору или парсеру. Визуальный контекст позволяет связывать подпись и значение даже без явной таблицы координат, а общий формат JSON объединяет разные задачи обучения.

Преимущество заметно на документах, где смысл зависит от оформления: расположения суммы возле подписи, повторяющихся секций, визуального типа страницы. Также упрощается создание прототипа, потому что не требуется проектировать OCR-разметку, порядок чтения и набор регулярных выражений до первого результата.

Цена этого упрощения — меньшая прозрачность. Нельзя легко посмотреть список распознанных слов и исправить одну координату. Для новых языков и схем нужны данные, а генеративный ответ необходимо проверять. Выбор между Donut и модульным OCR-конвейером зависитет от требований к геометрии, объяснимости, языку и объёму разметки.

Сравнение Donut с аналогами

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

ПрограммаЛучше подходит дляГлавное ограничение
DonutОбучаемого преобразования изображения документа в целевой JSON, классификации и DocVQAНет координат слов, для новой схемы нужны данные и дообучение
LayoutLMv3Задач, где уже доступны текст OCR, bounding boxes и изображение страницыЗависит от качества OCR и подготовки координат
Pix2StructУниверсальных image-to-text задач, визуальных вопросов и разбора сложных скриншотовДля бизнес-схемы также требуется специализированное дообучение
NougatПреобразования научных PDF с формулами и таблицами в разметкуУзкая специализация на академических документах
PaddleOCR PP-StructureV3Многоязычного OCR, анализа макета, таблиц и структурирования документовЭто многоэтапный OCR-конвейер с собственной настройкой моделей
PDF CommanderРучного редактирования, объединения, защиты и повседневной работы с PDFНе обучает image-to-JSON модель для извлечения реквизитов

Практический выбор между решениями

Donut выбирают, когда нужен собственный image-to-JSON парсер, есть возможность подготовить размеченные примеры и не требуются координаты каждого слова. LayoutLMv3 уместен, когда уже работает качественный OCR с bounding boxes и нужно использовать текст вместе с расположением. Pix2Struct ближе к универсальному визуальному image-to-text подходу и полезен для задач, похожих на разбор скриншотов и визуальных вопросов.

Nougat лучше подходит для научных PDF, где важны формулы, таблицы и вывод в разметку, а не произвольная бизнес-схема чека. PaddleOCR PP-StructureV3 удобнее, когда нужен готовый OCR-конвейер с распознаванием макета и широкой языковой поддержкой. PDF Commander выбирают для ручного редактирования, сборки и обычной работы с PDF, но он не заменяет обучение модели извлечения данных.

Сравнивать следует на собственных документах. Одно решение может лучше читать кириллицу, другое — сохранять структуру таблицы, третье — выдавать нужный JSON. Важны не только метрики модели, но и стоимость разметки, наличие GPU, требования к координатам, время ответа и объём ручной проверки.

Типовые рабочие сценарии

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

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

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

Когда Donut не подходит

Не выбирайте Donut как средство ручного редактирования PDF, объединения страниц, проставления подписей или изменения текста. Он анализирует изображение и формирует предсказание, но не предоставляет редактор страниц. Для таких действий нужен специализированный PDF-инструмент.

Другой неудачный сценарий — требование точных координат каждого слова и воспроизводимого OCR-текста для подсветки. Базовый output Donut не содержит bounding boxes. Также подход неудобен, когда нет данных для целевой схемы, язык сильно отличается от готовых моделей, а ручная разметка невозможна.

Для длинных научных статей с формулами и выводом в Markdown специализированный парсер будет практичнее. Для массового общего OCR на многих языках готовый OCR-набор может потребовать меньше дообучения. Donut оправдан, когда конечная цель — понимание документа и структурированный ответ, а не универсальная транскрипция.

Чек-лист перед внедрением

Зафиксируйте тип документа, список полей и допустимые отсутствующие значения. Подготовьте тестовую выборку по источникам, а не по случайным кадрам. Проверьте, что PDF корректно растрируется, страницы повёрнуты, края не обрезаны, а мелкий текст виден после processor. Выберите контрольную точку и prompt, совпадающие с задачей.

Создайте JSON Schema, арифметические и справочные проверки. Сохраняйте сырой ответ и нормализованную запись раздельно. Определите пороги ручной проверки, журналируйте модель и параметры, защищайте изображения и удаляйте временные файлы. Для очереди ограничьте batch и повторные попытки.

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

Проверка данных перед началом обучения

Скрипт предварительной проверки должен пройти по каждой строке metadata.jsonl, открыть изображение, декодировать ground_truth дважды — внешнюю строку и внутренний объект — и сериализовать его обратно. Дополнительно он считает длину токенизированной последовательности, частоту каждого ключа, долю пустых значений и число элементов в списках. Отчёт быстро обнаруживает поле, которое встречается только в validation, редкий ключ с опечаткой и примеры, не помещающиеся в max_length. Для изображений записывают размер, режим цвета, соотношение сторон и наличие исключений Pillow. Такой аудит выполняется до копирования данных на обучающий сервер и повторяется после любого преобразования файлов.

Проверка после растрирования

Для PDF полезен лист контроля, где рядом показаны исходная страница и итоговый PNG. Проверяют поворот, обрезание, порядок страниц, прозрачность, цветной профиль и читаемость мелких цифр. Затем несколько кадров пропускают через тот же processor, который будет использовать модель, и сохраняют реконструированную визуализацию. Именно она показывает реальный масштаб после resize и padding. Если реквизит читаем в исходном PDF, но исчезает в подготовленном тензоре, увеличение качества OCR не поможет — нужно менять рендер или размер входа.

Безопасное изменение JSON-схемы

Добавление нового поля к уже работающей схеме рассматривают как новую задачу обучения. Сначала размечают поле на всех релевантных примерах, определяют поведение при отсутствии и добавляют токены. Затем дообучают копию модели и сравнивают старые критичные поля на прежнем регрессионном наборе. Нельзя оценивать только новое поле: увеличение длины и изменение порядка могут ухудшить позиции и итоги. При постепенной миграции API возвращает версию схемы, а потребитель умеет принимать обе структуры до завершения перехода.

Разделение очередей по сложности

В рабочей очереди различают короткие формы, обычные страницы и длинные чеки. Короткие документы группируются в большие batch, длинные обрабатываются меньшими пакетами и с отдельным лимитом генерации. Повреждённые изображения отправляются в карантин до модели, а неизвестные классы — в ручную сортировку. Такое разделение делает задержку предсказуемой и не позволяет одному огромному кадру заблокировать поток. Метрики собирают по каждой группе, иначе среднее время скрывает медленные хвосты.

Тестирование post-processing

Post-processing проверяется независимо от нейросети. Набор тестов содержит корректные строки, пропущенные закрывающие токены, повторяющиеся ключи, пустые списки, валютные форматы и неожиданные символы. Функция не должна молча преобразовывать невалидный ответ в правдоподобный объект. При частичном восстановлении она возвращает предупреждение и исходную строку. Денежная нормализация тестируется на локалях отдельно, а даты — на неоднозначных комбинациях дня и месяца.

Сопоставление результата с изображением

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

Управление контрольными точками

Каждая контрольная точка получает неизменяемый идентификатор, описание схемы, хеш конфигурации и список совместимых токенизаторов. Production-алиас указывает на одобренную модель, но журналы сохраняют фактический идентификатор. Откат выполняется сменой алиаса без пересборки данных. Перед продвижением новая модель проходит тест точности, нагрузки и совместимости JSON. Так исключается ситуация, когда весовой файл обновился, а API продолжает ожидать старые ключи.

Проверка деградации после обновления

Регрессионный тест должен сравнивать не только строковое равенство, но и бизнес-поля. Допустимое изменение пробела не должно блокировать выпуск, а изменение суммы — всегда должно. Для каждой категории документов задают минимальную полноту и максимальную долю ручной проверки. Обновление принимается только после сравнения времени, памяти и процента невалидного JSON. Результаты сохраняют вместе с окружением, чтобы можно было воспроизвести различие.

Разметка длинных списков

Для длинных чеков разметчик обязан сохранить порядок строк и не объединять одинаковые товары без явного правила. Если одна позиция переносится на две печатные строки, в JSON она остаётся одним объектом. Если товар действительно повторён, создаются два элемента, даже когда значения совпадают. Перед обучением считают максимальное и типичное число позиций, длину названий и долю чеков, которые не помещаются в выбранный лимит. Это позволяет решить, нужен ли отдельный маршрут для длинных документов, а не обнаруживать усечение уже после запуска.

Работа с пустыми и повреждёнными страницами

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

Выравнивание порядка ключей

JSON-объект формально не требует порядка ключей, но для авторегрессионного обучения стабильная последовательность полезна. Определите порядок от шапки к таблице и итогам либо от обязательных полей к дополнительным и применяйте его ко всем эталонам. Вложенные объекты сериализуют тем же способом. Если разные инструменты разметки меняют порядок при сохранении, добавьте каноническую сериализацию перед созданием metadata.jsonl. Это сокращает число эквивалентных последовательностей, которые модель вынуждена изучать.

Проверка специальных токенов

После построения словаря выведите идентификаторы всех открывающих и закрывающих маркеров и убедитесь, что каждый представлен одним токеном. Маркер, разбитый на несколько обычных частей, не выполняет роль устойчивой границы поля. Проверьте также отсутствие коллизий между именами ключей и зарезервированными токенами tokenizer. Контрольный тест должен преобразовать эталонный JSON в последовательность и обратно без потери вложенности, порядка списков и специальных значений.

Устойчивость к повороту и перспективе

Набор оценки должен включать повороты на небольшие углы, фотографии под наклоном и разные поля вокруг документа. Это не означает, что все искажения нужно бездумно добавлять в обучение. Сначала измеряют, какие варианты действительно приходят из рабочего канала, затем создают реалистичные аугментации. Сильное случайное вращение может научить модель редкому шуму и снизить точность на нормальных сканах. Для регулярного поворота на 90 градусов лучше использовать отдельную коррекцию ориентации до Donut.

Работа с цветом и фоном

Цвет иногда несёт информацию: выделенная строка, красная печать или цветной бланк помогают определить тип страницы. Полное обесцвечивание перед моделью может удалить этот сигнал. Одновременно баланс белого фотографии не должен превращать серый текст в фон. Сравните RGB, мягкую нормализацию и контрастирование на закрытом наборе. Любой фильтр закрепляют в едином preprocessing, чтобы обучение и инференс видели одинаковое распределение.

Оценка новых шаблонов

Новый поставщик сначала проходит теневой режим. Модель формирует результат, но запись не уходит в учётную систему без подтверждения. Собираются типы ошибок, длина ответа и доля невалидной структуры. Если качество достаточно, шаблон включают в обычный поток; если нет, примеры размечают и добавляют в обучение. Такой процесс безопаснее мгновенного общего fine-tuning, который может ухудшить старые шаблоны и скрыть проблему в усреднённой метрике.

Версионирование схемы ответа

В API полезно возвращать schema_id вместе с данными. Потребитель тогда понимает, какие ключи обязательны и как трактовать вложенность. При изменении названия поля создают новую схему и период совместимости, а не переименовывают ключ незаметно. В журнале сохраняют исходную строку модели и версию преобразователя token2json, потому что одинаковая последовательность может интерпретироваться иначе после изменения post-processing.

Повторная обработка и идемпотентность

Одно и то же изображение не должно создавать несколько независимых записей при сетевом повторе. Идентификатор задания строят из документа, страницы и версии модели либо хеша входа. Повторный запрос возвращает сохранённый результат или явно запускает пересчёт с новой моделью. Это особенно важно для пакетных PDF: падение на последней странице не должно повторно создавать записи по уже обработанным страницам.

Нагрузочное тестирование

Нагрузочный тест использует реальное распределение размеров и длин ответов. Одни короткие формы дают слишком оптимистичную пропускную способность. Измеряют очередь, время растрирования, подготовку processor, генерацию, преобразование JSON и запись результата. Отдельно проверяют старт холодного воркера и загрузку весов. Резерв памяти оставляют для самого тяжёлого допустимого документа, иначе система будет стабильна только при среднем потоке.

Отслеживание дрейфа данных

После внедрения меняются камеры, шаблоны, шрифты и качество сканирования. Дрейф виден по росту ручных исправлений, невалидного JSON, длины последовательности и доли неизвестных классов. Сравнивают распределения по поставщикам и каналам, а не только общий показатель. Срабатывание порога запускает выборку примеров для анализа; автоматическое переобучение без разметки и проверки не рекомендуется.

Ручная верификация

Экран верификации показывает изображение, предсказанные поля, результаты правил и причину отправки на проверку. Оператор должен исправлять значение и при необходимости отмечать, что поле отсутствует, а не вводить произвольный комментарий вместо структуры. Исправления сохраняются как кандидаты для разметки после контроля качества. Так ручная работа улучшает будущую модель, а не остаётся отдельным неструктурированным архивом.

Тесты на числовые поля

Для сумм создают случаи с разделителями тысяч, запятой и точкой, отрицательными значениями, скидками, налогом и валютными символами. Проверяется не только строка, но и арифметическая связь. Для номеров документов сохраняют ведущие нули и буквенные префиксы; преобразование в число здесь недопустимо. Для дат тестируют неоднозначные форматы и отсутствие года. Эти проверки обнаруживают ошибки, которые визуально похожи на корректный JSON.

Тесты на многоязычный текст

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

Документирование ограничений для операторов

Пользователям системы сообщают, какие документы поддерживаются, какие страницы требуют хорошего качества и какие поля проверяются автоматически. Нельзя представлять любой сгенерированный JSON как подтверждённый факт. В инструкции описывают признаки ошибки: отсутствующий итог, повтор строк, неожиданный класс, обрезанный ответ и несогласованная сумма. Чёткие правила сокращают время проверки и предотвращают перенос неверных данных дальше по процессу.

Минимальный приёмочный набор

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

Проверка пропущенных полей

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

Обработка нескольких моделей

Если в потоке работают классификатор и несколько парсеров, маршрутизация сохраняет решение каждого этапа. Ошибка класса не должна выглядеть как ошибка извлечения. Для спорных страниц можно запускать два подходящих парсера и выбирать результат по валидности схемы и бизнес-правилам, но это увеличивает нагрузку. Контрольные точки загружают по требованию или распределяют между воркерами так, чтобы частое переключение не вытесняло веса из памяти.

Хранение эталонов и лицензирование данных

Изображения для обучения должны иметь понятное происхождение и разрешение на использование. Персональные поля обезличивают по процедуре, которая не разрушает расположение и шрифт важных областей. Эталонный JSON хранится с контролем версий и журналом исправлений. Синтетические шрифты, фоны и словари также проверяют по лицензиям. Иначе технически успешная модель создаёт юридический риск и не может быть воспроизведена другой командой.

Финальная проверка перед отправкой результата

Перед передачей записи downstream-системе проверяют идентификатор документа, число страниц, статус каждой страницы, версию схемы, синтаксис JSON и критичные межполевые зависимости. Если хотя бы одна обязательная страница не обработана, документ не помечают завершённым. После успешной записи сохраняют техническое подтверждение и только затем очищают временные изображения. Такой порядок предотвращает потерю данных при сбое между инференсом и сохранением. Отдельный контроль подтверждает, что downstream-система приняла именно ожидаемую версию объекта.

Итоговый рабочий подход

Наиболее надёжная схема применения Donut состоит из пяти этапов: качественный рендер страницы, модель строго под нужную задачу, неизменный task prompt, преобразование последовательности в JSON и обязательная бизнес-валидация. Каждый этап должен иметь отдельный лог и тест, чтобы ошибка не скрывалась за красивым конечным объектом.

Начинать стоит с узкой задачи, где результат легко проверить: класса страницы, нескольких реквизитов или одного вопроса. После измерения на закрытом наборе добавляют batch, многостраничную сборку и интерфейс оператора. Такой порядок позволяет использовать сильную сторону Donut — прямое преобразование визуального документа в структуру — и одновременно контролировать ограничения генеративной модели.

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