RetinaNet NP Scaling Results

June 22, 2026 · View on GitHub

Sweep date: 2026-05-12 17:39
dlio_benchmark commit: fc92d7f (feat/parquet-dgen-streaming)
DataLoader path: TorchIterableDatasetSimple + _s3_stream_next() pipelined chunking


Test Environment

ParameterValue
Host24 vCPU (Cascade Lake, no SHA-NI), 48 GB RAM
Object storagea local S3-compatible test server (http://127.0.0.1:9000, co-located on test host)
Bucket / pathmlp-retinanet/data/retinanet
Dataset50,000 JPEG files × 1 sample/file (≈ 15,399 MiB / ~15 GiB)
Record length322,957 bytes (~315 KiB / file)
Batch size24
Read threads8
computation_time0.04755 s (B200)
DataLoaderTorchIterableDatasetSimple — pipelined chunked GETs via _s3_stream_next()
prefetch_window256 (default) — chunk N+1 fetched in background while yielding chunk N
Epochs8
AU target≥ 85%
Model configretinanet_b200.yaml
MPI invocationmpirun -n NP -host 127.0.0.1:NP

⚠️ Co-located test configuration. The local S3-compatible test server and all benchmark processes run on the same 24 vCPU / 48 GB RAM host, sharing CPU cores, memory, and the loopback network interface. In a real deployment storage would be a dedicated remote system; the CPU/memory pressure that limits scaling here would not apply.

AU (Accelerator Utilization) — fraction of wall time the simulated accelerator was computing rather than waiting for I/O. AU ≥ 85% is the MLPerf Storage target for retinanet.


NP Scaling Results

NPAU% (mean ± σ)Samples/s (mean ± σ)I/O MiB/s (mean ± σ)Wall (s)AU ≥ 85%?
196.48 ± 0.08485.0 ± 0.4149.4 ± 0.1864✅ PASS
295.88 ± 0.07964.1 ± 0.8296.9 ± 0.2458✅ PASS
495.43 ± 0.201918.9 ± 4.5591.0 ± 1.4252✅ PASS

Per-epoch AU% breakdown

EpochNP=1NP=2NP=4
196.4295.8394.93
296.4196.0095.65
396.5695.9495.49
496.6095.8495.54
596.5195.8495.40
696.5395.9495.45
796.3895.8995.44
896.4195.7995.53

AU is extremely stable across epochs (σ < 0.2% at all NP values), confirming the pipelined I/O path is not accumulating latency or drift between epochs.


Scaling Analysis

Throughput Scaling Efficiency

TransitionSamples/sIdealEfficiency
NP=1 → NP=2485.0 → 964.1970.099.4%
NP=1 → NP=4485.0 → 1918.91940.098.9%

Near-perfect linear scaling through NP=4. The small efficiency loss at NP=4 is consistent with co-located SHA-256 signing load (no SHA-NI on this Cascade Lake host) competing for CPU cores with the benchmark processes.

I/O Throughput per NP

NPI/O MiB/sPer-accelerator MiB/s
1149.4149.4
2296.9148.5
4591.0147.8

Per-accelerator I/O throughput is flat (within 1.1%) across all NP values — the storage backend is not the bottleneck, and adding accelerators does not degrade per-accelerator I/O bandwidth.

DataLoader Architecture Note

RetinaNet (315 KiB × 50,000 files) is the most demanding small-object workload in the suite. Key design decisions that enable the above results:

  • TorchIterableDatasetSimple — file-sharded across workers, not map-style __getitem__, eliminating per-sample Python dispatch overhead.
  • _s3_stream_next() pipelined chunking — chunk N+1 is submitted to a background thread (via _PREFETCH_POOL) the instant the yield loop for chunk N begins. Since s3dlio releases the GIL during Rust async I/O, fetch and Python compute overlap truly concurrently. Peak concurrent GETs per worker: min(prefetch_window, 64) = 64.
  • Worker stagger — worker k delays k × computation_time seconds before its first chunk to spread startup I/O across one GPU-cycle window.

Raw Results Location

results/retinanet_np_sweep/20260512_173956/
├── NP1/training/retinanet/run/20260512_173956/summary.json
├── NP2/training/retinanet/run/20260512_175421/summary.json
└── NP4/training/retinanet/run/20260512_180159/summary.json