Распознавание текста в банке: трудности и решения. llm.. llm. ocr.. llm. ocr. ocr-технологии.. llm. ocr. ocr-технологии. модели.
Распознавание текста в банке: трудности и решения - 1

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

Банковские OCR-задачи

Задача по оптическому распознаванию символов (OCR) заключается в автоматическом извлечении печатного или рукописного текста из изображений. Сюда входит распознавание отдельных символов, их объединение в слова и предложения, а также коррекция ошибок. Результат — текстовая версия информации, представленной на изображении. Что это за задачи:

  • Пользовательские продукты. Например, умная камера: наводите смартфон на текст, и программа распознает платежные реквизиты, или номера телефонов, или реквизиты банковской карты. 

  • Внутренний документооборот. Нужно распознавание и классификация входящей корреспонденции, документов со встреч с клиентами: писем, договоров, паспортов, оферт, СНИЛС и так далее (у нас нет отделений и представители выезжают к клиентам для всех операций).

  • Модерация контента в различных источниках, например анализ содержимого мемов.

  • Помощь операторам с вводом данных.

  • Прикладная помощь бухгалтерам, юристам и прочим сотрудникам, работающим с документами.

  • Поиск документов в разных базах данных. 

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

Умная камера должна очень быстро работать с видеопотоком, при этом распознавать и печатный, и рукописный текст, желательно одной моделью. А для многообразия разовых задач нам нужна была максимальная гибкость настройки. Open-source для русского языка хорошо решал только задачу по чтению крупного, геометрически не искаженного текста.

Наш типичный конвейер OCR

Визуализация стадий обработки изображения OCR системой

Визуализация стадий обработки изображения OCR системой
  1. Сканирование исходника.

  2. Определение текста (Text Detection). CRAFT-модель на архитектуре DbNet++ предсказывает геометрию блоков текста или информацию об этих блоках.

  3. Затем изображение обрабатывают Cropper и LineOCR — аккуратно вырезают все блоки текста и читают их как отдельные строки. Задача по чтению строки текста — это практически сегментация временного ряда. Мы читаем слева направо и считаем, что у нас есть порядок букв, который нужно восстановить. 

  4. Последний этап — восстановление структуры документа: таблиц, расположения блоков на странице.

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

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

Детектор текста мы обучаем:

  • на «чистой» синтетике на основе syntext;

  • синтетике на основе различных сложноструктурированных документов из интернета;

  • небольшом количестве реальных данных для тонкой настройки под конкретные задачи, имеющие большое бизнес-значение.

LineOCR учим почти целиком с помощью синтетики: печатных данных, рукописных (полусинтетики на основе прописей и открытых данных), многочисленных открытых, но маленьких наборов кириллических рукописных текстов — всего около 100 тысяч картинок.

Суммарный объем обучающих данных для детектора текста составил:

  1. ~300 тысяч страниц отрендеренных PDF из интернета;

  2. ~300 тысяч синтетических данных для документо- и книгоподобного домена;

  3. ~400 тысяч синтетических данных с текстом in-the-wild: вывесок, надписей, псевдофотографий.

Для Line OCR:

  1. ~5 млн строк синтетических текстов с различными шрифтами;

  2. ~400 тысяч печатных строк с внутренних доменов;

  3. ~300 тысяч рукописных строк с внутренних доменов;

  4. ~200 тысяч строк из открытых датасетов — как печатных, так и рукописных.

Обнаружение текста

На изображении ниже — результат instance-сегментации моделью на основе CRAFT, которая предсказывает буквы, промежутки между ними и информацию о том, как символы соединены между собой в строки, как строки соединены в абзацы, абзацы соединены в текст. 

Зеленый цвет — гауссианы, которые собирают слова в строки, красные и синие — это буквы и связи «буквы — слова» 

Зеленый цвет — гауссианы, которые собирают слова в строки, красные и синие — это буквы и связи «буквы — слова» 

Хотя мы и обучаем Text Detector видеть все символы в документе и читать их, но еще можем тонко настраивать модель, чтобы она могла видеть только определенные типы текстов, например реквизиты. Это помогает в будущем распознавать не весь документ, а только небольшую его часть, что значительно ускорит работу.

В основном для обучения Text Detector использовали PDF из интернета — это хороший источник данных: там встречается сложная верстка, их можно обогащать, часто есть текстовый слой, который сразу является готовой разметкой. Если бы не несколько но:

  • Не все хотят, чтобы их PDF использовали в любых целях. И некоторые файлы защищены от извлечения текстового слоя: буквы превращаются в набор кривых или все рендерится как одна картинка. 

  • Сам PDF — это скан, текстовый слой поверх которого нанесен другой системой OCR. В этом случае мы не учимся читать честный текст, а делаем fine-tune под чужой OCR, обычно не очень хорошего качества. Ситуация крайне неприятная и внезапно достаточно распространенная в рунете. 

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

Распознавание текста

Схема архитектуры модели. Кастомный СТС декодер не разрешает склеивать подряд идущие символы

Схема архитектуры модели. Кастомный СТС декодер не разрешает склеивать подряд идущие символы

