Repository navigation
perf: accelerate Weka replay preparation - #543
Conversation
Signed-off-by: Alexandre Milesi <milesial@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📜 Recent review details
📝 Summary
Merge Risk: ⚪ Minimal · up to
|
Signed-off-by: Alexandre Milesi <milesial@users.noreply.github.com>
Record the measured command, cumulative runtime stages, component timings, and disk and RAM boundaries. Signed-off-by: Alexandre Milesi <milesial@users.noreply.github.com>
Signed-off-by: Alexandre Milesi <milesial@users.noreply.github.com>
tedzhouhk
left a comment
There was a problem hiding this comment.
Reviewed 7fb214aa; no new correctness issue found in the exercised paths. The buffered spool, per-play collision-checked hash memoization, streaming scan, and bounded estimate cache preserve the tested semantics. Cache identity/invalidation, malformed input, eviction, and current-headroom admission were checked.
Validation on the exact head: 164 Python resource tests and 207 Rust load-generator tests passed; 600 cold/warm/budget comparisons over 120 generated corpora also passed. The Python suites used a freshly built head-native extension.
The reported ~3x improvement is end-to-end command wall time dominated by preparation savings, not a 3x core-replay or modeled GPU-throughput improvement. I did not independently reproduce the private-trace performance measurement.
Why and what changed
Weka replay spends host time serializing rows, normalizing repeated prefix hashes, and inspecting the same trace twice before execution.
This change buffers row writes, parses rows from a reusable byte buffer, and reuses collision-checked source hashes within each play. Python admission consumes hash arrays through a streaming loop and caches completed corpus estimates. Both admission guards still apply current memory headroom.
The measured command takes 85.53 s before this PR, 42.86 s with buffering, and 28.02 s with all changes. This saves 57.51 s, or 67.24%, for a 3.05× overall speedup. The additional changes save 14.84 s beyond buffering, or another 1.53× speedup.
Command and end-to-end ladder
This is the public command measured from process launch through exit, including Python startup and output conversion:
CONFIGandOUTPUTreplace private absolute paths. All three configuration files contain identical JSON. The installed interpreter comes from the experiment virtual environment.The Linux x86_64 run uses a 64,882,247-byte Weka trace with 16 plays and 4,908 source requests. It uses one replica, 16 agentic lanes, seed 42, warmup, and a 3,600-second profile. The resource limits are 6 GB and four CPUs. The trace block size is 64.
RAM means resident set size, or memory resident in RAM. The RAM column is the sampled sum for the supervised process tree. It excludes the outer coordinator. One sample per stage does not establish a RAM reduction or timing variance.
Native replay takes 17.15 → 16.84 → 17.18 s. Time outside native replay falls from 68.38 → 26.02 → 10.83 s. That interval includes admission, import, model preparation, startup, and output conversion. The 0.35-second native variation does not establish a replay improvement or regression.
Completed requests, output tokens, simulated duration, predicted throughput, and the request lifecycle digest remain identical across all stages.
Only this public command has an end-to-end comparison. No separate end-to-end ablation exists for each change in the final stage.
Per-change time, disk, and RAM impact
The following component measurements use macOS arm64. Their times do not add to the Linux command ladder.
The native probe runs these diagnostic commands with the sample trace:
The probe timer covers import through graph finalization. It excludes process startup and a later digest pass. Three alternating pairs give a total median of 7.934 → 3.386 s, or 2.34×. Both builds already contain buffered writes.
The two native changes raise median process peak RAM from 207,142,912 to 219,971,584 bytes, an increase of 12.23 MiB. That peak includes the digest pass. The measurements do not isolate each native change's RAM cost. Phase medians do not sum to the total median.
The Python measurements time estimator calls, not complete CLI commands. Before/after parser calls share a process, so their RAM values are cumulative high-water marks. The cache series uses a separate process. Its full-source cold and warm calls report the same 47,906,816-byte high-water mark. Estimates remain byte-for-byte equal, and a cache hit still rejects insufficient live headroom.
Disk space boundary
A separate import probe finds the same 258,529,550-byte canonical row spool in both native builds. The source snapshot adds 64,882,247 bytes. They overlap during import, for 323,411,797 bytes of logical temporary file data, or 308.43 MiB. The measured spool-size difference is zero. Both probes remove their temporary files on exit.
This total excludes original input, output reports, filesystem overhead, and unrelated files. The directory sampler does not capture the exact filesystem allocation peak. No disk peak was measured during the Linux commands. Sufficient
TMPDIRcapacity remains necessary because this PR does not shrink the spool.Review map and evidence
_estimate_weka_traceinresources.py, thenWekaImporter::for_each_rowandnormalized_hashesinweka.rs.cd84034e7bab39854203c3b2f2bacbfb8319b204.Modeling and measurement limits
These changes affect host runtime. They do not change modeled GPU performance. Model, workload, scheduler configuration, and other experimental patches remain fixed across the end-to-end stages.
Those other patches, the source trace, diagnostic binaries, and complete model configuration are outside this PR. These observations are not a standalone reproducible benchmark or a general speedup guarantee. The 28.02-second result uses the sample trace. Full-source Python inspection is not a full-corpus simulation. Earlier full-corpus baselines did not complete, so this PR claims no full-corpus end-to-end speedup ratio.