Unlimited-OCR от Baidu: OCR, который читает страницу как картинку 📄👁️
Ну чё, малютки, OCR вы себе как представляете? Скан → программа находит буквы → выдаёт текст. Старый добрый Tesseract так и пашет. А вот baidu/Unlimited-OCR делает финт ушами: он вообще не «ищет буквы». Он берёт всю страницу как картинку, жмёт её в горстку визуальных токенов и скармливает языковой модели, которая разворачивает их обратно в текст. Звучит как извращение — а работает.
Это прямой наследник идеи DeepSeek-OCR, и сегодня разложу: что это, как устроено, что умеет и как запустить у себя.
Unlimited-OCR — это не распознавалка букв, а vision-language модель на 3B параметров (лицензия MIT). Она кодирует страницу документа в визуальные токены (оптическое сжатие, ~в 10 раз компактнее текста), а LLM-декодер превращает их в Markdown — с таблицами, формулами и многостраничными PDF. Контекст до 32K токенов, поэтому «long-horizon parsing» целых документов за один проход.
Компактная vision-language модель в BF16. Влезает на одну видеокарту.
Полностью открытая — бери в коммерцию без плясок с бубном.
Хватает, чтобы распарсить многостраничный документ или PDF за один заход.
Главная идея: оптическое сжатие
Вот в чём вся соль. Если кормить LLM длинный документ текстом, токены растут линейно с количеством слов — страница на 1000 слов это ~1400 токенов, десять страниц — уже 14 тысяч. А если ту же страницу закодировать как картинку, визуальный энкодер ужимает её в фиксированную горстку токенов (~256 на страницу), почти независимо от того, сколько там текста.
Потыкай — увидишь, как расходятся текстовые и визуальные токены:
Профит двойной: документ влезает в контекст целиком (отсюда «Unlimited»), и инференс дешевле — LLM обрабатывает сотни визуальных токенов вместо тысяч текстовых. Именно это придумали в DeepSeek-OCR, а Unlimited-OCR, по словам авторов, «толкает идею на шаг дальше» — в сторону длинных документов.
Как работает: пайплайн
Технически это связка «глаза + мозг»: визуальный энкодер видит картинку, языковая модель пишет текст. Жми по шагам:
Авторы прямо благодарят DeepSeek-OCR, DeepSeek-OCR-2 и PaddleOCR. То есть Unlimited-OCR — не магия из ниоткуда, а развитие линейки vision-OCR с оптическим сжатием. Точную начинку (какой именно энкодер и декодер) карточка модели не раскрывает, но архитектурно это тот же подход «картинка → визуальные токены → LLM».
Режимы: gundam vs base
У модели два режима подачи картинки, и это первое, с чем столкнёшься на запуске:
base_size=1024, image_size=640, crop_mode=True) — картинку режут на тайлы по 640px. Больше деталей для плотных и крупных сканов.base_size=1024, image_size=1024, crop_mode=False) — страница целиком в 1024px, без нарезки. Проще и быстрее.Грубое правило: плотный мелкий текст — gundam, обычная страница — base.
Что умеет
У OCR-моделей есть болячка — на длинном документе декодер может зациклиться и повторять один и тот же кусок. Поэтому в вызове стоят no_repeat_ngram_size=35 и окно ngram_window (128 для одной картинки, 1024 для многостраничных) — это защита от зацикливания генерации. Если на выходе ловишь повторы — крути эти параметры.
Как запустить
Вариант 1: transformers (быстро пощупать)
Зависимости (версии из карточки модели):
pip install torch==2.10.0 torchvision==0.25.0 transformers==4.57.1 \
Pillow==12.1.1 einops==0.8.2 addict easydict pymupdf
Сам инференс одной картинки:
import torch
from transformers import AutoModel, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('baidu/Unlimited-OCR', trust_remote_code=True)
model = AutoModel.from_pretrained(
'baidu/Unlimited-OCR',
trust_remote_code=True,
use_safetensors=True,
torch_dtype=torch.bfloat16,
)
model = model.eval().cuda()
model.infer(
tokenizer,
prompt='<image>document parsing.',
image_file='your_image.jpg',
output_path='your/output/dir',
base_size=1024, image_size=640, crop_mode=True, # gundam-режим
max_length=32768,
no_repeat_ngram_size=35, ngram_window=128,
save_results=True,
)
Результат (Markdown + разметка) ложится в output_path. Промпт <image>document parsing. — это задача парсинга документа; токен <image> — место, куда подставляется картинка.
Вариант 2: SGLang (для прода / API)
Если нужен сервер с OpenAI-совместимым API — модель поднимается через SGLang:
python -m sglang.launch_server --model-path baidu/Unlimited-OCR --trust-remote-code
Дальше дёргаешь обычными запросами в /v1/chat/completions с картинкой в content. Точные флаги (порт, размер контекста, tp) смотри в карточке модели — там готовый пример запроса.
transformers — чтобы за 5 минут проверить на паре картинок. SGLang — когда нужен throughput и API под нагрузку (он же даёт батчинг и нормальную утилизацию GPU). Для разовой пакетной обработки PDF хватит и transformers-скрипта в цикле.
Насколько хорош
По бенчмарку ParseBench (llamaindex) у модели средний балл 46.17: сильна в извлечении самого текста (Text Content 86.81), но проседает на сохранении форматирования (Text Formatting 0.97). То есть текст вытащит хорошо, а со сложной вёрсткой пока шероховато — это всё-таки молодая 3B-модель, а не финальный продакшен-комбайн.
Unlimited-OCR — отличный выбор, если надо дёшево и локально распарсить кучу документов/PDF в текст, особенно длинных (контекст 32K + оптическое сжатие — его конёк). Если критична идеальная вёрстка таблиц — тестируй на своих данных и сравни с PaddleOCR / облачными OCR.
TL;DR
Тренд понятен: OCR превращается из «найди буквы» в «vision-language модель, которая читает страницу глазами». Unlimited-OCR — дешёвый открытый способ это пощупать. Качай с HuggingFace и гоняй свои PDF. 🫡