Commit Graph

8 Commits

Author SHA1 Message Date
5dd62ac201 [0.1.35] OCR on the GPU runs as many detector and recognizer runs at once as fit in its memory
The workers ran gpu_workers (4) runs at once whatever the images: the server
model, four large images at a time, took 15 GB of a 16 GB GPU and spilled into
shared system memory, and a smaller GPU would fare far worse.

modules/OCR/budget.jai: each run reserves what it is expected to need, and
waits while the runs in flight or the GPU's free memory leave too little; one
run always goes. The need is measured when the engine is made, from the arena's
peak (AllocatorGetStats MaxInUse) over runs on two input sizes, so it holds for
any model and GPU: the mobile detector 6 MB + 137 MB a megapixel, the server's
4 MB + 1015, against 511 and 522 MB measured for a 2560 x 1440 tile. The limit
is the GPU's free memory less 10% (at least 512 MB), read at the start of each
ocr_process call (cudaMemGetInfo, ort_cuda_memory); the free memory is also read
as each run starts, since finished runs' blocks stay in the arena until the
stage ends.

gpu-bench, RTX 5080 laptop: the server model 335 ms a capture (854 before),
peak 13.1 GB (15.4), passes within 4%; the mobile model unchanged (140 ms,
5.7 GB), as its runs fit.
2026-10-17 21:33:32 -04:00
30cd00b6f2 [0.1.30] macOS phase 5: PP-OCRv5 mobile OCR on the GPU through native Core ML 2026-10-17 21:16:59 -04:00
2d0fb855b1 [0.1.29] macOS phase 5: SigLIP 2 labels on the GPU through native Core ML 2026-10-17 21:16:31 -04:00
12d0f30fc4 [0.1.25] macOS phase 1: builds and runs on a Mac, the library folder as a setting 2026-10-17 21:16:29 -04:00
8c8b2c6e38 [0.1.24] GPU memory: OCR runs largest first, gives its arenas' blocks back after each stage, and keeps its worker threads
OCR filled the GPU: 9 GB for the mobile model on gpu-bench's 30 images, past
16 GB for the server model, which Windows then paged into shared memory (1.5 to
11 s a capture). onnxruntime's logged arena extensions showed why: the arena
keeps every block it takes from CUDA and never joins or frees them, and OCR's
inputs grow from run to run (recognizer batches went narrowest first; images in
any order across calls), so each larger run left another block behind: 5.7 GB
of recognizer blocks where the widest batch needs 0.9 GB.

- Detection runs the largest images first, recognition the widest batches.
- The detector's and recognizer's arenas shrink once each stage of an
  ocr_process call is done, by a run on a small input with
  memory.enable_memory_arena_shrinkage. Shrinking after every run cost 33 to
  59% of the speed.
- The worker threads are made with the engine and kept, not made for every
  stage of every call (onnxruntime keeps GPU state for each thread that runs a
  session, microsoft/onnxruntime#33037); 6% faster.
- OCR's arenas grow by what is asked (kSameAsRequested).
- ort.log_level sets what the engines' onnxruntime environments log; INFO shows
  every arena extension.

Mobile OCR on gpu-bench (RTX 5080 laptop, 4 workers): peak 5.7 GB over the
baseline, 2 GB between calls, 142 ms a capture, against 9.0 GB and 126 ms. The
text read differs by a line in 2,986 (batches are grouped differently). The
server model is not yet measured again.
2026-10-17 21:12:57 -04:00
cb21b73460 [0.0.11] Segmentation phases 1-2: Mask2Former exported to ONNX, and modules/Segment to run it
- segmentation-plan.html: the plan for panoptic segmentation of images, per library folder, stored
  in .mcap chunks (no file version bump), in six phases.
- tools/export_mask2former.py: exports facebook/mask2former-swin-base-coco-panoptic to ONNX (opset 17,
  dynamic batch, 384 x 384 input) and checks it against PyTorch: on 25 images, all 180 segments
  identical (IoU 1.000). Writes the class list with names for people ("sky-other-merged" is "sky"),
  and PyTorch's own segmentations for segment-probe -check.
- modules/Segment: runs the model with onnxruntime (CUDA, else the CPU) and makes segments of its
  outputs as transformers' post_process_panoptic_segmentation does: a segment id map (longest side at
  most 1024) and each segment's class, score, area and bounds. Matches PyTorch on 99.8% of pixels,
  every segment scored 0.6 or more found. 57 ms an image at batch 4 on an RTX 5080 laptop.
- tools/segment_probe.jai (jai first.jai - segment_probe): segments image files; -out draws them,
  -check compares with PyTorch, -dump-input writes the model's input.
- modules/onnxruntime: ort_run_float_outputs, for a model with several outputs.
- first.jai copies the model to bin/segment-models. The model itself is not in git
  (modules/Segment/models, 462 MB); tools/export_mask2former.py makes it.
2026-10-10 03:39:28 +01:00
cf60dfa535 [0.0.5] Labels: SigLIP 2 labels and image vectors in .mcap version 3 chunks; label: and like: search 2026-10-08 11:37:21 +01:00
bb94f03b94 [0.0.0] OCR: an onnxruntime module and an OCR module, PP-OCRv5 mobile and server, on the GPU through CUDA when it can 2026-10-07 20:45:05 +01:00