LineOCR основана на модификации модели TrOCR для ее использования с CTC loss. Сверточный энкодер принимает на вход картинку и превращает ее в некоторую последовательность токенов. Дальше эта последовательность попадает в transformer-encoder-блок с ограниченным window attention. На выходе из трансформерного блока стоит CTC-декодер.

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

LineOCR обучали на синтетических печатных текстах, рукописных полусинтетических и открытых данных, а еще на небольшом количестве реальных размеченных рукописных текстов из документов внутри банка.

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

Распознавание текста в банке: трудности и решения - 5

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

Теперь нужно преобразовать выход TextDetector для подачи на вход LineOCR. Это довольно важная часть кода, которая должна работать быстро и решать нетривиальную задачу: находить маски слов, аккуратно их вырезать и собирать в батч.

Распознавание текста в банке: трудности и решения - 6

Код, реализующий функционал поиска масок слов, их вырезки и сбора в батч, у нас реализован на операциях scatter и gather. Они очень эффективно работают на видеокартах.

Cropper вырезает обнаруженный с помощью TD текст, собирает из него упакованный в батч вход для LineOCR, выравнивает смятые строки и делает так, чтобы вход LineOCR был линейным. Работает исключительно на GPU. 

Восстановление структуры документа

Прочитав все слова, нужно понять, в каком порядке читать текст. Если он линейный, то есть один документ и все упорядочено сверху вниз, сложностей никаких. А если текст нелинейный?

Пример простой и сложной структуры текста на изображении

Пример простой и сложной структуры текста на изображении

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

Алгоритм довольно быстрый. С его помощью можно из собранных в интернете PDF извлечь разметку для обучения TD. Большинство же проблем с качеством его работы без проблем решаются последующими за OCR NLP-моделями.

Оптимизация инференса

После всех инженерных трюков у нас получилось решение, эффективно работающее как на серверах, так и на мобильных устройствах. Вот пример профилирования инференса картинки плотного текста А4:

Результат профилирования инференса

Результат профилирования инференса

Эти результаты получены на RTX 3090. Первая часть — декодирование картинки. Она может быть в формате JPEG, PNG, BMP, GIF, PDF. Ее нужно превратить в тензор пикселей. Задача нетривиальная и может занимать довольно много времени. Вполне может быть картинка, которая декодируется 100 миллисекунд, — фотография на много мегапикселей. Картинки среднего размера отрабатываются за 20 миллисекунд, и оптимизировать эту часть практически невозможно. Есть декодеры на GPU, есть — на CPU. На GPU может быть раза в 1,5 быстрее, принципиального выигрыша нет.

TextDetector — это сегментационная модель, работающая с разрешением 1600 × 1600, на базе EfficientNet с головой DbNet++. Легкая модель примерно на 8—10 млн параметров, обрабатывает в среднем за 35 миллисекунд.

Дальше идет наш магический GPU-код. Он отрабатывает примерно за 10—13 миллисекунд, восстанавливая геометрию всех блоков и собирая вход для LineOCR.

LineOCR отрабатывает примерно за 0,4 миллисекунды на строку, но она работает пакетно, поэтому документы размером А4 обрабатываются в среднем за 16 миллисекунд на RTX 3090. Для устройств вроде iPhone 15 Pro или Google Pixel 7 длительность можно умножать примерно втрое.

Аугментации

Хочется обучать модели быстро, поэтому пришлось написать свой набор аугментации (геометрических искажений бумаги), который, может быть, даже когда-нибудь опубликуем. Аугментации должны работать на GPU, потому что мы учим хотя и легкую модель, но на картинках большого разрешения — 1600 × 1600 и больше. Процессору такое лучше не передавать. 

Распознавание текста в банке: трудности и решения - 9

Адаптация под задачи

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

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

И можно заставлять TD маскировать текст, находя только нужный, тем самым резко сокращая все последующие стадии обработки.

Взаимодействие с другими моделями

Разумеется, наша система будет взаимодействовать с другими моделями. В основном выход LineOCR предназначен либо для человека, либо для передачи в NLP-модели. А при значительном дообучении LineOCR разные модели ведут себя по-разному. 

Например, если это очень простые классические NLP-модели, работающие на токенах, им почти все равно на порядок слов, макет документа, выпадение отдельных предлогов и союзов. Если это NLP на старом DL (FastText, ELMO), их embedding часто ломаются от изменения макета документа. С более-менее современными NLP-моделями типа Bert, T5 или простенькими LLM все зависит от удачи и степени повреждения текста в процессе распознавания. Изменение порядка слов или грамматические опечатки их обычно не слишком беспокоят. А с большими LLM мы сейчас набираем статистику работы, но в среднем они не очень чувствительны к выходу LineOCR, и проблема достаточно неплохо решается за счет промпт-инжиниринга.

Советы тем, кто пойдет по нашему пути

  • Не гонитесь за использованием SOTA и больших моделей. Связка из нескольких простых моделей прекрасно работает, не давая значительных просадок в качестве.

  • Все решают данные. Архитектура почти не важна, когда параметров меньше 200 млн. 

  • Нужны генераторы качественной синтетики. На них нужно выделять очень много времени.

  • Нужны очень разнообразные аугментации данных.

  • Нужны данные из разных доменов. Чем шире, тем лучше.

Автор: inkln

Источник

Rambler's Top100