pimenov.ai

База знаний

Unlimited-OCR от Baidu: парсинг длинных документов одной моделью

Unlimited-OCR от Baidu — открытая модель для парсинга длинных документов и PDF: возможности, запуск через Transformers, vLLM и SGLang, лимиты и сценарии.

Опубликовано

Unlimited-OCR — открытая vision-language модель от Baidu для распознавания и структурного разбора документов. Её сильная сторона в том, что она парсит длинные и многостраничные документы за один проход, без дробления на мелкие фрагменты (подход, который авторы называют one-shot long-horizon parsing).

Что это такое

Unlimited-OCR — это модель на 3 млрд параметров (тип тензоров BF16) с открытыми весами под лицензией MIT. Она развивает идеи DeepSeek-OCR и умеет превращать изображение или скан документа в структурированный текст.

Модель мультиязычная и рассчитана на работу с плотными документами: страницы с мелким текстом, таблицами и сложной вёрсткой. Веса выложены на Hugging Face, где у модели уже больше миллиона загрузок за месяц. Инференс идёт локально на GPU — публичного inference-провайдера у модели пока нет, но её легко поднять через стандартные серверы вывода или развернуть в облаке Baidu.

💡
Vision-language модель (VLM) — это модель, которая принимает на вход изображение и текстовый промпт одновременно. Здесь промпт задаёт задачу (например, разбор документа), а изображение — сам документ.

Возможности и режимы работы

Основные возможности:

  • Разбор одиночного изображения документа в структурированный текст (document parsing).
  • Многостраничный режим для наборов изображений через метод infer_multi.
  • Работа с PDF: страницы конвертируются в изображения (через PyMuPDF), дальше идёт многостраничный разбор.
  • Мультиязычное распознавание.
  • Контекст до 32 768 токенов на один документ.

Для одиночного изображения есть два режима. Их важно различать, потому что от выбора зависит качество на мелком тексте:

РежимПараметрыКогда использовать
gundambase_size=1024, image_size=640, crop_mode=TrueОдиночное изображение с мелким или плотным текстом: режим нарезает страницу на фрагменты
basebase_size=1024, image_size=1024, crop_mode=FalseОдиночное изображение целиком, а также все PDF и многостраничные документы
📌
Для PDF и многостраничных документов доступен только режим base (image_size=1024). Режим gundam работает лишь с одиночным изображением.

На выходе модель отдаёт структурированный текст в Markdown: заголовки, абзацы, списки и таблицы восстанавливаются из вёрстки документа. Схематичный пример разбора страницы с таблицей:

# Отчёт о продажах за II квартал

Ключевые показатели по регионам.

| Регион | Выручка | Рост |
|--------|---------|------|
| Москва | 1.2 млн | +12% |
| СПб    | 0.8 млн | +7%  |

**Итого:** выручка выросла на 9% квартал к кварталу.

Именно сохранение форматирования (жирный текст, списки, таблицы) делает вывод пригодным для прямой индексации в RAG без дополнительной чистки. Пример иллюстративный — реальная разметка зависит от документа.

Требования и установка (Transformers)

Самый простой путь — запуск через Hugging Face Transformers на NVIDIA GPU. Набор зависимостей, проверенный авторами на Python 3.12.3 и CUDA 12.9:

torch==2.10.0
torchvision==0.25.0
transformers==4.57.1
Pillow==12.1.1
matplotlib==3.10.8
einops==0.8.2
addict==2.4.0
easydict==1.13
pymupdf==1.27.2.2
psutil==7.2.2

Загрузка модели и разбор одиночного изображения:

import torch
from transformers import AutoModel, AutoTokenizer

model_name = 'baidu/Unlimited-OCR'
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
model = AutoModel.from_pretrained(
    model_name,
    trust_remote_code=True,
    use_safetensors=True,
    torch_dtype=torch.bfloat16,
)
model = model.eval().cuda()

# Одиночное изображение, режим gundam (нарезка на фрагменты)
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,  # base: image_size=1024, crop_mode=False
    max_length=32768,
    no_repeat_ngram_size=35, ngram_window=128,
    save_results=True,
)

