
Machine Learning Librarian @huggingface 🤗 I like big datasets and small models.
Scotland
Joined September 2014
- Tweets5.3K
- Following1.4K
- Followers6.9K
- Likes9.1K
Pinned Tweet
Uploaded a dataset of 115,293 illustrated pages from the Encyclopaedia Britannica, 1st edition (1768) to 14th (1929) to the Hub
huggingface.co/datasets/bigl…
OCR models are getting very fast!
I OCR'd 14,483 pages of fossil fuel industry documents with LightOnOCR-3-0.8B from @LightOnIO. One RTX PRO 6000 on @huggingface Jobs with @vllm_project, about 7.7 pages/s once running. $1.67 in total, about $0.12 per 1,000 pages.
I tuned the recipe for Jobs. The video is the run in progress, with each page appearing when its text comes back.
One command to run it on your own pages: hf.co/spaces/uv-scripts/run-…
What does a private OCR eval on 20th-century documents find?
My agent and I ran 9 open-weight OCR models on 338 scanned government pages. A VLM judge compared the transcriptions in pairs, 10,730 times.
→ The top two are small: @LightOnIO OCR-3-0.8B and @TIIuae Falcon-OCR (270M)
→ The two 3B-class models came 4th and 7th
→ How you run a model matters: Unlimited-OCR-2 gained about 130 rating points with tiling
Built with ocr-bench on @huggingface Jobs. The pages stay private; only the scores are public: huggingface.co/datasets/dava…
v0 caveat: the judge is checked against ground truth on 19th-century books, not yet on pages like these.
IMO, more people should build private OCR evals!
Guide: github.com/davanstrien/ocr-b…
Pages like these (examples from the same collections, not from the eval set). The eval set has typescripts, letterpress and offset print, photocopies and microfilm, pages with handwriting, and 60 blank or near-blank pages since many models still mess this up still!
@LightOnIO's LightOnOCR-3-0.8B is first on 4 of the 5 page-type boards (blank pages are the exception).
2
284
Recent text-to-speech models small enough to run on a CPU:
phonon-31m-en - 31M
Paradee-8M - 7.9M
Leokani-tts - 7M (4.5M version too)
PiVo - 1.4M (vocoder included)
Paradee runs ~62x real time on a single CPU thread.
Links (all on @huggingface):
phonon-31m-en: huggingface.co/gradium/phono…
Paradee-8M: huggingface.co/sahilmahendra…
Leokani-tts: huggingface.co/milliwattlabs…
PiVo: huggingface.co/empero-ai/PiV…
More: huggingface.co/models?pipeli…
Nemotron 3.5 Transcribe from @NVIDIAAI is very fast with @vllm_project!
11.3 hours of 1971 Nixon tapes on one RTX PRO 6000 (NVFP4): under 3 minutes of transcription. Whole Job, setup included: about $0.30.
For batch jobs, I run vLLM inside the @huggingface Job and send many requests at once using my tool saturate, which tunes the concurrency as it goes. A 79.7-hour run took just under 10 minutes.
Recipe: huggingface.co/datasets/uv-s…
NVIDIA's model card puts NVFP4 at ~3.6% higher error than BF16 (BF16 took 5.0 min here). saturate: github.com/davanstrien/satur…
3
220
Does this work on other OCR models? I tried a different failure: @LightOnIO's LightOnOCR-2-1B answers blank pages with "There is no content in the provided image…"
An edit to 0.13% of its weights, no training, stops it. On the BHL historical-books board it moves from 14th to 8th of 26. Model here (pls don't use it!):
huggingface.co/davanstrien/L…
This model is now one gen behind, so if you just want a good OCR model then try the new one!
OCR models often get stuck in loops, so I asked Claude Opus if it could stop one from looping by editing its weights.
It changed 0.0085% of them and with no training, it now reads this 1881 page instead of writing 16,399 characters of dots!
Prompt was basically: "read this, find a smallish OCR model and fix its repetition doom loops. You can spend up to 5 hours and $100 on @huggingface Jobs."
It only took under 3 hours in the end and about $10 of Jobs compute.
OCR models often get stuck in loops, so I asked Claude Opus if it could stop one from looping by editing its weights.
It changed 0.0085% of them and with no training, it now reads this 1881 page instead of writing 16,399 characters of dots!
Prompt was basically: "read this, find a smallish OCR model and fix its repetition doom loops. You can spend up to 5 hours and $100 on @huggingface Jobs."
It only took under 3 hours in the end and about $10 of Jobs compute.
We asked GPT-6 Astra to edit Qwen3.5-0.8B weights to improve math.
It directly changed only 0.016% of weights, fixing 0.8B's reasoning loops & improving math up to 6x and even instruction following 3x, without gradients or training.
We call this Weight-Space Programming: frontier LLMs can now natively read/write neural network weights! 🧵
Blog: rikiyat.github.io/blog/weigh…
Readers added context they thought people might want to know
LLM was given weights explicitly as text in prompt and used code/forward passes (per authors' logs) to ablate Qwen looping direction, a known thinking-mode issue per model card. Primarily fixed repetition in that mode, not general 'natively' improving weights/math.
rikiyat.github.io/blog/weight-sp…
github.com/RikiyaT/lm_und…
huggingface.co/Qwen/Qwen3.5-0…
huggingface.co/RikiyaT/Qwen3.…
I re-OCR'd 14,483 pages of fossil fuel industry documents using Saturate. One GPU + $1.47.
8.9 pages/s once running via @huggingface Jobs.
Saturate is a library I've been working on for running models over a dataset or bucket against any OpenAI-compatible endpoint/inference engine. I didn't tune concurrency; saturate settled on 512 by itself.
The image is one line from one page I checked: existing OCR vs Xiaomi-OCR-0
Curious if this tool is at all useful for anyone else?
github.com/davanstrien/satur…
Try it on @huggingface Jobs with one command (10 pages of OCR, about 5 min): huggingface.co/buckets/davan…
The documents are from the UCSF Industry Documents Library: registry.opendata.aws/idl
4
468
Some things that were useful when my agent and I were building the data for this model:
- Check how well you can guess the answer from the options alone. One source looked like a +4.5 gain, but it was mostly "the longest option is right". Real gain was more like +2.3
- Weight wrong options by how common they are. arXiv labels with uniform wrong options got +18 over chance without reading any text
- Keep one writing style across classes. With one class written by humans and the other by an LLM, the model just learned to spot LLM style
- Shuffle the options per example. Models that read all the options together can flip answers when you reorder them (12-23% in Crivo)
- Try different mixes, but with more than one seed. Single runs differed by up to ~8 points on one test set. Adding diverse sources gave the same lift as 4x the rows and steps, at about a quarter of the compute
- Check what your trainer silently drops. Ours skipped 53k one-label rows, the only verification data in the mix
Data, with source, labeller and licence on every row: huggingface.co/datasets/dava…
I trained a specialist decision model for curating web-scale data. It's small (380M, fine-tuned from UltraBERT-380M), so it runs relatively cheaply at scale: 1M FineWeb pages took 19 minutes and ~$5 on @huggingface Jobs.
It thinks a quarter of those pages are product pages. 6% passed a simple "educational, not spam" filter, and 1 page in 1,020,000 got "outstanding".
I've shared the model, the training data (with the source, labeller, and licence for every row), and the full recipe.
I hope more people share how they prepare data for training open decision models! We've had some cool open model releases. Time for some more data releases!
huggingface.co/davanstrien/u…
Can a decision model help discover moments in old films?
Search 1,864 public-domain Prelinger films by caption, then ask a yes/no question. @liquidai's d1-2B checks 3 frames per result clip and jumps to one it labels yes.
"anyone wearing a mask?"
huggingface.co/spaces/davans…
Tried this on a bunch of old newspapers.
- 1760s Fraktur, polytonic Greek, pre-reform Russian: all read well to my untrained eye; layout included
- Big broadsheets need full-res input: error rate 25% → under 10% (these are examples where many OCR models struggle.
I trained a specialist decision model for curating web-scale data. It's small (380M, fine-tuned from UltraBERT-380M), so it runs relatively cheaply at scale: 1M FineWeb pages took 19 minutes and ~$5 on @huggingface Jobs.
It thinks a quarter of those pages are product pages. 6% passed a simple "educational, not spam" filter, and 1 page in 1,020,000 got "outstanding".
I've shared the model, the training data (with the source, labeller, and licence for every row), and the full recipe.
I hope more people share how they prepare data for training open decision models! We've had some cool open model releases. Time for some more data releases!
huggingface.co/davanstrien/u…
Try it on your own Hugging Face dataset: one command on @huggingface Jobs, no setup. Copy it from the model card:
huggingface.co/davanstrien/u…
The full recipe (data building, training, evaluation) is here:
github.com/davanstrien/curat…
6
264
Added a script to run this on @huggingface Jobs with one command (@vllm_project + NVIDIA's NeMo plugin, inside the job).
It's very fast: 4.9 hours of 1940s radio transcribed in 2.5 min once the model is up. Whole job, setup included: $0.48.
Speaker tags + word timestamps, here on Hitchcock's 1940 Suspense audition:
[5:21] spk2: No, I'll go.
[5:39] spk1: Is it not true that you let lodgings?
huggingface.co/datasets/uv-s…
Meet NVIDIA Nemotron 3.5 Transcribe 🎙️
An open-weight, promptable 30B MoE model with ~4B active parameters that brings transcription in 40 languages, speaker attribution, translation, contextual prompting and audio understanding into one checkpoint.
Watch it keep track of who said what when everyone’s talking at once.
1/ 🧵
Spooky OCR 🎃 Nearly 2 pages a second, through books about witchcraft, demons and vampires
Baidu's new Unlimited-OCR-2 on one GPU on @huggingface Jobs: 1,456 pages in 12 min 32 s, about $0.75.
2
16
735
The script, with an experimental live view of the run (add --live-port to watch the pages and text as they come in): huggingface.co/datasets/uv-s…
167
Added @OpenBMB's MiniCPM-OCR to FineBooks historical-books OCR leaderboard: 8th of 25.
One gotcha if you use it: its SDK excludes footnotes, running heads, and page numbers from the output by default. On old books that's a lot of text. Switching footnotes back on moves it from 15th to 8th place.
huggingface.co/spaces/finebo…
1
25
1,049
Re-OCR'd the 1771 Encyclopaedia Britannica again, this time with @Baidu_Inc's new Unlimited-OCR-2.
What's new: reads many pages in one request (Baidu show a whole book in one go), so sentences split across page breaks come back whole.
~$3.40 for 2,724 pages (~$0.0012/page) vs ~$5 in Feb, one command on @huggingface Jobs.
Re-OCR'd the complete 1771 Encyclopaedia Britannica (2,724 pages) with a single command on @huggingface Jobs.
- 0.9B model (GLM-OCR)
~$0.002/page
~$5 total on an L4 GPU
Before (old Tesseract ocr) → After:
Recipe: point it at a folder or Bucket of page images:
huggingface.co/datasets/uv-s…
Full 1771 output: huggingface.co/datasets/dava…
Footnote: it reads the long s (ſ) as "f", so on 1771 print GLM-OCR still gets more words right.
4
340
OCR is not solved!
I asked an OCR model claiming SOTA on popular benchmarks to read one line from an 1881 contents page.
It wrote 16,421 characters. Mostly dots.
Having done more work on this (aiming to have something to share next week), I am pretty confident that someone who releases a very high-quality dataset/recipe for generating training data for Jev-style models would be among the top 10 open contributions in 2026.
After a month or so of open Jev-style decision models, here's what I found on the question of data.
Most of the findings come from one paper, "Releasing the Inner Jev" (@JonathanGeuter et al.).
You may need less training than you think. Show the options as letters, run one forward pass, and read the scores for "A", "B", "C"… An instruct model done this way already gets close to Jev: Gemma 4 31B scores 79.6 on OpenDecisions vs Jev's 80.1.
LoRA vs the head (31B ablations):
→ Train only the head, backbone frozen: 78.9 (slightly below zero-shot)
→ Train only LoRA, head frozen at the letter rows: 84.9
→ Full recipe, LoRA + head: 84.4
So the gain comes from adapting the representations. The letter readout is already a good head.
Also:
→ Short runs win (400–800 steps); longer runs mostly lose calibration
→ Smaller models gain less: no gain at 4B without extra tricks
→ A validation split from your own training data predicted the leaderboard badly
I also checked ~100 decision-related datasets on the Hub:
→ Most training data is classic classification/NLI datasets recast as choice/yes-no/score questions
→ Much of the rest is labelled by an LLM teacher
→ Eval sets were tiny (100–350 questions) until OpenDecisions (2,352)
→ Labels need re-checking: when Contested Fast Decisions relabelled the items 8 models disagreed on, 52% changed
I'm working on this a bit more to understand what data actually helps when you train one for your own task. So far I've reproduced the paper's zero-shot 4B result on @huggingface Jobs (64.7 vs 63.6, ~$0.20).
Paper: huggingface.co/papers/2610.1…
Datasets: huggingface.co/collections/d…
2
29
2,439
A bunch of new OCR models came out while I was on leave, so I ran some evals on 2,165 historical book pages.
- @datalabto Chandra-OCR-2: 3rd of 20, close behind dots.ocr
- @LightOnIO LightOnOCR-3-4B: 5th, and invents far less text on blank pages than LightOnOCR-2
- Indra OCR: runs on CPU and ties Tesseract
FineBooks wants to help re-OCR the public domain to unlock a rich source of data for AI, for researchers, and for enjoyment.
Step one: work out which modern OCR models are actually good enough.
So we built a leaderboard. 14 open models, scored on 2,165 pages of expert human transcription. The best read historical print at ~97.6% character accuracy, for under $2 per 1,000 pages.
A new @huggingface and @AiEleuther project, with @storytracer!
Blog post: huggingface.co/blog/finebook…
After a month or so of open Jev-style decision models, here's what I found on the question of data.
Most of the findings come from one paper, "Releasing the Inner Jev" (@JonathanGeuter et al.).
You may need less training than you think. Show the options as letters, run one forward pass, and read the scores for "A", "B", "C"… An instruct model done this way already gets close to Jev: Gemma 4 31B scores 79.6 on OpenDecisions vs Jev's 80.1.
LoRA vs the head (31B ablations):
→ Train only the head, backbone frozen: 78.9 (slightly below zero-shot)
→ Train only LoRA, head frozen at the letter rows: 84.9
→ Full recipe, LoRA + head: 84.4
So the gain comes from adapting the representations. The letter readout is already a good head.
Also:
→ Short runs win (400–800 steps); longer runs mostly lose calibration
→ Smaller models gain less: no gain at 4B without extra tricks
→ A validation split from your own training data predicted the leaderboard badly
I also checked ~100 decision-related datasets on the Hub:
→ Most training data is classic classification/NLI datasets recast as choice/yes-no/score questions
→ Much of the rest is labelled by an LLM teacher
→ Eval sets were tiny (100–350 questions) until OpenDecisions (2,352)
→ Labels need re-checking: when Contested Fast Decisions relabelled the items 8 models disagreed on, 52% changed
I'm working on this a bit more to understand what data actually helps when you train one for your own task. So far I've reproduced the paper's zero-shot 4B result on @huggingface Jobs (64.7 vs 63.6, ~$0.20).
Paper: huggingface.co/papers/2610.1…
Datasets: huggingface.co/collections/d…






















