Привет, Хабр! Одним из моих направлений работ является создание базы знаний по обучающим курсам, которые включают текст и видеоматериалы. И некоторое время назад у меня возник вопрос: какое решение для меня будет оптимальным для распознавания текста на кадрах. В частности, что лучше мне подойдет — VLM или связка OCR + LLM, облачное решение или локальная установка.

Более того, я углубился в тематику OCR: посмотрел ряд типичных задач для OCR и материал на Хабр, провел ряд экспериментов. Надеюсь, данная обзорная статья и мои примеры на GitHub помогут Вам быстрее попробовать различные варианты и подобрать оптимальный для своих задач.

В статье рассмотрены следующие решения

  • VLM и OCR сервис на Yandex Cloud

  • VLM от cloud.ru

  • локальная установка Ollama с VLM моделью qwen3-vl:8b

  • локальная установка OCR от Provision

  • OCR библиотека Tesseract

Начну, пожалуй, с VLM, так как это более новый подход по сравнению OCR. VLM расшифровывается как Visual Language Model. Первоначально VLM (или image‑to‑text модели) использовались для описания изображений. В дальнейшем часть VLM моделей были обучены выдать текстовую информацию из изображений при соответствующем запросе (промпте).

Традиционный OCR (optical character recognition) появился еще до архитектуры Transformers, которую используют LLM. Тем не менее и в OCR есть значительный прогресс — можете сравнить классическую библиотеку Tesseract, например, с OCR от Yandex.

VLM на Yandex Cloud

Для использования VLM или любой другой функциональности Yandex Cloud требуется регистрация. При регистрации выдается грант сроком на 60 дней.

В Yandex Cloud есть модели с поднятыми инстансами и без них. На момент написания статьи среди поднятых инстансов не было VLM. VLM‑модели без поднятого инстанса — например, Qwen2.5-VL-32B‑Instruct — можно использовать для запуска задач в пакетном режиме. Если нужен сервис и для него есть приличный объём работы, можно поднять выделенный инстанс. Для объёмных, но не срочных задач — в частности, для моей задачи по распознаванию текста на видео — пакетный режим может быть оптимальным вариантом. Кроме распознавания текста, я также хотел маркировать типы кадров: слайд, демонстрация кода и так далее

У меня есть видеоматериал [1] по созданию аккаунта в Yandex Cloud с некоторыми деталями по выбору моделей. Про пакетный режим давайте я ограничусь скриншотом. Порядок действий: создаете датасет, нажимаете кнопку Запустить, через некоторое время проверяете результат и скачиваете его.

VLM на Cloud.ru

В статье [2] утверждается, что модель DeepSeek‑OCR-2 хорошо себя зарекомендовала для распознавания текста и таблиц на изображениях. Я попробовал запустить ее на задаче с заголовком слайда.

Для запуска этого примера нужно зарегистрироваться на cloud.ru. Как и для Yandex Cloud, нужно создать сервисный аккаунт, а затем создать и сохранить API‑ключ. В левом верхнем углу интерфейса есть кнопка с 9 точками. Нажимаете на нее, затем в строке поиска вводите Пользователи. Далее последовательность такая: Пользователи → Сервисные аккаунты → Создать аккаунт (выбрать уровень — Проект). При генерации API‑ключа для сервисного аккаунта нужно указать область действия Foundation Models.

Как выяснилось, модель хорошо работает на определенном наборе промптов, который можно найти на GitHub странице DeepSeek‑OCR. Получить только заголовок слайда у меня стабильно не получилось. Забегая вперед, скажу, что с данной задачей Qwen3-VL справился. А для DeepSeek‑OCR можно применить рекомендованный промпт «Convert the document to markdown.», а затем из результата извлечь заголовок. Если нужно распознать текст и получить его в структурированном виде, следует рассмотреть использование VLM.

Локальный запуск VLM на Ollama

Ollama — известный движок для локального запуска LLM. Это вариант подойдет тем, у кого есть достаточно мощная видеокарта. Следуя рекомендации из [3], я скачал модель qwen3-vl:8b с типом тензора bf16, но есть версии c fp8 и 4b. Я использую видеокарту AMD Radeon 7900 XTX c 24 гигабайтами видеопамяти. Пример со слайдом у меня отработал за 4 секунды, при этом использовалось 12.2 Gb видеопамяти. Текст успешно распознался.

