train_multi_turn function runs episodes against your environment, turns them into training samples, and trains on them.
Requirements
- A cookbook checkout, which provides the environment abstractions in
post_training_cookbook.envs. - A model with generator support. Models marked trainer-only in the catalog can’t run GRPO.
- Your own tasks and environment, unless you train on the cookbook’s bundled tool-use environment.
- Weights & Biases (W&B) logging set up or turned off.
GRPOConfiglogs to W&B by default, and the example on this page setswandb_project, so without a W&B setup, a run fails after it provisions the model resource. ExportWANDB_API_KEY, setWANDB_MODE=offlineto log locally, or passwandb_project=Noneto turn logging off.
Write an environment
SubclassEnv and implement its four members: reset, step, tool_specs, and messages. The environment owns the conversation history, tool dispatch, and the rule for when an episode ends. The training loop owns tokenization and sampling.
The following environment gives the model a calculator tool. It ends the episode when the model replies without a tool call, and scores that reply against the task’s target:
post_training_cookbook.envs:
Task: The spec for one episode, withprompt,target, andmetadatafields.Tool: Any object withname,description,parameters_schema, and anasync execute(arguments) -> ToolResultmethod.tool_to_specconverts a tool into the schema that the model’s chat template renders into the prompt.ToolResult: The return value ofexecute. Setshould_stop=Trueto ask the environment to end the episode. Yourstepdecides how to honor the request, for example by returningterminated=True, as the cookbook’s reference environment does.StepResult: The return value ofstep.terminatedmeans task logic ended the episode, for example on a final answer.truncatedmeans the episode was cut short for a reason other than task logic, such as a turn limit the environment enforces. The loop readsrewardandmetricsonly from the step that ends the episode, so put diagnostics in the final step’smetrics. Intermediate steps usually return arewardof0.0.
close() method when reset starts background work, such as a subprocess or a connection. The loop calls close() whenever an episode ends, including an episode the loop truncates before step returns a terminal result.
To build your own environment, start from a copy of the cookbook’s reference environment, ToolUseGameEnv in post_training_cookbook/envs/tool_use_game/. It provides three tools (list_fact_keys, lookup, and calculator) and a bundled task list. The training example trains on it.
Run multi-turn training
Calltrain_multi_turn with a config that sets max_turns, a list of tasks, and a factory that builds a fresh environment for each episode. The cookbook’s recipes/grpo/tool_use_game.py recipe trains on the reference environment’s bundled tasks:
Task list as tasks and a factory such as lambda task: MathEnv() as env_factory.
The GRPOConfig reference lists the settings specific to multi-turn training. The shared GRPO settings for length budgets, overlong handling, dynamic sampling, and loss variants also apply to multi-turn training.
Handle truncated episodes
An episode is truncated when it ends without the environment returningterminated=True. The cookbook adds the soft overlong penalty to a truncated episode’s reward only when the episode ran out of context or turns:
To leave truncated episodes out of training, set
overlong_masking=True. The cookbook then builds no samples from truncated episodes of any cause, but their rewards still count toward the group baseline.
To track how episodes end, watch the multi-turn metrics in the step log: terminated_ratio, truncated_ratio, context_overflow_ratio, and parse_failure_ratio.
Async training
By default, the cookbook runs in lockstep. Rollouts finish before training starts, so the generators sit idle during training and the trainer sits idle during sampling. Async training overlaps rollout collection with training.
max_steps_off_policy: An integer turns on continuous rollout workers and sets the maximum age of a group, in optimizer steps since its rollout started. Older groups are dropped as stale. The default,None, keeps lockstep.0admits only groups started under the current policy, but groups often arrive one version behind and get dropped, so start with1.groups_in_flight: The number of rollout groups collected concurrently. It defaults tobatch_size.weight_sync_type: How new weights reach the generators after each step.WEIGHT_SYNC_TYPE_SYNCHRONOUS, the default, publishes the weights inline.WEIGHT_SYNC_TYPE_BACKGROUND_PUBLISHdefers publication to a server worker and returns immediately.WEIGHT_SYNC_TYPE_PIPELINEalso defers publication and lets generation already in flight finish under the updated weights.
max_steps_off_policy bounds and measures the drift they allow. WEIGHT_SYNC_TYPE_PIPELINE also requires full-weight training (use_lora=False), because the server rejects it on adapter sessions. The cookbook checks for this before provisioning.
To turn on async training, pass a config like the following to train_multi_turn with your tasks and an environment factory, as in the training example:
recipes/grpo/tool_use_game_async.py recipe.
To track how long each step waits for rollouts and how many groups go stale, watch async/train_wait_s and async/dropped_stale_groups in the async collection metrics. Stale groups are counted separately, so they don’t inflate zero_variance_skip_ratio.
Next steps
Tune a GRPO recipe
Adjust length budgets, overlong handling, dynamic sampling, and loss variants.
Monitor training runs
Read the multi-turn and async metrics a run logs.
Evaluate models
Score a hosted model on your environment before you train.
Cookbook config reference
Look up every multi-turn
GRPOConfig field and its default.