Skip to content

📦 WP-087d — perf(data): rasterise mask targets in the loader workers

Research log · Phase 7 — Instance segmentation, v0.2.0

🔗 Depends on WP-087c · Needed by none

⬅️ WP-087c · Roadmap · WP-087e ➡️

WP-087d — rasterise mask targets in the loader workers

Vectorised, the rasterisation still sat between forward and loss — serial with the GPU and competing with the optimiser's dispatch loop for cores. Measured on COCO at batch 32 with mosaic on: 1,005 ms rasterising and 1,475 ms in an optimiser that costs 94 ms in isolation, the accelerator idle for most of a 2,250 ms step. The optimiser figure is the informative one: it is not slow, it is starved.

Moving the work into collate_detection puts it inside a DataLoader worker, so batches are rasterised concurrently and ahead of the step consuming them. Two design points that made it possible without handing the collate a model: the grid is the input canvas at a fixed stride of four, derivable because ProtoNet upsamples the stride-8 fused feature by two (A15); and masks travel as a bool (sum_N, Hp, Wp) stack split by boxes_per_image, exact because the values are {0,1} and a quarter the bytes.

That then put the collate on the critical path: 4,454 ms on one thread for 64 mosaic images carrying 2,170 instances — 2.09 s of a 3.04 s step in train_dataloader_next. Fixed by testing each ring only inside its own bounding window, which replaces 087c's flattened-edge batching rather than composing with it: sharing one grid across an image's instances is what made that bookkeeping worth carrying, and a window removes the shared grid.

instance span before after
30 px 32.41 ms 1.73 ms
60 px 35.00 ms 3.27 ms
120 px 35.74 ms 8.03 ms

Cost now tracks the instance instead of being flat in the grid. Note the "before" column barely moves across a 4× span — that flatness is the defect, visible in the numbers before any explanation.

The correctness argument is stronger than "the window is large enough": outside it the crossing test is provably False rather than merely unlikely, and the window slices the coordinate ranges without translating the ring, so surviving pixels are bit-identical rather than equivalent.