OCR для Data Lakehouse: от Apache Tika к собственному решению на базе Docling

от автора

Привет, Хабр!

Это Андрей Ловлин, руководитель команды «Фабрика данных. Платформа» компании Диасофт. В предыдущей статье мы рассказывали про S3 Архипелаг – слой хранения для нашей «Фабрики данных» (Digital Q.DataFactory). Сегодня речь пойдет о другой задаче: построение конвейера интеллектуального распознавания документов, загружаемых в нашу «Фабрику данных».

PDF-файлы, сканы, фотографии договоров – все это накапливается в организациях годами. Для построения RAG-систем и работы с LLM эти данные необходимо извлечь из неструктурированных документов и преобразовать в структурированный формат. Задача, на первый взгляд, тривиальная. На практике – не совсем.

Требования к решению

Прежде чем выбирать технологию, мы сформулировали ключевые требования:

  • On-premise развертывание – данные не покидают контур заказчика. Это требование не обсуждается.

  • Импортонезависимость – в Диасофте мы работаем с open source, но не просто     используем готовые решения. Мы форкаем проекты, дорабатываем их и берем на себя       ответственность за поддержку. Это позволяет гарантировать Заказчикам стабильность и независимость от внешних вендоров.

  • Структурированный вывод – Markdown или JSON, пригодный для дальнейшей обработки LLM.

  • Kubernetes – отказоустойчивость и горизонтальное масштабирование

С этими требованиями мы начали исследование доступных OCR-решений.

Этап 1: Выбор инструмента для парсинга документов

Вариант 1: Apache Tika

Apache Tika – зрелый проект с большим сообществом. Поддерживает сотни форматов

документов, имеет хорошую документацию. Логика выбора была простой: берем проверенное решение, интегрируем Tesseract для OCR, получаем рабочий пайплайн.

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

На практике все оказалось сложнее.

Интеграция с Tesseract потребовала установки дополнительных библиотек, языковых пакетов и шрифтов. Конфигурация через tika-config.xml :

<properties>
  <parsers>
     <parser class="org.apache.tika.parser.ocr.TesseractOCRParser">
       <params>
         <param name="language" type="string">rus+eng</param>
       </params>
     </parser>
   </parsers>
</properties>

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

