原文译自:https://medium.com/@sahin.samia/the-math-behind-deepseek-a-deep-dive-into-group-relative-policy-optimization-grpo-8a75007491ba
群体相对策略优化 (GRPO,Group Relative Policy Optimization) 是一种强化学习 (RL) 算法,专门用于增强大型语言模型 (LLM) 中的推理能力。与严重依赖外部评估模型(价值函数)指导学习的传统 RL 方法不同,GRPO 通过评估彼此相关的响应组来优化模型。这种方法可以提高训练效率,使 GRPO 成为需要复杂问题解决和长链思维的推理任务的理想选择。
GRPO 的本质思路:通过在同一个问题上生成多条回答,把它们彼此之间做“相对比较”,来代替传统 PPO 中的“价值模型”
近端策略优化 (PPO) 等传统 RL 方法在应用于 LLM 中的推理任务时面临着重大挑战:
对价值模型(Critic Model)的依赖:
计算成本高:
可扩展性问题:
图片来自:DeepSeekMath,https://arxiv.org/pdf/2402.03300
群体相对策略优化 (GRPO) 中的目标函数定义了模型如何学习改进其策略,从而提高其生成高质量响应的能力。让我们一步一步地分解它。
我们可以一步步解析 GRPO (Group Relative Policy Optimization) 目标函数,以理解它如何指导模型学习改进策略,从而提高生成高质量响应的能力。
GRPO 目标函数如下:
这个函数主要由三部分组成:
GRPO 目标函数如下:
该目标函数主要由三部分组成:
:对所有输入查询
进行期望计算,查询来自训练数据分布
。
:对于每个查询
,从旧策略
采样
个候选响应。
GRPO 目标函数对多个候选响应进行优化,使训练过程更加稳定。
生成
的概率相较于旧策略
的变化。
,说明策略更新过大,可能导致不稳定。
限制策略变动范围
,防止剧烈变化导致模型崩溃。
衡量
在同一组候选响应中的相对质量。
:对响应
计算的奖励。
:该组响应的平均奖励。
:该组奖励的标准差。
这种 归一化优势估计 可以减少奖励尺度的影响,提高训练稳定性。
计算新策略
与参考策略
之间的距离。
控制 KL 正则项的影响力度。
GRPO(群体相对策略优化)目标函数就像一个配方,通过比较模型自身的响应并逐步改进,让模型能够更好地生成答案。让我们将其分解成一个易于理解的解释:
想象一下,你正在教一群学生解决一道数学题。你不会直接告诉他们谁答对了谁答错了,而是比较所有学生的答案,找出谁答得最好(以及原因)。然后,你通过奖励更好的方法和改进较弱的方法来帮助学生学习。这正是 GRPO 所做的——只不过它教的是 AI 模型,而不是学生。
从训练数据集 P(Q) 中选择一个查询 (q)
示例:假设查询是“8 + 5 的总和是多少?”
该模型针对该查询生成一组 GGG 响应。
示例:该模型生成以下响应: o1:“答案是13。” o2:“十三。” o3:“是12。” o4:“总数是 13。”
什么是奖励?:
奖励通过量化模型的响应质量来指导模型的学习。
GRPO 中的奖励类型:
根据每个回复的优劣程度为其分配奖励 (ri) 。例如,奖励可能取决于:
例如: r1=1.0(正确且格式良好)。 r2=0.9(正确但不太正式)。 r3=0.0(错误答案)。 r4=1.0(正确且格式良好)。
计算每个响应相对于该组的优势 (Ai) :
简单来说你可以这样理解
)以偏好具有较高优势值(
)的响应,同时避免大幅度的不稳定更新:
,则会被裁剪以防止过度修正。
以确保更新后的策略
不会偏离参考策略
太远。 示例:如果模型开始生成格式差异极大的输出,KL 散度项会对其进行抑制。
来源:GRPO Trainer,https://huggingface.co/docs/trl/main/en/grpo_trainer
为了方便后人使用GRPO进行开发,DeepSeek团队开源了GRPO方法,并为此开发了名为GRPOTrainer的方法(囊括于trl包中),目前GRPO Trainer仍在积极开发当中。其导入方法如下:
from trl import GRPOTrainer
GRPO Trainer会记录以下指标:
GRPOTrainer支持使用自定义奖励函数,而不是密集的奖励模型。为确保兼容性,奖励函数必须满足以下要求:
1. 输入参数
标准格式
,prompts 和 completions 将是字符串列表。对话格式
,prompts 和 completions 将是消息词典的列表。2. 返回值:该函数必须返回浮点数列表。每个浮点数代表与单个完成对应的奖励。
官方给出了一下几个使用示例:
示例 1:奖励较长的completions
以下是奖励较长完成度的标准格式的奖励函数示例:
def reward_func(completions, **kwargs):
"""奖励功能:输出的completions越长,得分越高。"""
return [float(len(completion)) for completion in completions]
可以按如下方式对其进行测试:
prompts = ["The sky is", "The sun is"]
completions = [" blue.", " in the sky."]
print(reward_func(prompts=prompts, completions=completions))
[6.0, 12.0]
示例 2:具有特定格式的奖励完成
下面是一个奖励函数示例,该函数检查完成是否具有特定格式。此示例的灵感来自论文 DeepSeek-R1 中使用的格式奖励函数。它专为对话格式而设计,其中提示和完成由结构化消息组成。
import re
def format_reward_func(completions, **kwargs):
"""奖励函数:检查完成是否具有特定格式"""
pattern = r"^<think>.*?</think><answer>.*?</answer>$"
completion_contents = [completion[0]["content"] for completion in completions]
matches = [re.match(pattern, content) for content in completion_contents]
return [1.0 if match else 0.0 for match in matches]
可以按如下方式测试此函数:
prompts = [
[{"role": "assistant", "content": "What is the result of (1 + 2) * 4?"}],
[{"role": "assistant", "content": "What is the result of (3 + 1) * 2?"}],
]
completions = [
[{"role": "assistant", "content": "<think>The sum of 1 and 2 is 3, which we multiply by 4 to get 12.</think><answer>(1 + 2) * 4 = 12</answer>"}],
[{"role": "assistant", "content": "The sum of 3 and 1 is 4, which we multiply by 2 to get 8. So (3 + 1) * 2 = 8."}],
]
format_reward_func(prompts=prompts, completions=completions)
[1.0, 0.0]
示例 3:基于引用的奖励完成
下面是一个 reward 函数的示例,用于检查 the 是否正确。这个例子的灵感来自论文 DeepSeek-R1 中使用的准确率奖励函数。此示例专为标准格式设计,其中数据集包含名为 ground_truth 的列。
import re
def reward_func(completions, ground_truth, **kwargs):
# Regular expression to capture content inside \boxed{}
matches = [re.search(r"\\boxed\{(.*?)\}", completion) for completion in completions]
contents = [match.group(1) if match else "" for match in matches]
# Reward 1 if the content is the same as the ground truth, 0 otherwise
return [1.0 if c == gt else 0.0 for c, gt in zip(contents, ground_truth)]
可以按如下方式测试此函数:
prompts = ["Problem: Solve the equation $2x + 3 = 7$. Solution:", "Problem: Solve the equation $3x - 5 = 10$."]
completions = [r" The solution is \boxed{2}.", r" The solution is \boxed{6}."]
ground_truth = ["2", "5"]
reward_func(prompts=prompts, completions=completions, ground_truth=ground_truth)
[1.0, 0.0]
将 reward 函数传递给 trainer
要使用自定义奖励函数,请将其传递给 GRPOTrainer,如下所示:
from trl import GRPOTrainer
trainer = GRPOTrainer(
reward_funcs=reward_func, # 自定义奖励函数reward_func
...,
)
如果有多个奖励函数,则可以将它们作为列表传递:
from trl import GRPOTrainer
trainer = GRPOTrainer(
reward_funcs=[reward_func1, reward_func2], # 将奖励函数写为列表形式
...,
)
GRPO 目标的工作原理如下:
图片来源:https://huggingface.co/docs/trl/main/en/grpo_trainer
想象一下一群学生在解决一个问题。老师不再单独给每个学生打分,而是让学生自己比较答案。答案更好的学生会受到鼓励,而其他人则会从错误中吸取教训。随着时间的推移,整个团队会共同进步,变得更加准确和一致。GRPO 应用这一原则来训练 AI 模型,使它们能够有效、高效地学习。
GRPO 通过实现高效且可扩展的推理任务训练,推动了 DeepSeek 的卓越性能。以下是它如何转化为成功:
通过关注群体内的相对表现,GRPO 使 DeepSeek 能够在推理、长上下文理解和一般 AI 任务中设定新的基准,同时保持效率和可扩展性
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有