Why turning on Gym capability discovery without token capture crashes the first rollout

NVIDIA-NeMo/RL #4265. RL links pin head ed14402; #4266 links pin 98b3b6c. Traced from source; not run.

Before
Turning on discovery only asked Gym what it supports. Rollouts ran exactly as without it.
This PR
Registers every rollout with the Gym actor whenever discovery succeeded, reading two row keys that exist only with token capture.
Status
Open โ€” not fixed in this PR. Raised in the review comments.

Nine pages on this stack โ€” this one: #4265: a config that crashes on the first batch.

The three switches involved

Dotted words have a short explanation: hover or tap them.

The new bookkeeping in run_rollouts turns on when discovery has found Gym servers, not when participant checkpointing is on. It then reads the two row keys that only token capture adds.

Same setup, token capture on and off

capability_discovery_enabled: true, in both lanes setup runs discovery every Gym server answers actor keeps the list _gym_checkpoint_participants gate: list is non-empty โ†’ register every row โ†’โ†’ token_capture: on row has _ng_rollout_id="p7_g0", _ng_attempt_index=0 registered, runs token_capture: off row has neither key KeyError: '_ng_rollout_id' first batch, first row: the whole rollout step fails works crashes setup discovery :1798 list set :988 gate :1843 row[_ng_rollout_id] :1846 keys only with token capture :1174 config check (shards only) :1280

The config that crashes, and why nothing stops it:

rollout_checkpointing: gym: capability_discovery_enabled: true # "without enabling saves" token_capture: enabled: false # rows carry no _ng_rollout_id

๐Ÿ”ด review comment โ€” nemo_gym.py:1843

The review is still pending, so this link opens for others only after it is published.

What would fix it โ€” proposed, not in the PR

Nothing below is implemented. Turn the bookkeeping on with the switch it serves, participant checkpointing, instead of "discovery found servers". Setup already knows that switch; it only has to pass it to the actor.

# setup (proposed): pass the switch into the Gym actor actor_cfg["participant_checkpointing"] = cfg.gym.participant_checkpointing_enabled # False # nemo_gym.py run_rollouts, at the gate (proposed) if self._participant_checkpointing: # False โ†’ skip registration register(row["_ng_rollout_id"], row["_ng_attempt_index"]) # same check before the receipt fetch at :1904 # result: discovery-only + token capture off runs the rollout normally

Real code this changes: the gate at nemo_gym.py:1843, the receipt fetch at nemo_gym.py:1904, and the actor config built in setup (the switch itself is added by #4266).

So what. Anyone who turns on discovery by itself, which its own docs describe as safe, and does not use token capture, gets a KeyError on the first rollout batch. Gating on participant checkpointing makes discovery do only what it says: look, not change how rollouts run.