43 Million Fixes,
21 Minutes

A Rust + PyO3 OCR cleanup pipeline

The Problem

Training an LLM on pre-WWI history starts with cleaning OCR noise out of an Internet-Archive-scale corpus.

robotdad's timecapsule-data collects temporally-filtered text for LLM training. The Internet Archive index it draws on holds roughly 2.3M items for the years 0–1914, about 1.5M of them eligible to download — and their OCR text is riddled with systematic scanning errors.

The question isn't whether the corpus is big. It's how fast you can clean it.

One measured run fixed 43,314,454 errors in 21 minutes.

On a 100,000-document Internet Archive benchmark, the pipeline applied 43.3 million substitutions to 80,447 files — 99.8% of the files it processed — in about 21 minutes.

That kind of throughput is exactly what pure Python couldn't reach.

43,314,454
substitutions applied
80,447
files modified (99.8% of processed)
21 min
runtime on the 100k benchmark
~538
avg substitutions per file
The Wall

Pure-Python cleanup couldn't scale to millions of documents.

A corpus of this size needs unicode normalization, language detection, triage, boilerplate stripping and hundreds of correction passes per file. Done in pure Python across an eligible pool of ~1.5M documents, that work doesn't finish on a useful timeline — so the engine couldn't stay in Python.

The fix was to move the hot loop out of Python entirely.

timecapsule-data is robotdad's MIT-licensed corpus-collection project.

Built by robotdad — Marc Goodner at Microsoft, who authored all 120 commits — timecapsule-data collects temporally-filtered text corpora for LLM training. The OCR-cleanup work landed in a tight burst, January 17–24, 2026.

Inside that burst, the cleanup engine was rewritten from the ground up.

120
commits, all by Marc Goodner
Jan 17–24
project timeline, 2026
MIT
github.com/robotdad/timecapsule-data

The cleanup engine is Rust, called from Python via PyO3 and parallelized with Rayon.

The Rust/PyO3 library was added Jan 20; OCR was consolidated to Rust-only by Jan 23; Rayon parallelization landed Jan 24. It fans work out across 24 threads with par_iter().for_each() over file pairs.

On top of that engine sits the layer that does the actual fixing.

# Cargo.toml dependencies pyo3 = "0.27.0" rayon = "1.10" regex = "1.11" # src/lib.rs use pyo3::prelude::*; use rayon::prelude::*; file_pairs.par_iter() .for_each(...); # 24 threads

150+ regex correction patterns run at ~64 files/s on a Ryzen 5950X.

Tier 1 cleanup applies 150+ documented OCR-correction patterns — long-s, ligatures, ll→U, rn→m and word run-togethers. Benchmarked on a Ryzen 5950X with NVMe storage, it sustained 64.3 files/s and 50.9 MB/s.

Fast is only half the story. The other half is being right.

150+
documented OCR-correction patterns
64.3
files / second
50.9
MB / second
24
threads, Ryzen 5950X

Near-perfect precision: 99.98% on the 100k Internet Archive benchmark.

Vocabulary validation over 761.9M words surfaced 1,014,036 suspicious candidates. Only 225 turned out to be dictionary false positives — 99.98% precision. Just 972 confusable words remained, meaning the patterns caught ~99.9% of systematic OCR confusions.

Fast and near-perfect — because a human made the architectural calls.

99.98%
precision in noise detection
1,014,036
suspicious candidates checked
225
dictionary false positives
972
confusable words remaining (~99.9% caught)
The Takeaway

Put the hot loop in Rust; keep the judgment human.

This is human-directed, AI-executed performance engineering. The pattern is general: when pure Python hits a scaling wall, move the hot loop into a compiled, parallel engine behind a PyO3 boundary — and let a person keep making the architectural calls. robotdad made every one of those calls here.

Tens of millions of fixes in minutes, at precision you can trust.

Sources

Sources & Research Methodology

Data as of: January 24, 2026 (last commit in the source repo)

Feature status: Active / open source — Tier 1 (Rust patterns) & Tier 2 (SymSpell) implemented; Tier 3 (LLM) documented as future work

Primary source: github.com/robotdad/timecapsule-data (MIT) — verified via gh repo view robotdad/timecapsule-data

Research performed:

Corpus scale: ~2.3M Internet Archive items indexed for years 0–1914; ~1.5M eligible; measured cleanup run = 100,000 documents.

Gaps: Only one timed run (100k docs, 21 min) is documented; no Python baseline benchmark exists in the repo, so no speedup multiplier is claimed.

Primary contributor: robotdad (Marc Goodner, Microsoft) — 120 of 120 commits.

More Amplifier Stories