Разбор PDF: сначала переводим страницы в изображения, затем вызываем многостраничный метод infer_multi в режиме base:

import os, tempfile, fitz  # fitz = PyMuPDF

def pdf_to_images(pdf_path, dpi=300):
    doc = fitz.open(pdf_path)
    tmp_dir = tempfile.mkdtemp(prefix='pdf_ocr_')
    mat = fitz.Matrix(dpi / 72, dpi / 72)
    paths = []
    for i, page in enumerate(doc):
        out = os.path.join(tmp_dir, f'page_{i + 1:04d}.png')
        page.get_pixmap(matrix=mat).save(out)
        paths.append(out)
    doc.close()
    return paths

model.infer_multi(
    tokenizer,
    prompt='<image>Multi page parsing.',
    image_files=pdf_to_images('your_doc.pdf', dpi=300),
    output_path='your/output/dir',
    image_size=1024,
    max_length=32768,
    no_repeat_ngram_size=35, ngram_window=1024,
    save_results=True,
)

Запуск через vLLM

vLLM даёт OpenAI-совместимый HTTP-сервер, удобный для встраивания в пайплайны. Разработчики выкладывают готовые Docker-образы под разные GPU:

# По умолчанию (CUDA 13.0)
docker pull vllm/vllm-openai:unlimited-ocr

# Для GPU Hopper (CUDA 12.9)
docker pull vllm/vllm-openai:unlimited-ocr-cu129

Подробности развёртывания и параметры запуска — в официальном рецепте vLLM: https://recipes.vllm.ai/baidu/Unlimited-OCR.

Запуск через SGLang

SGLang — ещё один сервер вывода с OpenAI-совместимым API и поддержкой стриминга. Окружение поднимается через uv: сначала ставится локальный wheel SGLang, затем фиксируется версия kernels и добавляется PyMuPDF для конвертации PDF.

uv venv --python 3.12
source .venv/bin/activate

uv pip install wheel/sglang-0.0.0.dev11416+g92e8bb79e-py3-none-any.whl
uv pip install kernels==0.11.7
uv pip install pymupdf==1.27.2.2
📌
В карточке модели версия kernels указана по-разному: 0.9.0 в тексте и 0.11.7 в примере кода. Здесь взят вариант из блока кода — если сборка не встанет, попробуйте 0.9.0.

Запуск сервера:

python -m sglang.launch_server \
    --model baidu/Unlimited-OCR \
    --served-model-name Unlimited-OCR \
    --attention-backend fa3 \
    --page-size 1 \
    --mem-fraction-static 0.8 \
    --context-length 32768 \
    --enable-custom-logit-processor \
    --disable-overlap-schedule \
    --skip-server-warmup \
    --host 0.0.0.0 \
    --port 10000

Дальше запросы шлются на /v1/chat/completions в формате OpenAI: картинки передаются как image_url в base64, а для контроля повторов подключается кастомный logit-процессор (ngram_size=35). Для одиночного изображения используется image_mode="gundam", для PDF и наборов страниц — image_mode="base".

Запуск на Apple Silicon (Mac)

Все официальные рецепты выше рассчитаны на NVIDIA GPU с CUDA, которого на Mac нет — графика там работает через Metal/MPS. Поэтому на Mac (включая машины M-серии с большим объёмом памяти, например Mac mini M4 Pro с 48 ГБ) модель «из коробки» не запустится. Важный нюанс: упор именно в CUDA, а не в объём памяти — 3B в BF16 занимают ~6 ГБ, и 48 ГБ унифицированной памяти хватает с огромным запасом.

