Introduction

This repository hosts PaddleOCR PP-OCRv6 (the detector + recognizer) for the React Native ExecuTorch library, exported to .pte for the ExecuTorch runtime (XNNPACK, CoreML and Vulkan backends).

If you'd like to run these models in your own ExecuTorch runtime, refer to the official documentation for setup instructions.

PP-OCRv6 is the primary OCR pipeline — smallest and fastest. It ships as one fused .pte per backend with a single dynamic detect and recognize method each (no per-size method buckets). The .pte is a pure tensor→tensor function; all pre/post-processing (resize, normalize, DBNet box decode, perspective crop, CTC decode) is the client's job and is driven by config.json. One model covers all languages (18 709-entry multilingual charset).

Methods & I/O contract

method input output
detect (DBNet) [1,3,H,W] f32 RGB, ImageNet-normalized by the client: (x/255 − mean)/std, mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225] [1,1,H,W] probability map (sigmoid baked)
recognize (SVTR) [1,3,48,W] f32 RGB, client-normalized (x/255 − 0.5)/0.5 [1,W/8,18709+1] probs (softmax baked); charset[i] → logit i+1, blank = 0

Nothing is baked for input normalization — the client normalizes before calling. Note the two methods use different norms (ImageNet for detect, 0.5/0.5 for recognize).

Shape discovery (companion methods)

Every method carries exactly one no-arg discovery companion:

  • get_dynamic_dims_<method> — dynamic method. Returns one int32 [rank, 3] tensor per tensor input; each row is [min, max, step] (static dims are [n, n, 1]). Any conforming shape is valid.
  • get_enum_shapes_<method> — enumerated method. Returns one int32 [N, rank] tensor per tensor input; each row is a complete legal shape (cross-dimension coupling is exact — a listed 1280×640 does not imply 640×1280). Snap inputs to the nearest row.
backend detect recognize
xnnpack, vulkan get_dynamic_dims_detect → H, W ∈ [640, 1280] step 32 get_dynamic_dims_recognize → W ∈ [160, 1280] step 8 (H fixed 48)
coreml get_enum_shapes_detect → 640², 960², 1280², 1280×640 get_enum_shapes_recognize → widths 160, 320, 480, 640, 1280

Backends

backend target detect recognize warm latency (detect @960² / recognize)
xnnpack CPU fp32, true-dynamic fp32, true-dynamic ~574 ms / ~28 ms (Galaxy S24)
coreml Apple ANE weight-only int8, enumerated weight-only int8, enumerated ~12–15 ms / ~2 ms (Apple M-series ANE)
vulkan Android GPU fp16, true-dynamic (resize) fp32 on XNNPACK (mixed-delegate) ~73 ms / ~27 ms (Galaxy S24, Xclipse 940)

Vulkan is mixed-delegate: DBNet detects on the GPU, the SVTR recognizer runs on the CPU (XNNPACK) — the 18 709-token vocab head is not Vulkan-safe, and int8 SVTR is lossy, so the recognizer stays fp32 on CPU for correctness.

Why fp32 on CPU? Static-activation int8 quantization is not stable across dynamic input sizes for the detector (measured broken at ≥960px — including in the old per-bucket builds); fp32 is bit-exact at every shape.

CoreML notes (iOS)

  • The CoreML .pte is a multifunction Core ML model (detect + recognize share one precompiled .mlmodelc). Requires iOS 18+ and an ExecuTorch runtime ≥ 1.3 (multifunction loading via functionName).
  • First-ever load on a device triggers a one-time per-shape ANE specialization (OS-cached afterwards) — warm each model once after install.

Compatibility

If you intend to use these models outside of React Native ExecuTorch, make sure your runtime is compatible with the ExecuTorch version used to export the .pte files. For more details, see the compatibility note in the ExecuTorch GitHub repository. If you work with React Native ExecuTorch, the library constants guarantee compatibility with the runtime used behind the scenes.

Downloads last month
100
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Collection including software-mansion/react-native-executorch-pp-ocrv6