[Performance] Chunk process-slot worker results in AsyncBatchedCollector - #4305
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/rl/4305
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit 6108be6 with merge base b7f348e ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
The collection estimates are unmeasured GPU projections. Reaching the ceiling requires sufficient learner throughput (#4307). |
|
Measured on the target hardware (64-environment DreamerV3 run on a pixel task, one 4-GPU node, process-slot inference server with a static batch of 64, compiled and CUDA-graph learner step, bf16, train ratio 16), comparing the full stack #4305 + #4306 + #4307 + #4308 (with
The unthrottled collection phase before training reached 1,254 steps/s (298 before), the learner GPU now shows sustained full-utilization bursts instead of about a quarter duty cycle, and the run had no errors over the measured 1.3 hours. The two rates move together because the train ratio couples them, so the stack lifted both the collection ceiling and the learner cadence past the previous limits. This measures the combined effect of the four PRs; per-PR attribution has not been measured. |
|
Learning check (09 Sep): on the 64-environment task the stack keeps its throughput without CUDA-graph inference batches (1,234 env steps/s and 2.41 updates/s with |
Add an opt-in transition_chunk_size argument for the ProcessSlotTransport path. Each environment worker process accumulates that many consecutive transitions and sends them to the driver as one dense message instead of one message per transition. The driver receives one consolidated TensorDict per chunk, keeps chunks as dense blocks that are split only where a batch or the total frame budget ends (the remainder is carried into the next batch in order), assembles each batch with torch.cat and writes it to the replay buffer with the existing single routed extend. The driver's per-transition Python is amortized over the chunk; one result-capacity permit now covers a whole chunk. Profiling a 64-environment DreamerV3 Minecraft run on a 4-GPU node with inference served from the environment processes showed the driver main thread spending about 1.1 ms per transition in _rollout_frames (queue get and unpickling, the unpickler's filelock audit hook, replay extend) while environment workers waited in result_capacity.acquire: the bounded result queue back-pressured the environments at 371 steps/s. The default (transition_chunk_size=1) keeps the previous behavior, including lazy_stack batch assembly for every existing mode. Chunking requires ProcessSlotTransport and raises otherwise. Chunked batches are dense TensorDicts with a tensor env_index. pause(), shutdown(), total_frames trimming, background collection and completed-trajectory yielding work with chunks; partial chunks stay in the worker while paused and are dropped, like queued results, when the collector stops. Worker-owned replay streams were considered and not taken here: the collected batch is still needed in the driver for postproc and post_collect_hook, sampler window state, writer generation stamps and conditional patches live in the learner process, and CUDA replay storages would be excluded. Shipping chunks through shared-memory slots instead of the queue is a possible follow-up. Benchmarks: bench_collectors.py gains --transition-chunk-size and replay-mode support for async-process-slot; test_collectors_benchmark.py gains an async-process-slots-chunked series documented in ASYNC_BENCHMARKS.md. Tests cover exact budgets and per-stream ordering of dense chunked batches, routed writes into a StreamingSliceSampler ensemble with contiguous sampled windows, backpressure with pause and shutdown, trajectory yielding across chunk boundaries and validation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Add a driver_cpu_ms_per_frame column: the benchmarked process's user plus system CPU time over the measured window divided by the collected frames. End-to-end frames per second only exposes the driver's per-transition cost once the driver saturates; with process-backed environments and inference this column isolates the driver's own transition-path cost directly, which is what transition_chunk_size targets. Thread backends include their coordinator and inference-server threads in the same figure, as documented on the field. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
d3e9b60 to
6108be6
Compare
…tor (#4305) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Stack: #4305 → #4306 → #4307 → #4308 (base).
Batch worker transitions to reduce queue, unpickling, and replay-write overhead.
Chunks preserve stream order and frame budgets. Larger chunks increase latency and in-flight memory; batches become dense with tensor
env_index.Coverage: ordering/budgets, replay routing, trajectories, pause/shutdown. Reported CPU benchmark: ~6× less driver CPU/frame.