GRPO强化学习训练Agent智能体:组内相对策略优化2026完整教程
GRPO(Group Relative Policy Optimization,组内相对策略优化)是DeepSeek团队在训练DeepSeek-R1时提出的强化学习算法。与传统的PPO不同,GRPO无需训练独立的critic(价值)网络,而是通过对同一prompt生成一组completion,利用组内相对排名来估计优势函数。这一创新大幅简化了RL训练流程,降低了计算成本,同时保持了出色的训练效果。2026年,GRPO已成为Agent智能体强化学习训练的主流方法之一。
一、GRPO原理:用组内比较替代价值网络
传统PPO算法需要两个网络:一个策略网络(actor)负责生成动作,一个价值网络(critic)负责估计状态价值函数V(s),两者通过优势函数A(s,a) = R(s,a) - V(s)进行协作。critic网络的训练本身就是一个难题——它需要大量样本来准确估计value,且容易不稳定。对于语言模型来说,critic网络通常与策略网络同等规模,这意味着训练成本直接翻倍。
GRPO的核心创新在于:对于同一个prompt q,让当前策略模型生成一组(group)G个不同的completion {o_1, o_2, ..., o_G},然后用奖励函数对每个completion打分得到{r_1, r_2, ..., r_G}。接着计算组内平均分作为baseline,每个completion的优势为其奖励减去组内平均分:

# GRPO优势函数计算 # 对同一prompt的G个completion计算相对优势 advantages = [] group_mean = sum(rewards) / len(rewards) # 组内平均作为baseline group_std = std(rewards) + 1e-8 # 标准化 for r in rewards: # 相对优势 = (奖励 - 组均值) / 组标准差 adv = (r - group_mean) / group_std advantages.append(adv) # 高于平均的completion获得正优势(被强化) # 低于平均的completion获得负优势(被削弱)这种设计的精妙之处在于:它完全不需要critic网络。组内平均分天然就是一个无偏的baseline估计——高于平均的completion大概率是好的,应该被强化;低于平均的大概率是差的,应该被削弱。这比训练一个可能不准的critic要稳定得多。
GRPO的完整损失函数包含策略损失和KL散度惩罚两部分。策略损失采用clipped surrogate形式(与PPO类似),KL散度惩罚防止策略偏离参考模型太远:
# GRPO Loss (伪代码) ratio = exp(log_pi_theta(o|q) - log_pi_old(o|q)) # 重要性采样比 clipped_ratio = clip(ratio, 1-epsilon, 1+epsilon) # clip限制 policy_loss = -min(ratio * advantage, clipped_ratio * advantage) # KL散度惩罚 (防止偏离参考模型) kl = KL_divergence(pi_theta, pi_ref) total_loss = policy_loss + beta * kl # 其中epsilon=0.2 (clip_ratio), beta=0.04 (KL系数)二、与PPO对比:GRPO的优势在哪里
GRPO与PPO在策略更新部分非常相似(都使用clipped surrogate loss),关键区别在于优势函数的估计方式。以下表格详细对比了两种算法的异同:
从计算成本角度看,虽然GRPO每个prompt需要采样G次(增加推理开销),但它省去了critic网络的训练和推理开销。总体而言,GRPO在大多数Agent训练场景下比PPO更高效。特别是当奖励函数是确定性可验证的(如代码执行结果对错、数学答案正误),GRPO的优势最为明显。
三、RLVR方法:可验证奖励驱动的强化学习
RLVR(Reinforcement Learning with Verifiable Rewards)是GRPO的最佳搭档。RLVR的核心思想是:对于某些任务,奖励是可以通过确定性函数验证的,无需训练奖励模型。例如:数学题的答案可以直接验证对错,代码生成可以通过执行测试用例验证,工具调用的参数格式可以通过解析验证。
DeepSeek-R1的训练流程完美展示了RLVR+GRPO的威力:先用少量SFT数据建立格式遵循,然后直接用RLVR+GRPO从基座模型训练出前沿的推理能力,无需大量人工标注的推理数据。模型通过试错和组内比较,自发学会了链式推理、自我验证等高级推理策略。
RLVR的奖励函数设计遵循以下原则:从简单的确定性函数开始,reward = verify(output, expected)。以下是几种常见的可验证奖励函数实现:
# 1. 数学推理奖励: 验证最终答案是否正确 def math_reward(completion, expected_answer): # 提取 \boxed{} 中的答案 extracted = extract_boxed_answer(completion) if extracted is None: return -1.0 # 未找到答案,惩罚 return 1.0 if extracted == expected_answer else 0.0 # 2. 代码生成奖励: 执行测试用例 def code_reward(completion, test_cases): try: code = extract_code_block(completion) passed = run_tests(code, test_cases) return passed / len(test_cases) # 通过率作为奖励 except Exception: return -0.5 # 代码执行错误,部分惩罚 # 3. 工具调用奖励: 验证调用格式和参数正确性 def tool_call_reward(completion, expected_tool, expected_args): parsed = parse_tool_calls(completion) if not parsed: return -1.0 # 未生成工具调用 score = 0.0 for call in parsed: if call["name"] == expected_tool: score += 0.5 if call["arguments"] == expected_args: score += 0.5 return score # 4. 格式奖励: 验证输出格式是否合规 def format_reward(completion): if has_react_format(completion): # Thought/Action/Observation return 0.3 if has_valid_json(completion): return 0.3 return -0.2奖励函数的设计是RLVR成功的关键。建议从单一、简单的奖励函数开始,确认训练稳定后再逐步增加奖励维度。常见的做法是将多种奖励组合:total_reward = w1 * correctness + w2 * format + w3 * efficiency,其中权重需要根据任务调整。
四、训练流程:从SFT到GRPO的完整pipeline
GRPO训练的标准流程分为三个阶段。首先需要SFT模型作为起点(确保格式遵循),然后进入GRPO强化学习阶段,最后进行held-out评估。以下是完整的训练pipeline:
from trl import GRPOConfig, GRPOTrainer from datasets import Dataset # 阶段1: 加载SFT模型作为初始策略 model_path = "./sft_model" # SFT训练后的模型 # 阶段2: 配置GRPO训练参数 grpo_config = GRPOConfig( output_dir="./grpo_output", learning_rate=1e-6, num_generations=8, # G=8, 每个prompt生成8个completion max_completion_length=1024, max_prompt_length=512, per_device_train_batch_size=4, gradient_accumulation_steps=4, num_train_epochs=1, bf16=True, beta=0.04, # KL散度系数 epsilon=0.2, # clip ratio temperature=1.0, # 采样温度 log_completions=True, # 记录生成的completion用于分析 ) # 阶段3: 定义奖励函数并启动训练 def reward_func(completions, **kwargs): rewards = [] for comp in completions: r = math_reward(comp, kwargs["expected_answer"]) r += 0.1 * format_reward(comp) # 组合奖励 rewards.append(r) return rewards trainer = GRPOTrainer( model=model_path, args=grpo_config, train_dataset=rlvr_dataset, reward_funcs=reward_func, ) trainer.train()训练数据的准备也很关键。RLVR训练数据通常只包含prompt和期望答案(expected answer),不需要完整的gold-response。这意味着数据收集成本远低于SFT。数据格式如下:
{ "prompt": "计算 (3+5) * 2 的值,请逐步推理。", "expected_answer": "16", "reward_type": "math" }五、奖励函数设计:从简单到复杂的演进
奖励函数是GRPO训练中最需要工程经验的环节。一个设计良好的奖励函数应该具备以下特性:可验证性(结果确定,无歧义)、稀疏适当(不能太稀疏导致学习困难,也不能太密集导致奖励投机)、抗作弊(模型不能通过取巧获得高奖励)。
奖励函数的设计通常经历以下演进阶段:
一个常见的陷阱是"奖励投机"(reward hacking)。例如,如果格式奖励权重过高,模型可能只输出正确格式但内容错误,因为格式奖励已经足够高。解决方案是确保正确性奖励的权重远大于格式奖励,且格式奖励为辅助性质(如correctness * 1.0 + format * 0.1)。
六、Rollout实现:让模型跑起来生成轨迹
Rollout( rollout/采样)阶段是GRPO训练的核心环节。在每次参数更新前,需要让当前策略模型对一批prompt进行推理,生成完整的completion轨迹,然后用奖励函数对每条轨迹打分。这个过程本质上是让模型"跑一遍",收集训练数据用于后续的策略更新。
以下是Rollout阶段的核心实现逻辑:
import torch def rollout(model, prompts, num_generations=8, temperature=1.0, max_new_tokens=1024): """对每个prompt生成G个不同的completion""" all_completions = [] all_log_probs = [] model.eval() with torch.no_grad(): for prompt in prompts: # 重复prompt G次 batch = [prompt] * num_generations inputs = tokenizer(batch, return_tensors="pt", padding=True).to(model.device) # 使用高温采样生成多样化输出 outputs = model.generate( **inputs, max_new_tokens=max_new_tokens, temperature=temperature, top_p=0.95, do_sample=True, # 必须采样而非贪婪 return_dict_in_generate=True, output_scores=True ) # 提取completion和对应的log_probs for i in range(num_generations): completion = tokenizer.decode( outputs.sequences[i][inputs.input_ids.shape[1]:], skip_special_tokens=True ) all_completions.append(completion) # 计算奖励 rewards = [reward_func(c, expected) for c in all_completions] # 计算组内相对优势 for g_start in range(0, len(rewards), num_generations): group_rewards = rewards[g_start:g_start+num_generations] group_mean = sum(group_rewards) / len(group_rewards) group_std = (sum((r-group_mean)**2 for r in group_rewards) / len(group_rewards)) ** 0.5 + 1e-8 for i in range(num_generations): advantages[g_start+i] = ( (group_rewards[i] - group_mean) / group_std ) return all_completions, advantages, rewardsRollout阶段的性能优化至关重要,因为它通常是整个训练流程的瓶颈。推荐使用vLLM进行批量推理加速,可以将Rollout速度提升3-5倍。另外,num_generations(G值)的选择需要平衡效果和效率——G=8是常见默认值,G=16效果更好但推理成本翻倍。
七、评估方法:监控GRPO训练健康度
GRPO训练的评估比SFT更复杂,需要监控多个维度的指标。核心评估指标包括:奖励均值(应持续上升)、奖励标准差(应逐渐缩小)、KL散度(应保持在可控范围内)、格式准确率、正确性准确率等。
# GRPO训练监控指标 metrics = { "reward/mean": mean(rewards), # 目标: 持续上升 "reward/std": std(rewards), # 目标: 逐渐收敛 "reward/max": max(rewards), # 观察是否达到理论上限 "reward/min": min(rewards), # 观察最差表现 "kl_divergence": compute_kl(pi, ref), # 目标: 0.01-0.1之间 "loss/policy": policy_loss, # 应为负且逐渐减小 "format_accuracy": check_format(batch), # 应接近100% "correctness_rate": check_answers(batch),# 应持续提升 "avg_completion_length": mean(lengths), # 监控长度变化 "entropy": compute_entropy(pi), # 防止模式坍塌 }训练过程中需要特别关注以下异常信号:奖励不升反降(可能是学习率过高或奖励函数设计不当);KL散度暴增(策略偏离参考模型太远,需要增大beta);熵快速下降(模型陷入模式坍塌,输出缺乏多样性,需要降低学习率或增大temperature);completion长度暴增(模型可能在刷分,需要添加长度惩罚)。
八、FAQ:常见问题解答
Q1:GRPO必须先做SFT吗?能否直接从基座模型开始?
强烈建议先做SFT。虽然DeepSeek-R1展示了从基座模型直接RL的可能性,但那是在极大规模数据和算力下实现的。对于大多数开发者,如果模型连基本的输出格式都无法遵循,GRPO的组内比较会失去意义——所有completion格式都不对,奖励信号全是噪声。先用SFT建立格式遵循能力(达到95%以上),再进入GRPO阶段是更稳健的路径。
Q2:num_generations(G值)设多少合适?
G=8是常用默认值,适用于大多数场景。G=4可以节省推理成本但组内比较的统计可靠性下降;G=16效果更好但推理成本翻倍。建议从G=8开始,如果发现训练不稳定或奖励方差太大,可以增大到G=12-16。如果推理成本是瓶颈,可以降到G=4-6但需要更长的训练时间来弥补。
Q3:KL散度系数beta应该设多少?
推荐beta=0.01-0.05。beta过大会过度限制策略更新,模型学不到新东西;beta过小会导致策略偏离参考模型太远,可能出现输出质量下降或生成乱码。训练初期可以用较小的beta(0.01)让模型快速探索,后期逐渐增大到0.04-0.05来稳定训练。监控KL散度值,保持在0.01-0.1之间是健康的。
Q4:GRPO训练中奖励一直不升怎么办?
排查步骤:1) 检查奖励函数是否正确——手动检查几条completion的奖励是否合理;2) 检查SFT模型是否已具备基本能力——如果SFT模型的正确率低于10%,RL很难提升;3) 降低学习率到5e-7;4) 增大num_generations到12-16提高组内比较质量;5) 检查temperature是否合适——太低导致completion过于相似,太高导致质量太差;6) 尝试简化奖励函数,只用纯正确性奖励。
Q5:GRPO和DPO有什么区别?应该选哪个?
GRPO是在线RL方法,需要模型实时生成completion并用奖励函数打分,适合有明确可验证奖励的场景(数学、代码、工具调用)。DPO是离线方法,使用预先收集的偏好数据(chosen/rejected对),无需在线采样和奖励函数,适合偏好对齐场景(如回答风格、安全性)。如果任务有明确的正确答案,选GRPO;如果任务是对齐人类偏好,选DPO。两者也可以组合使用:先DPO对齐偏好,再GRPO提升能力。
Q6:GRPO训练需要多少显存?
以7B模型为例:需要同时加载策略模型(约14GB bf16)、参考模型(约14GB bf16,用于KL计算)、优化器状态(LoRA下约2GB)、Rollout缓存(约4-8GB,取决于batch size和G值)。总计约32-40GB显存。使用LoRA可以降低到约24GB。如果显存不足,可以减小per_device_train_batch_size、降低max_completion_length、或使用QLoRA量化参考模型。
Q7:如何防止模型在GRPO训练中出现"长度爆炸"?
模型可能学会通过输出更长的推理来获得更高奖励(因为更长通常意味着更详细的推理)。解决方案:1) 在奖励函数中添加长度惩罚,如reward = correctness - 0.001 * length;2) 设置max_completion_length限制最大生成长度;3) 监控avg_completion_length指标,如果超过阈值则增大惩罚权重;4) 使用长度归一化的奖励,如reward / log(length)。
Q8:GRPO训练一般需要多少步才能看到效果?
通常在100-500步后可以看到奖励均值的明显提升。完整训练一般需要1000-5000步,取决于任务难度和数据规模。建议每100步保存一次checkpoint,并在held-out测试集上评估,选择最佳checkpoint作为最终模型。过早停止会导致能力不足,过晚停止可能出现过拟合或奖励平台期。

