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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyturboocr-0.1.0-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

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

Hashes for pyturboocr-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c9f5f10f27bb75d1f19bbafa98353956480725d8768662197a2a5da783eeb3d
MD5 e082af826daf4870d5ddfcaaea57ecb1
BLAKE2b-256 1311d45c2d1d770e4760449f0b70908caeaa785469bf6c050569aefe8bef8c0a

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

1 file

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