The Problem

Documents that span many pages—contracts, academic papers, historical archives—break conventional OCR pipelines. Most systems process one page at a time, losing cross-page context, repeating content, and producing fragmented output. Unlimited-OCR is a Baidu research model that performs one-shot, long-horizon parsing: it ingests an entire document and produces a single coherent parse, eliminating the page-by-page stitching problem.

What This Does

The repository is a lightweight inference wrapper around the baidu/Unlimited-OCR model. It provides infer.py, a single Python file with 14 functions, that handles the full pipeline: converting PDFs to images (pdf_to_images), encoding images (encode_image), building prompts (build_content), and running inference through a local server (start_server, infer_one). It supports single-image, multi-page, and PDF inputs.

The repo includes documentation (README.md, CONTRIBUTING.md, Unlimited-OCR.pdf), a license, and an asset directory. It does not include tests, CI configuration, or a Dockerfile. The only code file is infer.py.

How It Is Wired

Execution starts at main in infer.py:319, which calls parse_args, start_server, run, and stop_server. run (at infer.py:267) calls build_jobs, which builds a job list from either a PDF (pdf_to_images) or a directory of images (collect_dataset_images). Each job flows through infer_one, which calls build_contentencode_image and collect_stream_silent to gather output.

The internal call graph has 14 edges across 14 functions. stop_server is the most-called function (2 call sites), but the real hub is infer_one—it routes through build_content, get_ngram_processor_str, and collect_stream_silent, and is the single point where a document is converted into a model request. start_server and stop_server manage the local inference server lifecycle, which is the only external effect: the code spins up a server, sends requests to it, and tears it down. There are no circular dependencies and no other modules.

File-by-file: infer.py owns all logic—parsing, image conversion, server management, and inference. The assets/ folder holds images and a 78MB GIF. The wheel/ folder contains a pinned sglang wheel.

How To Use It

Setup: Install the dependencies listed in the README (torch, transformers, pymupdf, etc.) with pip. There is no pyproject.toml or requirements.txt in the repo, so pin versions manually.

Running it: The README shows the intended usage—load the model via AutoModel.from_pretrained('baidu/Unlimited-OCR', trust_remote_code=True), then call model.infer() for single images or model.infer_multi() for multi-page PDFs. The infer.py CLI offers a local-server path; the README does not document its exact CLI flags, so inspect parse_args in infer.py:319 for the available options.

Real-World Use

A legal firm processes a 200-page contract. The workflow: convert the PDF to images at 300 DPI, feed all pages to model.infer_multi with image_size=1024 and max_length=32768, and receive a single structured text output. The no_repeat_ngram_size and ngram_window parameters control repetition suppression, which matters for long documents where the model might otherwise loop on boilerplate language.

Code Health & Issues

Static analysis of infer.py found 14 functions, 0 classes, and no circular dependencies. One medium-severity finding:

  • Medium - Large binaries in repo - assets/long-horizon-ocr.gif is 78.4MB and wheel/sglang-0.0.0.dev11416+g92e8bb79e-py3-none-any.whl is 11.9MB. Every clone pays for these. Move the GIF to LFS and the wheel to object storage.

SDLC observations from the file structure: no test files, no CI pipeline, and no lockfile. The single infer.py is untested and has no automated gate. The README references a requirements.txt-style list but no such file exists in the repo.

The Bottom Line

Unlimited-OCR is a functional inference wrapper for a strong research model, but it is not a production-ready package. The single-file design is easy to read and modify, but the lack of tests, CI, and a dependency manifest means you will be debugging against the model's own behavior. Use it for experimentation or as a reference implementation; for production, extract the model call into a service with proper packaging and test coverage.