Calamari OCR

Calamari OCR распознаёт заранее выделенные строки печатного или рукописного текста, обучает собственные нейросетевые модели на парах изображение — расшифровка, объединяет прогнозы нескольких моделей голосованием и измеряет качество по CER и таблице ошибок. Основные операции выполняются командами calamari-predict, calamari-train, calamari-cross-fold-train и calamari-eval, а Python API позволяет встроить тот же конвейер в скрипт обработки документов.

Работа начинается не с целой страницы, а с изображений текстовых строк либо с разметки, из которой строки можно вырезать по координатам. Пользователь подготавливает набор PNG или JPEG и при обучении добавляет к каждому изображению файл UTF-8 с эталонной строкой; затем выбирает готовый checkpoint либо задаёт параметры новой модели. После распознавания рядом с исходными файлами появляются текстовые результаты, а при необходимости — JSON с позициями символов, вероятностями и альтернативами.

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

Скачать Calamari OCR

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

Как Calamari OCR обрабатывает текстовые строки

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

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

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

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

Документация Calamari OCR с примером команды распознавания строки

Что считается интерфейсом

Основной интерфейс состоит из отдельных команд. calamari-predict применяет checkpoint к входным данным; calamari-train создаёт модель; calamari-resume-training продолжает остановленный запуск; calamari-cross-fold-train обучает несколько моделей по фолдам; calamari-predict-and-eval совмещает прогноз и оценку; calamari-eval сравнивает готовые результаты с эталоном. Дополнительные команды просмотра и статистики помогают проверить набор до дорогого обучения.

У каждой команды есть краткая справка и набор вложенных параметров. Имена с точкой отражают структуру конфигурации: например, --pipeline.batch_size относится к конвейеру пакетной обработки, --trainer.epochs — к обучению, а --data.input_channels — к входным каналам изображения. Такой синтаксис длиннее привычных флагов, зато позволяет управлять глубоко вложенными настройками без редактирования исходного кода.

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

Параметры calamari-predict в официальной документации

Подготовка окружения и зависимостей

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

В состав зависимостей входят TensorFlow, h5py, lxml, модуль двунаправленного текста, библиотека вычисления edit distance, инфраструктура tfaip и средство записи XLSX. Поэтому установка значительно тяжелее размера самого wheel-файла: основное место занимают вычислительный движок и его бинарные компоненты. На машине с ограниченным диском полезно заранее очистить кэш старых пакетов и убедиться, что для выбранной платформы доступна совместимая сборка TensorFlow.

Для CPU не требуется отдельная видеокарта. Такой режим удобен для проверки набора, запуска небольшой партии и воспроизводимого теста, однако обучение больших моделей занимает заметно больше времени. GPU ускоряет свёртки и рекуррентные вычисления, но требует совместимых драйверов, CUDA и cuDNN. Наличие видеокарты само по себе не включает её: идентификатор устройства передают параметром --device.gpus. Если флаг не задан, обучение остаётся на CPU даже при установленном ускорителе.

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

На Windows особенно важно запускать команды из активированного окружения и не смешивать пути разных Python. На Linux обычно проще установить системные компоненты для сборки и драйверы GPU, но права доступа к каталогам вывода и маски файлов требуют внимания. На macOS работа зависит от доступности подходящей TensorFlow-сборки; если пакетная установка не находит совместимый бинарник, разумнее начать с CPU в поддерживаемом окружении, а не вручную подменять случайные зависимости.

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

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

  • Проверить, что python и pip относятся к одному окружению.
  • Убедиться, что команды Calamari видны после активации окружения.
  • Запустить распознавание одной строки до обработки большой коллекции.
  • Зафиксировать список установленных пакетов для повторяемости.
  • Проверить свободное место для моделей, временных файлов и журналов.

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

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

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

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

Цветовой режим выбирают осознанно. По умолчанию RGB и RGBA преобразуются в один канал через OpenCV. Для коллекций, где цвет несёт смысл — например, красные рубрики должны отличаться от чёрного основного текста, — можно обучать сеть на трёх каналах, указав --data.input_channels=3. Это увеличивает объём входа и требования к памяти. Если цвет не помогает различать символы, серый режим проще и обычно устойчивее.

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

Настройки аугментации, цвета, загрузки данных и GPU

Согласование изображения и эталона

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

