Skip to content

Parallel-env training, compute plan, observation-validation fix#33

Merged
amcheste merged 1 commit into
mainfrom
feature/parallel-envs-and-compute-plan
Apr 30, 2026
Merged

Parallel-env training, compute plan, observation-validation fix#33
amcheste merged 1 commit into
mainfrom
feature/parallel-envs-and-compute-plan

Conversation

@amcheste-ai-agent

Copy link
Copy Markdown
Contributor

Summary

Three related changes triggered by the 2026-04-30 smoke test result.

1. scripts/train.py--n-envs N parallel-env support

The smoke test measured ~91 fps on the M3 Max with a single PyBoy env. At that rate each 10M-step pilot would take ~30 hours, putting the 9-pilot EWRL grid at ~270 hours (~11 days) sequential — too long for the 2026-05-25 deadline.

PyBoy is single-threaded CPU-bound, so SubprocVecEnv across multiple P-cores is the unlock. This PR adds:

  • --n-envs N flag (default 1). When N==1 the legacy DummyVecEnv single-env path is preserved bit-for-bit.
  • When N>1, _make_vec_env constructs N picklable PokemonRedGymEnv factories and passes them to SubprocVecEnv.
  • Each env writes its Monitor CSV to a rank-suffixed path (monitor.0, monitor.1, …) so parallel envs don't clobber each other's logs.
  • W&B integration, alerts, and callbacks are unchanged — they consume SB3's ep_info_buffer regardless of vectorisation.

Projected throughput on M3 Max: 4 envs → ~250-350 fps, 8 envs → ~500-700 fps.

2. scripts/run_pilots.sh--n-envs default to 4 + correct save-state path

  • Adds --n-envs N (default 4); forwards to every train.py invocation.
  • Bug fix: default save-state path was states/post_intro.state but the actual filename is states/s0_post_intro.state (the s0_ prefix comes from create_save_states.py's naming). The smoke test caught this — --save-state silently fell back to playing the intro from boot, which then failed.
  • At --parallel 3 --n-envs 4 the grid uses 12 P-cores (the realistic M3 Max max), completing 9 pilots in ~33 hours wall-clock.

3. pokemon_red_ai/environment/observations.py — obs-validation Box fix

validate_observation() assumed a Dict observation space, crashing with 'Box' object has no attribute 'spaces' on every step for the single-Box treatments (pixel, symbolic, minimal, screen_only). Non-fatal but spammed the log every step, both polluting training output and degrading throughput. Now handles Dict and Box correctly; clear error message for any other type.

4. paper/compute_plan.md — new operational doc

Projects compute needs across the 3-paper cascade (EWRL / NeurIPS workshop / TMLR), maps when cloud becomes uncomfortable vs mandatory, and lists action triggers for the NCSA ACCESS application (Linear AMC-69). Sits alongside compute_ledger.md (actuals) and analysis_plan.md (locked protocol).

Milestone Total env-steps Local M3 Max viable? Cloud needed?
M2 EWRL (now) 90M ✅ ~33-50h No
M3 PokeGym release <10M ✅ trivial No
M4 NeurIPS workshop ~1B 🟡 ~45 days local — uncomfortable Yes (recommended)
M5 TMLR campaign 4.2B ❌ ~190 days — infeasible Yes (mandatory)

Test plan

  • All 833 baseline tests pass
  • 8 new tests cover the --n-envs flag, the env factory (per-rank monitor paths, kwarg passthrough), and the dispatcher's choice between DummyVecEnv and SubprocVecEnv
  • Total: 841 passing
  • scripts/run_pilots.sh --rom PokemonRed.gb --dry-run shows --n-envs 4 and --save-state states/s0_post_intro.state in every emitted command
  • Manual: smoke test with --n-envs 4 to measure real speedup (next step on the user's machine)
  • Manual: launch the full pilot grid

Out of scope

  • The PyBoy 2.x button-press compatibility issue in pokemon_red_ai/game/controls.py (visible during the broken --save-state fallback path) is real but doesn't affect pilot runs that load a save state correctly. File for a separate PR.
  • The game/hp_ratio_mean = 5290 anomaly observed in the smoke-test W&B output (HP ratio should be 0–1). Separate metric-reporting bug; non-blocking for pilots.

🤖 Generated with Claude Code

The smoke test on 2026-04-30 measured ~91 fps with a single PyBoy env
on M3 Max, which would put each 10M-step pilot at ~30 hours and
threaten the EWRL deadline.  PyBoy is single-threaded CPU-bound, so
SubprocVecEnv across multiple cores is the right unlock.

scripts/train.py — new --n-envs N flag (default 1).  When N==1 the
single-env DummyVecEnv path is preserved bit-for-bit.  When N>1, build
N PokemonRedGymEnv factories and pass them to SubprocVecEnv.  Each env
writes its Monitor CSV to a rank-suffixed path so parallel envs don't
clobber each other's logs.  W&B integration, alerts, and callbacks are
unchanged — they consume SB3's ep_info_buffer regardless of the
vectorisation strategy.

scripts/run_pilots.sh — adds --n-envs (default 4) and forwards it to
every train.py invocation.  Also fixes the default --save-state path
from the playbook's incorrect "states/post_intro.state" to the actual
filename "states/s0_post_intro.state".  At --parallel 3 × --n-envs 4
the pilot grid uses 12 P-cores on the M3 Max — the realistic upper
bound that completes 9 pilots in ~33 hours wall-clock.

pokemon_red_ai/environment/observations.py — fix a real bug surfaced
by the smoke test: validate_observation() assumed a Dict observation
space, crashing with "'Box' object has no attribute 'spaces'" on the
pixel / symbolic / minimal / screen_only treatments (all single-Box
spaces).  The error is non-fatal but spammed the log every step,
which both polluted training logs and degraded throughput.  Now
handles Dict and Box correctly; emits a clear error for any other
type.

paper/compute_plan.md — new operational document projecting compute
needs across the 3-paper cascade.  Confirms M3 Max gets us through
EWRL (M2), maps when cloud becomes uncomfortable (M4 NeurIPS) vs
mandatory (M5 TMLR), and lists action triggers for the NCSA ACCESS
application (AMC-69) and other grants.  Sits alongside compute_ledger
(actuals) and analysis_plan (locked protocol).

Tests: 8 new tests covering the --n-envs flag, the env factory, and
the dispatcher's choice between DummyVecEnv and SubprocVecEnv.  All
841 tests pass (was 833).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants