Tools,

Kraken OCR, tested on a real scanned PDF

1,875

of 1,955 scan words, read in order

Get the setup

Ten scanned pages in 380 seconds

380 s for 10 pages, Mac GPU

23 MB model download

  1. Run pip install kraken. It installs torch.
  2. Run kraken get 10.5281/zenodo.10592716. It downloads CATMuS-Print Large, the default model in the README.
  3. Save kraken.sh below next to book.pdf, then run sh kraken.sh. It writes book.txt.
kraken.sh
# Kraken OCR on a PDF: book.txt plus page-NN.txt (brasspage.com/kraken-ocr/, Nov 12, 2026)
# Extra kraken options go first, for example: sh kraken.sh -d cpu --threads 2
set -e
pdftoppm -r 300 -png book.pdf page
kraken "$@" -I 'page-*.png' -o .txt segment -bl ocr -m catmus-print-fondue-large.mlmodel
# Join the pages, and the words the model split with a ¬ at the line end
for f in page-*.txt; do cat "$f"; echo; done | perl -CSD -0pe 's/\x{AC}\n//g' > book.txt

It needs Python 3.10 to 3.13, and pdftoppm from poppler. Kraken reads no PDF without its pdf extra, so the script turns each page into a picture first.

It marks split words with ¬

The default model writes ¬ where a word breaks at the line end:

different from those used by oystermen. Draw¬
Most of the neighboring fishermen had gath¬
fellow sat mending a net by the waterside, stop¬

1,864 words in order, raw pages

1,875 after kraken.sh joins them

It also puts a space before ? and :, the way French books do. That happened 11 times. The true text has none.

42 of the 64 missed places have a double quote mark. It also kept the running headers and page numbers.

Vision models read more, and faster

The same 10 scanned pages, scorer and Mac:

Scan words in order, of 1,955
Model Words Time
glm-ocr, Ollama 1,953 104 s
Qwen3-VL 8B 1,951 139 s
GOT-OCR 2.0 1,936 134 s
Kraken 1,875 380 s
docTR 1,869 13 s

Kraken is built for old prints and non-Latin scripts, and you can train it on your own pages. On a modern English scan, it was the slowest here.

German: umlauts come out as two characters

137 of 206 umlauts right

1,776 of 1,887 words right

The model writes ü as u plus a separate dot mark. It looks right, but a search for "über" in book.txt found 0 matches.

This line makes each umlaut one character again. Then "über" found 12:

perl -CSD -MUnicode::Normalize -pe '$_ = NFC($_)' book.txt > book-nfc.txt

Some marks are still wrong: "spât" for "spät" and "Silbermïnze" for "Silbermünze".

No GPU: 321 seconds for 10 pages

On the CPU only, with 2 threads, the same script took 321 s, faster than the Mac GPU. The text was the same, byte for byte:

sh kraken.sh -d cpu --threads 2

Kraken reads every page as a picture. On a typed cover page, it read 11 of 13 words: "chopter" for "chapter" and "Noy" for "Nov".

Kraken and our Actor: 1 win, 5 losses

Our Actor, from a file URL, with no install:

curl -s -X POST "https://api.apify.com/v2/acts/brasspage~pdf-ocr-to-markdown/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"documentUrls": ["https://api.apify.com/v2/key-value-stores/sTnmNrGoSsi7tLQvs/records/anythingllm-mixed-11-pages.pdf"]}' \
  | jq -r '.[].markdown' > mixed.md
Same files, Kraken on the Mac GPU
Test Kraken Actor
Scan words in order 1,875 1,874
Typed cover words 11 13
Umlauts 137 192
Two columns, in order 906 954
Time, 11 pages 385 s 133 s
Time, 3 German pages 207 s 59 s

The scan row is one word apart.

The Actor needs no GPU and no model download. It costs $0.006 a page.

Apache 2.0 code, CC BY 4.0 model

The Kraken license file is Apache 2.0, and PyPI says the same. I read it in full before the install.

The CATMuS-Print Large record on Zenodo says CC BY 4.0. Business use is fine if you credit its authors, Simon Gabay and Thibault Clérice.

How I tested it
  • Scan: the 10 pages of OCR in n8n, proofread Wikisource book scans, 1,955 true words. The 11-page file adds the 13-word typed cover page of AnythingLLM OCR.
  • German: the 3 pages of Paperless-ngx OCR, 1,887 words, 206 umlauts. One page has two columns, 972 words.
  • Score: true words found in order in book.txt, with the scorer of the tessdata test. German: the scorer of Tesseract German.
  • kraken 7.1.1 and torch 2.14.0, Python 3.12, on an Apple Silicon Mac, at the lowest priority. The default device picks the Mac GPU.
  • Times count the whole script, with the page pictures and the model load. The model was already downloaded. One run of each setup.
  • The glm-ocr, Qwen3-VL, GOT and docTR rows: the same files and scorer, on the same Mac, on November 12. They have their own pages.
  • The Actor: two real runs earlier the same day, build 0.1.65, on the same files.
What I did not test
  • Other models from the Zenodo list, and training your own.
  • ALTO, hOCR and PageXML output.
  • Right to left scripts, handwriting and manuscripts.
  • eScriptorium, the web app built on Kraken.
  • Windows, Linux and NVIDIA GPUs.
Sources

Two ways to skip the work

Run it yourself. Our Apify Actor turns scanned PDFs into Markdown, tables included.

Try the Actor

Or send us the scan. Tack, our AI, does the job for $29, up to 50 pages. First page free.

Get one page free

Questions people ask

Does Kraken need a GPU?

No. On the CPU only, with 2 threads, it read 10 scanned pages in 321 s, faster than on the Mac GPU, with the same text.

Why does Kraken write ¬ at the end of a line?

The default model marks a word that breaks at the line end with ¬. Join the two lines and drop the sign, as kraken.sh does.

Is Kraken free for business use?

Yes. The code is Apache 2.0. The default model is CC BY 4.0, so you may use it if you credit its authors.