← Back to Home

Unlimited-OCR: One-Shot Long-Horizon Document Parsing by Baidu

Introduction

Optical Character Recognition (OCR) has come a long way — from Tesseract's line-by-line extraction to modern vision-language models that understand document structure. But most tools still struggle with long-form documents, complex layouts, tables, and multi-page PDFs.

Unlimited-OCR by Baidu changes this entirely. Released on June 22, 2026, it's a vision-language model that performs one-shot long-horizon document parsing — meaning it can take an entire page (or 100+ pages) and produce structured text in a single inference pass. With over 11,000 GitHub stars in its first week, it's one of the fastest-growing open-source AI projects of 2026.

Unlimited-OCR builds on DeepSeek-OCR and DeepSeek-OCR-2, pushing further with larger context windows (32K tokens), better layout understanding, and a two-mode inference system (gundam for single pages, base for multi-page parsing). It supports vLLM and SGLang serving, making it deployable on any NVIDIA GPU via Docker.

This guide walks through what Unlimited-OCR is, why it matters, and how to self-host it on your own infrastructure.


Why Is Unlimited-OCR Trending?

The project exploded in popularity for several reasons:

  • One-shot parsing — no chunking, no stitching, no post-processing. Feed a document in, get structured text out.
  • Multi-page PDF support — converts entire PDFs to structured text with a single API call.
  • Two inference modesgundam mode (base_size=1024, image_size=640, crop_mode=True) for dense single-page documents, and base mode (base_size=1024, image_size=1024) for multi-page parsing.
  • OpenAI-compatible API — deploy via vLLM or SGLang and use any OpenAI SDK client.
  • 32K context window — handles long documents and books without losing coherence.
  • Baidu backing — developed by one of the world's largest AI research teams (no Israeli links — safe for self-hosters who care about provenance).
  • MIT license — free for personal and commercial use.

Architecture Overview

Unlimited-OCR Architecture

The processing pipeline breaks down into four stages:

  1. Input Layer — accepts images (JPG, PNG) or PDFs. For PDFs, PyMuPDF converts each page to a PNG at 300 DPI. Two image modes control how the input is preprocessed: gundam (crops dense content) for single-page documents, and base (full resolution) for multi-page parsing.

  2. Vision Encoder — processes pixel data into visual tokens. The model uses a vision transformer backbone trained on document layouts, tables, handwriting, and mixed-content pages.

  3. Language Model — a DeepSeek-based LLM with 32K token context window generates structured text from the visual tokens. The n-gram repetition avoidance processor (window size 35, ngram window 128–1024) ensures the output doesn't loop or repeat.

  4. Output Layer — returns parsed text as plain text or structured markdown. The results preserve layout order, table structure, and heading hierarchy.


Prerequisites

To self-host Unlimited-OCR, you'll need:

  • NVIDIA GPU with at least 16GB VRAM (RTX 4080, A10, A100, or better). The model runs in bfloat16.
  • Docker installed (for vLLM or SGLang deployment)
  • At least 32GB system RAM
  • 50GB free disk space for the model weights
  • CUDA 12.9 or 13.0 supported GPU drivers
  • Python 3.12+ (if running without Docker)

Setup and Deployment

Option 1: Docker + vLLM (Recommended)

The fastest way to get Unlimited-OCR running is via the official vLLM Docker image:

# For CUDA 13.0 GPUs (default)
docker pull vllm/vllm-openai:unlimited-ocr

# For Hopper GPUs (H100/H200) with CUDA 12.9
docker pull vllm/vllm-openai:unlimited-ocr-cu129

Create a docker-compose.yml for persistent deployment:

version: "3.8"

services:
  unlimited-ocr:
    image: vllm/vllm-openai:unlimited-ocr
    ports:
      - "8000:8000"
    volumes:
      - ~/.cache/huggingface:/root/.cache/huggingface
    command: >
      --model baidu/Unlimited-OCR
      --served-model-name Unlimited-OCR
      --gpu-memory-utilization 0.85
      --max-model-len 32768
      --port 8000
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    restart: unless-stopped

Start the server:

docker compose up -d

Option 2: SGLang Deployment

