Skip to main content

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

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 — pyturboocr handles 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.md are 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.

Metadata

Release files for pyturboocr 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for pyturboocr 0.1.0
File Interpreter ABI Platform
pyturboocr-0.1.0-py3-none-any.whl Python 3 none any Details

Release files / pyturboocr-0.1.0-py3-none-any.whl

Download URL pyturboocr-0.1.0-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9c9f5f10f27bb75d1f19bbafa98353956480725d8768662197a2a5da783eeb3d
BLAKE2b-256 checksum
How to use checksums
1311d45c2d1d770e4760449f0b70908caeaa785469bf6c050569aefe8bef8c0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for pyturboocr 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

1 release file No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page