A Python Tool for Restoring Spatial Search to VLM Transcriptions

When Large Language Models (LLMs) began cleaning up optical character recognition (OCR) output, or when Vision Language Models (VLMs) bypassed OCR and transcribed page images directly, something improved for researchers but something else broke. The text itself became dramatically cleaner: proper reading order, accurate spelling, no hyphens fracturing words across line breaks (example: “Pythagoras” rendered as “Pythag-” and “goras”).

The small errors that once made historical-document transcriptions frustrating to read—and often impossible to search—have largely fallen away. But the cleaned text comes back as a flat string, stripped of the bounding boxes that anchored each word to its place on the page, which was a very important feature in the older OCR’s documents. These coordinates let a search hit be located and often highlighted on the original page image so a researcher can see the searched word highlighted (keyword in context). The lack of bounding boxes in these new models is a massive problem for libraries and archives committed to accessibility and assistive technology.

The use of LLMs and VLMs has resulted in fewer of the small errors that make transcriptions of historical documents frustrating to read or copy and often impossible to search computationally. But, a problem remains: the cleaned text from these language models comes back as a flat, long text string and omits the bounding boxes (the coordinates that told us where on the page each word lived) that enable word searching and keyword-in-context highlighting that users expect when they search a document for a specific word or phrase.

While that sounds like a small technical detail, it alienates a large fraction of those who rely on documents that have been OCR’d. Bounding boxes are what make search-and-highlight work in PDF readers. They’re what assistive technology uses to read a page aloud in the right order. They’re what lets a researcher click a search result and land on the exact word in the scan. Lose them, and you’ve made the invisible text layer easier to read while making the page harder to navigate. For a library or archive, VLM corrected text is wonderful for accuracy, but a disservice for patrons.

OCR Text Aligner is a Python tool that I’ve developed that solves this problem. It takes the original OCR output from software like Tesseract (with all its errors but also all its coordinates) and the LLM-corrected or VLM-generated text (clean but coordinate-less), and aligns them, restoring positional information to the cleaner text.

The method combines fuzzy string matching, linguistic neighborhood analysis, and geometric and typographic cues. It handles the cases that break naive alignment: words split across line breaks, merged tokens, OCR errors that happen to look like other real words. It is meant for documents with context. Content with no semantic context such as crosswords, ads, tables, will require further consideration.

The goal isn’t to replace anyone’s OCR pipeline. It’s to slot into the workflows libraries and archives are already building around LLM correction, so they don’t have to choose between accuracy and discoverability, or accuracy and accessibility. The program runs on a CPU and does not itself require any AI, making it usable on any infrastructure.

The code is on GitHub: github.com/chloe-farr/ocr-text-aligner. I gave a talk on it at BiblioCon Berlin last week  [BiblioCon26 Presentation Slides].

It’s early-stage and I’d love feedback from anyone working on digitization pipelines, who have similar problems with other types of documents.

If you’re at a memory institution and this resonates, or you’ve been affected by the same problem and weren’t sure how to handle it, please get in touch with me.


Posted

in

,

by