Серверный OCR на vision-модели для отсканированных документов
Как Simmetric Chat читает отсканированные PDF через серверный OCR-конвейер на vision-модели: рендеринг страниц, vision-модель Ollama и шаг ручного одобрения.
Почему отсканированные документы ломают извлечение текста
Попросите текстовый экстрактор прочитать отсканированный PDF - и вы получите почти ничего. PDF, созданный текстовым процессором, несёт текстовый слой: символы хранятся как текст, и извлечение тривиально. PDF, созданный сканером, - это конверт из изображений страниц: текстового слоя нет, только пиксели. Парсер collector может извлечь лишь то, что действительно существует, поэтому чисто графические страницы возвращаются пустыми или почти пустыми, и документ, выглядящий в просмотрщике совершенно читаемым, вообще ничего не добавляет в базу знаний.
Simmetric Chat решает это на сервере, до того как документ достигнет этапа нарезки и эмбеддинга. Когда ingestion обнаруживает PDF, бедный текстом, платформа направляет его в выделенный OCR-конвейер, движок которого - не классическая OCR-библиотека распознавания образов, а языковая модель с vision-возможностями, работающая локально через Ollama. Результат - извлечённый Markdown, сохраняющий заголовки, списки и структуру таблиц намного лучше, чем посимвольный OCR, - и всё это работает полностью на вашей инфраструктуре. Ни один документ никогда не покидает сеть для чтения.
Эта статья описывает, как работает конвейер, какие контроли он открывает и шаг ручного одобрения, не дающий плохо читающей модели молча загрязнить базу знаний.
От пикселей к Markdown: конвейер
OCR в Simmetric Chat - серверный конвейер на базе задач. Загрузка, извлечённый текст которой не проходит преcheck - по умолчанию менее примерно 200 извлекаемых символов помечают документ как отсканированный, - становится OCR-задачей, а polling-планировщик забирает задачи каждые 10 секунд с глобальным лимитом параллелизма, так что пачка загрузок не может перегрузить машину. Дальше один документ проходит пять этапов:
- Загрузка.
pdfjs-distоткрывает PDF на сервере и перечисляет страницы, с потолком в 50 страниц на задачу как защитной границей от неконтролируемой обработки. - Рендеринг. Каждая страница рендерится в PNG-изображение в увеличенном масштабе - по умолчанию 2x, - чтобы даже мелкий шрифт скана факсового качества дошёл до модели с читаемым разрешением.
- Распознавание. Каждое изображение страницы отправляется настроенной vision-модели Ollama как base64-изображение, и модель транскрибирует страницу в текст Markdown.
- Защита. Сырая транскрипция проходит через антигаллюцинационную защиту и шаг очистки grounding. Vision-модели иногда размечают вывод grounding-маркерами или выдумывают правдоподобное содержимое, когда страница действительно нечитаема, - оба случая перехватываются здесь, а не сохраняются.
- Оценка и сборка. Каждая страница получает оценку качества, страницы конкатенируются в один документ, а задача завершается честным резюме: неудачные страницы подсчитываются и сообщаются как неудачные, никогда не растворяясь молча в чистом результате «завершено».
Каждый шаг этого списка выполняется на сервере. Браузер никогда не выполняет OCR, и никакой сторонний OCR-API не вызывается: единственный сетевой переход - от вашего сервера к вашему экземпляру Ollama.
Выбор модели
Vision-модель настраиваема, и конвейер включает небольшой реестр моделей, знающий, как говорить с каждым поддерживаемым семейством:
- glm-ocr - значение по умолчанию (
OCR_MODEL=glm-ocr:latest), vision-модель, специализированная на OCR. Реестр направляет её через chat-эндпоинт Ollama, который для этого семейства надёжнее определяет конец транскрипции. - deepseek-ocr - второе семейство, оптимизированное для OCR и использующее grounding-токены; реестр отправляет ему постраничные изображения и удаляет grounding-маркеры при очистке.
- Любая универсальная vision-модель - модели, которых реестр не знает, откатываются на универсальный промпт через generate-эндпоинт Ollama, так что даже мультимодальная модель, уже работающая у вас локально, подойдёт.
Параметры, связанные с моделью, - это переменные окружения, документированные вместе с остальной конфигурационной поверхностью:
# Серверный vision-OCR
OCR_MODEL=glm-ocr:latest # vision-модель (поддерживает model:version)
OCR_TIMEOUT=600000 # 10 минут - vision-модели медленные
OCR_NUM_PREDICT=8192 # максимум выходных токенов на страницуЭндпоинт prewarm позволяет администратору загрузить модель в память до первой задачи, чтобы первая за день сканированная загрузка не платила за холодный старт модели.
Человек в цикле: одобрить или отклонить
Качество транскрипции варьируется вместе с качеством скана, и база знаний - неподходящее место, чтобы узнать, что модель неверно прочитала страницу. Поэтому конвейер относится к OCR-выводу как к черновику, а не к факту. Каждая задача производит проверяемый артефакт: предпросмотр удерживает извлечённый текст привязанным к той же области страницы, что и панель с изображением, чтобы проверяющий мог сверить любую страницу со сканом, из которого она пришла.
Из панели настроек OCR администратор видит каталог моделей, список задач с оценками качества и достоверности по страницам и сам рабочий процесс:
- Одобрить - извлечённые страницы принимаются и продолжают путь: одобренная архивная задача материализует страницы в базе знаний, а из одобренного результата можно запустить прогон синтеза.
- Отклонить - вывод отбрасывается, и решение фиксируется на задаче.
Автоматизация доступна без отказа от шлюза. Управляемый событиями hook автоматического одобрения может финализировать задачи с чистыми сигналами качества и намеренно сохраняет ручной поток одобрения везде, где человеческое решение - это контракт: импорт, явно направленный в базу знаний, никогда не одобряется автоматически молча. В любом случае резюме задач остаются честными о состоянии страниц: задача, завершившаяся с тремя неудачными страницами, сообщает об этом в результате и логах.
Смысл церемонии - один инвариант: текст попадает в ваш RAG-индекс только после чистого прохождения контроля качества или после того, как его просмотрел человек.
Куда попадает извлечённый текст
Одобренный OCR-вывод возвращается в обычный поток ingestion. Для загруженных документов извлечённый Markdown заменяет отсутствовавший у скана текстовый слой, и документ продолжает путь с нарезкой, эмбеддингом и индексацией для гибридного поиска точно как нативный PDF. Для архивов одобренные страницы становятся частью кураторской базы знаний workspace, где wikilink'и, обратные ссылки и конвейер синтеза могут работать с ними как с любой другой страницей.
Поскольку конвейер серверный, он сочетается с гарантиями остальной платформы: DLP-фильтры продолжают сканировать содержимое до его выхода из сети, RBAC продолжает решать, кто может запускать задачи и одобрять результаты, и ни одна точка OCR-пути не требует исходящего соединения с облачным OCR-сервисом.
Практические настройки
Большинству развёртываний нужны всего три решения:
- Включить.
OCR_ENABLEDиOCR_PRECHECK_CHARS- порог символов, направляющий PDF в конвейер, - управляются в админ-настройках. - Выбрать модель.
glm-ocr:latest- разумное значение по умолчанию; каталог моделей перечисляет то, что знает реестр, выбор модели на задачу доступен из панели настроек, а собственные инструкции могут отточить поведение транскрипции под ваш домен документов. - Заложить время. Vision-OCR обменивает скорость на точность. Таймаут по умолчанию в 10 минут и лимит в 50 страниц существуют, чтобы патологический скан деградировал в видимый сбой, а не в заблокированный worker.
Если ваш корпус в основном из нативных PDF, вы редко будете замечать конвейер: здоровые текстовые слои полностью обходят OCR. Когда приходит отсканированный документ, он проходит рендеринг, vision-модель и ваше одобрение - и становится доступным для поиска вместо невидимого.

