Document OCR
A document reader turns a scanned page, a photo of a document or a whole PDF into clean text. These are specialists rather than chat models: they read pages, and they do not reason at length about them.
The Models
| Provider | Model | Size | Context | Licence |
|---|---|---|---|---|
| Baidu | Unlimited-OCR | 3B | 32K | MIT |
| PaddlePaddle | PaddleOCR-VL 1.6 | 0.9B | 128K | Apache-2.0 |
| LightOn | LightOnOCR-3 0.8B / 4B | 0.8B, 4B | 256K | Apache-2.0 |
Unlimited-OCR is the general document reader: structured parsing with the position of every block, whole-PDF runs, and a figure pass. PaddleOCR-VL 1.6 is the compact page reader, with strong coverage of Nordic and other European languages and specialist modes for tables, formulas, charts and seals. LightOnOCR-3 turns a page into Markdown, or into labelled blocks with their boxes; the 0.8B reads a page in about a fifth of the 4B's memory, and the 4B is the one for hard pages, old scans and dense tables. Each reads one page per request.
How PaddleOCR-VL Reads A Page
It does not read the page in one go. A layout model finds the text, tables, formulas and figures first, then PaddleOCR-VL reads each region in reading order and the page comes back as Markdown. That is how its authors' own pipeline works, and matching it matters: on a 64-page test set the word error rate is 0.65%, and 60 of those 64 pages come back byte-identical to the official pipeline's output.
The layout model downloads with PaddleOCR-VL and is the default for a page sent to chat completions. It runs on NVIDIA GPUs; on Apple Silicon the model reads whole pages instead.
A page that starts repeating itself is stopped at the first repeated phrase rather than looping to the token limit, and the Studio marks such a page for review. Send ocr.repetition_stop: false to let it run.
Both keep working memory for the image reader on top of their weights, about 1 GB and 1.9 GB respectively, and the Studio's fit chart counts it rather than leaving you to discover it at load time.
Reading Modes
A document is not one job. Asking for plain text and asking for a table's structure are different decodes, so the mode is part of the request rather than something you phrase in a prompt and hope for.
| Model | Modes |
|---|---|
| Unlimited-OCR | document structured text with each block's type and position · multipage for PDFs · free plain text with no structure · layout labelled regions · figure for charts and diagrams |
| PaddleOCR-VL 1.6 | ocr · table · formula · chart · spotting · seal |
Asking For A Mode
Add an ocr object to a chat request. It travels alongside the image or document content part in the ordinary way.
{
"model": "paddleocr-vl-1.6",
"messages": [{ "role": "user", "content": [ ... image or file part ... ] }],
"ocr": { "mode": "table" }
}On Unlimited-OCR the object also takes crop, which chooses how the page is cut up before reading: auto decides from the request, gundam is a tiled close-up pass that reads fine print well, and base is a faster whole-page pass that suits long documents. PaddleOCR-VL takes mode and nothing else, and says so: sending a field its interface does not have is refused rather than accepted and ignored, because silently accepting one would advertise behaviour that does not exist.
An invalid mode comes back as a 400 naming every mode that model does accept, so the vocabulary is discoverable without reading this page.
Finding Out What An Endpoint Offers
Modes differ per model, so they are advertised rather than assumed. GET /v1/models and the manager's /api/server both report an ocr object for a served document reader:
"ocr": { "modes": ["ocr", "table", "formula", "chart", "spotting", "seal"],
"crops": [], "grounding": false }On LightOnOCR-3 the object advertises "grounding": true and the mode is asked for as ocr: {"mode": "grounding"}, on chat completions, Messages or Responses alike.
A client builds its controls from that, which is how the Studio offers exactly the modes the loaded model has and never a mode it does not. A model that is not a document reader has no ocr object at all.
The same listing carries document_parser: true for these models, and clients should act on it: a request with no document is refused with a 400. These models read pages, so a text-only chat has nothing to work on and says so instead of answering from nowhere. A client that offers a chat box against one of them should require an attachment before it lets you send, which is what the Studio's composer does.
Grounded Regions
Unlimited-OCR and LightOnOCR-3 can point at where on the page each piece of text came from. Expect a grounded read to return about a quarter more text than a plain one, since every block is labelled.
Unlimited-OCR's form: When grounding is advertised, the response carries an ocr.regions extension: boxes as [x1, y1, x2, y2] normalised to a 0 to 999 grid, so they map onto the page at any rendered size without you having to know the resolution it was read at.
The association between a box and its text is kept rather than flattened, which is the difference between "here is the text and here are some boxes" and being able to click a line and see where it came from. In the Studio the boxes appear on the page as the answer streams.
Whole PDFs
A PDF is rendered to pages and fed through the reader for you. The page range you choose bounds the work: a 400-page document reads only the pages you asked for, rather than rendering the lot and discarding most of it. The cap is stated rather than silently applied.
For how attachments reach a model in the first place, including the text-extraction route that any model can use, see Documents and Images.