SGLang offers better batch processing for multi-document workloads:

# Create a Python 3.12 virtual environment with uv
uv venv --python 3.12
source .venv/bin/activate

# Install SGLang wheel for Unlimited-OCR
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

# Start the server
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 \
    --host 0.0.0.0 \
    --port 10000

Option 3: Transformers (Python)

For direct integration without a serving layer:

pip install torch==2.10.0 torchvision==0.25.0 transformers==4.57.1 \
Pillow==12.1.1 pymupdf==1.27.2.2 einops==0.8.2 addict==2.4.0
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,
    torch_dtype=torch.bfloat16,
).eval().cuda()

# Single image — gundam mode for dense content
model.infer(
    tokenizer,
    prompt="<image>document parsing.",
    image_file="invoice.jpg",
    output_path="./ocr_output",
    base_size=1024, image_size=640, crop_mode=True,
    max_length=32768,
    no_repeat_ngram_size=35, ngram_window=128,
)

# Multi-page PDF parsing
import fitz, os, tempfile

def pdf_to_images(pdf_path, dpi=300):
    doc = fitz.open(pdf_path)
    tmp = tempfile.mkdtemp(prefix="pdf_ocr_")
    mat = fitz.Matrix(dpi / 72, dpi / 72)
    paths = []
    for i, page in enumerate(doc):
        out = os.path.join(tmp, 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("report.pdf", dpi=300),
    output_path="./ocr_output",
    image_size=1024,
    max_length=32768,
    no_repeat_ngram_size=35, ngram_window=1024,
)

Using the OpenAI-Compatible API

Once vLLM or SGLang is running, you can use any OpenAI SDK to call Unlimited-OCR:

import base64
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"  # vLLM doesn't require an API key locally
)

with open("document.png", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()

response = client.chat.completions.create(
    model="Unlimited-OCR",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Parse this document completely."},
            {"type": "image_url", "image_url": {
                "url": f"data:image/png;base64,{b64}"
            }}
        ]
    }],
    temperature=0,
    max_tokens=32768
)

print(response.choices[0].message.content)

Batch Processing

For bulk OCR jobs, use the built-in infer.py script:

# Process an entire directory of images
python infer.py \
    --image_dir ./scans \
    --output_dir ./parsed \
    --concurrency 8 \
    --image_mode gundam

# Process a PDF
python infer.py \
    --pdf ./annual_report.pdf \
    --output_dir ./parsed \
    --concurrency 8 \
    --image_mode base

Configuration Reference

Parameter Default Description
base_size 1024 Base resolution for image preprocessing
image_size 640 (gundam), 1024 (base) Input image resolution
crop_mode True (gundam), False (base) Whether to crop dense content
max_length 32768 Maximum output token length
no_repeat_ngram_size 35 N-gram window for repetition avoidance
ngram_window 128 (gundam), 1024 (base) Context window for n-gram dedup

Verification Checklist

After deployment, test that everything works:

  • Single image OCR works: process an invoice or scanned page → verify structured text output
  • Multi-page PDF: process a 5+ page document → verify all pages are parsed in order
  • API endpoint responds: curl http://localhost:8000/v1/models returns the model list
  • GPU utilization: nvidia-smi shows the model using GPU memory
  • No repetition artifacts: output should not have repeated phrases (the n-gram processor prevents this)
  • No broken links: all dependencies (PyMuPDF, torch, transformers) are installed correctly

Resources

← Retour à l'Accueil

Unlimited-OCR : Parsing de Documents Long-Horizon en Un Seul Passage par Baidu

Introduction

La reconnaissance optique de caractères (OCR) a parcouru un long chemin — de l'extraction ligne par ligne de Tesseract aux modèles vision-langage modernes qui comprennent la structure des documents. Mais la plupart des outils peinent encore avec les documents longs, les mises en page complexes, les tableaux et les PDF multi-pages.

Unlimited-OCR par Baidu change tout cela. Publié le 22 juin 2026, c'est un modèle vision-langage qui effectue un parsing de documents long-horizon en un seul passage — il peut prendre une page entière (ou plus de 100 pages) et produire du texte structuré en une seule inférence. Avec plus de 11 000 étoiles GitHub en une semaine, c'est l'un des projets open source IA à la croissance la plus rapide de 2026.

