Tools,

Marker OCR, tested on a real scanned PDF

1,922

of 1,955 scan words, read in order

Get the setup

pip install alone stops on scans

marker-pdf 2.1.0 stopped on a scanned page: SpawnError, llama-server binary not found. Marker reads scans with a vision model in llama.cpp.

I got the official llama.cpp build for Mac with llama.sh:

curl -sL https://github.com/ggml-org/llama.cpp/releases/download/b12316/llama-b12316-bin-macos-arm64.tar.gz | tar xz

Then marker.sh points Marker at it. Run sh marker.sh next to book.pdf, and put flags after it:

export LLAMA_CPP_BINARY="$PWD/llama-b12316/llama-server"
marker_single book.pdf --output_dir out "$@"

1,922 of 1,955 words, in order

60 s for 10 pages, Mac GPU

The first run downloads a 1.4 GB model. With --mode balanced, I got the same text in 63 s.

Typed pages: leave --force_ocr off

Marker checks each page. In the 11-page file, it kept the typed cover page's own text and read the 10 scanned pages.

11 pages: a typed cover, then the scan
Setting Cover words Scan words
Default 13 of 13 1,922
--force_ocr 11 of 13 1,922

OCRmyPDF first? Strip its text

On OCRmyPDF's PDF, Marker kept Tesseract's hidden text on all 10 pages. It ran no OCR and found 1,868 words in order.

With --strip_existing_ocr, it read the scan again: 1,922, the same text as the scan alone.

German worked with no language setting

Marker has no language option. I gave it 3 German pages. One is a magazine page with two columns.

194 of 206 umlauts

966 of 972 words in order, two columns

No GPU: no page in 10 minutes

With TORCH_DEVICE=cpu, LLAMA_CPP_NGL=0 and 2 CPU threads, I ran the same 3 German pages.

After 600 s, Marker's request timeout cancelled all 3 pages. I stopped the run after 16 minutes, with no text.

A small cloud server with no GPU is this kind of machine. Our Actor read the same 3 pages in 65 s.

Marker read better than our Actor

Our Actor makes Markdown 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, Marker on the Mac GPU
Test Marker Actor
Scan words in order 1,922 1,874
Umlauts 194 192
Two columns, in order 966 954
Time, 11 pages 59 s 144 s

The Actor needs no GPU and no 2.6 GB setup. It costs $0.006 a page. Marker's model weights are free for research, personal use and startups under $5M. Past that, you buy a license.

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.
  • Score: true words found in order in the Markdown, with the scorer of the tessdata test. German: the scorer of Tesseract German.
  • marker-pdf 2.1.0 (surya-ocr 0.23.0), llama.cpp b12316, Python 3.12 arm64, on an Apple Silicon Mac. 2 threads at the lowest priority. Times include the model start.
  • The code blocks above are the files that ran. The Actor: two real runs, build 0.1.65.
What I did not test
  • Linux or Windows, and NVIDIA GPUs.
  • --use_llm, which sends pages to an LLM service.
  • Tables, math and handwriting.
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 Marker do OCR on scanned PDFs?

Yes, once it can find llama-server. Marker 2.1.0 read 1,922 of 1,955 words in order on a 10-page scan. With pip install alone, it stopped with SpawnError.

Do I need --force_ocr for scans?

No. Marker read the scanned pages without it and kept the typed cover page's own text, 13 of 13 words. With --force_ocr it read the cover again and got 11 of 13.

How do I set the OCR language in Marker?

Marker 2.1.0 has no language option. On 3 German pages with no setting, it kept 194 of 206 umlauts.