← all posts
// ocr · ocr-models

OCR models for scanned archives: local hardware and hybrid OCR deployment

So the pitch is always the same: point a vision-language model at every scanned page and let it read for you. It works, mostly, and that's the problem. A VLM can't tell the difference between recognizing a smudged word and guessing one that fits the sentence around it. On a modern printed page you'd never catch it. On a water-stained old ledger, it hands you a wrong account number in the exact same confident font as a right one. That's the entire risk.

Archive inputs are books, correspondence, old reports, and records off paper or microfilm, full of skew, bleed-through, stains, dead typefaces, and margin notes. The goal is text that keeps page identity, reading order, and an honest flag on anything the machine wasn't sure of.

Keep the ledger of every stage, not just the answer

Route by workload, not by what's newest. A conventional OCR engine with language packs and layout segmentation clears most clean printed pages for a fraction of what a multimodal model costs, and it does the job. Bring in a vision-language model only where it earns its keep: bad handwriting, layouts that won't parse into columns, scattered fields, or exceptions the deterministic pass punted on. It sits downstream of the cheap stage rather than replacing it.

Treat the source file as immutable and tag every page first. Log decode, preprocessing, OCR, layout, and VLM escalation as separate stages, and keep the chain: file hash, capture device, crop and denoise versions, which model ran, reading order and confidence, and whatever a reviewer changed. If a character could be an O or a 0, store what the recognizer saw and what the rule proposed as two separate values. Judge results on exact-match rates for identifiers and amounts, not error-rate averages that treat a dropped comma and a transposed account number as roughly the same mistake.

A wrong account number in a confident font

The recognizer isn't lying. It's finishing your sentence for you.

Language models continue plausible patterns, so a damaged surname or part number gets completed into something that reads naturally and is simply wrong. Build a real abstention path: low-resolution regions, glare, and totals that don't add up should raise an exception, not a guess. Confidence scores alone won't save you, they're often miscalibrated, so pair them with image-quality checks and disagreement between recognition passes. Store the bounding box for every field so a reviewer sees the crop beside the proposed value.

For multi-page work, keep page order and header identity explicit, and have the model separate what it observed from what it inferred. Database writes stay behind schema validation outside the model; text printed on a page is never an instruction, it's data. Local deployment keeps documents under your control and gets cheaper as volume climbs. A hosted API buys elasticity and a higher ceiling on exceptions, at the cost of upload time and per-page pricing. Hybrid works when the privacy line is firm and every escalation stays visible in the log.

So before you trust a clean-looking batch, pull the pages your confidence scores ranked worst and put the crop next to the shipped text.

#ocr-models#document-ai#vision