def preprocess_image(image_path):
   img = cv2.imread(image_path)
   angle = detect_skew(img)
   img = rotate_image(img, angle)
   gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
   binary = cv2.adaptiveThreshold(gray, 255,
     cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
   denoised = cv2.fastNlMeansDenoising(binary)
   return denoised

Проблемы с кириллицей. Классическая ситуация: Mojibake, некорректная кодировка, Ð вместо А . Приходилось писать обходные решения:

def fix_encoding(text):
   replacements = {
     'Ð': 'А', 'Ñ': 'С', 'а': 'а', 'б': 'б',
     # ... еще 50 строк замен
   }
   for wrong, correct in replacements.items():
     text = text.replace(wrong, correct)
   return text

Выводы по Apache Tika

Apache Tika – мощный инструмент для извлечения текста. Однако для задач OCR он требует значительных усилий по настройке препроцессинга. Каждый новый тип документа – новый цикл доработки.

Главное ограничение: Apache Tika не анализирует структуру документа. Заголовки, таблицы, списки – все превращается в плоский текст. Для RAG-систем это существенный недостаток.

Вариант 2: docling-serve

Возможности

docling-serve – решение другого класса. Оно изначально построено с использованием нейросетевых моделей и умеет:

  • Layout Analysis – анализ структуры документа

  • Распознавание таблиц – с сохранением структуры

  • Вывод в Markdown – готовый формат для RAG

Тот же документ, который требовал ручной настройки препроцессинга в Apache Tika, docling-serve обработал корректно без дополнительных усилий.

Сравнение подходов

Критерий

Apache Tika + Tesseract

docling-serve

Структура документа

Плоский текст

Markdown с заголовками

Таблицы

Теряется структура

Сохраняется

Препроцессинг

Ручной (OpenCV)

Встроенный

Vision-модели

Нет

Да

Кириллица

Требует доработки

Работает корректно

Настройка

XML-конфигурация

Docker

Ограничения

docling-serve включает PyTorch и набор моделей: VL-модель для OCR, Layout Analysis, Table Former, Figure Classifier, ASR. Docker-образ занимает значительный объем:

REPOSITORY                  TAG                               SIZE
docling-serve           local-cpu-with-models-asr         8.2GB

При этом размер образа напрямую зависит от выбранных моделей. Хотите модель качественнее – образ станет больше. Хотите другую модель – нужно пересобирать образ. Гибкости нет.

В Kubernetes это создает дополнительные сложности. В HA-режиме поднимаются API-серверы и воркеры из одного образа. Например, типовая конфигурация: 3 API-сервера + 3 воркера. Каждый под требует значительных ресурсов, а при обновлении модели необходимо пересобирать и передеплоивать весь образ.

Этап 2: Сервис интеллектуального парсинга документов

Концепция

Идея: сохранить логику обработки документов docling-serve, но вынести VL-модель (Vision-Language) на отдельный сервис.

Этим сервисом стал Шлюз вызова ИИ-моделей из платформы Digital Q.GPT. Digital Q.GPT – платформа для управления ИИ-ассистентами, которая объединяет микросервисы для настройки, запуска и масштабирования моделей на корпоративных данных. В контексте нашей задачи парсинга Digital Q.GPT предоставляет доступ к различным генеративным моделям, включая VL-модели для анализа изображений, по стандартному OpenAI-протоколу.

Благодаря этому мы разделили инфраструктуру. Легковесные модели анализа структуры (Layout Analysis, Table Former, Figure Classifier) работают локально, прямо рядом с документами. А ресурсоемкий инференс VL-моделей переложен на GPU-ноды платформы.

Docling-serve поддерживает расширяемую архитектуру через систему плагинов. Мы написали свой, который вместо локальной VL-модели стучится в удаленный API Digital Q.GPT. Так и получился Сервис интеллектуального парсинга документов.

Принцип работы

Алгоритм обработки: предобработка изображения → кодирование в Base64 → запрос к Шлюзу

вызова ИИ-моделей (Digital Q.GPT) → преобразование ответа в структуру docling-serve.

Сервис использует стандартный OpenAI-совместимый протокол:

{
   "model": "<ваша VL-модель>",
   "messages": [
     {
       "role": "user",
       "content": [
         {"type": "text", "text": "Извлеки текст с изображения. Языки: ru, en"},
         {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}}
       ]
     }
   ]
}

Стандартный формат позволяет использовать любой совместимый провайдер.

Рекурсивная обработка вложений

Реальные документы часто содержат вложенные файлы: PDF с прикрепленными документами, DOCX с внедренными таблицами Excel, презентации с вложенными PDF. Стандартные OCR-решения обычно игнорируют такие вложения или обрабатывают их поверхностно.

Мы реализовали полноценную рекурсивную обработку:

  1. При обработке входного файла (PDF, DOCX, XLSX, PPTX и др.) сервис определяет наличие вложенных файлов.

  2. Каждый вложенный файл извлекается.

  3. Для каждого извлеченного файла рекурсивно выполняется процедура распознавания,

  4. включая повторный анализ вложений.

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

Обработка изображений в Office-документах

Отдельная задача – изображения, встроенные в документы. DOCX, PPTX и другие форматы Office часто содержат сканы, фотографии, схемы с текстом.

Сервис автоматически:

  • Извлекает все изображения из документа.

  • Определяет, содержат ли они текст.

  • Применяет OCR к изображениям с текстовым содержимым.

  • Включает распознанный текст в итоговый результат.

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

Конфигурация

Настройка выполняется через переменные окружения:

# Пример конфигурации (Docker env vars)

DOCLING_SERVE_ENABLE_REMOTE_SERVICES=true
REMOTE_OCR_BASE_URL=http://<ingress-ai-gateway>/api
REMOTE_OCR_MODEL=<ваша VL-модель> # дефолтная модель
REMOTE_OCR_TIMEOUT_S=120
REMOTE_OCR_MAX_IMAGE_SIZE=2400
REMOTE_OCR_JPEG_QUALITY=85