Для установки Ollama на Linux нужно запустить скрипт

curl -fsSL https://ollama.com/install.sh | sh

На Windows можно скачать установщик с официального сайта. Также доступна установка в Docker.

Для запуска на CPU или видеокарты от Nvidia нужно использовать образ ollama/ollama (docker pull ollama/ollama), а для видеокарты от AMD — ollama/ollama:rocm. Для запуска на AMD Radeon можно использовать такую команду:

gpu_options="--device /dev/kfd --device /dev/dri"
docker run -d \
  --name ollama \
  ${gpu_options} \
  -v /usr/share/ollama/.ollama:/root/.ollama \
  -p 11434:11434 \
  ollama/ollama:rocm

Для запуска на Nvidia GPU укажите gpu_options=“‑gpus=all”, а для запуска на CPU оставьте опцию пустой.

OCR на Yandex Cloud

В отличие от примера с VLM, в данном случае будет использоваться API. Для его использования потребуется создание сервисного аккаунта и ключа для него. В видео [1] демонстрируется создание сервисного аккаунта для использования LLM. Это видео можно использовать и для случая OCR. Только при создании сервисного аккаунта нужно указать роль в каталоге ai.vision.user вместо ai.langugeModels.user, а при создании ключа для этого сервисного аккаунта нужно указать его область действия yc.ai.vision.execute (вместо yc.ai.languageModels.execute).

В документации Yandex Cloud приводится пример с использованием IAM‑токена, но это усложнение по сравнению с использование API‑ключа. Для получения IAM‑токена нужно создать авторизованный ключ, потом поставить на компьютер Yandex Cloud CLI, и «поменять» авторизованный ключ на IAM‑токен. В мое примере используется API‑ключ.

Итак, пример отправляет POST‑запрос и получает JSON с довольно сложной структурой, которая включает:

  • fullText — распознанный текст; для случая обработки скана договора и его последующего анализа, например, с помощью LLM этим можно и ограничиться

  • blocks — блоки текста, для которых приводятся координаты, тип блока (layoutType, например. Заголовок)

  • lines (строки), words (слова)

Все эти дополнительные данные могут пригодится, например, для работы с документами. Рассмотрим, например, паспорт. Номер паспорта написан сбоку. Рядом с номером нет заголовка «номер паспорта».

Кстати, Yandex Cloud поддерживает различные типы документов. Указать тип документа можно при передачи параметров запроса в поле model. По умолчанию тип документа page. Для обработки скана паспорта нужно указать passport. При получении данных паспорта в выводе добавился список entities с данными паспорта, например, {'name': 'gender', 'text': 'муж'}.

Для работы с таблицами надо указать модель table. При этом в ответе добавляется поле tables в котором присутствует rowCount, columnCount и cells, в котором присутствует поле text. Текст выдается как есть, например, «Поясне‑\nние» и нуждается в пост‑обработке.

OCR от Provision

Для ознакомления или личного использования можно воспользоваться trial версией. У этой версии нет пробного периода, но есть ограничение — 50 обращений к сервису до перезапуска. Можно скачать установщик для Windows или использовать docker‑образ

docker pull registry.provlabs.tech/hub/trial/provision_ocr:latest

API Provision предоставляет енд‑поинты вида processing/<тип_документа>, где тип документа может быть

  • default — шаблон общего вида, для которого выдаются блоки с текстом (block[“text”]), координатами (block[“loc”]), меткой (block[“tag”] — аналог layoutType) и вероятностью (block[“prob”])

  • passport — выдается готовый json с осмысленными полями, например, ru_passport_number

  • agreement — выдается текст, разбитый на параграфы; именно этот шаблон имеет смысл использовать для получения текста из сканов договоров

Пример запуска для Provision также использует изображение слайда и выводит его заголовок — определить, что это заголовок, можно легко по размеру шрифта. И все же, основное назначение OCR — работа со сканами документов.

Таблицы могут обрабатываться в шаблоне default. При этом, в отличие от Yandex Cloud, ячейки представлены двумерным массивом. Это позволяет сформировать из ответа данные в csv — формате, написав буквально 4 строчки (демонстрируется в соответствующем примере).

