Привет, Хабр!
Это Андрей Ловлин, руководитель команды «Фабрика данных. Платформа» компании Диасофт. В предыдущей статье мы рассказывали про 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 SIZEdocling-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-решения обычно игнорируют такие вложения или обрабатывают их поверхностно.
Мы реализовали полноценную рекурсивную обработку:
-
При обработке входного файла (PDF, DOCX, XLSX, PPTX и др.) сервис определяет наличие вложенных файлов.
-
Каждый вложенный файл извлекается.
-
Для каждого извлеченного файла рекурсивно выполняется процедура распознавания,
-
включая повторный анализ вложений.
Таким образом, документ с многоуровневой вложенностью обрабатывается полностью — ни один вложенный файл не теряется.
Обработка изображений в Office-документах
Отдельная задача – изображения, встроенные в документы. DOCX, PPTX и другие форматы Office часто содержат сканы, фотографии, схемы с текстом.
Сервис автоматически:
-
Извлекает все изображения из документа.
-
Определяет, содержат ли они текст.
-
Применяет OCR к изображениям с текстовым содержимым.
-
Включает распознанный текст в итоговый результат.
Это позволяет не терять информацию, которая в исходном документе представлена только в виде изображений.
Конфигурация
Настройка выполняется через переменные окружения:
# Пример конфигурации (Docker env vars)
DOCLING_SERVE_ENABLE_REMOTE_SERVICES=trueREMOTE_OCR_BASE_URL=http://<ingress-ai-gateway>/apiREMOTE_OCR_MODEL=<ваша VL-модель> # дефолтная модельREMOTE_OCR_TIMEOUT_S=120REMOTE_OCR_MAX_IMAGE_SIZE=2400REMOTE_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/