В переменной REMOTE_OCR_MODEL указывается VL-модель по умолчанию. При обращении к сервису можно использовать любую VL-модель, доступную на Шлюзе вызова ИИ-моделей.

Автоматическое определение типа обработки

Не все документы требуют OCR. Сервис автоматически определяет оптимальный способ обработки:

Формат

OCR

Причина

PDF (скан)

Да

Отсутствует текстовый слой

PDF (текст)

Опционально

Текст уже доступен

IMAGE (PNG, JPEG)

Да

Растровое изображение

DOCX, XLSX, PPTX

Текст + изображения

Структура в XML, но изображения требуют OCR

Markdown, HTML

Нет

Текстовая разметка

Это позволяет экономить ресурсы: VL-модель вызывается только когда это необходимо.

Интеграция с корпоративной инфраструктурой

SSO через Keycloak. Сервис интегрирован с Keycloak для единой точки аутентификации.

Пользователи авторизуются через корпоративный SSO — отдельных учетных записей для

сервиса парсинга не требуется. Поддерживаются стандартные протоколы OIDC/OAuth 2.0.

Локализация интерфейса. UI сервиса поддерживает несколько языков. На текущий момент доступны русский и английский интерфейсы. Язык определяется автоматически на основе настроек браузера или может быть выбран вручную.

Результат

  • Размер образа – 2.76GB вместо 8GB (VL-модель вынесена за шлюз, Layout/Table Former/Figure Classifier остались).

  • VL-модели размещены централизованно за Шлюзом вызова ИИ-моделей в составе Digital Q.GPT.

  • Масштабирование – Сервис интеллектуального парсинга документов и шлюз масштабируются независимо.

  • Гибкость – смена VL-модели без пересборки образа, достаточно указать другую модель при запросе.

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

Архитектура решения

Схема взаимодействия

Пайплайн обработки документа

Компоненты решения

Компонент

Назначение

Сервис интеллектуального парсинга документов

Обработка документов, извлечение текста, структуризация

Шлюз вызова ИИ-моделей (Digital Q.GPT)

Маршрутизация запросов к ИИ-моделям, авторизация, логирование, балансировка

ИИ-Ассистент (Digital Q.GPT)

Взаимодействие с пользователями, обработка запросов на естественном языке

S3 Архипелаг

Хранение документов и результатов распознавания

Бенчмарки

В таблице ниже представлено сравнение трех подходов к обработке документов: классического (Apache Tika), монолитного ML (docling-serve) и нашей гибридной архитектуры.

Ключевые архитектурные отличия:

  • Apache Tika: извлекает сырой текст (эвристика) + локальный Tesseract для сканов. Не понимает структуру (таблицы, заголовки).

  • docling-serve: Монолитный ML-пайплайн. Все модели (Layout, TableFormer, Figure Classifier) и OCR работают локально внутри пода.

  • Наш сервис (гибридный): анализ структуры (Layout Analysis, TableFormer, Figure Classifier) работает локально. При этом чистый текст извлекается локально, а распознавание сканов, картинок и печатей делегируется мощной VL-модели через внешний Шлюз ИИ.

Условия тестирования: замеры выполнены для «прогретого» состояния (модели уже загружены в RAM/VRAM, холодный старт исключен). Для нашего сервиса на GPU используется nVidia RTX PRO 5000 Blackwell.

Скорость обработки

Документ

Apache

Tika + Tesseract

docling-

serve (aio на CPU, 8 ядер)

docling-

serve (aio на GPU)

Наш сервис (CPU: 1 ядро + Шлюз вызова ИИ-моделей)

Наш сервис (GPU:

Blackwell + Шлюз вызова ИИ-моделей)

PDF 10 стр., текст

~1.5 сек

~38 сек

~3 сек

~22 сек

~0.6 сек

PDF 10 стр., скан

~25 сек

~65 сек

~12 сек

~40 сек

~16 сек

Изображение 1920×1080

~4.5 сек

~7 сек

~1 сек

~3.5 сек

~2.5 сек

Договор с печатью

~23 сек

~40 сек

~8 сек

~30 сек

~3.5 сек

