Explainer for NVIDIA-NeMo/RL #4266
(stack part 3 of 3, on top of #4264 and
#4265). All permalinks pin the PR head 98b3b6c;
"before" links pin the base ed14402.
rollout_checkpointing.gym.participant_checkpointing_enabled) that pauses Gym at turn boundaries and saves its agents, model and resources into the same snapshot, so a restart continues from the last finished turn.Nine pages on this stack โ this one: #4266: what a crash costs, before and after.
Single Controller already takes a rollout snapshot every snapshot_attempt_interval_s: it takes the data-plane barrier, saves the data plane plus the replay and recovery files, and publishes the directory with one rename
(before: _save_rollout_checkpoint).
This PR keeps that same path and adds Gym steps on both sides of it
(_save_rollout_checkpoint_locked).
Before the barrier, it closes rollout admission, asks Gym to park every agent at a turn boundary, and has Gym write its state into the unpublished snapshot directory.
After the rename, it tells Gym to resume. If anything fails before the rename, Gym is aborted with the same checkpoint ID and the previous snapshot stays in use.
One prompt group with 3 siblings. The agent needs 5 turns per sibling. The process dies right after a snapshot, at this point:
How the restart gets there with this PR:
Trainer checkpoints get a second, safer layer. Each one first writes a gym_restart_fallback.json marker
(:5313)
and then tries the snapshot above. If that snapshot never lands, restore uses the marker and falls back to the "before" column for unfinished work
(setup.py:1439).
Why keep both paths: the old one needs nothing from Gym and never pauses rollouts. The new one needs a Gym build that supports the checkpoint protocol, token_capture.enabled: true, max_row_attempts: 1, and exactly one Gym actor. Every snapshot also closes rollout admission until Gym has parked.
The PR has no timing numbers yet for that pause.
RuntimeError. The loop only retries OSError and TimeoutError, so one HTTP 500 on commit ends the run instead of being retried
(:4870).
(2) With prompt_group recovery, a finished sibling is acknowledged only after its whole group finishes. Gym prepare waits for that acknowledgement, while its parked siblings can't finish. Every snapshot then times out after prepare_timeout_s, and three failures in a row end the run. Both have a one-place fix in the review.
๐ด review comment (1) โ single_controller.py:1968 review comment (2) โ config.py:1407