Tools,

Ollama OCR, tested on a real scanned PDF

1,953

of 1,955 scan words, read in order

Get the setup

Pull glm-ocr, then run it

The Ollama library has two OCR models: glm-ocr and deepseek-ocr. glm-ocr read the most words on our scan.

1,953 of 1,955 words, in order

104 s for 10 pages, Mac GPU

Install Ollama, and Poppler for pdftoppm. Run ollama pull glm-ocr, a 2.7 GB download.

Then run sh glm.sh next to the PDF. You get one Markdown file, book.md.

The full glm.sh script
pdftoppm -r 200 -png book.pdf page
for p in page-*.png; do
  ollama run glm-ocr "Text Recognition: ./$p" > "${p%.png}.md" || exit 1
done
cat page-*.md > book.md

Each model needs its own prompt

glm-ocr takes the prompt on its library page: Text Recognition: and then the image path.

deepseek-ocr wants the image path first, a line break, and then Free OCR. The script puts a real line break there.

The full deepseek.sh script
pdftoppm -r 200 -png book.pdf page
for p in page-*.png; do
  ollama run deepseek-ocr "./$p
Free OCR." > "${p%.png}.md" || exit 1
done
cat page-*.md > book.md

GLM-OCR did better in Ollama

The same 10 scanned pages, scorer and Mac GPU:

Scan words in order, of 1,955
Model Words Time
glm-ocr, Ollama 1,953 104 s
deepseek-ocr, Ollama 1,952 101 s
GLM-OCR, llama.cpp 1,950 118 s
DeepSeek OCR 2, llama.cpp 1,948 83 s

Ollama's glm-ocr is the BF16 file. Our llama.cpp test of the same model used a smaller Q8_0 copy.

Ollama's deepseek-ocr is the first DeepSeek-OCR. Ollama has no version 2.

The misses: 2 words and 3 words

glm-ocr wrote "tommyrot" as "tomyrot" and dropped one closing quote. It kept no running page header.

deepseek-ocr fixed two dialect words: "belongin's" became "belonging's", and "photograft" became "photograph".

It also added a quote, and it kept 1 running page header.

Typed pages: 11 of 13 cover words

Both models read every page as a picture, typed pages too. glm-ocr skipped the title line, COVER SHEET, and read the other 11 words.

In the 11-page file, the scan words stayed at 1,953, in 114 s.

German: deepseek-ocr read more umlauts

Neither script has a language option. I gave both 3 German pages. One is a magazine page with two columns.

Of 206 umlauts and 972 two-column words
Model Umlauts Two columns
deepseek-ocr 201 951
glm-ocr 193 955

deepseek-ocr took 42 s for the 3 pages. glm-ocr took 61 s.

dots.ocr is still the best here, with 204 umlauts.

Ollama and our Actor: 4 wins, 2 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, glm-ocr in Ollama on the Mac GPU
Test glm-ocr Actor
Scan words in order 1,953 1,874
Typed cover words 11 13
Umlauts 193 192
Two columns, in order 955 954
Time, 11 pages 114 s 133 s
Time, 3 German pages 61 s 59 s

glm-ocr read more scan words. The Actor read all 13 cover words.

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

The license allows business use

Ollama is MIT. The deepseek-ocr download holds the plain MIT license.

The glm-ocr download has no license file, but the GLM-OCR model card says MIT. I read all three before the download.

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 book.md, with the scorer of the tessdata test. German: the scorer of Tesseract German.
  • Ollama 0.40.16 for macOS on an Apple Silicon Mac GPU, at the lowest priority. glm-ocr:latest and deepseek-ocr:latest, with the library settings (temperature 0).
  • Times count the script only, one model start included. The Ollama server ran before each script.
  • One run each. The 11-page file holds the same 10 scan pages, and their text was the same in both runs, page for page.
  • The llama.cpp rows: the same files and scorer, on the same Mac, on November 12. Each has its own page.
  • The scripts above are the files that ran. The Actor: two real runs earlier the same day, build 0.1.65, on the same files.
What I did not test
  • glm-ocr:q8_0, and the table and figure prompts.
  • deepseek-ocr grounding mode and its Markdown prompt.
  • Library vision models that are not OCR models.
  • The Ollama app, Windows, Linux and NVIDIA GPUs.
  • Handwriting, tables, charts, math and forms.
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

Can Ollama do OCR?

Yes. Its library has two OCR models, glm-ocr and deepseek-ocr. On a Mac GPU, glm-ocr read 10 scanned pages in 104 s.

Which Ollama model is best for OCR?

On our English scan, glm-ocr, by 1 word, and it is 4 GB smaller. On German pages, deepseek-ocr read 8 more umlauts.

Can a business use Ollama OCR?

Yes. Ollama is MIT, and both models say MIT, with no added terms. Keep the license notice if you share them.