Наличие GPU (в нашем случае nVidia RTX PRO 5000 Blackwell) кардинально меняет правила игры для нашего сервиса. Модели анализа структуры отрабатывают за доли секунды, а чистый текст извлекается программно без вызова нейросетей. В итоге на смешанных документах (договоры с печатями) сервис упирается только в скорость инференса удаленной VL-модели, но при этом выдает структурированный результат в 6 раз быстрее Apache Tika и почти в 10 раз быстрее стандартного docling-serve на CPU.

Качество распознавания (кириллица)

Метрика: Character Error Rate (CER) – процент ошибочно распознанных символов. Чем ниже, тем лучше.

В этом сравнении мы оцениваем качество распознавания текста классического OCR-движка (Tesseract внутри Apache Tika) и современной VL-модели, используемой в нашем сервисе через Шлюз ИИ. Стандартный docling-serve пропущен, так как использует тот же Tesseract или EasyOCR, которые находятся в одной лиге по качеству с Apache Tika.

Тип документа

Apache Tika + Tesseract (CER)

Наш сервис (VL-модель через Шлюз) (CER)

Чистый скан (высокое качество, ровный)

~2 — 4%

~0.5 — 1

Фото под углом (перспектива, тени)

~15 — 25%

~2 — 5%

С печатью/штампом (текст перекрыт)

~20 — 35%

~3 — 7%

Рукописный текст (кириллица)

~80 — 100%

~10 — 20%

Классический OCR (Tesseract) хорошо работает только на идеальных сканах. Любое отклонение (перекос, тень) или перекрытие текста печатью приводит к катастрофическому росту ошибок. VL-модели, благодаря пониманию семантики и визуального контекста, способны «читать сквозь печать» и компенсировать плохое качество фото, как это делает человеческий глаз. Рукописный текст для Tesseract в принципе недоступен, тогда как VL-модель способна считывать смысл даже со сложной скорописи.

Потребление ресурсов (Kubernetes)

Метрика

Apache Tika

docling-serve (all-in-one)

Сервис интеллектуального парсинга документов

Docker-образ

~500MB

~8GB

2.76GB

CPU limits

2

8

1

Memory limits

1792Mi

8196Mi

1792

CPU requests

1

1

100m

Memory requests

128Mi

512Mi

128Mi

GPU

Не требуется

Желательно

Опционально*

*На GPU могут разворачивается только модели Layout Analysis, Table Former, Figure Classifier.Вычислительно тяжелая VL-модель остается за Шлюзом вызова ИИ-моделей.

Дальнейшее развитие

Аналогичный подход мы применили для обработки аудио. ASR-модели (Whisper) также

размещены за Шлюзом вызова ИИ-моделей. Сервис теперь обрабатывает не только документы,но и голосовые сообщения.

Планы развития:

  • Плагин для Computer Vision – структурированное описание содержимого изображений (диаграммы, схемы, фотографии) для включения в RAG-контекст.

  • Пакетная обработка – очереди, приоритизация, retry-логика.

  • Кэширование – исключение повторной обработки идентичных документов.

  • Расширение форматов – видео, презентации с аудиодорожкой.

Заключение

Путь от Apache Tika к собственному сервису парсинга занял несколько итераций, но результат себя оправдал. Мы использовали расширяемую архитектуру docling-serve и разработали плагин, который заменяет локальную VL-модель на вызов удаленного API.

Результат: сервис с размером образа 2.76GB вместо 8GB, лимитами памяти 1792Mi вместо

8196Mi, при этом с доступом к любым VL-моделям через централизованный Шлюз вызова ИИ-моделей в составе Digital Q.GPT.

Ключевые возможности:

  • Рекурсивная обработка вложенных файлов любой глубины.

  • OCR для изображений, встроенных в Office-документы.

  • Интеграция с корпоративным SSO через Digital Q.Security/Keycloak.

  • Локализованный интерфейс (RU/EN).

Каждый компонент масштабируется независимо. Сервис интеллектуального парсинга документов может не требовать GPU — вычислительные ресурсы сосредоточены за шлюзом. Смена VL-модели не требует пересборки образа.

Если вы решаете аналогичную задачу — описанный подход работает.

ссылка на оригинал статьи https://habr.com/ru/articles/1039044/