pyturboocr
Pure-Python OCR. Same PP-OCRv6 ONNX weights that TurboOCR's
C++/CUDA/TensorRT server bakes into its Docker image — loaded here with
onnxruntime and decoded with plain NumPy/OpenCV.
No C++ binding, no CUDA/TensorRT requirement, no server process, no Docker.
pip install pyturboocr
from pyturboocr import OCR
ocr = OCR(tier="tiny") # downloads + caches ONNX weights on first use
result = ocr.recognize_image("invoice.png")
print(result.text)
for line in result:
print(line.text, line.confidence, line.box)
Contents
- Installation
- Why this exists
- How it works
- Model tiers
- Usage
- Benchmarks
- Accuracy
- How this compares
- Development
- Known limitations
- License
- Acknowledgments
Installation
pip install pyturboocr
Optional extras:
pip install pyturboocr[gpu] # onnxruntime-gpu, for CUDAExecutionProvider
Requires Python ≥ 3.9. Runs on Linux, macOS, and Windows (CPU); GPU support
depends on your platform's onnxruntime-gpu / onnxruntime-directml
availability.
Why this exists
TurboOCR's C++ server is built around a persistent GPU-resident pipeline — worker pools, watchdog threads, TensorRT engine caches — designed to serve hundreds of requests per second behind HTTP/gRPC. That's the right architecture for a high-throughput inference server, but it's the wrong shape for "I just want to call a function from my Python script."
The detection and recognition models themselves, however, are published as
plain ONNX files on GitHub Releases, independent of the server. And the
algorithms wrapped around them — DB (Differentiable Binarization) for
text detection, CTC greedy decoding for text recognition — are standard,
well-documented techniques from the PaddleOCR ecosystem, not proprietary
logic. pyturboocr re-implements just that thin layer in Python, so the
whole thing runs in-process with no server and no compiled extension.
How it works
flowchart LR
A[Input image] --> B["Resize + normalize<br/><i>preprocess.py</i>"]
B --> C["Detection ONNX model<br/><i>onnxruntime</i>"]
C --> D["DB post-process<br/>threshold → contours → unclip<br/><i>postprocess/db.py</i>"]
D --> E["Per-line crop + perspective warp<br/><i>preprocess.py</i>"]
E --> F["Recognition ONNX model<br/><i>onnxruntime</i>"]
F --> G["CTC greedy decode<br/><i>postprocess/ctc.py</i>"]
G --> H["TextResult(text, confidence, box)"]
Model weights are downloaded once from TurboOCR's GitHub Release assets and
cached under ~/.cache/pyturboocr (override with PYTURBOOCR_CACHE_DIR).
Everything after that first download runs offline, in-process.
Model tiers
| Tier | Detection params | Use case |
|---|---|---|
tiny |
smallest | fast, low-memory, good for short/clean text |
small |
medium | balance of speed and accuracy |
medium |
largest | best accuracy, slowest |
OCR(tier="small")
Usage
Basic:
from pyturboocr import OCR
ocr = OCR(tier="tiny")
result = ocr.recognize_image("page.png")
print(result.text)
Per-line results with boxes and confidence:
for line in result:
print(f"{line.text!r} conf={line.confidence:.3f} box={line.box}")
From a NumPy array (e.g. a frame from OpenCV/a webcam):
import cv2
frame = cv2.imread("page.png")
result = ocr.recognize_image(frame)
GPU:
ocr = OCR(tier="tiny", providers=["CUDAExecutionProvider", "CPUExecutionProvider"])
Custom detection thresholds:
from pyturboocr.postprocess.db import DBParams
ocr = OCR(tier="tiny", db_params=DBParams(thresh=0.3, box_thresh=0.6, unclip_ratio=1.5))
See examples/quickstart.ipynb for a runnable walkthrough with visualized
detection boxes.
Benchmarks
Full methodology, raw numbers, and an explicitly-caveated comparison against
RapidOCR live in
benchmarks/RESULTS.md. Reproduce on your own
machine with:
pip install -r benchmarks/requirements.txt
python benchmarks/benchmark_all.py # writes benchmarks/results.json
The script benchmarks pyturboocr alongside other installed OCR engines
(RapidOCR's onnxruntime/OpenVINO backends, EasyOCR if installed, ...),
skipping anything not installed, and records per-call timings plus system
info (CPU, cores, RAM) as JSON — see benchmarks/results.sample.json for an
example.
Headline numbers (1 vCPU, CPU-only, tier=tiny, steady-state after warm-up):
| Image | Lines | ms/image | img/s |
|---|---|---|---|
| Single line | 1 | ~30 | ~33 |
| 4-line invoice | 4 | ~70–110 | ~9–14 |
These numbers are from a single-core sandbox and will not match a real deployment target — benchmark on your own hardware before relying on this for capacity planning. For high-throughput batch processing (GPU, thousands of pages), TurboOCR's own TensorRT server is meaningfully faster than any pure-Python inference path, this one included.
Accuracy
pyturboocr loads the exact same PP-OCRv6 ONNX weights TurboOCR's server
uses — the model itself is identical, only the pre/post-processing
implementation differs. In practice, expect near-identical text output to
the TurboOCR server on the same input, modulo:
- floating-point differences between ONNX Runtime and TensorRT execution
- any TurboOCR-side preprocessing (e.g. PDF rasterization, layout detection)
that this package does not implement —
pyturboocrhandles raster images only, not PDFs or layout analysis
This package's own pre/post-processing has been validated against real
rendered text images (see tests/data/) but has not been stress-tested
against noisy real-world scans, rotated text, or handwriting the way a
mature library like RapidOCR or PaddleOCR has. See
Known limitations.
How this compares
pyturboocr |
TurboOCR (server) | RapidOCR | |
|---|---|---|---|
| Model | PP-OCRv6 ONNX | PP-OCRv6 → TensorRT | PP-OCRv6 ONNX (and others) |
| Runtime | in-process, onnxruntime |
persistent GPU server | in-process, multi-backend |
| Setup | pip install |
Docker / native build + running server | pip install |
| Backends | CPU / CUDA (via onnxruntime) | TensorRT (GPU only) | onnxruntime / OpenVINO / TensorRT / PaddlePaddle / PyTorch |
| Best for | scripts, small apps, embedding | high-throughput batch/production serving | general-purpose production OCR |
If you need a battle-tested, actively maintained pure-Python OCR library and
don't specifically need TurboOCR's exact packaging, RapidOCR is a reasonable
default. pyturboocr exists for cases where you specifically want the
TurboOCR model weights with zero server/binding overhead.
Development
git clone <this-repo>
cd pyturboocr
pip install -e '.[dev,examples]'
pytest
Run a notebook:
jupyter notebook examples/quickstart.ipynb
Known limitations
- Raster images only — no PDF handling, no layout/table detection (the underlying TurboOCR server does more than text OCR; this package doesn't).
- Detection/recognition post-processing is a from-scratch reimplementation of standard DB/CTC algorithms, tested against clean rendered text and a handful of real-model smoke tests — not yet validated on noisy scans, rotated/skewed text, or handwriting at the scale a mature library has been.
- No batching — each detected line is recognized one at a time; batching crops into a single recognition call would improve throughput and isn't implemented yet.
- CPU benchmarks only — GPU numbers haven't been collected; if you run
them, contributions to
benchmarks/RESULTS.mdare welcome.
License
MIT — see LICENSE. Downloaded model weights are a separate
artifact from this repository's source and carry their own upstream terms;
verify those before redistributing the weights themselves.
Acknowledgments
pyturboocr exists entirely downstream of TurboOCR —
this package would not exist without its published PP-OCRv6 ONNX weights and
the detection/recognition algorithms its C++ server implements. If you need
production-grade throughput on GPU, use TurboOCR's own server directly
rather than this pure-Python re-implementation.
Model architecture: PP-OCRv6, part of the PaddleOCR project by PaddlePaddle/Baidu.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyturboocr-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pyturboocr-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c9f5f10f27bb75d1f19bbafa98353956480725d8768662197a2a5da783eeb3d
|
|
| MD5 |
e082af826daf4870d5ddfcaaea57ecb1
|
|
| BLAKE2b-256 |
1311d45c2d1d770e4760449f0b70908caeaa785469bf6c050569aefe8bef8c0a
|