How turn-level recovery differs from the existing sibling recovery
NVIDIA-NeMo/RL #4500
(Gym turn-level rollout recovery). RL permalinks pin head 341b9ad; Gym permalinks pin
the submodule at 120d516.
Before
After a crash, an unfinished rollout always starts over from its prompt. sibling keeps the finished rollouts of a group; prompt_group redoes the whole group.
This PR
Adds rollout_recovery.target_level: turn: an unfinished rollout continues from its last finished turn, on the same Gym server copy.
Status
Proposed in this PR, with open review findings. The biggest one is on page 2: turn stalls with most Gym agents. the review
Four pages on this PR. This one: what turn adds next to the recovery that already exists.
Background. In RL training with NeMo Gym, Gym runs each rollout: an agent talks to the
policy model and to a tool server (a resources server) over several turns.
RL keeps a recovery ledger that says, for every rollout in flight, whether it is finished,
running in Gym, or not sent yet. A rollout snapshot saves that ledger plus the token data in TransferQueue (TQ).
Dotted words have a short explanation: hover or tap them.
Both levels save the same things through the same exclusive TQ barrier
(single_controller.py:4902),
and both restore through one function,
prepare_for_restart.
turn adds one thing before the barrier: it makes Gym stop every rollout at a turn boundary and write
its state to disk
(_prepared_gym_checkpoint).
On restart, a rollout Gym saved is restored on the same Gym copy and continues as Gym attempt + 1
(rollout_recovery.py:527-540).
Under sibling the same rollout is thrown away and started over
(:548).
One prompt group, three rollouts, through save and restart
What turn costs
Generation pauses at every turn snapshot. From step 1 until Gym resumes, RL sends no new
/run and Gym holds every rollout at its turn boundary. Training keeps going on data already
buffered. Gym gets up to gym_prepare_timeout_s (300 s by default) to park
(config.py:719).
A rollout in the middle of a tool call is waited for, since a sandbox cannot be saved mid-call, so one long tool call can use up those 300 s.
Nothing measures how long the pause lasts yet, and the PR has no number for it. review comment โ single_controller.py:4727
The same Gym layout on restart. A restored rollout must go back to the Gym copy that saved it, so
the restart needs the same Gym servers and replica counts.
So what.turn is not a second recovery system. It is one extra Gym step
in front of the save, and one extra branch in the restart, on top of the sibling path that already
exists. What it buys is keeping finished turns of a long, multi-turn rollout instead of generating them again.
What it costs is a pause in generation at every snapshot, and today it works only with the Gym agent and tool
servers that can save a rollout mid-way.