Unlimited-OCR s'appuie sur DeepSeek-OCR et DeepSeek-OCR-2, allant plus loin avec des fenêtres de contexte plus larges (32K tokens), une meilleure compréhension de la mise en page, et un système d'inférence à deux modes (gundam pour les pages simples, base pour le parsing multi-pages). Il prend en charge vLLM et SGLang, ce qui le rend déployable sur n'importe quel GPU NVIDIA via Docker.

Ce guide explique ce qu'est Unlimited-OCR, pourquoi il est important, et comment l'auto-héberger sur votre propre infrastructure.


Pourquoi Unlimited-OCR Est-Il Tendance ?

Le projet a explosé en popularité pour plusieurs raisons :

  • Parsing en un seul passage — pas de découpage, pas d'assemblage, pas de post-traitement. Insérez un document, obtenez du texte structuré.
  • Support PDF multi-pages — convertit des PDF entiers en texte structuré avec un seul appel API.
  • Deux modes d'inférence — mode gundam (base_size=1024, image_size=640, crop_mode=True) pour les documents denses d'une seule page, et mode base (base_size=1024, image_size=1024) pour le parsing multi-pages.
  • API compatible OpenAI — déployez via vLLM ou SGLang et utilisez n'importe quel SDK OpenAI.
  • Fenêtre de contexte 32K — gère les documents longs et les livres sans perte de cohérence.
  • Soutien de Baidu — développé par l'une des plus grandes équipes de recherche IA au monde.
  • Licence MIT — gratuit pour usage personnel et commercial.

Architecture

Architecture Unlimited-OCR

Le pipeline de traitement se décompose en quatre étapes :

  1. Couche d'entrée — accepte les images (JPG, PNG) ou les PDF. Pour les PDF, PyMuPDF convertit chaque page en PNG à 300 DPI. Deux modes d'image contrôlent le prétraitement : gundam (recadrage du contenu dense) pour les documents d'une seule page, et base (pleine résolution) pour le parsing multi-pages.

  2. Encodeur visuel — traite les données pixel en tokens visuels. Le modèle utilise un transformateur visuel entraîné sur des mises en page de documents, des tableaux, des écritures manuscrites et des pages à contenu mixte.

  3. Modèle de langage — un LLM basé sur DeepSeek avec une fenêtre de contexte de 32K tokens génère du texte structuré à partir des tokens visuels. Le processeur de répétition n-gram (taille de fenêtre 35, fenêtre ngram 128–1024) empêche les boucles et répétitions.

  4. Couche de sortie — retourne le texte parsé sous forme de texte brut ou markdown structuré. Les résultats préservent l'ordre de mise en page, la structure des tableaux et la hiérarchie des titres.


Prérequis

Pour auto-héberger Unlimited-OCR, vous aurez besoin :

  • GPU NVIDIA avec au moins 16 Go de VRAM (RTX 4080, A10, A100, ou mieux). Le modèle fonctionne en bfloat16.
  • Docker installé (pour le déploiement vLLM ou SGLang)
  • Au moins 32 Go de RAM système
  • 50 Go d'espace disque libre pour les poids du modèle
  • Pilotes GPU compatibles CUDA 12.9 ou 13.0
  • Python 3.12+ (si exécution sans Docker)

Installation et Déploiement

Option 1 : Docker + vLLM (Recommandé)

La façon la plus rapide d'exécuter Unlimited-OCR est via l'image Docker officielle vLLM :

# Pour GPU CUDA 13.0 (par défaut)
docker pull vllm/vllm-openai:unlimited-ocr

# Pour GPU Hopper (H100/H200) avec CUDA 12.9
docker pull vllm/vllm-openai:unlimited-ocr-cu129

Créez un docker-compose.yml pour un déploiement persistant :

version: "3.8"

services:
  unlimited-ocr:
    image: vllm/vllm-openai:unlimited-ocr
    ports:
      - "8000:8000"
    volumes:
      - ~/.cache/huggingface:/root/.cache/huggingface
    command: >
      --model baidu/Unlimited-OCR
      --served-model-name Unlimited-OCR
      --gpu-memory-utilization 0.85
      --max-model-len 32768
      --port 8000
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    restart: unless-stopped

