Chandra OCR, tested on a real scanned PDF
1,911
of 1,955 scan words, read in order
On a Mac, add --method hf
chandra-ocr 0.2.0 needs a vLLM server by default. On a Mac, use
pip install "chandra-ocr[hf]" and chandra.sh:
chandra book.pdf out --method hf
1,911 of 1,955 words, in order
169 s for 10 pages, Mac GPU
Run it next to book.pdf. The first run downloads a 10.6 GB model. The text is in out/book/book.md.
No --method: 0 words, no error
The README starts with chandra input.pdf ./output. That
sends each page to a vLLM server on localhost:8000. With no server, it
tried for 60 s. Then it wrote an empty book.md and exited with
code 0.
A script that checks only the exit code will not see this. Check that book.md has text.
Typed pages: 12 of 13 cover words
Chandra reads every page as a picture, typed pages too. In the 11-page file, it read the typed cover page. But the CLI joins pages with no space, so the last cover word, 2026., ran into the first word of page 2.
The code has a --paginate_output flag that puts a line
between pages. I did not run it.
German worked with no language setting
Chandra has no language option. I gave it 3 German pages. One is a magazine page with two columns.
199 of 206 umlauts
958 of 972 words in order, two columns
Chandra read more, our Actor was faster
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
| Test | Chandra | Actor |
|---|---|---|
| Scan words in order | 1,911 | 1,874 |
| Typed cover words | 12 | 13 |
| Umlauts | 199 | 192 |
| Two columns, in order | 958 | 954 |
| Time, 11 pages | 175 s | 133 s |
| Time, 3 German pages | 161 s | 59 s |
The Actor needs no GPU and no 11.5 GB setup. It costs $0.006 a page.
The model license has limits
Chandra's code is Apache-2.0. Its model weights are free for personal use, research and businesses under $2M in revenue and funding. A business that competes with Datalab cannot use them.
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.
- chandra-ocr 0.2.0, PyTorch 2.15.0, Python 3.12 arm64, on an Apple Silicon Mac GPU, at the lowest priority. One run each. Times include the model start.
- The code blocks 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
- vLLM, NVIDIA GPUs, and a run with no GPU.
- The GGUF and MLX copies of the model that others posted.
- Handwriting, tables, math and forms.
Two ways to skip the work
Run it yourself. Our Apify Actor turns scanned PDFs into Markdown, tables included.
Or send us the scan. Tack, our AI, does the job for $29, up to 50 pages. First page free.
Questions people ask
Does Chandra OCR run on a Mac?
Yes, with --method hf. On a Mac GPU it read 10 scanned pages in 169 s. The default method needs a vLLM server.
Why did chandra write an empty file?
With no --method, chandra sends each page to a vLLM server on localhost:8000. With no server, it wrote an empty book.md after 60 s and exited with code 0.
Can Chandra OCR read German?
Yes. Chandra has no language option. On 3 German pages with no setting, it kept 199 of 206 umlauts.
Related guides
- PaddleOCR-VL on a scanned PDF: Mac setup and results, tested
- Surya OCR on a scanned PDF: setup and results, tested
- Marker OCR for scanned PDFs: setup and results, tested
- PDF to Markdown in Python: 5 libraries tested
- EasyOCR vs Tesseract vs PaddleOCR vs RapidOCR, tested
- Joplin OCR for scanned PDFs: what it reads, tested
- dots.ocr on a scanned PDF: Mac setup and results, tested