AI media

Extract Text from PDFs and Images with Local OCR

3 min read

Scanned PDFs and photos of documents hide their text from search, copy-paste and RAG. A local OCR model turns those pixels back into characters on your own machine, with no upload and no per-page API bill. This guide uses datalab-to/indra-ocr: a small, CPU-only model that reads images and PDFs and returns clean Markdown.

1. Pick a local OCR model

OCR models split into two camps. Large vision-language models like baidu/Unlimited-OCR (about 3B parameters) are accurate but want a CUDA GPU; weigh that against your hardware in how much RAM or VRAM a model needs. indra-ocr sits at the other end: it runs on ONNX Runtime on the CPU, needs no PyTorch, and downloads about 76 MB of weights. For a copy-paste pipeline that works on any laptop, start there.

2. Install the package

pip install indra-ocr

That pulls the ONNX runtime and the helper code; the model weights download on first use, and Python 3.10 or newer is required.

3. OCR a single image

import indra_ocr

conv = indra_ocr.load(threads=4)  # mode="auto" | "ocr" | "text"

for i, page in conv.convert("scan.png"):
    print(page.text)

load() fetches the weights once and caches them, and convert() yields one page per input, where page.text holds the plain extracted text.

4. Extract a multi-page PDF

for i, page in conv.convert("paper.pdf"):
    print(f"--- page {i} ---")
    print(page.markdown)

Pass a PDF and the same loop runs page by page; page.markdown keeps headings, lists and tables as structured Markdown instead of a flat text dump.

5. Batch many files

if __name__ == "__main__":
    for path, result in indra_ocr.convert_many(["a.pdf", "b.pdf"], cores=None):
        print(path, "done")

convert_many runs one worker per CPU core and returns results in input order; it spawns processes, so the __main__ guard is mandatory.

6. Find the cached weights

On first run the weights download from the Hub and cache alongside your other models; see where Hugging Face caches files. To pin a fixed copy for an air-gapped box or CI, point INDRA_OCR_MODEL_DIR at a folder holding a pre-downloaded copy and nothing hits the network.

If it fails


Next: describe and query images with a vision model · run a model with transformers pipeline() · how much RAM or VRAM a model needs.

Open the full interactive version (with copy buttons) ↗

← All guides