Skip to content

fix(grpo): per-env starvation guard in the difficulty-filter buffer - #73

Open
flaviusburca wants to merge 1 commit into
mainfrom
fix/buffer-per-env-starvation
Open

fix(grpo): per-env starvation guard in the difficulty-filter buffer#73
flaviusburca wants to merge 1 commit into
mainfrom
fix/buffer-per-env-starvation

Conversation

@flaviusburca

Copy link
Copy Markdown
Contributor

Problem

With online_difficulty_filtering, an env whose every example gets classified easy/hard becomes silently unschedulable:

  • sample_examples() deals only envs with a non-empty normal pool
  • the recycle safety-valve (normal_pool_min_examples) is global — it cannot trip while other envs stay populated

So an outage that scores one env's whole registry under hard_threshold removes that env from training with no log line and no error. Observed on a live campaign: a 45-step harness outage zeroed one lane's rewards; after resume, the lane's registry sat in the hard pool and every other lane kept the global floor satisfied — the lane was never dealt again.

Fix

_recycle_examples_if_needed now returns all of a weighted env's easy/hard examples to the normal pool whenever that env's normal pool is empty (logged). Difficulty re-classifies as fresh results arrive. The global-floor path is unchanged.

Contract change: sampling no longer raises when a weighted env still holds easy/hard examples — it recycles them instead. The ValueError remains for the truly-empty case. One existing test encoded the old behavior and was updated; a new test constructs the starvation state directly (full env keeps the global floor satisfied, starved env must recycle).

Tests

tests/grpo/test_buffer.py: 6 passed (1 new, 1 rewritten to the new contract).

🤖 Generated with Claude Code

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

flaviusburca pushed a commit that referenced this pull request Aug 4, 2026
…gating

- harbor.py: per-step compose teardown (_teardown_harbor_projects) after every
  Harbor job incl. timeout path — a 64-rollout repo group otherwise exhausts
  the docker network pool mid-group; close() handles harbor>=0.20 '<trial>__env'
  project naming (was silently never matching)
- scripts/harbor_sweeper.sh: standing GC for leaked compose containers/networks,
  per-trial build images, and LRU eviction of unused base images below 80GB free
- heldout_probe.py: --lanes subset runs; _wait_repo_quiet() gates the repo lane
  on a quiet Harbor window (concurrent campaign repo groups starve probe agent
  loops -> harbor phase timeouts -> every episode quarantines to 0.0)
- trainer.py: reorder_micros_for_vtc_guard (upstreamed as PR #75, issue #74)
- buffer.py: per-env starvation guard (upstreamed as PR #73)
- MISSION.md: launch steps 4/6/7 (harbor env, lane-liveness gate, GC), corrected
  probe baselines, vtc root-cause facts
An env whose every example gets classified easy/hard becomes silently
unschedulable: sample_examples() only deals envs with a non-empty NORMAL
pool, and the global normal_pool_min_examples floor cannot trip while
other envs stay populated. An outage that scores one env's whole registry
under hard_threshold therefore removes that env from training with no log
line and no error (observed on a live campaign: a 45-step harness outage
zeroed one lane's rewards and the lane stopped being dealt).

_recycle_examples_if_needed now returns ALL of a weighted env's easy/hard
examples to the normal pool whenever that env's normal pool is empty;
difficulty re-classifies as fresh results arrive. The global floor path is
unchanged.

Contract change: sampling no longer raises when a weighted env still has
easy/hard examples — it recycles them instead (test updated); the
ValueError remains for the truly-empty case.
@flaviusburca
flaviusburca force-pushed the fix/buffer-per-env-starvation branch from 42420a9 to 894288c Compare August 4, 2026 18:10
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.

1 participant