Привет, Хабр!
Это Андрей Ловлин, руководитель команды «Фабрика данных. Платформа» компании Диасофт. В предыдущей статье мы рассказывали про 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=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‑модели не требует пересборки образа.
Если вы решаете аналогичную задачу — описанный подход работает.