Начальные и конечные пробелы в файлах ground truth вызывают скрытые ошибки: визуально строка выглядит правильно, но оценка считает лишний символ. Аналогично различаются обычный пробел, неразрывный пробел и узкий пробел. Перед обучением полезно нормализовать переводы строк, проверить кодировку UTF-8 и вывести невидимые символы. Особенно внимательно обрабатывают комбинируемые диакритические знаки, которые могут иметь одинаковый вид, но разное представление Unicode.

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

Форматы наборов данных

Calamari поддерживает несколько способов связать изображения и текст. Выбор формата влияет не на саму нейросеть, а на чтение строк, получение эталона и запись результата. Простейший вариант — отдельные файлы строк и парные текстовые файлы. Для проектов с координатной разметкой подходят PageXML и ABBYY XML. HDF5 хранит массивы и транскрипции в одном контейнере и удобен для заранее собранных больших наборов.

Обычные файлы: PNG или JPEG и GT

В файловом режиме у изображения и эталона должно быть одинаковое базовое имя. Например, 0001.png соответствует 0001.gt.txt. Распознанный текст по умолчанию получает суффикс .pred.txt. Важная особенность: всё после первой точки считается расширением. Поэтому имя вроде book.001.png может быть разобрано не так, как ожидает пользователь. Безопаснее использовать дефис или подчёркивание: book_001.png.

