Repository navigation
v3.6.0 — reading order from the layout model, word boxes on every route, requests past 120 s
Latestv3.6.0 — reading order from the layout model, word boxes on every route, requests past 120 s
Response shapes are unchanged apart from the new, opt-in words. Detection now matches PaddleOCR's box geometry, so boxes and some text differ slightly from 3.5.x (see below).
Reading order follows the layout model (#37)
reading_order=1 and as_blocks=1 now order the text by the reading order PP-DocLayoutV3 predicts for its boxes, with a guard that keeps a column top to bottom, a tie guard, and the column-splitting XY-cut when the model gives no order. Multi-column pages no longer interleave their columns. OmniDocBench (100-page subset): reading-order edit distance 0.2344 → 0.1625. GPU and CPU order agree (Kendall τ 0.999).
Word boxes (#35)
?words=1 on every HTTP route (words = 20 on the gRPC requests) adds a words array to each result: each word's text, confidence and its own box, in the line's point order. Words split at spaces, every CJK character is a word of its own, punctuation stays with its word; boxes are cut at the line's real ink gaps and trimmed to the word's ink. On /ocr/pdf, text-layer lines take their words from the PDF itself. On 24 unseen OmniDocBench pages: 0.11% of words cut, 0.20% missed.
On the GPU server the per-pixel work runs on the GPU for every line of a page at once (TURBO_WORDS_GPU, default on), with the same boxes as the CPU placement to the pixel, and off the GPU worker on /ocr/raw, /ocr/stream and /ocr. RTX 5090, 32 connections: 197 pages/s with ?words=1 against 218 without (110 with TURBO_WORDS_GPU=0). Requests without words are unaffected.
Requests longer than 120 s
A request is silent on its connection until its response is written, and both the server's idle timeout and the bundled nginx's proxy timeouts were a fixed 120 s, so a long PDF failed with 502 after all its work. IDLE_CONNECTION_TIMEOUT_S / --idle-connection-timeout-s (default 120, 0 = never, up to 86400) sets the limit, and the image's nginx follows it. The server warns at startup when it is shorter than REQUEST_TIMEOUT_MS.
Detection matches PaddleOCR
Two differences from the reference pipeline with the same PP-OCRv6 models: DB's unclip grew each region's pixel outline where PaddleOCR grows its min-area rectangle, so boxes came out about a pixel smaller per side and lost the narrow last glyph of a line (、。,); and tall crops were turned clockwise where PaddleOCR turns them anticlockwise. OmniDocBench (34 pages): word recall 95.05 → 95.23 (tiny), 95.02 → 95.11 (medium); punctuation 91.31 → 92.84 (tiny). The CPU tiny pipeline is about 9% faster. With DISABLE_ANGLE_CLS=1, Latin text running bottom to top now comes out upside down, as in PaddleOCR — the angle classifier is what turns it.
GPU server fixes
- A 10,000-page PDF answered 503 "GPU queue full": all its pages were queued at once. A job now keeps a bounded window of pages in flight; the PDF completes (10 s) while other requests are served.
- CMYK JPEGs answered 503: nvJPEG does not decode them. The JPEG header now sends them to the host decoder.
- The medium models ran out of VRAM at startup: the automatic pool assumed 2 GiB per pipeline. It is now sized from the first pipeline's measured footprint; an explicit
PIPELINE_POOL_SIZEis built exactly, or startup fails. - Line order could change between restarts: lines were banded by y / 10 into fixed rows, so boxes a pixel apart could swap lines. Lines are now clustered by vertical overlap.
Verified
The images built from this tree were verified before tagging. GPU: 438 unit tests, integration 324 passed / 0 failed, all 16 routes, robustness and determinism checks; word boxes identical to the CPU placement (0 of 71,596 words differ); compute-sanitizer memcheck, racecheck, initcheck and synccheck clean; a 90 s mixed soak answered 8,606/8,606 requests with VRAM and memory flat. CPU amd64: 375 unit tests, integration 286 passed / 0 failed, all 14 routes, robustness and determinism checks. The CPU arm64 image is built by CI from the same tag.
Images
- GPU (TensorRT, x86_64):
ghcr.io/aiptimizer/turboocr:v3.6.0(also:latest) - CPU (ONNX Runtime, amd64+arm64):
ghcr.io/aiptimizer/turboocr-cpu:v3.6.0(also:latest, andghcr.io/aiptimizer/turboocr:v3.6.0-cpu)