Skip to main content

Overview

GRPO (Group Relative Policy Optimization) is an online RL algorithm introduced in the paper DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models. It is a variant of PPO that reduces memory usage by replacing the value model with a group-relative advantage estimate. At each step, GRPO generates a group of completions per prompt, computes rewards for each completion, normalizes the rewards within the group to obtain advantages, and updates the policy to increase the probability of high-advantage completions. This approach has become the standard method for training reasoning models such as DeepSeek-R1.

Quick start

How GRPO works

1

Generate completions

At each training step, sample a batch of prompts and generate num_generations (G) completions per prompt.
2

Compute advantages

For each completion, compute a scalar reward. Normalize within the group:
  • Group normalization (default): subtract the group mean and divide by the group standard deviation.
  • Batch normalization: compute mean at group level but standard deviation at the batch level (scale_rewards="batch").
  • No scaling: disable normalization entirely (scale_rewards=False).
3

Estimate KL divergence

Use the Schulman approximator to estimate KL divergence between the policy and a fixed reference model. With beta=0.0 (default), no reference model is loaded.
4

Compute loss and update

Maximize advantages while penalizing deviation from the reference policy. The default loss type is "dapo", which normalizes by the number of active tokens in the batch to remove length bias.

Dataset format

The dataset must include a "prompt" column. All other columns are passed to reward functions as keyword arguments.
For VLM training, include an image or images column alongside prompt.

Custom reward functions

A reward function must accept prompts, completions, completion_ids, and any dataset columns as keyword arguments, and return a list of floats (one per completion). Use **kwargs to accept all arguments.
Pass reward functions to the trainer:
Reward functions can be async def coroutines. Multiple async functions are executed concurrently via asyncio.gather, so their latency overlaps.

Multi-task reward functions

Return None for samples that a reward function does not apply to. The trainer ignores None values and sums only valid rewards:

Built-in rewards

TRL provides built-in reward functions in trl.rewards, including accuracy_reward for checking mathematical correctness.

Key configuration parameters

int
default:"8"
Number of completions to generate per prompt (the group size G). The effective batch size must be divisible by this value.
int | None
default:"256"
Maximum number of tokens to generate per completion.
float
default:"1.0"
Sampling temperature. Higher values produce more diverse completions.
float
default:"1.0"
Nucleus sampling cutoff. Set below 1.0 to restrict sampling to a smaller token set.
float
default:"0.0"
KL coefficient controlling deviation from the reference model. When 0.0 (default), the reference model is not loaded. DeepSeek-R1 uses 0.001.
str
default:"dapo"
Loss normalization strategy. Options: "dapo" (normalizes by active tokens in batch, default), "dr_grpo" (normalizes by max_completion_length), "grpo" (normalizes by sequence length, not recommended), "bnpo", "cispo", "sapo", "luspo", "vespo".
str | bool
default:"group"
Reward scaling strategy. "group" (default): normalize within each prompt group. "batch": normalize across the entire batch. False: no scaling.
float
default:"0.2"
Clipping range for the policy ratio in the surrogate objective.
int
default:"1"
Number of gradient update passes per generated batch (μ in the original paper). When greater than 1, uses the clipped surrogate objective.
bool
default:"false"
Exclude truncated completions from the loss. Recommended for training stability, especially with long-chain-of-thought responses.
list[float] | None
Per-function weights when using multiple reward functions. If None, all functions are weighted equally.
bool
default:"false"
Use vLLM for faster generation. Requires pip install trl[vllm].
str
default:"colocate"
How to run vLLM: "colocate" (shares training GPUs) or "server" (separate process on dedicated GPUs).
float
default:"0.3"
Fraction of GPU memory reserved for vLLM when running in colocate mode.

Accelerating generation with vLLM

Generation is typically the bottleneck in online RL training. vLLM can provide a significant speedup.
vLLM runs inside the trainer process and shares GPU memory with the training model:
In server mode, ensure the vLLM server uses different GPUs than the trainer. Use the CUDA_VISIBLE_DEVICES environment variable to separate them, or you may encounter NCCL errors.
By default, Truncated Importance Sampling is applied when using vLLM to correct for the training–inference mismatch between the two engines. Disable it with vllm_importance_sampling_correction=False.

Training with PEFT/LoRA

Agent training

GRPO supports agentic workflows through tool use. Pass a list of Python functions as tools:
Tools must be Python functions with type-hinted arguments, return types, and a Google-style docstring. The model uses these to determine how to call each tool.

Logged metrics