Tesseract — классика OCR

Tesseraсt — известная OCR библиотека, но уступает современным решениям. Так как у меня Ubuntu, я решил воспользоваться docker‑образом от Jitesoft, сделанным из оригинальной библиотеки.

docker pull jitesoft/tesseract-ocr

В этой поставке отсутствует русский язык. Нужно скачать данные для русского и английского языков со страницы Tesseract на GitHub, положить эти данные в одну директорию и указать ее при вызове. Ниже пример запуска:

 docker run \
   -v ./data_samples/${image}:/tmp/${image} \
   -v ./tessdata/:/tmp/tessdata \
   jitesoft/tesseract-ocr -l rus+eng --tessdata-dir /tmp/tessdata /tmp/${image} stdout

Альтернативный вариант — установка без Docker и использование с применением библиотеки pytesseract — описан в статье [4].

О запуске OCR на CPU

При локальной обработке документов можно организовать связку: OCR на CPU, пост‑обработка с помощью LLM на GPU с использованием локальной установки Ollama. У меня 16 ядер, запуск OCR от Provision занимает порядка 5 секунд. За это время на GPU можно провести пост‑обработку предыдущего результат запуска OCR. Для меня это самый простой вариант организации пайплайна, но есть возможность разделения видео‑карты между сервисами [5]. Кроме того, можно сначала запустить все задачи OCR на GPU, а потом запускать пост‑обработку.

Не качественные сканы

С оцифровкой документов может работать, например, бухгалтерия. На обработку, к сожалению, могут приходить плохие сканы. В этом случае галлюцинации VLM крайне нежелательны. Пусть лучше документ будет помечен как требующий ручной перепроверки. Также вспомнил случай в Китае, когда я отправил скан загран‑паспорта для сервиса WeChat. Мне пришла просьба отправить скан заново. Я присмотрелся и увидел, что на скане есть блики. В связи с этим хотелось бы подчеркнуть важность предоставления вероятности. Кстати, в ответе OCR сервиса от Yandex Cloud вероятностей почему‑то нет.

VLM бенчмарка

Я решил проверить, насколько хорошие будут результаты VLM на своей задаче по распознаванию текста на обучающих видеоматериалах. Для этого я взял бенчмарку от сервиса videodb — один из сервисов для создания базы знаний для обучающих видеоматериалов. Для получения измерений для статьи бенчмарку пришлось поправить:

  • добавить модели, о которых я написал в статье

  • заменить контент — теперь это обучающие видео с русским и английским текстом

Бенчмарка доступна на GitHub. cмотрите ветку article. В дальнейшем я планирую проверить и качество маркировки кадров (слайд, IDE, сайт с документацией, работа с командной строкой), но это уже не имеет отношение к тематике OCR.

Как выяснилось, DeepSeek OCR не заточен на эту задачу. У DeepSeek OCR, как написано на его странице в GitHub, нативное разрешение в пределах 1280. Это ниже разрешения экрана. А может он не так уж и хорош для русского языка.

Qwen3 VL (запуск с Ollama)

99.2%

DeepSeek OCR

82.0%

Подчеркну, что результаты для данного бенчмарка не означают, что Qwen3 VL всегда предпочтительнее DeepSeek OCR.

Когда использовать VLM, а когда OCR

VLM имеет смысл применять для извлечения текста из изображения в структурированном виде. Это достаточно эффективное решение, которое выдает текст, а не ответ со сложной структурой.

Связку OCR + LLM можно использовать для того, чтобы:

  • получить более дешевое решение для простых задач (OCR модель можно запускать даже на CPU)

  • получить более детальную информацию по распознаванию, в частности, вероятности вместо галлюцинаций

  • OCR + пост‑обработку легче настроить для какого‑то нестандартного случая, чем дообучать VLM

Материалы

  1. Видео на RUTUBE Создание и настройка аккаунта в Yandex Cloud

  2. Статья на habr Как и зачем мы сделали собственный OCR‑бенчмарк (cloud.ru)

  3. Статья на habr Применение локальных LLM для OCR

  4. Статья на habr Разворачиваем простой OCR‑сервер на Python

  5. Статья на habr Оцифровываем сырую документацию компании с помощью ИИ локально! DeepSeek‑OCR + Qwen 1.5