Performance#
docTR runs on the CPU out of the box. This page lists the levers to make it faster, from the most effective to the most specialized.
Run on a GPU#
Predictors are PyTorch modules: move them to a device like any model. Inputs are moved automatically.
import torch
from doctr.models import ocr_predictor
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
predictor = ocr_predictor(pretrained=True).to(device)
# or simply: ocr_predictor(pretrained=True).cuda()
import torch
from doctr.models import ocr_predictor
device = torch.device("mps" if torch.backends.mps.is_available() else "cpu")
predictor = ocr_predictor(pretrained=True).to(device)
The same applies to every predictor: detection_predictor, recognition_predictor, layout_predictor,
table_predictor, crop_orientation_predictor and page_orientation_predictor.
Half precision#
On a GPU, half-precision inference uses 16-bit floats instead of 32-bit: it is faster and uses less memory, with the same results in practice.
from doctr.models import ocr_predictor
predictor = ocr_predictor(pretrained=True).cuda().bfloat16() # or .half() for float16
result = predictor(pages)
Format |
Method |
Notes |
|---|---|---|
bfloat16 recommended |
|
Same range as float32, so no overflow. Requires an Ampere GPU or newer (compute capability 8.0+) |
float16 |
|
More precision but a much narrower range. Use it on older GPUs |
Note
Half precision is only supported on GPU devices. The CLI enables bfloat16 automatically on compatible GPUs.
Batch sizes#
The predictor processes pages and word crops in batches: det_bs pages at a time for detection (default 2) and
reco_bs crops at a time for recognition (default 128). On a GPU with free memory, larger batches are faster;
lower them if you run out of memory:
predictor = ocr_predictor(pretrained=True, det_bs=8, reco_bs=512)
Pass all the pages of a document (or several documents) in one call so that batches are full.
Skip what you don’t need#
Keep
assume_straight_pages=True(default) for upright documents: it avoids the orientation classifiers and the more expensive rotated-box post-processing.With rotated documents,
disable_page_orientation=Trueanddisable_crop_orientation=Trueskip the orientation classifiers when you know the text is horizontal (see Rotated documents).Only enable
detect_layout,detect_tables,detect_orientationanddetect_languagewhen you use them.Use lighter architectures, see the model zoo.
Compile the models#
torch.compile converts the models into
optimized graphs. Compile the models first, then build the predictor with them:
import torch
from doctr.models import (
crop_orientation_predictor,
fast_base,
mobilenet_v3_small_crop_orientation,
mobilenet_v3_small_page_orientation,
ocr_predictor,
page_orientation_predictor,
vitstr_small,
)
detection_model = torch.compile(fast_base(pretrained=True).eval())
recognition_model = torch.compile(vitstr_small(pretrained=True).eval())
predictor = ocr_predictor(detection_model, recognition_model, assume_straight_pages=False)
# Only needed when the orientation classifiers are used (rotated documents)
predictor.crop_orientation_predictor = crop_orientation_predictor(
torch.compile(mobilenet_v3_small_crop_orientation(pretrained=True).eval())
)
predictor.page_orientation_predictor = page_orientation_predictor(
torch.compile(mobilenet_v3_small_page_orientation(pretrained=True).eval())
)
result = predictor(pages)
Important
The first calls are slow while the graphs are compiled: warm the predictor up before measuring.
The
masterrecognition architecture does not support compilation yet.Only the default
inductorbackend is officially supported.
CPU inference#
PyTorch uses all the cores by default. When several workers share a machine, limit each of them with
torch.set_num_threads(n).For the smallest footprint, export the models to ONNX and run them with OnnxTR, optionally with 8-bit quantized models.
Measure#
The latency.py scripts of the references benchmark any
architecture on your hardware:
python references/detection/latency.py fast_base --it 100