Пути можно передавать маской оболочки. Для небольшого набора удобно указать train/*.png, но при сотнях тысяч файлов оболочка может превысить лимит длины аргументов ещё до запуска Python. Тогда данные делят по каталогам, используют поддерживаемый список имён либо вызывают обработку из скрипта, где пути формируются программно. Передача каталога без подходящих файлов не создаёт ошибку распознавания — команда просто не получает нужные элементы.

Структура обычного набора изображений и файлов ground truth

PageXML

PageXML хранит геометрию страницы, регионы, строки и текстовые эквиваленты в XML. В этом режиме пользователь передаёт изображения страниц и соответствующие XML-файлы, а reader вырезает строки по координатам. Параметр text index выбирает нужный текстовый слой, если в разметке есть несколько вариантов. Отступ вокруг полигона можно увеличить, чтобы не обрезать выносные элементы, а режим вырезания определяет, использовать полигон или другую геометрию.

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

ABBYY XML

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

HDF5

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

Примеры структуры PageXML и ABBYY XML для Calamari OCR

Описание HDF5-набора для Calamari OCR

ФорматЧто передаётсяКогда выбиратьТипичный риск
Обычные файлыИзображение строки и файл GTНебольшие и средние наборы, ручная проверкаНесовпадение базовых имён
PageXMLИзображение страницы и XML с линиямиПроекты оцифровки с геометрией и слоями текстаНеверные полигоны или text index
ABBYY XMLИзображение и файл .abbyy.xmlИмпорт существующей ABBYY-разметкиНеожиданная структура XML
HDF5Контейнер с массивами и транскрипциямиБольшие подготовленные наборыСложнее исправлять отдельную строку

Просмотр и статистика до обучения

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

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

Распознавание предобученной моделью

Минимальный вызов calamari-predict содержит путь к checkpoint и маску изображений. Путь к модели указывается без расширения, если набор файлов checkpoint использует общий префикс. После загрузки команда создаёт reader, преобразует изображения, объединяет их в пакеты и передаёт предиктору. Результаты записываются рядом с входом либо в каталог, заданный через --output_dir. Для PageXML каталог вывода особенно важен, потому что желательно не смешивать исходную разметку с машинным результатом.

Размер пакета --pipeline.batch_size влияет на скорость и память. Большой пакет лучше использует GPU, но самая широкая строка определяет объём дополнения внутри пакета. Если строки сильно различаются по длине, bucket boundaries группируют сходные элементы и уменьшают пустое дополнение. Когда память заканчивается на одном выбросе, простое уменьшение batch size помогает, но лучше также найти аномально длинную строку и проверить сегментацию.

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

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

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

Пример распознавания исторической и современной печатной строки

Выбор checkpoint

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

Если checkpoint загружается, но вывод систематически пропускает нужный символ, причина может быть в кодеке модели. Кодек задаёт допустимый алфавит. Символ, которого нет в нём, не появится в предсказании независимо от уверенности. Для новой коллекции либо выбирают модель с подходящим алфавитом, либо выполняют warm start и расширяют кодек на своих ground truth. Простая замена символа после OCR допустима только для однозначных правил, а не как способ скрыть отсутствие знака в модели.

Голосование нескольких моделей

Calamari умеет применять несколько checkpoint к одним строкам и объединять результаты confidence voting. Каждая модель выдаёт последовательность символов и вероятности; voter согласует прогнозы и выбирает итог. Метод полезен, когда модели обучены на разных фолдах одного набора: их ошибки частично независимы, и большинство исправляет отдельные неудачные решения. Передача нескольких путей в --checkpoint включает этот сценарий без отдельного этапа слияния текстовых файлов.

Голосование не заменяет разнообразие. Если все модели являются копиями одного checkpoint или обучены на одинаково загрязнённых данных, они повторяют одну и ту же ошибку. Наиболее практичный ансамбль получают через cross-fold training: набор делят на фолды, каждую модель обучают на своей комбинации обучающей и валидационной частей, а лучшие checkpoint сохраняют отдельно. Затем все модели применяют совместно.

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

Команда calamari-predict-and-eval может вывести результаты отдельных участников и итогового voter, а также сохранить сериализованный отчёт. Это позволяет понять, действительно ли ансамбль сильнее каждого checkpoint. Если одна модель заметно хуже и тянет голосование вниз, её исключают. Сравнивать следует на независимой тестовой выборке, а не на тех строках, по которым выбирались лучшие модели.

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

Расширенные результаты и Python API

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

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

Python API начинается с Predictor.from_checkpoint. Для списка готовых изображений можно вызвать predict_raw, predict_pipeline или predict_dataset. Объект создаёт внутренние конвейеры на время вызова и закрывает их после завершения. Возвращаемый sample разделён на inputs, outputs и meta; собственно строка находится в prediction, а идентификатор и сведения о происхождении данных — в meta.

Для сервера или интерактивной программы выгодно держать raw predictor открытым. Модель загружается один раз, затем функция вызывается для каждой новой строки. Контекстный менеджер гарантирует корректное освобождение ресурсов. Такой режим сокращает задержку, потому что TensorFlow не инициализируется заново на каждом запросе. Одновременно надо ограничивать параллелизм: несколько процессов, каждый с копией модели на одной GPU, могут исчерпать память быстрее, чем один пакетный предиктор.

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

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

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

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

Обучение собственной модели

Команда calamari-train получает обучающий и валидационный наборы, создаёт кодек, строит сеть и сохраняет checkpoint в заданный каталог. До запуска нужно определить критерий успеха: целевой CER на независимой выборке, набор обязательных символов и допустимое время обработки. Без измеримой цели легко продолжать обучение после того, как модель уже переобучилась, либо менять архитектуру, не понимая, стало ли лучше.

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

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

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

Стратегии валидации

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

Автоматическое разделение задаётся режимом SplitTrain и долей validation split ratio. Это удобно для первого эксперимента, но перед публикацией модели лучше зафиксировать список фолдов. Режим TrainOnly использует те же данные для обучения и выбора лучшего checkpoint; документация прямо предупреждает о высоком риске переобучения. Его можно применять для технической проверки, но не для честной оценки качества.

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

Параметры обучения и варианты валидации Calamari OCR

Аугментация

Параметр --n_augmentations задаёт отношение синтетических строк к реальным. Значение 5 означает пять изменённых вариантов на один оригинал. Аугментация помогает сети переносить небольшие деформации, шум и вариации печати, но не исправляет неправильный ground truth. Если синтетические искажения сильнее реальных, модель учится читать артефакты, которых нет в коллекции, и теряет точность на чистых строках.

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

Архитектура сети

Готовые профили включают базовую сеть, более глубокий вариант с несколькими BiLSTM и архитектуру htr+, рассчитанную на увеличенную высоту строки. Профиль выбирают как отправную точку, а не как гарантию качества. Более глубокая сеть требует больше памяти и данных; на маленьком наборе она может переобучиться. Высота строки должна соответствовать архитектуре: слишком низкая теряет детали, слишком высокая замедляет обучение без полезной информации.

Краткий синтаксис --network позволяет перечислить слои: свёртку, pooling, LSTM и dropout. Базовый пример содержит две пары conv/pool, затем двунаправленный LSTM и dropout. Расширенный синтаксис задаёт типы слоёв и параметры каждого отдельно: число фильтров, шаг, размер pooling, число скрытых узлов и долю dropout. Изменять архитектуру стоит по одному фактору, иначе невозможно понять причину улучшения или ухудшения.

Поддерживаются BiLSTM, Concat, Conv2D, DilatedBlock, Dropout, Pool2D и TransposedConv2D. Pooling уменьшает размер признаковой карты и ускоряет вычисление, но чрезмерное сжатие по горизонтали оставляет слишком мало временных шагов для длинной транскрипции. CTC нуждается в достаточной длине последовательности, поэтому агрессивный горизонтальный pooling особенно опасен для мелкого плотного текста.

Предустановленные и настраиваемые архитектуры сети Calamari OCR

Кодек, warm start и заморозка слоёв

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

Warm start загружает веса предобученной модели и адаптирует кодек к новому алфавиту. Веса общих символов сохраняются, новые классы инициализируются, а отсутствующие в новом наборе символы по умолчанию могут быть удалены. Опция keep loaded формирует объединение алфавитов, если важно не потерять знаки исходной модели. Это полезно при дообучении универсальной модели на одной книге, но расширенный алфавит требует примеров, иначе редкие классы остаются плохо откалиброванными.

Регулярное выражение no train scope исключает выбранные слои из обновления. Заморозка ранних свёрточных слоёв ускоряет адаптацию и снижает риск разрушить общие визуальные признаки на маленьком наборе. Если новый материал сильно отличается по масштабу, цвету или письму, слишком большая заморозка мешает сети адаптироваться. Практический путь — начать с частичной заморозки, измерить CER, затем разрешить обновление большего числа слоёв при достаточном объёме данных.

Скорость обучения, оптимизатор и градиенты

По умолчанию используется Adam, но доступны SGD, RMSProp и AdaBelief. Выбор оптимизатора связан со скоростью обучения и расписанием learning rate. Постоянная скорость — понятная отправная точка; при нестабильном обучении сначала уменьшают шаг, проверяют нормализацию входа и размер пакета. Переключение оптимизатора без изменения остальных условий редко даёт полезный вывод.

Gradient clipping ограничивает норму, отдельные значения или глобальную норму градиента. Он помогает при редких всплесках и длинных последовательностях, но не должен маскировать систематическую ошибку данных. Если loss становится NaN, проверяют повреждённые изображения, пустые строки, чрезмерный learning rate и несовместимую mixed precision. Только после этого подбирают clipping.

Предзагрузка всего набора в RAM ускоряет повторные эпохи, потому что изображения не читаются с диска заново. Для крупной коллекции она вызывает нехватку памяти; параметры --train.preload False и --val.preload False переводят чтение в потоковый режим. В таком режиме особенно важны быстрый диск, число процессов и стабильный список файлов. Случайное изменение набора во время обучения нарушает воспроизводимость.

Настройки learning rate, кодека и оптимизатора

Продолжение и cross-fold training

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

Cross-fold training создаёт несколько моделей и сохраняет лучшие checkpoint каждого фолда. Параметр n_folds задаёт число разбиений, best_models_dir — каталог итоговых моделей, best_model_label — шаблон имени. Временный каталог хранит промежуточные файлы, max_parallel_models ограничивает одновременные процессы, а single_fold позволяет переобучить только выбранный фолд. Параллельный запуск нескольких тяжёлых моделей на одной GPU часто хуже последовательного из-за конкуренции за память.

Параметры cross-fold training и оценки распознавания

Оценка качества и разбор ошибок

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

Команда calamari-eval читает ground truth и соответствующие файлы предсказаний. По умолчанию прогноз ищется по суффиксу .pred.txt, но можно передать отдельный набор. Параметр n_confusions ограничивает число наиболее частых ошибок, а отрицательное значение выводит все. n_worst_lines показывает строки с наибольшим числом ошибок. Пустые эталоны при необходимости исключаются отдельным флагом.

Таблица confusion различает вставку, удаление и замену. Если модель регулярно путает c и e, нужно проверить разрешение и похожие примеры. Если удаляет пробелы, проверяют правила транскрипции и ширину межсловных интервалов. Если вставляет диакритику, смотрят, не смешаны ли нормализованные и комбинируемые Unicode-формы. Частота ошибки важнее одного эффектного примера.

XLSX-отчёт содержит лист по строкам с эталоном, прогнозом, длиной, числом ошибок, CER и списком замен, глобальную таблицу confusion и гистограмму распределения CER. Это удобно для сортировки и передачи корректировщику. Файл не заменяет исходный журнал: при повторной оценке надо знать checkpoint, список данных и параметры предобработки, иначе одинаковое имя отчёта не гарантирует одинаковый эксперимент.

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

Качество полезно разбивать по ширине строки, году издания, гарнитуре, языку, типу бумаги и способу сканирования. Такая стратификация показывает, где нужны дополнительные ground truth. Например, общий CER может быть низким, но строки с курсивом остаются плохими. Добавление нескольких сотен целевых примеров и warm start обычно рациональнее, чем увеличение глубины сети на всём наборе.

Типичные ошибки и способы их устранения

Команда не находит checkpoint

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

Передана целая страница, а текст бессмысленный

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

Файлы GT не сопоставляются с изображениями

Проверяют базовые имена и правило первой точки. Пара 001.png и 001.gt.txt корректна, а дополнительные точки в идентификаторе могут изменить вычисленное расширение. Также учитывают регистр на файловых системах Linux: Line01.PNG и маска *.png не совпадают. Скрипт проверки должен вывести изображения без GT, GT без изображений и дубликаты базовых имён.

Результаты не появляются в ожидаемом каталоге

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

Процесс падает с нехваткой памяти

Сначала уменьшают batch size. Затем находят максимальную ширину и исключают ошибочно сегментированные строки, содержащие целый абзац. Отключают предзагрузку, если RAM заполнена набором, и ограничивают число параллельных моделей. На GPU проверяют, не запущены ли другие процессы TensorFlow. Bucket boundaries помогают группировать строки по длине и уменьшают дополнение, но неверно выбранные границы могут создать слишком крупный пакет длинных строк.

GPU видна, но обучение идёт на CPU

Устройство нужно указать параметром, а TensorFlow должен видеть совместимую CUDA-среду. Проверяют журнал размещения операций, список доступных устройств и соответствие драйвера библиотекам. Soft device placement может незаметно перенести неподдерживаемую операцию на CPU, поэтому факт установленного драйвера не доказывает ускорение. Для контрольного теста сравнивают время нескольких прогретых пакетов, а не первый запуск.

Первое распознавание очень медленное

Задержку создают импорт TensorFlow, загрузка модели и инициализация устройства. Обрабатывать каждую строку отдельным запуском неэффективно. Используют одну команду с маской файлов, пакетный режим либо постоянный Predictor в Python. Если сервис обязан отвечать по одной строке, модель загружают при старте процесса и выполняют пробный прогрев до приёма пользовательских запросов.

Loss становится NaN

Проверяют learning rate, повреждённые изображения, пустые транскрипции и экстремальные размеры. Затем уменьшают шаг, отключают подозрительную аугментацию и запускают маленький чистый набор. Gradient clipping может стабилизировать редкие всплески, но если NaN появляется на одном и том же примере, его надо открыть и исправить. При mixed precision проверяют, поддерживается ли она выбранным оборудованием и зависимостями.

Модель переобучается

Признак переобучения — продолжающееся улучшение train при ухудшении val. Увеличивают разнообразие данных, используют аугментацию, dropout и раннюю остановку, уменьшают сеть или замораживают часть слоёв при warm start. Главное — проверить разбиение: соседние строки одной страницы в train и val могут сначала скрывать проблему, а независимая книга сразу показывает падение качества.

В выводе пропадают редкие символы

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

Пробелы и переносы считаются ошибками

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

PageXML даёт неверные вырезки

Открывают полигоны в редакторе разметки и проверяют систему координат, ориентацию изображения и масштаб. Если XML относится к другой версии скана, координаты будут смещены. Padding вокруг строки увеличивают умеренно: слишком малый обрезает диакритику, слишком большой захватывает соседние строки. При нескольких TextEquiv выбирают правильный text index и не обучаются случайно на нормализованном слое вместо дипломатического.

Слишком много аргументов в оболочке

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

Практические рабочие процессы

Историческая печатная книга

Сначала страницы выравнивают и сегментируют на регионы и строки. В PageXML сохраняют координаты и идентификаторы. Из нескольких страниц вручную создают точные TextEquiv, разделяя документы на train, val и test. Для первого прохода применяют подходящую смешанную модель, затем исправляют наиболее типичные ошибки и выполняют warm start. Итоговый ансамбль фолдов распознаёт весь том, а результат записывается обратно в PageXML для корректуры и сборки текста по порядку чтения.

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

Коллекция газет с несколькими гарнитурами

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

При оценке важно учитывать порядок колонок и переносы между строками. Calamari возвращает строковый текст, но не решает, какая колонка читается первой. Сборщик страницы должен использовать разметку региона и reading order. Ошибки склейки абзацев нельзя приписывать модели распознавания, иначе команда будет улучшать не тот компонент.

Дообучение на новой типографике

Берут готовый checkpoint с близким алфавитом, подготавливают несколько сотен или тысяч репрезентативных строк и выполняют warm start. Валидацию составляют из других страниц или выпусков, чтобы не измерять запоминание фона. Сначала замораживают часть общих слоёв, затем при необходимости размораживают. После каждого этапа сравнивают не только средний CER, но и confusion по новым символам.

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

Интеграция в сервер обработки

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

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

Работа с PDF и многостраничными документами

PDF не является непосредственным входом строкового recognizer. Сначала страницы преобразуют в изображения с контролируемым разрешением, затем выполняют анализ макета и получают отдельные строки или PageXML. Разрешение выбирают так, чтобы высота строчных букв оставалась достаточной после вырезания. Слишком раннее уменьшение страницы уничтожает тонкие штрихи, а чрезмерное увеличение создаёт большие файлы без новых деталей. Для одного проекта параметры рендеринга фиксируют и не меняют между train, val и массовым распознаванием.

Если PDF уже содержит текстовый слой, надо решить, использовать ли его как черновой ground truth. Автоматически извлечённый текст часто имеет неверный порядок, пропуски и нормализацию, поэтому его нельзя без проверки связывать со строками. Более безопасный сценарий — использовать старый OCR для предварительного заполнения, затем сверить каждую обучающую строку по изображению. Ошибки исходного движка, оставленные в GT, станут обучающим сигналом и будут воспроизводиться новой моделью.

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

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

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

Многоязычные, исторические и двунаправленные строки

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

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

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

Комбинируемые знаки нормализуют одинаково во всём наборе. Символ с диакритикой может храниться одной кодовой точкой или последовательностью базовой буквы и combining mark. Визуально варианты совпадают, но для CTC это разные метки. Подход выбирают заранее и применяют к train, val, test и результатам перед оценкой. В противном случае confusion показывает ложные замены, которые пользователь не видит на экране.

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

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

Организация проекта и воспроизводимость

Удобная структура разделяет исходные сканы, разметку, подготовленные строки, списки разбиений, модели и результаты. Исходники делают только для чтения; все преобразования пишут в новый каталог. Тогда ошибочную бинаризацию или сегментацию можно пересоздать, не теряя оригинал. Для каждого набора хранят манифест с идентификатором, путём к изображению, путём к GT, происхождением страницы и назначением train, val или test.

Манифест защищает от утечки между разбиениями. Если одна и та же строка была сохранена в двух разрешениях или после двух вариантов обработки, случайное распределение файлов может поместить копии в train и test. Сравнение perceptual hash и исходного идентификатора выявляет такие дубликаты. Для книг разбиение лучше делать по страницам, выпускам или томам, чтобы тест отражал перенос на новый документ.

Каталоги моделей называют по задаче и параметрам, но окончательное решение фиксируют не именем, а метаданными. Сохраняют команду, хэш манифеста, кодек, случайное зерно, версии зависимостей и итоговые метрики. Имя best без контекста быстро теряет смысл, особенно после повторного обучения. Отдельный файл описывает, почему checkpoint выбран: минимальный CER, лучший результат на редких символах или приемлемый компромисс скорости.

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

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

Ground truth версионируют отдельно от моделей. Исправление одной систематической ошибки меняет смысл метрики: старый checkpoint надо оценить на новой разметке повторно, а не сравнивать старое число с новым. Для крупных коллекций удобно хранить журнал исправлений и номер схемы транскрипции. Это особенно важно при изменении правил пробелов, лигатур и Unicode-нормализации.

Точная настройка производительности

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

Batch size увеличивают ступенчато, пока скорость растёт и память остаётся с запасом. Последние проценты заполнения GPU опасны: одна необычно длинная строка вызывает OOM и останавливает пакет. Практично оставить резерв и установить ограничение максимальной ширины или отдельную очередь для выбросов. Короткие и длинные строки группируют по bucket boundaries; границы выбирают по квантилям распределения, а не произвольно.

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

Prefetch увеличивает очередь готовых пакетов. Большое значение сглаживает задержки диска, но удерживает в памяти несколько дополненных тензоров. При строках переменной ширины это может быть значительный объём. Начинают с автоматического значения, затем наблюдают загрузку GPU и RAM. Если память растёт без ускорения, очередь уменьшают.

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

Скорость записи тоже может стать ограничением при extended JSON. Файл с альтернативами и вероятностями значительно больше простого текста, а тысячи мелких JSON нагружают файловую систему. Для массового запуска расширенный вывод включают только для контрольной выборки или объединяют результаты в контейнер последующим скриптом. Обычные .pred.txt сохраняют для всех строк, если нужен лёгкий повторный eval.

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

Корректура и активное улучшение модели

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

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

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

Новый цикл обучения формируют из исправленных строк и исходного разнообразного набора. Добавление только плохих примеров смещает распределение и может ухудшить обычные строки. Warm start выполняют с меньшим learning rate, оставляют неизменный test и сравнивают confusion. Если исправление одной группы вызывает рост другой ошибки, подбирают баланс примеров или разделяют модели по доменам.

Строки с невозможной геометрией не отправляют в активное обучение. Если распознавание плохо из-за захвата соседней строки, правильная реакция — исправить сегментацию и пересоздать вырезку. Обучение на таком фрагменте учит сеть игнорировать часть изображения непредсказуемым образом. Очередь корректуры должна уметь пометить проблему как segmentation, image quality, transcription или model error.

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

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

ПрограммаЛучше подходит дляГлавное ограничение
Calamari OCRОбучение специализированных моделей распознавания строк, историческая печать, ансамбли фолдовНе выполняет разметку страницы и требует подготовленных строк
KrakenПолный исследовательский конвейер с сегментацией, распознаванием и обучением моделейБольше компонентов и сложнее конфигурация всего процесса
TesseractБыстрое OCR готовых страниц и выпуск TXT, hOCR, TSV или searchable PDFТонкая адаптация к редкой типографике требует отдельного обучения и подготовки
PaddleOCRСовременные многоступенчатые OCR-конвейеры, детекция текста и развёртывание моделейТяжёлый стек и множество модулей избыточны для узкой задачи строк
PDF CommanderРаспознавание сканов внутри рабочего процесса редактирования и сохранения PDFНе предназначен для обучения собственных нейросетевых моделей

Calamari выбирают, когда уже есть сегментация и нужен контролируемый recognizer под конкретный шрифт, письмо или коллекцию. Kraken удобнее, если требуется вместе обучать разметку страницы и чтение строк. Tesseract рационален для массового распознавания обычных страниц и создания поискового PDF без исследовательской настройки. PaddleOCR подходит разработчикам, которым нужны детектор, классификаторы и готовые производственные конвейеры. PDF Commander проще для пользователя, который хочет распознать скан, проверить текст и продолжить редактирование PDF без подготовки ground truth и обучения модели.

Как получить устойчивый результат

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

Перед большим запуском нужен минимальный воспроизводимый эксперимент: фиксированные train, val и test; сохранённая команда; неизменный кодек; несколько контрольных строк; журнал зависимостей. Затем меняют один параметр и сравнивают CER, confusion, скорость и память. Такой порядок даёт больше информации, чем одновременная смена архитектуры, аугментации, размера пакета и правил ground truth.

Готовая модель должна сопровождаться описанием алфавита, высоты строки, типа данных, правил транскрипции и ожидаемой предобработки. Без этого checkpoint формально загружается, но используется неверно. Особенно важны сведения о том, сохранялись ли лигатуры, как кодировались исторические символы и какой text index применялся в PageXML.

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

Calamari раскрывает наибольшую ценность не как кнопка для целого PDF, а как точный обучаемый этап внутри документного конвейера. Подготовленные строки, согласованный ground truth, независимая валидация, разумный warm start и разбор матрицы ошибок дают модель, которую можно проверять и улучшать. При соблюдении этих условий пользователь получает не только распознанный текст, но и воспроизводимую методику для следующей книги, гарнитуры или рукописной коллекции.