Что можно попробовать и с какими оговорками:

  • Transformers на MPS. Заменить в коде model.eval().cuda() на model.to("mps"). Иногда срабатывает, но модель тянет собственный custom-код и FlashAttention — часть операций на MPS может быть не реализована, так что это эксперимент без гарантий.
  • Transformers на CPU. Убрать .cuda() и считать на процессоре (torch_dtype=torch.float32). Формально заработает, но для 3B vision-language модели будет очень медленно — годится разве что для разовых тестов.
  • Удалённый GPU. Поднять модель через vLLM или SGLang на NVIDIA-GPU (своём или в облаке, в том числе Baidu Cloud), а Mac использовать как клиент к OpenAI-совместимому API.
🍎
Если обработка документов нужна именно локально на Mac, посмотрите Docling: он работает на CPU и Apple Silicon и на M4 Pro пойдёт без плясок с CUDA.

Где ещё доступна модель

  • Hugging Face — основные веса и карточка модели.
  • ModelScope — зеркало весов для доступа из Китая и не только.
  • Baidu Cloud — размещение модели в облаке Baidu (см. OCR-документацию).
  • Hugging Face Spaces — публичное демо, где можно прогнать документ без установки.

Лицензия, стоимость и ограничения

Модель распространяется под лицензией MIT — можно использовать в коммерческих проектах без роялти. Сами веса бесплатны.

Реальная стоимость сводится к железу: нужен NVIDIA GPU. Модель на 3B в BF16 занимает примерно 8–10 ГБ VRAM только под веса, плюс запас на изображения и контекст — на практике комфортный минимум это ~12–16 ГБ (уровень RTX 3060 12 ГБ или 4080), а для длинных PDF и пакетной обработки лучше 24 ГБ и больше. Ключевые ограничения:

  • Публичного inference-провайдера и стороннего API нет — модель разворачивается самостоятельно (Transformers, vLLM или SGLang); облачный запуск от самого вендора возможен через Baidu Cloud.
  • Контекст ограничен 32 768 токенами на документ.
  • Для стабильного качества на длинных документах нужен контроль повторов (параметры no_repeat_ngram_size и ngram_window).
⚠️
На момент публикации Unlimited-OCR не развёрнута ни одним inference-провайдером. Это self-hosted инструмент: без своего GPU (или облака Baidu) запустить его не получится.

Качество: результаты на ParseBench

Модель протестирована на бенчмарке llamaindex ParseBench (pipeline unlimitedocr):

МетрикаЗначение
Text Content (распознавание текста)86.81
Text Formatting (сохранение форматирования)0.97
Mean (усреднённая оценка)46.17

Сильная сторона по цифрам — извлечение текстового содержимого. Метрики приведены в разных шкалах, поэтому интерпретируйте их осторожно и обязательно тестируйте модель на своих документах перед промышленным использованием.

Практические сценарии

  • Оцифровка длинных PDF. Договоры, отчёты, архивы сканов переводятся в структурированный текст за один проход, без ручной нарезки на страницы.
  • Подготовка данных для RAG и базы знаний. Документы превращаются в чистый текст, пригодный для индексации и поиска.
  • Пакетный разбор сканов. Многостраничный режим обрабатывает наборы изображений одним вызовом.
  • Встраивание в агентские пайплайны. Через vLLM или SGLang модель поднимается как OpenAI-совместимый сервис, к которому обращаются ваши агенты и скрипты.

Когда выбирать Unlimited-OCR, а когда соседние инструменты. Unlimited-OCR имеет смысл брать, когда нужен self-hosted парсинг длинных документов одной моделью и есть свой GPU: полный контроль над данными, нулевая стоимость лицензии, ничего не уходит во внешний сервис. Если держать GPU не хочется, а важнее фиксированная цена за страницу и готовый сервис с поддержкой таблиц, формул и 100+ языков — ближе SotaOCR (порядка 25 копеек за страницу, без своей инфраструктуры). Если же задача не столько распознать скан, сколько собрать из офисных форматов (PDF, DOCX, PPTX, HTML) чистую структуру для RAG — сильнее Docling, который работает даже на CPU.

Ссылки


По теме

Если вы собираете пайплайн обработки документов или базу знаний для ИИ-агентов, открытая OCR-модель вроде этой закрывает первый и самый болезненный шаг — превращение сканов и PDF в чистые данные.

Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov.