Unlimited-OCR — модель Baidu с открытым репозиторием на 3 млрд параметров для распознавания документов и преобразования их структуры в Markdown. Она поддерживает одиночные изображения и многостраничные документы с контекстом до 32 768 токенов.

Материал основан на официальном репозитории и документации, актуальных на 7 сентября 2026 года. Команды ниже не проверялись практическим запуском в рамках подготовки руководства.

Что делает Unlimited-OCR

Модель принимает изображение документа и текстовую инструкцию, распознаёт содержимое и восстанавливает элементы вёрстки. Результат может содержать заголовки, абзацы, списки и таблицы в разметке Markdown.

💡
Визуально-языковая модель (VLM, vision-language model) одновременно обрабатывает изображение и текстовую инструкцию. Для Unlimited-OCR формулировка промпта и параметры декодирования входят в конфигурацию запуска.

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

  • разбор одного изображения методом infer;
  • обработка набора страниц методом infer_multi;
  • разбор PDF после преобразования страниц в изображения через PyMuPDF;
  • генерация структурированного результата в Markdown;
  • локальный запуск через Transformers, vLLM или SGLang;
  • обучение через ms-swift, поддержка которого добавлена 21 июля 2026 года.

Режимы для изображений и PDF

РежимПараметрыКогда использовать
gundambase_size=1024, image_size=640, crop_mode=TrueОдно изображение, особенно страница с мелким или плотным текстом
baseДля infer: base_size=1024, image_size=1024, crop_mode=False; для infer_multi: image_size=1024Одно изображение целиком, набор страниц или PDF
📌
Многостраничный режим и PDF используют только конфигурацию base. Для них задайте image_size=1024, а окно защиты от повторов увеличьте до 1024.

Запуск через 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

Пример использует BF16, 16-битный формат чисел, и рассчитан на запуск с CUDA:

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,
).eval().cuda()

model.infer(
    tokenizer,
    prompt='document parsing.',
    image_file='your_image.jpg',
    output_path='your/output/dir',
    base_size=1024,
    image_size=640,
    crop_mode=True,
    max_length=32768,
    no_repeat_ngram_size=35,
    ngram_window=128,
    save_results=True,
)
⚠️
Параметр trust_remote_code=True разрешает выполнение пользовательского кода из репозитория модели. Зафиксируйте проверенную ревизию и изучите код перед использованием в среде с чувствительными данными.

Разбор PDF через Transformers

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

import os
import tempfile
import fitz  # PyMuPDF


def pdf_to_images(pdf_path, dpi=300):
    doc = fitz.open(pdf_path)
    tmp_dir = tempfile.mkdtemp(prefix='pdf_ocr_')
    matrix = fitz.Matrix(dpi / 72, dpi / 72)
    paths = []

    for index, page in enumerate(doc):
        output = os.path.join(tmp_dir, f'page_{index + 1:04d}.png')
        page.get_pixmap(matrix=matrix).save(output)
        paths.append(output)

    doc.close()
    return paths


model.infer_multi(
    tokenizer,
    prompt='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,
)

Контекст в 32 768 токенов ограничивает объём результата одного вызова. Длинный PDF может не поместиться целиком, несмотря на поддержку нескольких страниц.

Сервер с OpenAI-совместимым API через vLLM

Для vLLM используется отдельный релизный образ. В официальном рецепте указаны vLLM 0.25.0 и NVIDIA GPU минимум с 8 ГБ VRAM для инференса в BF16; там же отмечено, что архитектура пока недоступна в стабильном pip-wheel.

# Основной образ, CUDA 13.0
docker pull vllm/vllm-openai:unlimited-ocr

# Образ для Hopper, CUDA 12.9
docker pull vllm/vllm-openai:unlimited-ocr-cu129

Пример запуска сервера:

docker run --rm --gpus all --network host --ipc host \
  vllm/vllm-openai:unlimited-ocr \
  baidu/Unlimited-OCR \
  --trust-remote-code \
  --logits_processors vllm.model_executor.models.unlimited_ocr:NGramPerReqLogitsProcessor \
  --no-enable-prefix-caching \
  --mm-processor-cache-gb 0

У модели нет шаблона чата (chat template), поэтому для корректного ответа нужны все части рецепта:

  • текстовый промпт должен начинаться с предусмотренной моделью буквальной инструкции, например document parsing.;
  • skip_special_tokens должен иметь значение False;
  • сервер должен загрузить NGramPerReqLogitsProcessor;
  • запрос должен передать ngram_size=35 и window_size=128;
  • для нескольких страниц или PDF используется window_size=1024.

Без специального промпта модель может вернуть пустой ответ. Без процессора защиты от повторов длинная генерация может зациклиться на координатных токенах. Сырой результат содержит служебные токены привязки к областям страницы, поэтому перед индексацией Markdown потребуется постобработка.

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

Официальный репозиторий содержит пример SGLang с локальным wheel-файлом:

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
⚖️
В README есть расхождение: пояснение требует kernels==0.9.0, а команда устанавливает kernels==0.11.7. Авторы не устранили противоречие, поэтому версию нужно проверять вместе с выбранной ревизией репозитория.

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

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. В примере репозитория также используются skip_special_tokens=False, DeepseekOCRNoRepeatNGramLogitProcessor, ngram_size=35 и window_size 128 или 1024.

Для одиночного изображения задайте image_mode='gundam' и окно 128, для набора страниц — image_mode='base' и окно 1024.

Репозиторий также содержит infer.py для пакетной обработки каталога изображений или PDF с настраиваемой параллельностью.

Как проверить результат

После первого запуска используйте одну страницу с известным содержимым и таблицей:

  1. Убедитесь, что в output_path появился непустой результат.
  2. Сравните заголовки, порядок абзацев и значения нескольких ячеек с оригиналом.
  3. Проверьте, что генерация не повторяет один фрагмент текста или координатные маркеры.
  4. Для серверного запуска проверьте HTTP-ответ /v1/chat/completions и непустое поле choices[0].message.content.
  5. После очистки служебных маркеров откройте Markdown в том же рендерере, который используется в вашем RAG-контуре.

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

Apple Silicon и другие платформы без CUDA

Официальные инструкции описывают NVIDIA GPU и вызов .cuda(). Проверенного рецепта для Apple Silicon в предоставленных источниках нет.

Перенос модели на MPS или CPU потребует самостоятельной проверки пользовательского кода и используемых операций. Для воспроизводимого рабочего контура разумнее использовать удалённый NVIDIA GPU либо облачный сервис. Наличие достаточного объёма унифицированной памяти не означает совместимость CUDA-зависимых компонентов с MPS.

Облачный вариант Baidu Cloud

Официальный репозиторий сообщает, что с 3 июля 2026 года модель доступна в Baidu Cloud. Одновременно Baidu публикует асинхронный API разбора документов, но предоставленный снимок документации не позволяет однозначно подтвердить, что каждый вызов этого API выполняется именно Unlimited-OCR.

Документный API Baidu Cloud принимает 18 форматов, включая PDF, изображения, DOCX, PPTX и XLSX, и может возвращать Markdown, структуру страниц, таблицы и заголовки. Документация также указывает поддержку более 20 языков для этого API.

Схема работы:

  1. Отправьте документ на POST /rest/2.0/brain/online/v2/parser/task и получите task_id.
  2. Опросите POST /rest/2.0/brain/online/v2/parser/task/query.
  3. После статуса success скачайте результат по markdown_url или parse_result_url.

На 21 августа 2026 года документация указывает следующие ограничения:

  • до 50 МБ при передаче файла в base64;
  • до 300 МБ для PDF, переданного по URL;
  • до 50 МБ для остальных форматов по URL;
  • до 2000 страниц в PDF;
  • 2 запроса в секунду (QPS) для создания задач и 10 запросов в секунду для получения результата;
  • ссылки на результат действуют 30 дней.

Это облачный сервис с передачей документов внешнему провайдеру. Для конфиденциальных данных заранее проверьте требования к хранению и обработке информации.

Полезные сценарии

Оцифровка многостраничного PDF

Задача — получить проверяемый Markdown из договора, отчёта или архива сканов. Преобразуйте страницы в изображения и передайте их одним вызовом infer_multi в режиме base. Наблюдаемый результат — непустой результат в output_path, который можно сравнить с оригиналом по заголовкам, абзацам и таблицам. Сценарий ограничен контекстом 32 768 токенов и доступной видеопамятью.

Подготовка документов для RAG

Задача — подготовить документ для RAG (retrieval-augmented generation, генерации ответа по найденным фрагментам). Полученный Markdown очистите от служебных координатных маркеров, проверьте порядок блоков и только затем разбивайте текст на фрагменты для индексации. Наблюдаемый результат — фрагменты, которые сохраняют структуру исходного документа и проходят проверку по страницам. Для критичных документов сохраняйте ссылку фрагмента на страницу и координаты исходной области, если они нужны для последующей проверки. Сценарий не подходит для автоматического принятия решений без контроля качества распознавания.

Пакетная обработка сканов

Задача — обработать каталог изображений или PDF без ручного запуска каждого файла. Используйте infer.py или собственную очередь запросов к SGLang. Начните с небольшой параллельности, измерьте расход памяти и долю ошибочных результатов, затем увеличивайте concurrency. Наблюдаемый результат — отдельный проверяемый результат для каждого входного документа. Сценарий ограничен доступной видеопамятью и параметрами выбранного сервера.

Интеграция в существующий сервис

Задача — подключить OCR к приложению через привычный HTTP-клиент. Поднимите vLLM или SGLang и отправляйте запросы на /v1/chat/completions, передавая обязательный промпт, настройки обработки специальных токенов и параметры защиты от повторов. Наблюдаемый результат — HTTP-ответ с непустым choices[0].message.content. Сценарий требует NVIDIA GPU для официальных локальных рецептов либо передачи документов внешнему облачному провайдеру.

Лицензия и ограничения

Код репозитория распространяется под лицензией MIT. Веса можно запускать самостоятельно, а основные расходы связаны с GPU и инфраструктурой.

Официальный рецепт vLLM называет 8 ГБ VRAM достаточным минимумом для BF16-инференса на одном GPU. Реальный расход зависит от числа и размера страниц, длины результата, выбранного сервера и параллельности, поэтому планировать производственную конфигурацию только по размеру весов нельзя.

Ключевые ограничения:

  • официальные локальные рецепты рассчитаны на NVIDIA GPU;
  • максимальная длина контекста составляет 32 768 токенов;
  • для стабильной длинной генерации требуется защита от повторов;
  • результат нуждается в проверке и очистке служебных маркеров;
  • vLLM пока использует специализированный образ;
  • в инструкции SGLang сохраняется противоречие по версии kernels.

Официальные ссылки

Следующий шаг

Сравните локальный контур с Docling — превращает документы в данные для ИИ: это соседний вариант для той же задачи преобразования документов в данные.

Эта тема полезна командам, которые выбирают между локальным запуском, OpenAI-совместимым сервером и облачной обработкой документов.

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