{"id":64601,"date":"2026-07-24T16:25:36","date_gmt":"2026-07-24T20:25:36","guid":{"rendered":"https:\/\/overcentral.com\/en\/?p=64601"},"modified":"2026-07-24T16:25:36","modified_gmt":"2026-07-24T20:25:36","slug":"unlimited-ocr-pipeline","status":"publish","type":"post","link":"https:\/\/overcentral.com\/en\/unlimited-ocr-pipeline\/","title":{"rendered":"Unlimited-OCR Builds Full OCR Pipeline for High-Res, Multi-Page PDFs"},"content":{"rendered":"<p>Baidu\u2019s Unlimited-OCR model, a 3-billion-parameter vision-language system, is reshaping how developers approach document parsing. Unlike traditional OCR pipelines that rely on separate layout analysis, text detection, and recognition stages, this model processes entire pages\u2014including headings, tables, paragraphs, and footnotes\u2014in a single decoding pass. The result is a unified, end-to-end workflow that handles both high-resolution single-page documents and multi-page PDFs with remarkable fidelity. In this tutorial, we walk through the complete pipeline: from GPU environment setup and dependency installation to generating sample documents, running single-image inference in Gundam and Base modes, and extending the system to parse multi-page PDFs using PyMuPDF and the model\u2019s <code>infer_multi()<\/code>codecodecodecodecode method. The entire workflow is designed for reproducibility inside <a href=\"https:\/\/www.google.com\/\" target=\"_blank\" rel=\"noopener noreferrer\" data-iacss-external=\"1\">Google<\/a> Colab, making it accessible to researchers, engineers, and data scientists who need accurate, long-context OCR without the overhead of traditional multi-stage systems.<\/p>\n<h2>Setting Up the GPU Environment for Unlimited-OCR Inference<\/h2>\n<p>The first step in building a reliable OCR pipeline is configuring the runtime environment to support the model\u2019s memory and compute requirements. Unlimited-OCR, with its 3 billion parameters, demands a CUDA-enabled GPU and sufficient VRAM. In Google Colab, this means selecting a GPU runtime (T4, V100, or A100). The setup script begins by installing essential Python packages: <code>transformers<\/code>codecodecodecodecode (version 4.57.1), <code>Pillow<\/code>codecodecodecodecode, <code>matplotlib<\/code>codecodecodecodecode, <code>einops<\/code>codecodecodecodecode, <code>addict<\/code>codecodecodecodecode, <code>easydict<\/code>codecodecodecodecode, <code>pymupdf<\/code>codecodecodecodecode, <code>psutil<\/code>codecodecodecodecode, and <code>accelerate<\/code>codecodecodecodecode. These libraries handle model loading, image processing, PDF rasterization, and performance monitoring.<\/p>\n<p>After installation, the script checks for GPU availability and automatically selects the optimal data type. If the GPU supports bfloat16, the model loads in bfloat16; otherwise, it falls back to float16. This adaptive dtype selection is critical for memory efficiency\u2014bfloat16 halves the memory footprint compared to float32 without sacrificing numerical stability. The model and tokenizer are then loaded from <a href=\"https:\/\/overcentral.com\/en\/hugging-face-ai-agent-hack\/\" title=\"Hugging Face Fights AI Agent Hack with Open LLM\" data-iacss-internal=\"1\">Hugging Face<\/a> using <code>AutoModel.from_pretrained()<\/code>codecodecodecodecode and <code>AutoTokenizer.from_pretrained()<\/code>codecodecodecodecode with <code>trust_remote_code=True<\/code>codecodecodecodecode, because the model relies on custom code for its architecture. The model is moved to the GPU in evaluation mode, ready for inference.<\/p>\n<h2>Generating Realistic Sample Documents for Testing<\/h2>\n<p>To validate the pipeline, we create three sample pages that mimic a quarterly operations report. Each page is a 1240\u00d71754 pixel image generated with PIL, containing a title, a multi-line paragraph, a table with regional revenue data, and a footnote. The table includes columns for Region, Q1, Q2, and Q3, with rows for North, South, East, and West. The footnotes reference cross-page content, testing the model\u2019s ability to maintain context across pages. The images are saved as PNG files in an <code>inputs<\/code>codecodecodecodecode directory. A quick preview using Matplotlib confirms the layout before feeding the images into the OCR pipeline.<\/p>\n<p>This synthetic data generation step is essential for controlled testing. It allows us to verify that the model correctly extracts structured information from tables, reads body text without hallucination, and preserves the hierarchical relationship between headings and content. The same approach can be adapted to <a href=\"https:\/\/overcentral.com\/en\/real-mo-tama-anime-adaptation\/\" title=\"Real mo Tama Manga Gets Anime Adaptation in 2027\" data-iacss-internal=\"1\">real<\/a>aa-world documents by replacing the <code>make_sample_page()<\/code>codecodecodecodecode function with a PDF-to-image conversion routine.<\/p>\n<h2>Single-Image OCR: Gundam Mode vs. Base Mode<\/h2>\n<p>Unlimited-OCR offers two inference modes for single images: Gundam (tiled) and Base (single view). Understanding the difference is key to choosing the right configuration for your use case.<\/p>\n<h3>Gundam Mode: Tiled Crops for Dense, Small Text<\/h3>\n<p>Gundam mode combines a global view of the document with a series of tiled image crops. The pipeline sets <code>base_size=1024<\/code>codecodecodecodecode and <code>image_size=640<\/code>codecodecodecodecode with <code>crop_mode=True<\/code>codecodecodecodecode. The smaller tile size (640 pixels) allows the model to focus on fine details, such as small font sizes, dense tables, or footnotes. The global view provides context, while the crops ensure that no text region is missed. This mode is ideal for documents with complex layouts, multiple columns, or very small print. The inference call uses <code>max_length=32768<\/code>codecodecodecodecode to accommodate long outputs, <code>no_repeat_ngram_size=35<\/code>codecodecodecodecode to reduce repetition, and <code>ngram_window=128<\/code>codecodecodecodecode to stabilize the decoding process. The results are saved to the <code>outputs\/single_gundam<\/code>codecodecodecodecode directory.<\/p>\n<h3>Base Mode: Single View for Clean, Clearly Printed Pages<\/h3>\n<p>Base mode processes the entire image at a single resolution of 1024 pixels, with <code>crop_mode=False<\/code>codecodecodecodecode. This eliminates the overhead of tiling, making inference faster and more memory-efficient. For documents with clean, large fonts and simple layouts, Base mode produces equally accurate output while reducing latency. The same generation parameters (max_length, no_repeat_ngram_size, ngram_window) are retained to ensure consistency. The output is saved to <code>outputs\/single_base<\/code>codecodecodecodecode.<\/p>\n<p>A direct comparison between the two modes reveals that Gundam mode excels on documents with dense, small text or irregular layouts, while Base mode is sufficient for standard printed pages. The choice depends on the quality and complexity of your input images.<\/p>\n<h2>Building a Multi-Page PDF Pipeline<\/h2>\n<p>Real-world documents often span multiple pages. Unlimited-OCR supports multi-page parsing through the <code>infer_multi()<\/code>codecodecodecodecode method, which processes a sequence of page images in a single long-horizon inference pass. This is a significant advantage over traditional OCR, which typically processes each page independently and then merges results\u2014often losing cross-page context such as table continuations or footnotes that reference earlier pages.<\/p>\n<p>To prepare the input, we construct a three-page PDF from the sample images using PyMuPDF (fitz). The PDF creation step opens each image as a separate page, then saves the combined document. Next, we rasterize the PDF back to high-resolution PNG images at 300 DPI using a custom <code>pdf_to_images()<\/code>codecodecodecodecode function. This ensures that the model receives the same visual quality as the original generated pages. The resulting list of image paths is passed to <code>model.infer_multi()<\/code>codecodecodecodecode with <code>image_size=1024<\/code>codecodecodecodecode, <code>max_length=32768<\/code>codecodecodecodecode, and a wider <code>ngram_window=1024<\/code>codecodecodecodecode to maintain coherence across the entire document.<\/p>\n<p>The <code>infer_multi()<\/code>codecodecodecodecode method is designed to handle long context <a href=\"https:\/\/www.microsoft.com\/windows\" target=\"_blank\" rel=\"noopener noreferrer\" data-iacss-external=\"1\">windows<\/a>. It concatenates the tokenized representations of each page image, allowing the model to reference information from earlier pages when generating the output for later pages. This is particularly useful for documents with cross-page tables, multi-page narratives, or sequential annotations. The output artifacts\u2014text, Markdown, MMD, and JSON\u2014are saved to <code>outputs\/multi_page<\/code>codecodecodecodecode.<\/p>\n<h2>Inspecting OCR Outputs and Understanding the Artifacts<\/h2>\n<p>After inference, the pipeline inspects the output directories for each run. It lists all files, their sizes, and for text-based formats (TXT, MD, MMD, JSON), it displays a preview of the first 1500 characters. This step is crucial for verifying the quality of the OCR extraction. The model produces structured output that mirrors the original document layout: headings are preserved, tables are formatted as markdown tables, and paragraphs are separated by line breaks. The JSON output includes the raw text, as well as metadata such as bounding boxes for each detected element (if saved).<\/p>\n<p>In the Gundam mode output, we typically see more detailed table extraction because the tiled crops capture cell boundaries precisely. Base mode may occasionally merge adjacent table cells if the global resolution is insufficient. The multi-page output demonstrates coherence across pages: the footnote on page 3 correctly references \u201cNote 3\u201d and the table on page 2 appears in sequence. The model does not repeat headers or lose the narrative flow, thanks to the long-context generation settings.<\/p>\n<h2>How Does Unlimited-OCR Compare to Traditional OCR Pipelines?<\/h2>\n<p>Traditional OCR systems (e.g., Tesseract, Google Cloud Vision) typically require a separate layout analysis step to detect text regions, then perform character recognition, and finally post-process the results. This multi-stage pipeline is error-prone\u2014misalignment in layout analysis can cascade into incorrect text recognition. Unlimited-OCR, as a vision-language model, bypasses this by directly generating text from the visual input. It uses a single transformer-based architecture that learns to attend to both global and local features. The model is pre-trained on a large corpus of document images and text, enabling it to understand structural cues like tables, headings, and lists without explicit rules.<\/p>\n<p>For dense, small text, the Gundam mode\u2019s tiling strategy mimics human reading: we scan the page in a grid, focusing on each region. The model\u2019s ability to repeat this process for multiple crops ensures that no text is missed. In contrast, traditional OCR with fixed sliding windows may miss small fonts or fail to detect table boundaries. Additionally, the long-context generation (up to 32,768 tokens) allows Unlimited-OCR to output entire documents in one pass, reducing the need for complex stitching algorithms.<\/p>\n<h2>Configuring Generation Parameters for Stable Long-Output<\/h2>\n<p>One of the key challenges in large language model-based OCR is preventing repetitive or degenerate outputs, especially when the model generates thousands of tokens. The pipeline uses two critical parameters: <code>no_repeat_ngram_size<\/code>codecodecodecodecode and <code>ngram_window<\/code>codecodecodecodecode. <code>no_repeat_ngram_size=35<\/code>codecodecodecodecode prevents the model from generating the same 35-gram (sequence of 35 tokens) more than once. This dramatically reduces repetitive loops, which are common when the model is uncertain about the layout. The <code>ngram_window<\/code>codecodecodecodecode parameter limits the context over which the repetition penalty is applied\u2014128 for single pages and 1024 for multi-page documents. A larger window allows the model to use longer-range context but may increase computational cost. These settings are adopted from the original model\u2019s best practices and have been validated on long-form document parsing tasks.<\/p>\n<p>Another important parameter is <code>max_length<\/code>codecodecodecodecode. The default of 32768 tokens is sufficient for most multi-page documents. If your document is extremely long (e.g., 50 pages), you may need to increase this value, but GPU memory will become a bottleneck. The model\u2019s architecture supports a maximum context length of 4096 tokens per image, but multi-page inputs are concatenated, so the effective limit depends on the number of pages and the tokenizer\u2019s compression rate.<\/p>\n<h2>Practical Considerations for Scaling the Pipeline<\/h2>\n<p>The pipeline as described runs comfortably on a single Colab GPU (T4 with 16GB VRAM). For larger documents or higher-resolution images, consider the following optimizations:<\/p>\n<ul>\n<li><strong>Reduce image resolution<\/strong>: If the document uses large fonts, lowering the DPI from 300 to 150 can speed up rasterization and inference without sacrificing accuracy.<\/li>\n<li><strong>Batch processing<\/strong>: For multiple single-page documents, use <code>infer()<\/code>codecodecodecodecode in a loop. The model is not designed for batched multi-page inference, but you can parallelize single-page jobs across multiple GPUs if available.<\/li>\n<li><strong>Mixed precision<\/strong>: The pipeline already uses bfloat16\/float16. For further memory savings, enable gradient checkpointing (though not required for inference) or use <code>torch.cuda.amp.autocast()<\/code>codecodecodecodecode in custom loops.<\/li>\n<li><strong>Output post-processing<\/strong>: The model often outputs Markdown tables with aligned columns. If you need machine-readable JSON, you can parse the Markdown output with libraries like <code>pandas<\/code>codecodecodecodecode or <code>markdown<\/code>codecodecodecodecode.<\/li>\n<\/ul>\n<h2>Reusing the Workflow for Your Own Documents<\/h2>\n<p>The pipeline is designed to be easily adapted. To process your own files, simply upload them to Colab\u2019s file system, then point the <code>image_file<\/code>codecodecodecodecode parameter (for single pages) or the <code>pdf_to_images()<\/code>codecodecodecodecode function (for PDFs) to your file. The model supports a wide variety of document types: scanned forms, technical reports, academic papers, invoices, and even handwritten notes (though accuracy may vary). The cheat sheet provided in the original code summarizes the best mode for each scenario:<\/p>\n<ul>\n<li>Dense, small text \u2192 Gundam mode (640, crop_mode=True)<\/li>\n<li>Clean print \u2192 Base mode (1024, crop_mode=False)<\/li>\n<li>Multi-page PDF \u2192 infer_multi() with image_size=1024, ngram_window=1024<\/li>\n<li><a href=\"https:\/\/overcentral.com\/en\/baidu-unlimited-ocr-flat-kv-cache\/\" title=\"Baidu Releases Unlimited OCR 3B Model With Flat KV Cache for Long Documents\" data-iacss-internal=\"1\">Long documents<\/a> \u2192 keep max_length=32768 and repetition controls<\/li>\n<\/ul>\n<p>This pipeline eliminates the need for a separate traditional OCR and layout analysis stack, offering a single, reproducible solution for high-res, multi-page document parsing. The combination of Gundam and Base modes, long-context generation, and adaptive dtype selection makes it a robust foundation for both research and production workflows.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Baidu\u2019s Unlimited-OCR model, a 3-billion-parameter vision-language system, is reshaping how developers approach document parsing. Unlike traditional OCR pipelines that rely on separate layout analysis, text detection, and recognition stages, this model processes entire pages\u2014including headings, tables, paragraphs, and footnotes\u2014in a single decoding pass. The result is a unified, end-to-end workflow that handles both high-resolution single-page [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":83763,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/cards.overcentral.com\/cards\/en\/64601.png","fifu_image_alt":"Unlimited-OCR Builds Full OCR Pipeline for High-Res, Multi-Page PDFs","footnotes":""},"categories":[349],"tags":[],"class_list":["post-64601","post","type-post","status-publish","format-standard","has-post-thumbnail","category-articles"],"fifu_image_url":"https:\/\/cards.overcentral.com\/cards\/en\/64601.png","fifu_image_alt":"Unlimited-OCR Builds Full OCR Pipeline for High-Res, Multi-Page PDFs","_links":{"self":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/64601","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/comments?post=64601"}],"version-history":[{"count":0,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/posts\/64601\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/media\/83763"}],"wp:attachment":[{"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/media?parent=64601"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/categories?post=64601"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/overcentral.com\/en\/wp-json\/wp\/v2\/tags?post=64601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}