十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AReaL 中 PPO/GRPO 系列 RL 算法实战指南:从 Vanilla PPO 到 IcePop/KPop 的配置切换与源码原理

AReaL 中 PPO/GRPO 系列 RL 算法实战指南:从 Vanilla PPO 到 IcePop/KPop 的配置切换与源码原理 AReaL 中 PPO/GRPO 系列 RL 算法实战指南从 Vanilla PPO 到 IcePop/KPop 的配置切换与源码原理【免费下载链接】AReaLThe RL Bridge for LLM-based Agent Applications. Made Simple Flexible.项目地址: https://gitcode.com/GitHub_Trending/are/AReaL本指南系统讲解 AReaLThe RL Bridge for LLM-based Agent Applications对类 PPO 强化学习算法族的统一实现涵盖 Vanilla PPO、GRPO、Dr.GRPO、LitePPO、RLOO、DAPO、SAPO、GSPO以及 IcePop/KPop 两种 token 掩码策略。这些算法共享同一套基础目标仅在归一化策略、裁剪机制、重要性采样级别上存在差异通过修改少量配置即可在它们之间自由切换。读完本文你将掌握 AReaL 中这些算法的配置矩阵、CLI 运行方式、GAE 优势估计细节以及每个算法在源码中的实现位置与验证路径。算法总览一个配置框架十种算法策略AReaL 将一系列 PPO 变体整合进统一的训练框架中全部配置定义于areal/api/cli_args.py的PPOActorConfig与NormConfig数据类。当前支持的算法包括Vanilla PPO使用学习到的 critic 价值函数通过 GAE 估计优势GRPODeepSeekMath去掉 critic使用组内奖励归一化论文 arXiv:2402.03300Dr.GRPOGRPO 的改进版移除长度归一化与标准差归一化论文 arXiv:2503.20783LitePPO轻量级 PPO论文 arXiv:2508.08221RLOOREINFORCE Leave-One-Out用留一均值做基线论文 arXiv:2402.14740DAPO非对称裁剪 动态采样论文 arXiv:2503.14476SAPO软自适应策略优化用 sigmoid 软门替换硬裁剪论文 arXiv:2511.20347GSPOQwen3序列级重要性采样论文 arXiv:2507.18071IcePop基于重要性比率的 token 掩码可与其它 RL 算法组合KPop双向二元 KL 散度 token 掩码可与其它 RL 算法组合IcePop 和 KPop 是 token 掩码策略可以叠加在上面任意 RL 算法之上。这些算法共享相同的基础目标但在归一化策略、裁剪机制、重要性采样级别等方面有所不同——这正是 AReaL 将它们统一到一套配置框架的原因通过调整少量配置参数即可在不同算法之间切换。运行方式统一的执行入口所有算法使用相同的执行模式AReaL 官方建议直接修改配置 YAML 文件中的参数。训练入口脚本是examples/math/gsm8k_rl.py它通过PPOTrainer驱动完整 RL 循环加载 config、tokenizer、数据集后以字符串路径areal.workflow.openai.math_agent.MathAgent指定 rollout workflow详见 examples/math/gsm8k_rl.py。后端命令localpython3 examples/math/gsm8k_rl.py --config examples/math/gsm8k_algo.yaml scheduler.typelocalraypython3 examples/math/gsm8k_rl.py --config examples/math/gsm8k_algo.yaml scheduler.typerayslurmpython3 examples/math/gsm8k_rl.py --config examples/math/gsm8k_algo.yaml scheduler.typeslurm将algo替换为ppo、grpo、drgrpo、liteppo、rloo、gspo、dapo_dynamic_bs、sapo、icepop或kpop。这些配置文件都真实存在于仓库中例如 examples/math/gsm8k_grpo.yaml、examples/math/gsm8k_ppo.yaml、examples/math/gsm8k_icepop.yaml、examples/math/gsm8k_kpop.yaml 等。通过 CLI 覆盖切换算法除了直接编辑 YAML你还可以通过覆盖配置参数来切换算法不必为每个算法单独准备一份配置# Dr.GRPO (从GRPO配置) python3 examples/math/gsm8k_rl.py \ --config examples/math/gsm8k_grpo.yaml \ scheduler.typelocal \ actor.adv_norm.mean_levelgroup \ actor.adv_norm.std_levelnull # GSPO (从GRPO配置) python3 examples/math/gsm8k_rl.py \ --config examples/math/gsm8k_grpo.yaml \ scheduler.typelocal \ actor.importance_sampling_levelsequence # SAPO (从GRPO配置) python3 examples/math/gsm8k_rl.py \ --config examples/math/gsm8k_grpo.yaml \ scheduler.typelocal \ actor.use_sapo_losstrue \ actor.sapo_tau_pos1.0 \ actor.sapo_tau_neg1.05 \ actor.use_decoupled_lossfalse注意添加原始 YAML 中不存在的键时必须使用前缀如actor.importance_sampling_levelsequence否则会因键不存在而报错。核心配置参数所有配置都定义在areal/api/cli_args.py中的PPOActorConfig和NormConfig下完整字段清单可参考 CLI 配置参考。奖励和优势归一化actor.reward_norm和actor.adv_normNormConfig数据类源码位置控制奖励和优势的归一化方式参数类型选项描述mean_levelstr | Nonebatch、group、None计算均值的级别std_levelstr | Nonebatch、group、None计算标准差的级别mean_leave1outbooltrue、false使用留一法平均值排除当前样本std_unbiasedbooltrue、false使用无偏标准差计算默认true该默认值自 v0.3.4 起由false变更而来epsfloat-避免除零的小常数默认1e-5group_sizeint-分组级归一化的组大小Batch 级在整个全局批次上计算均值/标准差而 group 级在组内计算例如共享相同提示的轨迹。分组边界来自 rollout 批次元数据TrajBatchMeta.traj_group_sizes而非group_size因此即使各组大小不一例如部分样本被过滤仍会按提示逐组归一化仅当该元数据不可用时group_size才作为固定步长的回退方案生效。将mean_level或std_level设为None分别跳过均值减法或标准差缩放。如果整个字段被省略例如 YAML 中的adv_norm: null则不执行归一化。示例actor: adv_norm: null reward_norm: mean_level: group std_level: group group_size: ${gconfig.n_samples}从源码看NormConfig的__post_init__会校验mean_level/std_level必须是batch、group或None且使用分组统计时group_size必须为正整数源码位置。PPOActorConfig还提供了uses_group_statistics属性与resolve_min_usable_group_size()方法用于在部分 rollout 样本失败或过滤时推导最少可用组大小使用分组统计时至少需要 2 个组内成员否则归一化无从谈起源码位置。AReaL 默认实践默认配置使用std_level: batch进行优势归一化。这已成为 AReaL 团队在各种 RL 应用中的标准实践从游戏 AIStarCraft到 LLM 训练RLHF、推理、agent 设置。虽然 Dr.GRPO 建议使用std_level: null以获得潜在更好的性能但 AReaL 保留std_level: batch以保持向后兼容性。寻求 Dr.GRPO 风格行为的用户应设置actor.adv_norm.std_levelnull。作为参考examples/math/gsm8k_grpo.yaml 中实际的默认 GRPO 配置为reward_norm: mean_level: group std_level: group group_size: ${gconfig.n_samples} adv_norm: mean_level: batch std_level: batch裁剪策略actor.eps_clip*参数类型默认值描述eps_clipfloat0.2下裁剪边界比率裁剪到[1-eps_clip, ...]eps_clip_higherfloat | NoneNone上裁剪边界设置时比率裁剪到[1-eps_clip, 1eps_clip_higher]当eps_clip_higher为None时使用对称裁剪$\text{clip}(r, 1-\epsilon, 1\epsilon)$。当设置eps_clip_higher时DAPO 风格使用非对称裁剪$\text{clip}(r, 1-\epsilon_{\text{low}}, 1\epsilon_{\text{high}})$。注意实际配置文件中eps_clip的取值随数据集与场景变化例如 GRPO 示例中使用了eps_clip: 0.4examples/math/gsm8k_grpo.yaml。重要性采样级别actor.importance_sampling_level参数类型选项描述importance_sampling_levelstrtoken、sequence计算重要性比率的级别token默认标准逐 token 重要性比率GRPO、PPO 等sequenceGSPO逐 token 比率的序列级几何平均值在实现层面重要性权重统一通过_compute_importance_weight()计算为exp(logp_num - logp_denom)源码位置sequence 级别则在此基础上对逐 token 对数概率取序列级几何平均。PPOActorConfig.__post_init__还会校验importance_sampling_level只能是token或sequence源码位置。算法配置矩阵下表展示了如何通过设置适当的参数来配置每个算法算法adv_norm.mean_leveladv_norm.std_leveladv_norm.mean_leave1outimportance_sampling_level特殊配置PPObatchbatchfalsetoken需要 critic 模型GRPObatchbatchfalsetoken-Dr.GRPOgroupnullfalsetoken-LitePPOgroupbatchfalsetoken-RLOOgroupnulltruetoken-GSPObatchbatchfalsesequence-DAPObatchbatchfalsetoken非对称裁剪动态采样SAPObatchbatchfalsetokenuse_sapo_losstrueIcePopbatchbatchfalsetokenrejection_sampling.metricratioKPopbatchbatchfalsetokenrejection_sampling.metricbinary_kl注意GRPO 行反映原始 DeepSeekMath 公式。AReaL 的默认 GRPO 配置使用这些设置但已移除长度归一化见下文AReaL 实现说明。此外源码中的PPOActorConfig还提供了算法矩阵之外的更多开关例如use_cispo_lossCISPO来自 MiniMax-M1arXiv:2506.13585它要求eps_clip_higher 0、importance_sampling_leveltoken且与 SAPO 互斥源码位置进一步扩展了这套配置即算法框架的表达能力。算法特定选项Vanilla PPOVanilla PPO 使用学习到的价值函数critic通过 GAE 估计优势。关键配置差异是它需要一个critic:配置部分包含自己的模型和优化器——这在源码中对应PPOCriticConfig数据类源码位置其中eps_clip默认值为0.5用于价值损失裁剪。完整的配置示例见examples/math/gsm8k_ppo.yaml。GRPO$$ J_{\text{GRPO}}(\theta) \mathbb{E}{\substack{q \sim P(Q), \ {o_i}{i1}^G \sim \pi_{\theta_{\text{old}}}(O \mid q)}} \left[ \frac{1}{G} \sum_{i1}^G \sum_{t1}^{|o_i|} \min\left( r_{i,t}(\theta) \hat{A}{i,t}, \text{clip}\left( r{i,t}(\theta), 1-\epsilon, 1\epsilon \right) \hat{A}{i,t} \right) - \beta D{\mathrm{KL}}\left[ \pi_\theta \middle| \pi_{\text{ref}} \right] \right] $$其中$$ r_{i,t}(\theta) \frac{\pi_\theta(o_{i,t} \mid q, o_{i,t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,t})}, \quad \hat{A}{i,t} \frac{r_i - \text{mean}({r_i}{i1}^G)}{\text{std}({r_i}_{i1}^G)}. $$RLOO (REINFORCE Leave-One-Out)RLOO 通过平均其他采样响应的奖励排除当前响应来估计基线。这通过设置actor.adv_norm.mean_leave1outtrue实现。$$ J_{\text{RLOO}}(\theta) \mathbb{E}{\substack{q \sim P(Q), \ {o_i}{i1}^G \sim \pi_{\theta_{\text{old}}}(O \mid q)}} \left[ \frac{1}{G} \sum_{i1}^G \frac{1}{|o_i|} \sum_{t1}^{|o_i|} \min\left( r_{i,t}(\theta) \hat{A}{i,t}, \text{clip}\left( r{i,t}(\theta), 1-\epsilon, 1\epsilon \right) \hat{A}_{i,t} \right) \right] $$其中$$ \hat{A}{i,t} r_i - \frac{1}{G-1} \sum{j \neq i} r_j. $$GSPO (Group Sequence Policy Optimization)GSPO 在序列级别而非 token 级别计算重要性采样比率。标准 PPOtoken 级$$ r_{i,t}(\theta) \frac{\pi_\theta(o_{i,t} \mid q, o_{i,t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,t})} $$GSPO序列级$$ r_i(\theta) \exp\left(\frac{1}{|o_i|}\sum_{t1}^{|o_i|} \log\frac{\pi_\theta(o_{i,t} \mid q, o_{i,t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,t})}\right) $$这一序列级几何平均语义不仅用于 GSPO 的目标函数也复用在RejectionSamplingConfig的 sequence 级过滤中aggmean时比率在 log 空间聚合为几何平均长度不变式length-invariant与 GSPO 语义保持一致源码位置。SAPO (Soft Adaptive Policy Optimization)SAPO 用软 sigmoid 门替换 PPO 的硬裁剪提供平滑梯度和非对称控制。标准 PPO$$ L^{\text{PPO}} -\mathbb{E}_t[\min(r_t A_t, r_t^{\text{clip}} A_t)] $$SAPO带软门对于正向优势$g_t^ \frac{4}{\tau_{\text{pos}}} \sigma(\tau_{\text{pos}} (r_t - 1))$对于负向优势$g_t^- \frac{4}{\tau_{\text{neg}}} \sigma(\tau_{\text{neg}} (r_t - 1))$损失$L^{\text{SAPO}} -\mathbb{E}_t[g_t A_t]$其中如果 $A_t 0$ 则 $g_t g_t^$否则 $g_t g_t^-$参数类型默认值描述actor.use_sapo_lossboolfalse启用 SAPO 损失代替 PPO 裁剪actor.sapo_tau_posfloat1.0正向优势的温度参数actor.sapo_tau_negfloat1.05负向优势的温度参数注意SAPO 需要actor.use_decoupled_lossfalse。这一约束在源码中有强制校验PPOActorConfig.__post_init__会在use_sapo_losstrue且use_decoupled_losstrue时直接抛出ValueError同时校验两个温度参数必须为正数源码位置。actor: use_sapo_loss: true sapo_tau_pos: 1.0 sapo_tau_neg: 1.05 use_decoupled_loss: falseDAPODAPO 引入非对称裁剪和动态采样后者排除所有响应都完全正确或完全错误的样本。$$ J_{\text{DAPO}}(\theta) \mathbb{E}{\substack{(q,a) \sim \mathcal{D}, \ {o_i}{i1}^G \sim \pi_{\theta_{\text{old}}}(o \mid q)}} \left[ \frac{1}{\sum_{i1}^G |o_i|} \sum_{i1}^G \sum_{t1}^{|o_i|} \min\left( r_{i,t}(\theta) \hat{A}{i,t}, \text{clip}\left( r{i,t}(\theta), 1-\epsilon_{\text{low}}, 1\epsilon_{\text{high}} \right) \hat{A}_{i,t} \right) \right] $$其中 $\hat{A}{i,t}$ 是分组归一化优势$r{i,t}(\theta)$ 是 token 级策略比率。非对称裁剪参数参数类型默认值描述actor.eps_clipfloat0.2下裁剪边界actor.eps_clip_higherfloat-上裁剪边界设置以启用非对称过长惩罚参数参数类型默认值描述actor.overlong_reward_penaltyboolfalse启用过长响应惩罚actor.overlong_tokensint-被视为过长的尾部 token 数量actor.overlong_penalty_factorfloat-应用于过长响应的惩罚因子在实现层面过长惩罚在PPOActor._compute_advantages()的最前端通过reward_overlong_penalty()施加然后再进入 reward scaling、clip 与归一化流程源码位置。动态采样AReaL 通过传递给PPOTrainer.train()的dynamic_filter_fn支持动态采样。该函数接收从相同提示采样的分组轨迹并返回布尔值指示是否接受它们进行训练trainer.train( workflow..., dynamic_filter_fnlambda x: 0 x[rewards].mean() 1 )在RLTrainer的训练循环中dynamic_filter_fn作为should_accept_fn传入prepare_batch由_collect_trainable_rollout_batch()依据dynamic_bs决定收集行为源码位置。默认情况下AReaL 使用固定批量大小的动态过滤——它等待收集到batch_size个接受样本后再进行训练。这与某些使用动态批量大小的 DAPO 实现不同后者收集整个批次的样本然后过滤它们。以下选项控制批量大小行为参数类型默认值描述dynamic_bsboolfalse启用动态批量大小IcePopIcePop 对重要性比率 $r_{i,t} \frac{\pi_\theta(o_{i,t} \mid q, o_{i,t})}{\pi_{\theta_\text{old}}(o_{i,t} \mid q, o_{i,t})}$ 超出可配置范围 $[\alpha, \beta]$ 的 token 进行掩码其中 $\pi_\theta$ 为当前训练策略$\pi_{\theta_\text{old}}$ 为采样时的行为策略。重要性比率过低或过高的 token 不参与损失计算。通过rejection_sampling配置的metricratio实现actor: use_decoupled_loss: true rejection_sampling: level: token action: mask metric: ratio lower: 0.5 upper: 5.0参数类型默认值描述actor.rejection_sampling.metricstr-设置为ratio以启用 IcePopactor.rejection_sampling.lowerfloat0.5重要性比率下界actor.rejection_sampling.upperfloat5.0重要性比率上界注意IcePop 需要actor.use_decoupled_losstrue否则rejection_sampling不生效。源码中PPOActorConfig.__post_init__会对该组合发出明确警告rejection_sampling is configured but use_decoupled_lossFalse. Filtering will be ignored.源码位置。完整的配置示例见examples/math/gsm8k_icepop.yaml。RejectionSamplingConfig源码位置是 IcePop/KPop 及更一般过滤策略的统一实现它取代了旧版的behave_imp_weight_cap/behave_imp_weight_mode两个参数。除ratio外还支持kl_k1、kl_k2、kl_k3三种 KL 估计量action可选mask将 loss_mask 置零、完全排除梯度或clamp将重要性权重截断到边界、保留有界梯度。校验规则包括ratio度量下upper必须大于 1.0、lower必须为正clamp动作只支持ratio度量。KPopKPop 对双向二元 KL 散度超过阈值的 token 进行掩码。对于每个 token计算$$ \text{KL}{\text{fwd}} \text{KL}(P\theta | P_{\theta_\text{old}}), \quad \text{KL}{\text{rev}} \text{KL}(P{\theta_\text{old}} | P_\theta) $$其中每个 token 概率被视为伯努利参数$\text{KL}(P | Q) p \log \frac{p}{q} (1-p) \log \frac{1-p}{1-q}$。$\max(\text{KL}{\text{fwd}}, \text{KL}{\text{rev}}) \phi$ 的 token 被掩码此处 $\phi$ 对应actor.rejection_sampling.upper。通过rejection_sampling配置的metricbinary_kl实现actor: use_decoupled_loss: true rejection_sampling: level: token action: mask metric: binary_kl upper: 2.0参数类型默认值描述actor.rejection_sampling.metricstr-设置为binary_kl以启用 KPopactor.rejection_sampling.upperfloat2.0KL 散度阈值$\phi$注意KPop 仅支持actionmask不支持clamp且lower在binary_kl中不使用。KPop 需要actor.use_decoupled_losstrue否则rejection_sampling不生效。完整的配置示例见examples/math/gsm8k_kpop.yaml。核心概念奖励AReaL 假设基于结果的奖励。每个可能由连接的 LLM 输入-输出对组成的轨迹在序列级而非 token 级被分配一个标量奖励。优势AReaL 为轨迹中的每个输出 token 计算逐 token 优势。PPO 算法将结果奖励视为最后一个 token 的奖励所有前面的 token 奖励为 0。然后 AReaL 通过广义优势估计GAE应用标准折扣和 TD 误差反向传播来计算每个 token 的优势。使用默认的 token 级递推时如果discount1、gae_lambda1、critic value 为 0 且禁用 KL 正则化终止结果奖励会等效广播到每个生成 token。GAE 时间步单位actor.gae_timestep_unit用于选择 GAE 按生成 token 还是生成 turn 推进。Prompt、tool、padding 及其他被 mask 的位置都不会消耗 GAE 时间步。该参数在源码中被限制为token或turn两个取值源码位置。Token 级 GAEtoken是默认值并保留 AReaL 原有行为。对于相邻的有效生成 tokenAReaL 计算$$ \delta_t r_t \gamma V_{t1} - V_t, \qquad A_t \delta_t \gamma \lambda A_{t1}, \qquad G_t A_t V_t, $$其中 $\gamma$ 为actor.discount$\lambda$ 为actor.gae_lambda配置解析出的逐轨迹取值。奖励 $r_t$ 包含结果奖励增量和 token 级 KL 惩罚。以 EOS 结束的轨迹使用 0 作为终止 bootstrap没有 EOS 的截断轨迹则使用最后一个 value 估计进行 bootstrap。这一递推逻辑对应_compute_token_level_gae()的实现源码位置它从序列末尾向前迭代并用loss_mask跳过不贡献损失的 token。Turn 级 GAEturn将每个非空生成 turn 视为一个宏观时间步。对于 turn $u$AReaL 将其中的 task reward 增量求和为 $r_u^{\mathrm{task}}$并使用该 turn 第一个有效 action token 位置的 value 作为 $V_u$然后计算$$ \delta_u^{\mathrm{task}} r_u^{\mathrm{task}} \gamma V_{u1} - V_u, \qquad A_u^{\mathrm{task}} \delta_u^{\mathrm{task}} \gamma \lambda A_{u1}^{\mathrm{task}}. $$Task advantage $A_u^{\mathrm{task}}$ 和 critic target $G_uA_u^{\mathrm{task}}V_u$ 会广播到该 turn 中的每个有效 token。Token 级 KL 不会进入 turn 递推和 critic target在可选的actor.adv_norm之前turn $u$ 中 token $j$ 的 actor advantage 为 $A_{u,j}A_u^{\mathrm{task}}r_{u,j}^{\mathrm{KL}}$。这样可以避免先对一个 turn 的 KL 惩罚求和再将总和广播回每个 token。Turn 级 GAE 依赖turn_ids元数据的校验_validate_turn_ids()要求turn_ids与loss_mask形状相同、位于同一 device、使用整数 dtype且所有有效 loss token 的 ID 非负并小于序列长度源码位置。动态 GAE lambdaactor.gae_lambda既可以是静态 float也可以是 callable 的点分路径。actor.gae_lambda_kwargs用于向 callable 传递关键字参数配置静态 float 时会被忽略。该函数接收包含三个[B]形状 tensor 的 contextGAELambdaContext源码位置effective_token_lengths有效生成 token 数量包括有效的 EOS tokenturn_counts非空生成 turn 数量token 模式缺少turn_ids时为 0timestep_lengths由gae_timestep_unit选择的长度 $L$。Callable 必须在相同 device 上返回[B]形状的有限浮点 tensor即每条本地轨迹一个 lambda。返回的 lambda 会用于该轨迹的所有选定时间步。静态 float 在运行时被resolve_gae_lambda_fn()包装为constant_gae_lambda()逐轨迹返回同一个常量而字符串路径则通过import_from_string()动态导入源码位置。内置了两个长度自适应函数函数路径参数定义areal.trainer.ppo.lambda_fn.vapo_length_adaptive_gaealpha 0$L0$ 时 $\lambda\max(0, 1 - 1/(\alpha L))$$L0$ 时取 0areal.trainer.ppo.lambda_fn.relative_position_gae_lambda0 q 1$L\ge2$ 时 $\lambdaq^{1/(L-1)}$$L1$ 时取 1$L0$ 时取 0。相对保留率解释假设 $\gamma1$其中vapo_length_adaptive_gae实现了 VAPO 论文的长度自适应 lambda其timestep_lengths由gae_timestep_unit决定token 模式下为有效生成 token 数turn 模式下为有效 turn 数空轨迹与过短轨迹取 lambda 0源码位置。relative_position_gae_lambda则保证在 $\gamma1$ 时终端结果奖励在等相对位置上保留相同的比例——第 1 个时间步恰好保留 $q$最后一个时间步保留 1源码位置。配置示例actor: gae_timestep_unit: turn gae_lambda: areal.trainer.ppo.lambda_fn.relative_position_gae_lambda gae_lambda_kwargs: q: 0.5自定义 workflow 的turn_ids约定Turn 级 GAE 要求 workflow 返回原始、与 token 对齐的turn_idsactor 会在内部将其与 next-token prediction mask 对齐。该 tensor 必须满足与input_ids和loss_mask形状相同batch 后为[B, S]使用整数 dtype建议使用有符号整数来表示-1哨兵值为每个有效生成 token 分配[0, S)范围内的 ID有效 ID 随时间单调不减同一个 assistant turn 中的所有 token 使用相同 IDprompt、user、tool、padding 及其他非 loss 位置使用-1。编号允许跳跃且不会额外消耗 GAE 时间步但建议从 0 开始连续编号。自定义 workflow 可以按如下方式构造该字段不要在 workflow 中进行 rollturn_ids [-1] * input_len [turn_idx] * resp.output_len result[turn_ids] torch.tensor(turn_ids, dtypetorch.int32).unsqueeze(0)AReaL 实现说明AReaL 的 GRPO 实现在两个关键方面与原始 DeepSeekMath 论文不同长度归一化AReaL 从原始 GRPO 目标中移除了逐 token 长度归一化项。这与 Dr.GRPO 的建议一致并消除了优势估计中的偏差。KL 正则化AReaL 不是将 KL 散度项直接添加到目标函数中而是通过actor.kl_ctl将 KL 正则化纳入 actor advantagePPO 风格。在 token 模式下KLEstimator计算的惩罚会在 GAE 之前加入逐 token 奖励在 turn 模式下它仅作为 token 局部的 actor 惩罚不进入 turn 递推和 critic target。源码中kl_ctl默认值为0.1kl_estimator可选k1/k2/k3源码位置而 examples/math/gsm8k_grpo.yaml 中的默认 GRPO 配置将kl_ctl设为0.0。总结与延伸阅读本文完整覆盖了 AReaL 中 PPO/GRPO 算法族的配置与原理统一的gsm8k_rl.py执行入口、PPOActorConfig/NormConfig核心参数、算法配置矩阵、各算法的公式与 YAML 配置以及 GAE 时间步单位、动态 GAE lambda 和turn_ids约定等进阶话题。相关测试用例如tests/test_ppo_gae.py、tests/test_cispo_loss.py、tests/test_ppo_actor_truncation.py可以作为验证这些行为的参考更多 CLI 参数细节可查阅 CLI 配置参考。若想了解 RL 训练流程的整体架构可继续阅读 RL 训练器文档 下的相关章节。【免费下载链接】AReaLThe RL Bridge for LLM-based Agent Applications. Made Simple Flexible.项目地址: https://gitcode.com/GitHub_Trending/are/AReaL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表