ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

verl 中 GRPO(Group Relative Policy Optimization)算法详解:配置、损失实现与 DrGRPO 扩展

verl 中 GRPO(Group Relative Policy Optimization)算法详解:配置、损失实现与 DrGRPO 扩展 verl 中 GRPOGroup Relative Policy Optimization算法详解配置、损失实现与 DrGRPO 扩展【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verl导读本文以 verl 仓库的官方算法文档 docs/algo/grpo.md 为骨架结合源码verl/trainer/ppo/core_algos.py、verl/trainer/config/algorithm.py、verl/trainer/config/actor/actor.yaml与示例脚本examples/grpo_trainer/run_qwen3_8b_fsdp.sh系统讲解 GRPO 在 verl 中的工作原理、完整配置项、KL 正则化机制以及面向长 CoT 稳定性优化的 DrGRPO 扩展。读完本文你将掌握在 verl 中从零配置并启动一次 GRPO 训练含分组采样、组内相对奖励、KL 损失、损失聚合模式等关键参数并能理解每个参数在源码中的实际作用。GRPO 核心思想无 Critic 的组相对策略优化在经典强化学习算法如 PPO中训练过程依赖一个独立的critic价值模型来估计动作价值从而指导策略更新。但训练 critic 模型本身会引入大量额外计算与内存开销。GRPOGroup Relative Policy Optimization源自 DeepSeekMath 论文的核心创新在于彻底去掉 critic 模型改用组内相对比较来构造学习信号。其训练循环围绕一个 prompt 展开Group Sampling分组采样对同一个问题prompt当前策略模型采样生成多条候选答案构成一个组group。Reward Assignment奖励分配根据答案的正确性或质量为组内每条答案计算奖励。Baseline Calculation基线计算以该组奖励的平均值作为基线。Policy Update策略更新将组内每条答案的奖励与该组基线做差高于平均水平的答案得到正向强化低于平均水平的答案被抑制进而更新策略参数。由于不再训练独立的价值估计模型GRPO 显著降低了计算开销使学习过程更加高效。这也是 verl 中所有 GRPO 示例脚本如examples/grpo_trainer/目录下的各类脚本所遵循的基本范式。三个关键组成要素No Value Function无价值函数与 PPO 不同GRPO 不训练独立的 value 网络critic因此无需 critic 前向与价值损失计算。Group Sampling分组 Rollout与每个输入只采样一次 rollout 不同GRPO 对每个 prompt 从当前策略生成多条补全response这一组补全称为 group。分组信息通过index数组在批次中标识。Relative Rewards相对奖励在组内各补全按正确性等指标打分并相对该组做归一化减去组均值、按组标准差缩放。源码中的 GRPO advantage 实现从源码结构看GRPO 的 advantage 计算位于 verl/trainer/ppo/core_algos.py 的compute_grpo_outcome_advantage通过register_adv_est(grpo)注册为 advantage 估计器。其核心逻辑是将 token 级奖励沿序列维度求和得到每条 response 的标量分数scores token_level_rewards.sum(dim-1)按index即 group 标识对分数分组计算每组的均值id2mean与标准差id2std当norm_adv_by_std_in_grpoTrue时advantage 为(score - mean) / (std epsilon)当为False时仅做score - mean去均值最后将组内标量 advantage 广播到 token 维度并与response_mask相乘得到与 loss 对齐的 token 级优势。该函数注释明确指出norm_adv_by_std_in_grpoTrue对应原始 GRPO 论文做法False对应 DrGRPO见下文扩展章节。此外源码还提供向量化实现compute_grpo_vectorized_outcome_advantagecore_algos.py注册为grpo_vectorized逻辑等价但通过group_mean_std批量计算组均值/标准差性能更好。verl 中 GRPO 的配置详解在 verl 中尽管许多配置以ppo_前缀开头但由于 GRPO 的训练循环与 PPO 相似仅去掉 critic这些配置对 GRPO 等不同 RL 算法同样适用。所有包含micro_batch_size的配置仅用于控制每次前向/反向传播的最大样本数或 token 数以避免 GPU OOM不会改变算法的收敛行为。分组采样相关配置项作用默认值/GRPO 建议actor_rollout.ref.rollout.n每个 prompt 采样 n 次默认 1GRPO 必须设为大于 1 以启用分组采样data.train_batch_size用于生成一组采样轨迹rollout的全局 prompt 批次大小按显存设置actor_rollout_ref.actor.ppo_mini_batch_size采样轨迹集被切分为多个 mini-batch全局大小跨所有 worker用于 PPO/GRPO actor 更新默认 256actor_rollout_ref.actor.ppo_epochs对同一组采样轨迹执行 GRPO 更新的 epoch 数默认 1actor_rollout_ref.actor.clip_ratioGRPO 的 clip 范围默认 0.2其中response/轨迹总数等于data.train_batch_size * actor_rollout_ref.rollout.n即每条 prompt 采样 n 条补全共同构成一个组。在 examples/grpo_trainer/run_qwen3_8b_fsdp.sh 中默认ROLLOUT_N5、train_batch_size1024、ppo_mini_batch_size256即每步 1024 个 prompt × 5 条补全再切成 256 的 mini-batch 进行更新。Advantage 估计与损失聚合配置项作用默认值/GRPO 建议algorithm.adv_estimatorAdvantage 估计器类型默认gaeGRPO 必须设为grpoactor_rollout_ref.actor.loss_agg_mode损失聚合方式默认token-mean可选token-mean、seq-mean-token-sum、seq-mean-token-mean等loss_agg_mode的底层实现在 verl/trainer/ppo/core_algos.py 的agg_loss中支持的聚合模式包括token-mean、token-sum、seq-mean-token-sum、seq-mean-token-sum-norm、seq-mean-token-mean等。原始 GRPO 论文采用样本级损失seq-mean-token-mean但在长 CoTChain-of-Thought场景下可能不稳定因此verl 提供的所有 GRPO 示例脚本均使用默认配置token-mean进行损失聚合。相关字段在 verl/trainer/config/actor/actor.yaml 中有完整注释说明。KL 正则化在损失中加入 KL 而非奖励惩罚GRPO 与传统 PPO 的另一个重要区别是不在奖励函数中加 KL 惩罚而是直接将训练策略与参考策略之间的 KL 散度加入 actor 损失。相关配置配置项作用默认值/GRPO 建议actor_rollout_ref.actor.use_kl_loss在 actor 中使用 KL 损失此时不在奖励函数中加 KL默认FalseGRPO 需设为Trueactor_rollout_ref.actor.kl_loss_coefKL 损失系数默认 0.001actor_rollout_ref.actor.kl_loss_typeKL 散度估计方式支持kl(k1)、abs、mse(k2)、low_var_kl(k3)、fullkl_loss_type各选项的语义可参考 John Schulman 的 KL 近似分析klk1logprob - ref_logprob即反向 KL 的无偏估计abs|logprob - ref_logprob|msek20.5 * (logprob - ref_logprob)^2其梯度是 KL 的无偏估计low_var_klk3exp(kl) - kl - 1其中kl ref_logprob - logprob并做数值截断为低方差估计器full需要完整词表 logits当前在 core_algos.py 中标记为NotImplementedError不要使用。关于后缀straight-through 技巧kl_loss_type支持在末尾追加如k1、k3其原理是k1 与 k3 估计器的期望值等于真实 KL但其期望梯度并不等于 KL 的期望梯度而 k2mse给出了正确的梯度估计。因此 verl 通过 straight-through 技巧core_algos.py 的kl_penalty函数在前向使用 k1/k3 估计 KL 值在反向使用 k2 的梯度backward_score - backward_score.detach() forward_score.detach()从而获得无偏的梯度估计。该实现细节在 core_algos.py 注释中有明确说明。DrGRPO消除 GRPO 的长度偏差论文 Understanding R1-Zero-Like Training: A Critical Perspective 指出GRPO 基于组内奖励归一化计算 advantage 的方式存在优化偏差会导致模型人为地生成更长的 response尤其对错误答案更明显。DrGRPO 通过引入全局常量归一化 token 级损失来消除这种长度偏差。在 verl 中启用 DrGRPO 只需调整以下几项其余参数与 GRPO 完全一致配置项值说明actor_rollout_ref.actor.loss_agg_modeseq-mean-token-sum-norm关闭序列维度平均actor_rollout_ref.actor.loss_scale_factor可选固定常数如最大 response 长度确保训练全程归一化一致不设置则使用当前批次的 response 长度actor_rollout_ref.actor.use_kl_lossFalseDrGRPO 不使用 KL 损失algorithm.norm_adv_by_std_in_grpoFalse关闭标准差归一化从源码看seq-mean-token-sum-norm在agg_losscore_algos.py中实现先按序列求和后除以loss_scale_factor未设置时取loss_mask.shape[-1]即当前批次 response 长度从而将损失归一化到与序列长度无关的量纲。而norm_adv_by_std_in_grpoFalse时advantage 仅做组内去均值score - mean不再除以组标准差core_algos.py这正是 DrGRPO 消除长度偏差的关键。此外algorithm.norm_adv_by_std_in_grpo的默认值为True见 verl/trainer/config/algorithm.pyDrGRPO 需要显式关闭。参考示例Qwen3-8B GRPO 训练verl 提供了开箱即用的 GRPO 训练脚本 examples/grpo_trainer/run_qwen3_8b_fsdp.sh支持 NVIDIA GPU 与 Ascend NPU运行方式bash examples/grpo_trainer/run_qwen3_8b_fsdp.sh该脚本完整展示了上文所有关键参数的落地用法节选核心部分# 数据与算法 DATA( algorithm.adv_estimatorgrpo algorithm.use_kl_in_rewardFalse data.train_batch_size${train_batch_size} # 默认 1024 data.max_prompt_length${max_prompt_length} # 默认 1024 data.max_response_length${max_response_length} # 默认 2048 data.filter_overlong_promptsTrue data.truncationerror ) # ActorKL 损失与损失聚合 ACTOR( actor_rollout_ref.actor.ppo_mini_batch_size${ppo_mini_batch_size} # 默认 256 actor_rollout_ref.actor.use_dynamic_bszTrue actor_rollout_ref.actor.ppo_max_token_len_per_gpu${ppo_max_token_len_per_gpu} actor_rollout_ref.actor.use_kl_lossTrue # GRPO 必需 actor_rollout_ref.actor.kl_loss_coef${kl_loss_coef} # 默认 0.001 actor_rollout_ref.actor.kl_loss_typelow_var_kl # k3 低方差估计 ) # Rollout分组采样 ROLLOUT( actor_rollout_ref.rollout.name${INFER_BACKEND} # vllm | sglang | trtllm actor_rollout_ref.rollout.tensor_model_parallel_size${rollout_tp} actor_rollout_ref.rollout.n${rollout_n} # 默认 5分组采样 actor_rollout_ref.rollout.log_prob_use_dynamic_bszTrue )脚本中的可调旋钮Knobs通过环境变量暴露ROLLOUT_N每组采样数默认 5、TRAIN_BATCH_SIZE默认 1024、PPO_MINI_BATCH_SIZE默认 256、KL_LOSS_COEF默认 0.001、ACTOR_LR默认 1e-6、TOTAL_EPOCHS默认 15、INFER_BACKEND默认 vllm可选 sglang / trtllm等。NPU 场景会自动切换到use_kl_lossTruelow_var_kl的组合并设置更大的序列并行度sp_size4与 32K 的max_response_length适配长 CoT 训练。注意训练前需要准备 GSM8K 与 MATH 数据集脚本默认从$HOME/data/gsm8k与$HOME/data/math读取 parquet 文件数据集预处理脚本可参考 examples/data_preprocess/gsm8k.py 与 examples/data_preprocess/math_dataset.py。更多基线性能对比可参阅 docs/algo/baseline.md。总结GRPO 通过组内相对奖励替代 critic 价值函数在保持策略优化能力的同时大幅降低训练开销是 verl 中数学推理、长 CoT 等场景 RL 后训练的主力算法。在 verl 中启用 GRPO 只需四步设adv_estimatorgrpo、rollout.n 1启用分组采样、use_kl_lossTrue将 KL 正则化并入损失、按需选择loss_agg_mode聚合方式。若遇到长 response 膨胀问题可切换 DrGRPO 配置seq-mean-token-sum-normnorm_adv_by_std_in_grpoFalse加以缓解。结合 examples/grpo_trainer/ 下的示例脚本即可快速复现端到端 GRPO 训练。【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进