|
Professor Seleznov
|
Привет, Хабр! Это Андрей Ловлин, руководитель команды «Фабрика данных. Платформа» компании Диасофт. В предыдущей статье мы рассказывали про 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-решения обычно игнорируют такие вложения или обрабатывают их поверхностно. Мы реализовали полноценную рекурсивную обработку:
- При обработке входного файла (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 сек |
| Изображение 1920x1080 |
~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-модели не требует пересборки образа. Если вы решаете аналогичную задачу — описанный подход работает.-Источник
|