How to Build an End-to-End OCR Pipeline with Baidu’s Unlimited-OCR for High-Resolution Images and Multi-Page PDF Parsing Baidu's Unlimited-OCR, a 3B-parameter vision-language model, enables end-to-end OCR for high-resolution images and multi-page PDFs without separate layout analysis, according to a tutorial published on Hugging Face. The tutorial demonstrates a complete pipeline using the model's tiled Gundam and Base inference modes, supporting structured output for dense layouts, tables, and cross-page content. In this tutorial, we build a complete workflow for running Baidu’s Unlimited-OCR https://huggingface.co/baidu/Unlimited-OCR model on document images and multi-page PDFs. We configure the GPU environment, install the required dependencies, load the 3B-parameter vision-language model with automatic selection of bfloat16 or float16, and generate structured sample documents for testing. We then evaluate both the tiled Gundam inference mode and the faster Base mode for single-page OCR before extending the pipeline to multi-page PDF parsing with PyMuPDF and infer multi . Throughout the workflow, we preserve long-context generation settings, repetition controls, and structured output handling to process dense layouts, tables, paragraphs, and cross-page content in a reproducible end-to-end pipeline. python import subprocess, sys def pip install pkgs : subprocess.check call sys.executable, "-m", "pip", "install", "-q", pkgs print " Installing dependencies 1-2 min ..." pip install "transformers==4.57.1", "Pillow", "matplotlib", "einops", "addict", "easydict", "pymupdf", "psutil", "accelerate", print " Done." import os import torch from transformers import AutoModel, AutoTokenizer assert torch.cuda.is available , "No GPU detected In Colab: Runtime - Change runtime type - GPU." gpu name = torch.cuda.get device name 0 print f" GPU: {gpu name}" use bf16 = torch.cuda.is bf16 supported DTYPE = torch.bfloat16 if use bf16 else torch.float16 print f" Using dtype: {DTYPE}" MODEL NAME = "baidu/Unlimited-OCR" print " Downloading model ~6 GB for 3B params in BF16 . First run takes a while..." 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=DTYPE, model = model.eval .cuda print " Model loaded and moved to GPU." We install the required libraries and prepare the Google Colab environment for Unlimited-OCR inference. We verify that a CUDA-enabled GPU is available and automatically choose bfloat16 or float16 based on hardware support. We then load the tokenizer and the 3B-parameter model from Hugging Face, switch them to evaluation mode, and move them to the GPU. python from PIL import Image, ImageDraw, ImageFont import textwrap os.makedirs "inputs", exist ok=True os.makedirs "outputs/single gundam", exist ok=True os.makedirs "outputs/single base", exist ok=True os.makedirs "outputs/multi page", exist ok=True def load font size : for path in "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", : if os.path.exists path : return ImageFont.truetype path, size return ImageFont.load default def make sample page path, page no : W, H = 1240, 1754 img = Image.new "RGB", W, H , "white" d = ImageDraw.Draw img title f, head f, body f = load font 48 , load font 34 , load font 26 d.text 80, 70 , f"Quarterly Operations Report — Page {page no}", fill="black", font=title f d.line 80, 145 , W - 80, 145 , fill="black", width=3 body = "This document demonstrates Unlimited-OCR's one-shot long-horizon " "parsing. The model reads an entire page — headings, paragraphs, " "and tables — and emits structured text in a single decoding pass. " "Unlike classic OCR pipelines, no separate layout-analysis stage " "is required." y = 190 for line in textwrap.wrap body, width=72 : d.text 80, y , line, fill="black", font=body f y += 40 y += 30 d.text 80, y , f"Table {page no}: Regional Revenue USD, millions ", fill="black", font=head f y += 60 rows = "Region", "Q1", "Q2", "Q3" , "North", "12.4", "13.1", "15.0" , "South", "9.8", "10.2", "11.7" , "East", "14.3", "13.9", "16.2" , "West", "11.1", "12.5", "12.9" , col w, row h, x0 = 260, 56, 80 for r, row in enumerate rows : for c, cell in enumerate row : x = x0 + c col w d.rectangle x, y, x + col w, y + row h , outline="black", width=2 d.text x + 14, y + 12 , cell, fill="black", font=body f y += row h y += 50 footer = f"Note {page no}: Figures are illustrative. Multi-page mode stitches " "context across pages, so cross-page references remain coherent." for line in textwrap.wrap footer, width=72 : d.text 80, y , line, fill="black", font=body f y += 40 img.save path return path IMAGE PATH = make sample page "inputs/sample page 1.png", 1 PAGE 2 = make sample page "inputs/sample page 2.png", 2 PAGE 3 = make sample page "inputs/sample page 3.png", 3 print f" Sample pages written: {IMAGE PATH}, {PAGE 2}, {PAGE 3}" import matplotlib.pyplot as plt plt.figure figsize= 6, 8 plt.imshow Image.open IMAGE PATH plt.axis "off" plt.title "Input document page 1 " plt.show We create the required input and output directories and generate three realistic sample document pages with PIL. We add headings, paragraphs, tables, and footnotes to test the model on structured, layout-rich content. We also preview the first generated page with Matplotlib before sending it to the OCR pipeline. print "\n" + "=" 76 print "STEP 4: Single image — GUNDAM mode tiled, high detail " print "=" 76 model.infer tokenizer, prompt="