Démarrez le serveur :

docker compose up -d

Option 2 : Déploiement SGLang

SGLang offre un meilleur traitement par lots pour les charges de travail multi-documents :

# Créez un environnement virtuel Python 3.12 avec uv
uv venv --python 3.12
source .venv/bin/activate

# Installez la roue SGLang pour Unlimited-OCR
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

# Démarrez le serveur
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 \
    --host 0.0.0.0 \
    --port 10000

Option 3 : Transformers (Python)

Pour une intégration directe sans couche de service :

pip install torch==2.10.0 torchvision==0.25.0 transformers==4.57.1 \
Pillow==12.1.1 pymupdf==1.27.2.2 einops==0.8.2 addict==2.4.0
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,
    torch_dtype=torch.bfloat16,
).eval().cuda()

# Image unique — mode gundam pour contenu dense
model.infer(
    tokenizer,
    prompt="<image>document parsing.",
    image_file="facture.jpg",
    output_path="./ocr_output",
    base_size=1024, image_size=640, crop_mode=True,
    max_length=32768,
    no_repeat_ngram_size=35, ngram_window=128,
)

# Parsing PDF multi-pages
import fitz, os, tempfile

def pdf_to_images(pdf_path, dpi=300):
    doc = fitz.open(pdf_path)
    tmp = tempfile.mkdtemp(prefix="pdf_ocr_")
    mat = fitz.Matrix(dpi / 72, dpi / 72)
    paths = []
    for i, page in enumerate(doc):
        out = os.path.join(tmp, 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("rapport.pdf", dpi=300),
    output_path="./ocr_output",
    image_size=1024,
    max_length=32768,
    no_repeat_ngram_size=35, ngram_window=1024,
)

Utilisation de l'API Compatible OpenAI

Une fois vLLM ou SGLang en cours d'exécution, vous pouvez utiliser n'importe quel SDK OpenAI pour appeler Unlimited-OCR :

import base64
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="non-nécessaire"
)

with open("document.png", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()

response = client.chat.completions.create(
    model="Unlimited-OCR",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Parsez ce document complètement."},
            {"type": "image_url", "image_url": {
                "url": f"data:image/png;base64,{b64}"
            }}
        ]
    }],
    temperature=0,
    max_tokens=32768
)

print(response.choices[0].message.content)

Traitement par lots

Pour les travaux OCR en masse, utilisez le script infer.py intégré :

# Traitez un répertoire entier d'images
python infer.py \
    --image_dir ./scans \
    --output_dir ./parsed \
    --concurrency 8 \
    --image_mode gundam

# Traitez un PDF
python infer.py \
    --pdf ./rapport_annuel.pdf \
    --output_dir ./parsed \
    --concurrency 8 \
    --image_mode base

Référence de Configuration

  • base_size — 1024 (résolution de base pour le prétraitement d'image)
  • image_size — 640 (gundam), 1024 (base) (résolution d'image d'entrée)
  • crop_mode — True (gundam), False (base) (recadrage du contenu dense)
  • max_length — 32768 (longueur maximale des tokens de sortie)
  • no_repeat_ngram_size — 35 (fenêtre n-gram pour éviter les répétitions)
  • ngram_window — 128 (gundam), 1024 (base) (fenêtre de contexte n-gram)

Liste de Vérification

Après le déploiement, testez que tout fonctionne :

  • OCR d'image unique fonctionne : traitez une facture ou une page scannée → vérifiez la sortie de texte structuré
  • PDF multi-pages : traitez un document de 5+ pages → vérifiez que toutes les pages sont parsées dans l'ordre
  • L'endpoint API répond : curl http://localhost:8000/v1/models renvoie la liste des modèles
  • Utilisation GPU : nvidia-smi montre le modèle utilisant la mémoire GPU
  • Aucun artefact de répétition : la sortie ne doit pas contenir de phrases répétées
  • Aucun lien cassé : toutes les dépendances sont installées correctement

Ressources