cheap-ocr
cheap-ocr was born from the need to OCR a large corpus of PDF documents with complex layouts quickly and at low cost. It converts PDF documents to markdown and json, including documents with complex layouts and tables. It uses pp-doclayout-v3 for layout detection and GLM-OCR to recognize text. We measured throughput at more than 14 pages per second on our benchmark. For other datasets, we reached up to 20 pages per second. It runs on a single L40S GPU (or similar).
Read our blog to learn all about the optimizations that we apply.
Benchmarks
We use 100 PDF documents from the European Medicines Agency to benchmark throughput. The documents are typical business documents with a mix of tables, text, and some figures. All metrics are reported end-to-end including download and upload. Warm-up (model loading and initialization) is excluded from our measurements. We compare cheap-ocr against the official GLM-OCR SDK. The benchmarks ran on a single L40S for both solutions.
| Metric | GLM-OCR SDK | cheap-ocr |
|---|
| Pages/sec | 5.29 | 14.26 |
| Output tokens/sec | 4,316 | 11,801 |
| Page regions/sec | 75 | 205.4 |
Features
| Feature | Description |
|---|
| Fast & cheap | Fastest and cheapest VLM-based OCR that we know of. |
| VLM-based OCR | State-of-the-art text recognition that handles difficult text extraction well. |
| Layout detection | Recognizes bounding boxes for headings, paragraphs, images, tables, and more. |
| OCR from cloud storage | Processes PDFs from and writes outputs to S3 buckets, Azure storage containers, or Google Cloud buckets. |
| One-line deployment | Runs the full pipeline on Modal with a single CLI command. |
| Bare-metal deployment | Runs on any machine with an NVIDIA GPU. |
Use on Modal (easiest, no local GPU required)
Log into Modal or register a new account. If you are already logged in, skip this step.
uvx --python 3.12 modal login
Then run cheap-ocr directly with uvx; no project files or persistent install are needed. The local command only needs the modal extra. The GPU stack is installed in the remote Modal image.
# run with local files
# startup takes a few minutes because models need to be loaded and CUDA graphs c