← all posts
// ocr · ocr-models

OCR models for invoices and receipts: layout and reading order

Here's the rule up front: run OCR and vendor templates first, bring in a vision-language model only where it earns a real edge, and never let it replace machinery that already works. The rest of this article earns that rule.

Feed the pipeline a supplier invoice, a crumpled receipt, a credit note, or a phone photo of an expense slip, and you're doing several jobs at once: work out what belongs on the page, what order it reads in, whether the characters can be trusted, and how each value traces back to the page. Paper crumples, thermal print fades, shadows and perspective warp the photo, a logo passes for a table cell, totals repeat across sections. None of that is exotic. It's Tuesday.

The pipeline order that actually holds up

Start with OCR, then vendor templates, then anchors and arithmetic checks: subtotal plus tax against the total, line items against their sum, currency against the vendor's country. That chain is unglamorous and correct most of the time, because most invoices from a known vendor look like the last one. A generative OCR or vision-language model earns its place only when it beats that chain: handwriting a classic recognizer can't parse, an irregular layout, a mislocated label, or an exception the deterministic pass can't clear. It shouldn't quietly replace stages that already worked: a model reading ambiguous layout will also swap an uncertain character for language that sounds more like a real document. Fluent isn't correct. On a receipt, fluent is often the failure.

What you log before you trust a single digit

Keep the source file immutable, assign every page and document a stable identifier, and test against representative multi-column, sidebar, header, footer, and page-continuation layouts, scoring structure separately from plain transcription. From there, keep a trail you can replay later: file hash, page, and capture device; original dimensions, color, and orientation; every crop, dewarp, threshold, and denoise version; the OCR, layout, or vision-language model and runtime version; language hints and dictionaries; raw text, regions, reading order, and confidence; the normalized field, validation, and any reviewer change; plus latency, memory, and cost. Never let normalization overwrite transcription: if a character could be an O or a zero, an I or a one, or a decimal point, minus sign, unit, or diacritic is ambiguous, store what the recognizer saw and what the business rule proposed as two separate facts. Judge the system on field and line-item accuracy, arithmetic reconciliation, duplicate detection, and exception-queue rate, plus exact-match checks on identifiers, dates, amounts, and units that matter, not character or word error rate alone, which treats a missing comma the same as a wrong account number.

The wrong number that looks completely right

The failure worth worrying about isn't garbled text. It's a syntactically perfect amount lifted from the subtotal or balance-forward line instead of the total you needed. A model trained to continue plausible patterns does the same with a damaged surname, a part number, or a total: it completes toward something that looks right rather than admitting it doesn't know. The trap is flattening a page into one string and asking a model to reconstruct geometry that's already gone; you can't recover spatial truth from something that never carried it. Build a real path to say no: a low-resolution region, a clipped page, glare, unreadable handwriting, or contradictory totals should raise an exception, not a confident guess. The model's confidence score isn't enough, since scores are model-specific and often poorly calibrated; pair them with image-quality checks, format validators, cross-field arithmetic, known dictionaries, and disagreement between recognition passes. Make review fast: store the page number and bounding polygon for every important field and put the crop beside the value, a five-second check instead of a hunt through the document. Hold the same discipline across pages: keep order and repeated-header identity intact, split documents on purpose, attach identifiers to each piece, and state whether a table or paragraph may continue across a boundary, instead of handing the model a bundle it might merge into one.

Where the model earns supervision, not blind trust

Used well, a vision-language model is good at things a template can't do: tying a label to a distant value, piecing together a fragmented table, or explaining why two totals disagree. Ask it to keep observation and interpretation separate, and never let its output write to a database or trigger a tool call without schema validation and rules outside the model. Text printed inside a document is data the model reads, not an instruction channel: a line telling it to ignore prior instructions is still just text on a page, and treating it otherwise is how a document becomes an attack. Keep spatial structure alive through the pipeline and flatten it only for the one consumer that doesn't need it. Version the model, the preprocessing, the dictionaries, the schema, and the validation rules together, and when one piece changes, replay it against a fixed set covering clean pages, ordinary noise, awkward layouts, critical fields, and a few known-impossible documents. Local deployment keeps documents under your own roof and gets cheaper at steady, high volume, once you count storage, backup, memory, accelerator time, and review staff. A hosted document API or a frontier vision model buys elasticity and a wider exception ceiling, at the cost of upload time, retention and residency, rate limits, and a per-page or per-token bill. Hybrid routing works when the privacy rule is non-negotiable and escalation stays visible to whoever signs off on it.

The single rule worth keeping: never let a fluent paragraph stand in for a number you can't trace back to the page it came from.

#ocr-models#document-ai#vision