[Performance] Avoid parent env construction in ParallelEnv startup - #4029
[Performance] Avoid parent env construction in ParallelEnv startup#4029vmoens wants to merge 1 commit into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/rl/4029
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit 5ab5a17 with merge base 9f397fd ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
theap06
left a comment
There was a problem hiding this comment.
The ParallelEnv in batched_env throws a TypeError at the start. The metaclass converts single-worker ParallelEnvs to SerialEnv but forwards the new flag, which SerialEnv rejects.
|
It's weird that our tests did not catch this, the SerialEnv fallback is used in the tests for sure no? |
|
@vmoens The fallback is covered, but never together with the new flag: test_serial_for_single predates this PR. The flag only reaches SerialEnv on the num_workers==1 && serial_for_single=True early-return in _PEnvMeta.call, which pops serial_for_single but not metadata_from_workers before return SerialEnv(*args, **kwargs). so the failing line is never executed in CI. minor nitpick tbh |
Summary
create_env_kwargs, preserving task, instruction, group, worker-offset, seed, and init-state assignmentParallelEnv(metadata_from_workers=True)startup so real workers provide metadata before initialization and the parent never creates shadow environmentsEnvCreatorand instantiated-environment ownershipWhy
A sequence of distinct per-worker callables makes
ParallelEnvtreat a homogeneous LIBERO workload as heterogeneous. Metadata discovery then constructs every environment serially in the subcollector parent before constructing the same environments again in the real workers. At 320 environments this creates 320 unnecessary MuJoCo/EGL environments and contaminates the parent with EGL state.The worker metadata handshake removes that shadow wave while keeping the default
ParallelEnvbehavior unchanged. The initial implementation deliberately uses direct pipe communication;use_buffers=Truefails clearly rather than selecting an unsafe path.Benchmark
Production LIBERO was measured on the 5 subcollector x 64 environment topology. The verified worker-metadata/spawn run produced:
[0, 0, 0, 0, 0]A controlled one-subcollector/64-environment comparison on the same node was:
Worker metadata reduced readiness latency by 4.24x and first-batch latency by 3.39x versus the legacy path. Forkserver was not materially faster than spawn in the paired run, so the recipe keeps spawn as the safer default. Outer subcollectors also remain on spawn.
Complete commands, output, construction markers, and JSON summaries are stored under:
The aggregate is
comparison.json; each run directory containscommand.txt,run.log, andsummary.json.Validation
uv run pytest -q test/envs/test_parallel.py(83 passed, 66 skipped)uv run pytest -q sota-implementations/vla_grpo/test_openvla.py(14 passed, 22 skipped for unavailable optional dependencies)uv run pytest -q sota-implementations/vla_grpo/test_openvla.py -k 'factory or instruction or group'(10 passed)