GDPO:英伟达提出多奖励强化学习的“解耦归一化“策略,解决GRPO的优势崩溃问题

GDPO:英伟达提出多奖励强化学习的"解耦归一化"策略,解决GRPO的优势崩溃问题

一句话总结:NVIDIA 提出 GDPO(Group reward-Decoupled Normalization Policy Optimization),通过对每个奖励信号单独进行组内归一化后再聚合,解决了 GRPO 在多奖励场景下的"优势崩溃"问题,在工具调用、数学推理、代码推理三大任务上全面超越 GRPO。


📖 目录

  1. 引言:为什么多奖励强化学习会"翻车"?
  2. [问题剖析:GRPO 的优势崩溃现象](#问题剖析:GRPO 的优势崩溃现象)
  3. [GDPO 方法详解:解耦归一化的三步走策略](#GDPO 方法详解:解耦归一化的三步走策略)
  4. 奖励优先级优化:条件奖励设计
  5. [实验验证:三大任务全面超越 GRPO](#实验验证:三大任务全面超越 GRPO)
  6. [代码实现:从 GRPO 到 GDPO 的简单改造](#代码实现:从 GRPO 到 GDPO 的简单改造)
  7. 深度思考与启示
  8. 总结与展望

1. 引言:为什么多奖励强化学习会"翻车"?

1.1 从单一奖励到多奖励的演进

随着大语言模型(LLM)能力的不断提升,用户对模型的期望也越来越高。我们不仅希望模型能给出正确的答案,还希望它能:

  • 📝 遵守特定格式(如 JSON、Markdown、特定标签)
  • 📏 控制输出长度(不要太长也不要太短)
  • 🐛 避免运行时错误(代码能正常执行)
  • 🎯 满足多种偏好(安全、有帮助、诚实等)

这就引出了**多奖励强化学习(Multi-reward RL)**的需求------用多个奖励信号同时引导模型学习。

图1:(a) GDPO 方法概览------对每个奖励分别进行组内归一化,然后聚合并进行批次级归一化以保持数值稳定;(b) Qwen2.5-Instruct-1.5B 工具调用任务的奖励曲线对比,GDPO 在正确性和格式奖励上均收敛到更高分数。

1.2 当前主流做法的问题

目前最流行的做法是使用 GRPO(Group Relative Policy Optimization) 算法。GRPO 是 DeepSeek 团队在 2024 年提出的高效强化学习算法,核心思想是:

  • 对同一个问题生成多个候选答案(rollout)
  • 通过组内奖励的相对比较来计算优势值
  • 无需训练额外的价值网络(Critic),大幅降低计算成本

但问题来了 :当我们有多个奖励信号时,通常的做法是直接把它们加起来,然后用 GRPO 处理。这看起来很自然,但 NVIDIA 的研究团队发现,这种做法会导致一个严重的问题------优势崩溃(Advantage Collapse)


2. 问题剖析:GRPO 的优势崩溃现象

2.1 什么是优势崩溃?

让我们用一个生活化的比喻来理解这个问题。

想象你是一位老师,需要同时评价学生的数学成绩语文成绩。现在有两个学生:

  • 小明:数学 90 分,语文 60 分,总分 150 分
  • 小红:数学 60 分,语文 90 分,总分 150 分

如果你只看总分,这两个学生是"一样好"的。但实际上,他们的能力结构完全不同!如果你想培养数学人才,应该更看重小明;如果你想培养文科人才,应该更看重小红。

这就是 GRPO 在多奖励场景下的问题:它把不同的奖励组合"压扁"成了相同的优势值,丢失了关键的区分信息。

2.2 数学上的问题分析

让我们看看具体的数学公式。假设我们有两个奖励 r 1 r_1 r1 和 r 2 r_2 r2,GRPO 的做法是:

第一步:求和
r sum ( i , j ) = r 1 ( i , j ) + r 2 ( i , j ) r_{\text{sum}}^{(i,j)} = r_1^{(i,j)} + r_2^{(i,j)} rsum(i,j)=r1(i,j)+r2(i,j)

第二步:组内归一化
A sum ( i , j ) = r sum ( i , j ) − mean { r sum } std { r sum } A_{\text{sum}}^{(i,j)} = \frac{r_{\text{sum}}^{(i,j)} - \text{mean}\{r_{\text{sum}}\}}{\text{std}\{r_{\text{sum}}\}} Asum(i,j)=std{rsum}rsum(i,j)−mean{rsum}

问题在于,当我们先求和再归一化时,不同的奖励组合可能会得到相同的优势值。

图2:二进制奖励场景下 GRPO 和 GDPO 的优势计算对比。GRPO 将不同奖励组合映射到仅两个优势组,而 GDPO 对每个奖励独立归一化后保留了三个不同的优势组。

2.3 一个具体的例子

假设我们有 4 个 rollout,每个都有两个二进制奖励(0 或 1):

Rollout r 1 r_1 r1 r 2 r_2 r2 r sum r_{\text{sum}} rsum
1 0 0 0
2 0 1 1
3 1 0 1
4 1 1 2

用 GRPO 的方法:

  • 均值 = (0+1+1+2)/4 = 1
  • 标准差 = 0.816
  • Rollout 2 和 Rollout 3 的优势值 = (1-1)/0.816 = 0

问题 :Rollout 2(只满足 r 2 r_2 r2)和 Rollout 3(只满足 r 1 r_1 r1)被认为是"一样好"的,但如果 r 1 r_1 r1 是正确性奖励、 r 2 r_2 r2 是格式奖励,这两者的重要性可能完全不同!

2.4 优势组数量的可视化分析

图3:GRPO、GRPO w/o std 和 GDPO 产生的不同优势组数量对比。随着 rollout 数量(左)或奖励数量(右)增加,GDPO 始终保留更多的优势组,提供更具表达力的训练信号。

从图3可以清楚地看到:

  • GRPO(蓝色):产生的不同优势组数量最少,区分度最低
  • GRPO w/o std(橙色):去掉标准差归一化后稍有改善
  • GDPO(绿色):产生的不同优势组数量最多,区分度最高

3. GDPO 方法详解:解耦归一化的三步走策略

3.1 核心思想:先分别归一化,再聚合

GDPO 的核心创新非常简洁:不要先求和再归一化,而是先对每个奖励单独归一化,再求和

这就像评价学生时,先把数学成绩和语文成绩各自转换成班级排名(归一化),再综合考虑,而不是直接看总分。

3.2 三步走策略

步骤1:单奖励组内归一化(解耦)

对每个奖励 r k r_k rk( k = 1 , . . . , n k=1,...,n k=1,...,n)单独进行组内归一化:

A k ( i , j ) = r k ( i , j ) − mean { r k ( i , 1 ) , . . . , r k ( i , G ) } std { r k ( i , 1 ) , . . . , r k ( i , G ) } A_k^{(i,j)} = \frac{r_k^{(i,j)} - \text{mean}\{r_k^{(i,1)}, ..., r_k^{(i,G)}\}}{\text{std}\{r_k^{(i,1)}, ..., r_k^{(i,G)}\}} Ak(i,j)=std{rk(i,1),...,rk(i,G)}rk(i,j)−mean{rk(i,1),...,rk(i,G)}

其中:

  • ( i , j ) (i,j) (i,j) 表示第 i i i 个问题的第 j j j 个 rollout
  • G G G 是每个问题的 rollout 数量

作用

  • 消除不同奖励的量纲差异(比如一个奖励范围是 0-1,另一个是 0-100)
  • 保留每个奖励内部的相对优劣
  • 避免某一个奖励主导整个优化过程

步骤2:多奖励优势求和

将所有归一化后的单奖励优势加权求和:

A sum ( i , j ) = w 1 ⋅ A 1 ( i , j ) + . . . + w n ⋅ A n ( i , j ) A_{\text{sum}}^{(i,j)} = w_1 \cdot A_1^{(i,j)} + ... + w_n \cdot A_n^{(i,j)} Asum(i,j)=w1⋅A1(i,j)+...+wn⋅An(i,j)

其中 w k w_k wk 是每个奖励的权重。

作用:融合多个目标的优化信号,此时每个目标的贡献已经通过步骤1进行了归一化处理。

步骤3:批次级优势归一化(稳定性保障)

对整个批次的优势值进行再次归一化:

A ^ sum ( i , j ) = A sum ( i , j ) − mean { A sum } std { A sum } + ϵ \hat{A}{\text{sum}}^{(i,j)} = \frac{A{\text{sum}}^{(i,j)} - \text{mean}\{A_{\text{sum}}\}}{\text{std}\{A_{\text{sum}}\} + \epsilon} A^sum(i,j)=std{Asum}+ϵAsum(i,j)−mean{Asum}

作用

  • 确保数值范围稳定,防止优势值随奖励数量增加而膨胀
  • 实验表明,去掉这一步会导致偶尔的收敛失败

3.3 直观理解

让我们用一个更生活化的比喻来理解 GDPO:

想象你在招聘员工,需要同时考虑技术能力沟通能力

GRPO 的做法(先求和再归一化):

  1. 给每个候选人的技术和沟通打分
  2. 直接把两个分数加起来
  3. 在所有候选人中比较总分

问题:如果技术分数范围是 0-100,沟通分数范围是 0-10,那技术分数会主导最终结果。

GDPO 的做法(先分别归一化再求和):

  1. 给每个候选人的技术和沟通打分
  2. 分别计算技术排名和沟通排名(归一化)
  3. 综合两个排名来评估

优势:每个维度的贡献是均衡的,不会因为分数范围不同而产生偏差。


4. 奖励优先级优化:条件奖励设计

4.1 问题:不同奖励的优化难度差异

在实际应用中,不同的奖励可能有不同的优化难度:

  • 长度约束:相对容易满足(模型很快就能学会控制输出长度)
  • 正确性:相对困难(需要真正理解问题才能给出正确答案)

如果简单地将两者相加,模型可能会"偷懒"------只优化容易的长度约束,而忽视困难的正确性。

4.2 解决方案:条件奖励

GDPO 提出了一种巧妙的解决方案------条件奖励(Conditioned Reward)

R ~ length = { R length if R correct ≥ t 0 otherwise \tilde{\mathcal{R}}{\text{length}} = \begin{cases} \mathcal{R}{\text{length}} & \text{if } \mathcal{R}_{\text{correct}} \geq t \\ 0 & \text{otherwise} \end{cases} R~length={Rlength0if Rcorrect≥totherwise

含义 :只有当正确性奖励达到阈值 t t t 时,才给予长度奖励。

效果:强制模型优先保证正确性,在正确的基础上再优化长度。

4.3 条件奖励的直观理解

这就像考试时的评分规则:

  • 普通规则:答案正确得 60 分,书写工整得 40 分
  • 条件规则:答案正确得 60 分;只有答案正确时,书写工整才额外得 40 分

第二种规则会促使学生优先保证答案正确,而不是花大量时间在书写上。


5. 实验验证:三大任务全面超越 GRPO

NVIDIA 团队在三个典型任务上验证了 GDPO 的效果:工具调用、数学推理、代码推理。

5.1 工具调用任务

任务描述 :训练模型学习如何调用外部工具,需要满足特定的输出格式(如 <tool_call><response> 标签)。

奖励设置

  • 格式奖励:检查输出结构是否正确
  • 正确性奖励:评估工具调用的名称、参数是否匹配

实验结果

方法 模型 Live Acc Multi-Turn Acc Non-Live Acc Avg Acc Format
GRPO Qwen2.5-1.5B 59.73 56.43 72.04 62.73 98.25
GDPO Qwen2.5-1.5B 62.50 59.01 73.85 65.12 99.38
GRPO Qwen2.5-3B 65.27 59.50 80.14 68.30 99.00
GDPO Qwen2.5-3B 67.12 61.39 80.95 69.82 99.63

表1:工具调用任务上 GDPO vs GRPO 的对比。GDPO 在所有指标上均优于 GRPO。

图4:Qwen2.5-1.5B 在工具调用任务上的训练曲线。GDPO 在正确性和格式奖励上均收敛到更高分数,而 GRPO w/o std 虽然正确性接近 GDPO,但格式奖励几乎没有提升。

关键发现

  • GDPO 在准确率上平均提升 2-3%
  • 格式正确率接近 100%
  • 训练过程更加稳定

5.2 数学推理任务

任务描述:解决高难度数学问题(AIME、AMC、MATH 等),同时遵守长度约束(响应长度 ≤ 4000 tokens)。

奖励设置

  • 长度奖励:检查响应长度是否合规
  • 正确性奖励:检查最终答案是否正确

实验结果

方法 模型 AIME Acc AMC Acc MATH Acc Exceed Rate
GRPO DeepSeek-R1-1.5B 35.0 62.5 85.7 11.3%
GDPO DeepSeek-R1-1.5B 39.2 67.5 87.2 4.8%
GRPO DeepSeek-R1-7B 51.7 75.0 91.2 8.7%
GDPO DeepSeek-R1-7B 55.0 77.5 92.1 3.2%

表2:数学推理任务上 GDPO vs GRPO 的对比。GDPO 准确率更高,长度超出比例显著更低。

图5:DeepSeek-R1-1.5B 在数学推理任务上的训练行为。两者都快速最大化长度奖励,但 GDPO 随后恢复并超越 GRPO 的正确性。约 400 步后,GRPO 正确性下降且长度违规增加,而 GDPO 持续改善。

关键发现

  • GDPO 解决了 GRPO 在训练后期的正确性下降问题
  • 长度超出比例降低了 50% 以上
  • 在高难度问题(AIME)上提升最为明显

5.3 代码推理任务

任务描述:生成代码,需通过测试用例,遵守长度约束,且无运行时错误。

奖励设置

  • 通过率奖励:通过测试用例的比例
  • 条件长度奖励:仅当代码正确且长度合规时给予奖励
  • Bug 奖励:代码是否无编译或运行时错误

实验结果

方法 奖励设置 Apps CodeContests Codeforces Taco Exceed Bug
GRPO 2 rewards 26.8 12.5 8.3 18.7 15.2% 28.3%
GDPO 2 rewards 27.5 13.2 9.1 19.4 8.7% 25.1%
GRPO 3 rewards 25.9 11.8 7.9 17.9 12.8% 22.5%
GDPO 3 rewards 27.1 12.9 8.7 19.1 7.3% 18.7%

表3:代码推理任务上 GDPO vs GRPO 的对比。GDPO 在多目标平衡上表现更好。

关键发现

  • 在三奖励设置下,GDPO 表现出更好的多目标平衡能力
  • Bug 比率降低了 15-20%
  • 长度超出比例降低了 40% 以上

5.4 权重敏感性分析

图6:DeepSeek-R1-7B 在不同长度奖励权重 {1.0, 0.75, 0.5, 0.25} 下的准确率和超长比例,对比了普通长度奖励与条件长度奖励的效果。

从图6可以看到:

  • GRPO 对奖励权重非常敏感,权重选择不当会导致性能大幅下降
  • GDPO 对权重变化更加鲁棒,在不同权重设置下都能保持较好的性能

5.5 条件奖励的效果

图7:DeepSeek-R1-7B 使用条件长度奖励时 GRPO 和 GDPO 的训练曲线。使用条件奖励后,训练初期没有剧烈的正确性下降,GDPO 在正确性恢复和提升上优于 GRPO。

使用条件奖励后:

  • GDPO 能更有效地利用放松的长度约束来提升准确率
  • GRPO 在条件奖励下仍然存在训练不稳定的问题

6. 代码实现:从 GRPO 到 GDPO 的简单改造

GDPO 的一大优势是实现简单,只需要对现有 GRPO 代码做少量修改。

6.1 GRPO 原始实现(TRL 框架)

python 复制代码
# GRPO: 先聚合所有奖励
rewards = (rewards_per_func * self.reward_weights.to(device).unsqueeze(0)).nansum(dim=1)

# 计算组内均值和标准差
mean_grouped_rewards = rewards.view(-1, self.num_generations).mean(dim=1)
std_grouped_rewards = rewards.view(-1, self.num_generations).std(dim=1)

# 扩展到每个 rollout
mean_grouped_rewards = mean_grouped_rewards.repeat_interleave(self.num_generations, dim=0)
std_grouped_rewards = std_grouped_rewards.repeat_interleave(self.num_generations, dim=0)

# 归一化计算优势值
advantages = rewards - mean_grouped_rewards
if self.scale_rewards:
    advantages = advantages / (std_grouped_rewards + 1e-4)

6.2 GDPO 改进实现(TRL 框架)

python 复制代码
# GDPO: 先对每个奖励单独归一化
rewards_per_func_filter = torch.nan_to_num(rewards_per_func)
all_reward_advantage = []

# 循环对每个奖励单独进行组内归一化
for i in range(len(self.reward_weights)):
    reward_i = rewards_per_func_filter[:, i]
    
    # 计算组内均值和标准差
    each_reward_mean_grouped = reward_i.view(-1, self.num_generations).mean(dim=1)
    each_reward_std_grouped = reward_i.view(-1, self.num_generations).std(dim=1)
    
    # 扩展到每个 rollout
    each_reward_mean_grouped = each_reward_mean_grouped.repeat_interleave(self.num_generations, dim=0)
    each_reward_std_grouped = each_reward_std_grouped.repeat_interleave(self.num_generations, dim=0)
    
    # 计算单个奖励的归一化优势
    each_reward_advantage = reward_i - each_reward_mean_grouped
    each_reward_advantage = each_reward_advantage / (each_reward_std_grouped + 1e-4)
    all_reward_advantage.append(each_reward_advantage)

# 聚合所有归一化后的奖励
combined_reward_advantage = torch.stack(all_reward_advantage, dim=1)
pre_bn_advantages = (combined_reward_advantage * self.reward_weights.to(device).unsqueeze(0)).nansum(dim=1)

# 批次级归一化(稳定性保障)
bn_advantages_mean = pre_bn_advantages.mean()
bn_advantages_std = pre_bn_advantages.std()
advantages = (pre_bn_advantages - bn_advantages_mean) / (bn_advantages_std + 1e-4)

6.3 Verl 框架实现

python 复制代码
# GDPO 在 Verl 框架中的实现
# 分别处理正确性和格式奖励
correctness_normalized_score, _ = core_algos.compute_grpo_outcome_advantage(
    token_level_rewards=token_level_scores_correctness,
    ...
)

format_normalized_score, _ = core_algos.compute_grpo_outcome_advantage(
    token_level_rewards=token_level_scores_format,
    ...
)

# 相加后再进行掩码白化处理
new_advantage = correctness_normalized_score + format_normalized_score
advantages = masked_whiten(new_advantage, response_mask) * response_mask

6.4 代码改动量分析

从上面的代码可以看出,GDPO 相对于 GRPO 的改动非常小:

  1. 把单次归一化改为循环对每个奖励归一化
  2. 增加一步批次级归一化
  3. 总代码改动量约 20 行

这使得 GDPO 可以作为 GRPO 的即插即用替代品


7. 深度思考与启示

7.1 为什么归一化顺序如此重要?

这个问题的本质是信息保留

当我们先求和再归一化时,不同奖励组合之间的差异被"压缩"了。这就像把不同颜色的颜料混合后再调色------你已经无法恢复原来的颜色了。

而先分别归一化再求和,相当于先把每种颜色调到相同的亮度,再混合。这样每种颜色的贡献是均衡的,最终的混合色能更好地反映各种颜色的特点。

7.2 批次级归一化的必要性

为什么需要第三步的批次级归一化?

这是因为当奖励数量增加时,求和后的优势值范围也会增加。如果不进行归一化,可能会导致:

  • 梯度过大,训练不稳定
  • 不同批次之间的优势值范围差异过大

批次级归一化确保了优势值始终在一个合理的范围内,保证了训练的稳定性。

7.3 条件奖励的设计哲学

条件奖励的设计体现了一个重要的思想:优先级约束

在多目标优化中,不同目标的重要性可能不同。简单的加权求和无法很好地处理这种情况,因为:

  • 权重需要精心调整
  • 难度差异可能需要极大的权重才能抵消

条件奖励提供了一种更优雅的解决方案:通过依赖关系来强制优先级。这类似于约束优化中的"主约束"和"次约束"的概念。

7.4 对未来研究的启示

  1. 多奖励 RL 的设计原则:在设计多奖励系统时,需要仔细考虑奖励之间的相互作用,避免信息丢失。

  2. 归一化策略的重要性:归一化不仅仅是一个技术细节,它可能对最终性能有重大影响。

  3. 简单方法的力量:GDPO 的改动非常简单,但效果显著。这提醒我们,有时候最有效的改进来自于对问题本质的深入理解。

  4. 条件奖励的潜力:条件奖励为处理多目标优先级提供了一种新思路,值得在更多场景中探索。

7.5 复现建议

如果你想在自己的项目中使用 GDPO,以下是一些建议:

  1. 从 GRPO 基线开始:先确保你的 GRPO 实现是正确的
  2. 逐步添加 GDPO 的改动
    • 首先添加单奖励归一化
    • 然后添加批次级归一化
    • 最后考虑条件奖励
  3. 监控训练指标:特别关注不同奖励的收敛情况,确保没有某个奖励主导优化
  4. 调整超参数:虽然 GDPO 对超参数更鲁棒,但仍需要根据具体任务进行调整

8. 总结与展望

8.1 核心贡献

GDPO 的核心贡献可以总结为:

  1. 发现问题:揭示了 GRPO 在多奖励场景下的"优势崩溃"问题
  2. 提出方案:通过解耦归一化策略解决了这个问题
  3. 验证有效性:在三大任务上全面超越 GRPO
  4. 开源实现:提供了 TRL、Verl、Nemo-RL 三个框架的实现

8.2 主要优势

  • 简单有效:代码改动量小,效果提升显著
  • 通用性强:适用于各种多奖励场景
  • 稳定性好:避免了训练过程中的优势崩溃问题
  • 即插即用:可以直接替换现有的 GRPO 实现

8.3 局限性

  • 当奖励数量非常多时,计算开销会增加
  • 条件奖励的阈值需要根据具体任务调整
  • 对于某些特殊的奖励结构,可能需要进一步优化

8.4 未来方向

  1. 自适应权重:自动学习不同奖励的权重
  2. 层次化奖励:支持更复杂的奖励依赖结构
  3. 理论分析:从理论上分析 GDPO 的收敛性质
  4. 更多应用:在更多任务上验证 GDPO 的效果

📚 参考资料

相关推荐
rgb2gray2 小时前
论文深度解析:基于大语言模型的城市公园多维度感知解码与公平性提升
大数据·人工智能·机器学习·语言模型·自然语言处理·数据分析·可解释
草莓熊Lotso2 小时前
Qt 信号与槽深度解析:从基础用法到高级实战(含 Lambda 表达式)
java·运维·开发语言·c++·人工智能·qt·数据挖掘
东坡肘子2 小时前
AT 的人生未必比 MT 更好 -- 肘子的 Swift 周报 #118
人工智能·swiftui·swift
huazi-J4 小时前
Datawhale 大模型基础与量化微调 task0:Tokenizer
语言模型·大模型·tokenizer·datawhale
雅欣鱼子酱5 小时前
USB Type-C PD取电(诱骗,诱电,SINK),筋膜枪专用取电芯片
网络·人工智能·芯片·电子元器件
kisshuan1239610 小时前
【深度学习】使用RetinaNet+X101-32x4d_FPN_GHM模型实现茶芽检测与识别_1
人工智能·深度学习
Learn Beyond Limits10 小时前
解构语义:从词向量到神经分类|Decoding Semantics: Word Vectors and Neural Classification
人工智能·算法·机器学习·ai·分类·数据挖掘·nlp
崔庆才丨静觅10 小时前
0代码生成4K高清图!ACE Data Platform × SeeDream 专属方案:小白/商家闭眼冲
人工智能·api
qq_3564483711 小时前
机器学习基本概念与梯度下降
人工智能