Agent 速成笔记 · 第 11 章 Agentic-RL

Agent 速成笔记 · 第 11 章 Agentic-RL

源:Datawhale《Hello-Agents》第 11 章 | 定位:概念原理 + 工程实现 | 一句话:提示工程到顶之后,如何用强化学习把 LLM 从"对话助手"训练成"会推理、会用工具"的自主智能体。


0. 一章速览(30 秒)

  • 一句话:Agentic RL 把 LLM 当作"可学习的策略"塞进智能体的感知—决策—执行循环里,用多步交互产生的轨迹与累积奖励来优化它,从而突破模仿学习的上限。
  • 本章解决什么问题:SFT 只能模仿人类给出的解题路径,模型无法超越数据;RL 让模型自己试错,学会"哪些推理路径更优、哪一步是关键"。
  • 必须记住的 4 个点:
    1. 训练主线是三步走:SFT(学格式、建基线)→ 奖励建模(学人类偏好)→ RL 微调(PPO/GRPO);SFT 是地基,直接上 RL 往往失败。
    2. PPO 的痛点是 Value Model:要同时维护 Policy / Reference / Value / Reward 四个模型;GRPO 用"组内相对奖励"替掉优势函数,只需 Policy + Reference 两个模型。
    3. RL 里真正决定成败的是奖励函数设计,不是算法花样;奖励稀疏、奖励欺骗(reward hacking)、方差过大是三大杀手,KL 惩罚是防止"跑偏把 SFT 学的能力忘掉"的安全绳。
    4. 工程上的一切都围绕显存与稳定性:LoRA 参数高效微调(rank 8/16、alpha 为 rank 的 2 倍)+ kl_coef 0.05~0.1 + 学习率 SFT 5e-5 / GRPO 1e-5。

1. 从 LLM 训练到 Agentic RL(11.1)

1.1 为什么 Agent 需要训练:监督学习的三个天花板

智能体要做复杂任务时会露馅,核心追问是:如何让它推理更强、更会用工具、能自我改进?在 RL 之前,主流做法是监督微调,但它有三个结构性局限:

  1. 数据质量直接决定训练质量——模型只能模仿训练数据,无法超越标注者;
  2. 缺乏探索能力——只能被动学习人类给的路径;
  3. 难以优化长期目标——无法精确优化多步推理的中间过程。

强化学习(Reinforcement Learning,RL)走的是另一条路:让智能体自主生成多个候选答案,按正确性拿奖励,于是它可以学到"哪些推理路径更优、哪些步骤是关键",甚至发现比人类标注更好的解法。

把一道小学数学题映射到 RL 框架,五个要素一一对应:智能体 = 基于 LLM 的推理系统;环境 = 数学问题 + 验证系统;状态 = 当前问题描述 + 已有推理步骤;行动 = 生成下一步推理或最终答案;奖励 = 答案是否正确(正确 +1,错误 0)。

这就是 Agentic RL 的核心思想:把 LLM 视为可学习策略,嵌入智能体的感知—决策—执行循环,用 RL 优化多步任务表现。

1.2 LLM 训练全景图:预训练 / SFT / 奖励模型 / RL

一个强模型的诞生分两大阶段:预训练(Pretraining) 与 后训练(Post-training)。

预训练用数 TB 级文本做自监督学习,任务是因果语言建模(Causal Language Modeling),也就是下一个词预测(Next Token Prediction)。给定序列 \(x_1,...,x_t\),最小化负对数似然:

\[\mathcal{L}_{\text{pretrain}} = -\sum_{t=1}^{T} \log P(x_t \mid x_1, x_2, \ldots, x_{t-1}; \theta) \]

符号含义:\(\theta\) 是模型参数;\(P(x_t \mid x_1,\ldots,x_{t-1};\theta)\) 是模型在给定前文时对下一个词给出的概率。目标是最大化预测正确词的概率。这一步学到的只是通用语言能力,模型并不知道如何遵循指令、如何拒绝不当请求。

后训练要补齐的正是这些,它由三步构成:

第一步,监督微调(Supervised Fine-Tuning,SFT):让模型学会遵循指令和对话格式,数据是 (prompt, completion) 对:

\[\mathcal{L}_{\text{SFT}} = -\sum_{i=1}^{N} \log P(y_i \mid x_i; \theta) \]

\(x_i\) 是输入提示(prompt),\(y_i\) 是期望输出,\(N\) 是样本数。注意 \(x_i\) 只出现在条件位置——所以梯度实际上落在 completion 的 token 上,prompt 只提供条件(等价于把 prompt 段"屏蔽"掉不计算损失)。SFT 的特点是数据量小、需人工标注、见效快,主要学任务格式与基本能力。

第二步,奖励建模(Reward Modeling,RM):SFT 后的模型能听指令了,但回答质量参差不齐,需要一把"打分尺"。奖励模型用偏好对比数据训练,同一问题给两个回答,一个更好(chosen,\(y_w\))、一个更差(rejected,\(y_l\)):

\[\mathcal{L}_{\text{RM}} = -\mathbb{E}_{(x, y_w, y_l)} \left[ \log \sigma\left( r_\phi(x, y_w) - r_\phi(x, y_l) \right) \right] \]

\(r_\phi(x,y)\) 是奖励模型,输入 (提示, 回答) 对、输出质量分数;\(\sigma\) 是 sigmoid 函数。这个损失的含义就是让好回答的得分比差回答更高,且差值越大越好。

第三步,强化学习微调:有了打分尺,就可以优化语言模型生成更高质量的回答。经典算法是 PPO(Proximal Policy Optimization)。

1.3 RLHF 三阶段串起来 + RLAIF 降本

把上面三步连起来就是 RLHF(Reinforcement Learning from Human Feedback,基于人类反馈的强化学习):SFT 模型负责"会说话",奖励模型负责"判好坏",PPO 负责"按分数改行为"。它的瓶颈很直接:需要大量人工标注偏好数据,成本高昂。

于是有了 RLAIF(RL from AI Feedback,基于 AI 反馈的强化学习):用强大的 AI 模型(如 GPT-4)替代人类标注员。四步流程是——用 SFT 模型生成多个候选回答 → 用强 AI 模型对回答评分和排序 → 用 AI 的评分训练奖励模型 → 用奖励模型做强化学习。实验表明 RLAIF 的效果接近甚至超过 RLHF,同时成本大幅降低。

1.4 PPO 的目标函数与 KL 约束(必背公式)

后训练第三步用的 PPO 目标函数(奖励模型版本)写作:

\[J_{\text{PPO}} = \mathbb{E}_{x, y \sim \pi_\theta} \left[ r_\phi(x, y) \right] - \beta \cdot D_{KL}(\pi_\theta \parallel \pi_{\text{ref}}) \]

逐符号解释:\(\pi_\theta\) 是当前策略,也就是正在被训练的语言模型;\(\pi_{\text{ref}}\) 是参考策略,这里通常是 SFT 模型;\(r_\phi(x,y)\) 是奖励模型给出的评分;\(D_{KL}\) 是 KL 散度,度量当前策略与参考策略的分布差异;\(\beta\) 是平衡系数。

一句话读懂整个式子:在尽量拿高奖励的同时,别偏离原始模型太远。前半项是"进取",后半项是"守成"——没有它,模型会为了骗奖励把语言本身说崩,也就是后面会反复出现的"能力遗忘/策略崩塌"。

延伸方向(免奖励模型):本章参考文献收录了 DPO(Direct Preference Optimization,直接偏好优化,Rafailov 等,2023,Your Language Model is Secretly a Reward Model,arXiv:2305.18290)。其直觉是:语言模型本身就隐式地是一个奖励模型,因此可跳过显式奖励模型与 RL 采样循环,直接在偏好对(chosen/rejected)上优化策略——这正是"免奖励模型"路线与本章 GRPO"免价值模型"路线的分野。本章工程主线仍是 PPO → GRPO。

1.5 PBRFT vs Agentic RL:MDP 视角下的五点差异(核心)

本章把传统的后训练称作 PBRFT(Preference-Based Reinforcement Fine-Tuning,基于偏好的强化微调),它只关注单轮对话质量:给一个问题,生成一个回答,按回答质量给分。这对需要多步推理、工具使用、长期规划的任务就力不从心了。

举个对照例子最清楚。PBRFT 场景:用户问"请解释什么是强化学习",模型生成完整回答,直接按质量给分。Agentic RL 场景:用户说"帮我分析这个 GitHub 仓库的代码质量",智能体要经历——调用 GitHub API 拿到仓库结构(+0.1)→ 读取主要代码文件(+0.1)→ 分析代码质量合理(+0.2)→ 生成报告质量高(+0.6),总奖励是各步累积 1.0。

RL 用马尔可夫决策过程(MDP)形式化,五元组 \((S, A, P, R, \gamma)\):状态空间 \(S\)、行动空间 \(A\)、状态转移函数 \(P(s'\mid s,a)\)、奖励函数 \(R(s,a)\)、折扣因子 \(\gamma\)。两者逐项对比如下。

维度 PBRFT Agentic RL
状态 \(s_0=\text{prompt}\),\(T=1\) \(s_t=(\text{prompt}, o_1,\ldots,o_t)\),\(T \gg 1\)
行动 只有文本生成 \(a=y\) \(a_t \in \{a_t^{\text{text}}, a_t^{\text{tool}}\}\)
转移 无转移,直接到终止 \(s_{t+1} \sim P(s_{t+1}\mid s_t, a_t)\)
奖励 单步 \(R=r(s_0, y)\) \(R=\sum_{t=0}^{T}\gamma^t r(s_t,a_t)\)
目标 \(\max \mathbb{E}[r(s_0,y)]\) \(\max \mathbb{E}_\tau[\sum_t \gamma^t r(s_t,a_t)]\)

两个目标函数写全:

\[J_{\text{PBRFT}}(\theta) = \mathbb{E}_{s_0, y \sim \pi_\theta} [r(s_0, y)] \qquad J_{\text{Agentic}}(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \left[\sum_{t=0}^{T} \gamma^t r(s_t, a_t)\right] \]

其中 \(\tau = (s_0, a_0, s_1, a_1, \ldots, s_T)\) 是完整轨迹(trajectory),\(\gamma \in [0,1]\) 是折扣因子。奖励 \(r(s_t,a_t)\) 有三种形态:稀疏奖励(只在任务完成时给,如答案正确 +1)、密集奖励(每步都给,如工具调用成功 +0.1)、以及两者结合的混合奖励。

这不是技术细节差异,而是思维方式转变:PBRFT 想的是"怎么生成更好的单个回答",关注语言表达、做单步决策;Agentic RL 想的是"怎么完成复杂任务",关注行动策略、做多步规划。正因如此,智能体才愿意为了最终目标执行看似"绕路"的中间步骤。

1.6 Agentic RL 要练的六大核心能力

能力 训练信号与要点
推理 Reasoning 生成推理链 \(c\) 与答案 \(a\);\(r(q,c,a)=1\)(\(a=a^*\))否则 \(0\)
工具使用 Tool Use \(a_t^{\text{think}}\) 与 \(a_t^{\text{tool}}=(\text{tool\_name}, \text{arguments})\)
记忆 Memory 学"记什么、何时更新、何时删",超越静态 RAG
规划 Planning 试错发现行动序列,权衡短期与长期收益
自我改进 识别错误、分析失败原因、调整策略
感知 Perception 多模态理解、视觉推理与视觉工具使用

推理是核心:CoT 提示依赖少样本示例、泛化有限,SFT 只能模仿数据里的推理模式;RL 通过试错能让模型学会何时需要深度思考、何时可以快速回答。工具使用的关键是时机与组合:解数学题时该用计算器、代码解释器还是直接推理。记忆的动机是上下文窗口有限、静态检索策略无法针对任务优化;规划的动机是 CoT 线性思考无法回溯、静态模板难以适应新情况。

1.7 HelloAgents 的技术选型与四层架构

选型很明确:TRL(Transformer Reinforcement Learning,Hugging Face 的 RL 库) + Qwen3-0.6B。理由:TRL 成熟稳定、功能完整、易集成;0.6B 参数适合普通 GPU 训练,开源免费。

实现上是自底向上的四层,每一层对应一个工程关注点:

层 核心类 / 函数 职责
统一接口层 RLTrainingTool 四个 action:train / load_dataset / create_reward / evaluate
训练器层 SFTTrainerWrapper、GRPOTrainerWrapper 训练逻辑与 LoRA 支持
奖励函数层 MathRewardFunction 基类、AccuracyReward、LengthPenaltyReward、StepReward 定义"什么是好行为"
数据集层 GSM8KDataset、create_sft_dataset()、create_rl_dataset() 数据加载与格式转换

调用骨架只有一个入口,算法由 algorithm 字段切换:

result = rl_tool.run({
    "action": "train", "algorithm": "sft",     # 或 "grpo"
    "model_name": "Qwen/Qwen3-0.6B",
    "max_samples": 100, "num_epochs": 3, "batch_size": 4,
    "use_lora": True, "lora_rank": 8, "lora_alpha": 16,
})

这段在干什么:用同一套 run() 字典接口完成数据加载、训练、评估;换成 algorithm="grpo" 就是 RL 训练,训练代码无需重写。快速跑通时要注意两点:GRPO 的 batch_size 必须能被 num_generations(默认 8)整除;跑完准确率很低是正常的(只见过 0.7% 的训练样本、且只训一轮)。


2. 数据集与奖励函数(11.2)

数据集定义"要学什么任务",奖励函数定义"什么是好行为"——这是 RL 训练的两大基石。

2.1 为什么选 GSM8K,以及三种数据格式

选数学推理做例子的理由有三:答案明确可自动评估(无需人工标注或复杂奖励模型);必须分解问题、逐步推导,是典型多步推理场景;推理能力可迁移。相比之下,开放式问答(如"如何学习编程")的答案质量难以客观评估。

GSM8K(Grade School Math 8K):7473 个训练样本 + 1319 个测试样本,难度为小学数学(2~8 年级)应用题,需 2~8 步推理。标注格式很有讲究:<<48/2=24>> 是中间计算步骤的标记,#### 72 标记最终答案——这两个标记正是后面奖励函数提取答案的抓手。

同一份原始数据要转成两种格式,用途完全不同:

格式 关键字段 用途与特点
原始 question、answer(含步骤) 人类可读,作为转换源
SFT prompt、completion 含完整解题过程,学格式与推理模式
RL prompt、ground_truth 只给最终答案,迫使模型自己推理

这里的设计意图非常关键:SFT 格式里 prompt 是对话模板拼的用户问题,completion 是完整解题过程(结尾带 <|im_end|>);RL 格式里 prompt 与 SFT 相同,但只放 ground_truth 最终答案。把过程拿走,模型就只能自己生成推理链,而不是背答案。

转入格式还有一个不可省略的细节:必须使用模型自己的对话模板(Qwen 是 <|im_start|>user ... <|im_end|>\n<|im_start|>assistant\n),否则模型学到的分隔符和推理时的不一致。

2.2 三种内置奖励函数(公式 + 适用性)

RL 的一般目标是最大化累积奖励:

\[J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \left[\sum_{t=0}^{T} \gamma^t r(s_t, a_t)\right] \]

对数学推理任务可以简化为 \(r(q, a) = f(a, a^*)\),\(q\) 是问题、\(a\) 是模型答案、\(a^*\) 是正确答案。好奖励函数应满足:清楚定义什么叫成功、能提供梯度信号、方差不过大、易调整与组合。坏奖励函数则表现为:只在任务结束时给分中间无反馈、存在奖励欺骗、多目标互相矛盾、方差过大导致不收敛。

(1)准确率奖励 AccuracyReward——最基础的二值奖励:

\[r_{\text{acc}}(a, a^*) = \begin{cases} 1 & a = a^* \\ 0 & \text{otherwise} \end{cases} \]

实现上有两个坑:答案提取(查 Final Answer: 后的数字、查 #### 后的数字、或用正则取最后一个数字)与答案比较(72.0 与 72 应视为相同、1000 与 1k 需单位转换、"72" 与 "seventy-two" 属格式差异)。优点是简单直接;缺点是奖励稀疏,无法区分"接近正确"和"完全错",训练初期缺乏有效反馈。

(2)长度惩罚 LengthPenaltyReward——治啰嗦:

\[r_{\text{length}}(a, a^*, l) = r_{\text{acc}}(a, a^*) - \alpha \cdot \max(0,\; l - l_{\text{target}}) \]

\(l\) 是生成长度(字符数或 token 数),\(l_{\text{target}}\) 是目标长度,\(\alpha\) 是惩罚系数(默认 0.001)。只在答案正确时才施加惩罚,否则模型会为了少受罚而故意输出短错误答案。举例:目标 200 字符、实际 500 字符、\(\alpha=0.001\),奖励 \(= 1 - 0.001\times(500-200) = 0.7\)。它同时降低了推理成本(token 更少),但可能抑制必要的详细推理。

(3)步骤奖励 StepReward——鼓励可解释:

\[r_{\text{step}}(a, a^*, s) = r_{\text{acc}}(a, a^*) + \beta \cdot s \]

\(s\) 是检测到的推理步骤数,\(\beta\) 是步骤奖励系数(默认 0.1),同样只在答案正确时给予。步骤检测靠匹配 "Step 1:" / "Step 2:" 标记、统计换行数或正则匹配推理模式。例:3 个清晰步骤的正确答案得 \(1 + 0.1\times3 = 1.3\)。优点是答案更易验证和调试;缺点是模型可能为凑步数写冗余步骤,且步骤检测本身可能不准。

2.3 奖励组合与选用规则

三种奖励可以组合,对应三类目标:

组合 公式 适用场景
准确率 + 长度惩罚 \(r = r_{\text{acc}} - \alpha\max(0, l-l_{\text{target}})\) 对话、问答系统
准确率 + 步骤奖励 \(r = r_{\text{acc}} + \beta s\) 教育场景、可解释 AI
三者平衡 \(r = r_{\text{acc}} - \alpha\max(0,l-l_{\text{target}}) + \beta s\) 同时优化质量、简洁、可解释

组合的算术直觉可以看原文的算例:准确率 1.0、长度惩罚 −0.1、步骤奖励 +0.3,合计 1.200。调和权重 \(\alpha\) 与 \(\beta\) 时要防止某个目标过度主导——这正是"奖励设计比算法选择更重要"的体现。

2.4 扩展框架:自定义数据集与奖励函数

数据要求先说清楚。SFT 格式需要 prompt、completion,可选 text;RL 格式需要 question、prompt、ground_truth、full_answer(含推理过程)。只要原始数据有 question 和 answer 两个字段,就可以用 format_math_dataset(dataset, format_type="sft"|"rl", model_name=...) 一键转换。

自定义奖励函数有强制签名约定,返回的每个值应在 0.0~1.0 之间:

from typing import List
import re

def custom_reward_function(completions: List[str], **kwargs) -> List[float]:
    ground_truths = kwargs.get("ground_truth", [])   # 数据集字段自动传入
    rewards = []
    for completion, truth in zip(completions, ground_truths):
        numbers = re.findall(r'-?\d+\.?\d*', completion)   # 取最后一个数字
        reward = 0.0
        if numbers:
            error = abs(float(numbers[-1]) - float(truth))
            reward = 1.0 if error < 0.01 else (0.8 if error < 1.0 else (0.5 if error < 5.0 else 0.0))
            if "step" in completion.lower() or "=" in completion:
                reward += 0.1                              # 过程分
        rewards.append(min(reward, 1.0))
    return rewards

这段在干什么:演示部分奖励(partial credit)的写法——按误差分档给 1.0 / 0.8 / 0.5,再对"展示了推理步骤"额外 +0.1,最后统一截断到 1.0。它比二值奖励提供了更密的梯度信号。

奖励函数与数据集的两种挂载方式:直接传入(custom_dataset= / custom_reward=),或注册使用(register_dataset(name, ds) / register_reward_function(name, fn),之后用 dataset="my_dataset" 引用)。推荐注册方式——数据集与奖励函数同名时会被自动配对,适合反复复用。


3. SFT 训练(11.3)

SFT 是 RL 训练的第一步,也是最重要的基础。没有 SFT,直接上 RL 往往会失败——因为模型连基本的输出格式都不会。

3.1 为什么必须先 SFT:一个对照实验

预训练模型的训练目标是"预测下一个词",不是"解数学题",因此它的输出是自由文本。原文的实验展示了同一道 GSM8K 题在三个阶段的表现差异:

  • 预训练模型:能理解问题,但输出冗长、无结构、没有明确答案(甚至冒出"也许我该用计算器?或者我可以估算一下……")。这种输出无法提取答案、无法评估质量、无法提供奖励信号。
  • SFT 后模型:输出变成 Let me solve this step by step. → Step 1: ... → Step 2: ... → Final Answer: 72,结构清晰、推理正确、格式统一。

因此 SFT 的四个作用可以精确概括:学输出格式("Step 1"、"Final Answer" 等标记)、学推理模式(如何分解问题、逐步推导)、建立基线能力(给 RL 一个合理起点)、减少探索空间(RL 不必从零开始)。SFT 是"从预训练模型到强化学习的桥梁"。

3.2 LoRA:参数高效微调

动机是显存:Qwen3-0.6B 全量微调需要约 12GB 显存(FP16)或 24GB(FP32),7B/13B 模型在消费级 GPU 上几乎不可能全量微调。

LoRA(Low-Rank Adaptation)的核心假设是:微调时的参数变化可以用低秩矩阵表示。设原权重 \(W \in \mathbb{R}^{d\times k}\),微调后 \(W' = W + \Delta W\),LoRA 令:

\[\Delta W = BA, \quad B \in \mathbb{R}^{d \times r},\; A \in \mathbb{R}^{r \times k},\; r \ll \min(d,k) \]

前向传播变为:

\[h = Wx + \Delta Wx = Wx + BAx \]

原参数 \(W\) 冻结,只训练 \(B\) 与 \(A\)。参数量从 \(d\times k\) 降到 \(r(d+k)\)。原文给的算例很有说服力:\(d=k=4096\)、\(r=8\) 时,\(4096\times4096 = 16{,}777{,}216\) 对 \(8\times(4096+4096) = 65{,}536\),参数减少 256 倍。优势是显存大幅降低、训练更快、易部署、抗过拟合;代价是效果通常略差于全量调参。

三个关键超参:秩 rank \(r\)(4-8 小任务、16-32 复杂任务、64 大规模微调,默认 8)、Alpha \(\alpha\)(缩放因子,实际更新为 \(\Delta W = \frac{\alpha}{r}BA\),通常设为 rank 的 2 倍,即 rank=8/16 对应 alpha=16/32)、target_modules(通常选注意力层 q_proj, k_proj, v_proj, o_proj,也可加 MLP 层 gate_proj, up_proj, down_proj)。

3.3 SFT 训练实操:参数、监控与显存

标准 SFT 配置(关键字段):model_name="Qwen/Qwen3-0.6B"、num_epochs=3、batch_size=4、learning_rate=5e-5、use_lora=True、lora_rank=8、lora_alpha=16。若做完整训练则使用全部 7473 个样本、batch_size=8、lora_rank=16、lora_alpha=32、target_modules=["q_proj","k_proj","v_proj","o_proj"]、warmup_ratio=0.1、weight_decay=0.01、save_steps=500、logging_steps=100、eval_steps=500——这套配置适合 8GB 显存 GPU,预计 30~60 分钟。

调参经验值(可直接照抄的判断标准):

参数 建议值 判断规则
max_samples 测试 100-1000,完整 7473 数据越多越好但更慢
num_epochs 从 3 起步 1-2 轮欠拟合,>10 轮过拟合
batch_size 4GB→1-2;8GB→4-8;16GB→8-16 受显存约束,越大越稳
learning_rate SFT 5e-5,LoRA 可 1e-4 1e-6 太慢,1e-3 不收敛

训练中要盯的三个指标:Loss 应逐渐下降(不降可能是学习率太小或数据有问题;降后又升可能是学习率太大或过拟合);梯度范数 合理区间是 0.1~10(>100 是梯度爆炸、需降学习率;<0.01 是梯度消失、需检查模型配置);学习率应按 warmup 策略先在前 10% 步数线性增加、再线性衰减到 0。

四类常见故障与处置:显存不足 → 减小 batch_size 或 max_length、用梯度累积或更小模型;训练慢 → 增大 batch_size、降低 logging 频率、混合精度训练;损失不降 → 增大学习率、检查数据格式、增加轮数;过拟合 → 增大 weight_decay、减少轮数、加数据。

3.4 模型评估与基准预期

评估三个指标:准确率(Accuracy)——答案完全正确的比例,0~1;平均奖励(Average Reward)——综合准确率、长度、步骤等因素;推理质量(Reasoning Quality)——清晰度与逻辑性,需人工或专门评估模型。

必须记住的基准值:Qwen3-0.6B 这类小模型,SFT 后在 GSM8K 上达到 40~50% 属正常水平,RL 后可提升到 60~70%。评估时的对比方法很实用:分别对预训练模型(use_lora=False)、SFT 模型、GRPO 模型跑同一批测试样本,看准确率、平均长度、格式正确率的联合变化。


4. GRPO 训练(11.4)

SFT 模型只是学会了"模仿"训练数据中的推理过程,并没有真正学会"思考"。RL 让它通过试错优化推理策略,从而超越训练数据的质量。

4.1 PPO 的三个痛点与 GRPO 的解法

PPO 是 RL 领域最经典的算法之一,靠"限制策略更新幅度"保证稳定,但在 LLM 训练中有三个现实问题:需要训练 Value Model(价值模型),增加复杂度与显存;要同时维护四个模型(Policy、Reference、Value、Reward),工程实现复杂;训练不稳定,容易出现奖励崩塌或策略退化。

GRPO(Group Relative Policy Optimization,群组相对策略优化)是专为 LLM 设计的 PPO 简化变体,三点改进:不需要 Value Model——用组内相对奖励代替绝对奖励;只需 Policy Model 与 Reference Model 两个模型;训练更稳定,减少奖励崩塌风险。

维度 PPO GRPO
优势估计 需 Value Model 估 \(A(s,a)\) 用 \(r - \bar{r}_{\text{group}}\)
模型数量 4 个 2 个
训练稳定性 易崩塌 更稳定
显存占用 高 低

4.2 两个目标函数:公式与逐符号解释(必背)

PPO 的目标函数(带裁剪):

\[J_{\text{PPO}}(\theta) = \mathbb{E}_{s,a \sim \pi_\theta}\left[ \min\left( \frac{\pi_\theta(a|s)}{\pi_{\text{old}}(a|s)} A(s,a),\; \text{clip}\left(\frac{\pi_\theta(a|s)}{\pi_{\text{old}}(a|s)}, 1-\epsilon, 1+\epsilon\right) A(s,a) \right) \right] \]

这里 \(\frac{\pi_\theta(a|s)}{\pi_{\text{old}}(a|s)}\) 是新旧策略的概率比(重要性采样比),\(\text{clip}(\cdot, 1-\epsilon, 1+\epsilon)\) 把比值限制在 \([1-\epsilon, 1+\epsilon]\) 内防止单次更新过猛,\(\epsilon\) 由 clip_range 控制(建议 0.2)。其中优势函数需要 Value Model 估计:

\[A(s,a) = Q(s,a) - V(s) = r(s,a) + \gamma V(s') - V(s) \]

\(Q(s,a)\) 是动作价值、\(V(s)\) 是状态价值。麻烦就麻烦在这个 \(V\)——它是整套 Value Model 存在的原因。

GRPO 直接把优势项换成组内相对奖励:

\[J_{\text{GRPO}}(\theta) = \mathbb{E}_{s,a \sim \pi_\theta}\left[ \frac{\pi_\theta(a|s)}{\pi_{\text{ref}}(a|s)} \cdot \left( r(s,a) - \bar{r}_{\text{group}} \right) \right] - \beta \cdot D_{KL}(\pi_\theta \parallel \pi_{\text{ref}}) \]

符号对照:\(\bar{r}_{\text{group}}\) 是同一问题下多个采样答案的平均奖励,\(r(s,a) - \bar{r}_{\text{group}}\) 就是"比同组平均水平好多少";\(\pi_{\text{ref}}\) 是参考策略(SFT 模型);\(\beta\) 是 KL 惩罚系数(对应工程参数 kl_coef)。

GRPO 的三个关键差异:用 \(r(s,a)-\bar{r}_{\text{group}}\) 代替 \(A(s,a)\),不需要 Value Model;用组内相对奖励减少奖励方差;保留 KL 散度惩罚防止策略偏离太远。工程结论很直接:对于 LLM 训练,GRPO 更简单、更稳定、显存占用更低,是更好的选择。

4.3 GRPO 训练循环的五步

  1. 采样:对每个问题,用当前策略生成 num_generations 个答案,它们构成一个"组";
  2. 奖励计算:对每个答案算奖励 \(r_i\)(准确率 / 长度惩罚 / 步骤奖励或组合);
  3. 相对奖励:算组内均值 \(\bar{r} = \frac{1}{N}\sum_{i=1}^{N} r_i\),再算 \(\hat{r}_i = r_i - \bar{r}\);
  4. 策略更新:用相对奖励更新策略,并加上 KL 散度惩罚;
  5. 重复:直到跑完所有轮次。

用原文的算例感受一下这个机制。问题 "What is 48 + 24?",生成 4 个答案,奖励为 [1.0, 1.0, 0.0, 0.8](第 4 个因冗长被长度惩罚扣分),均值 \(0.7\),则相对奖励是 [+0.3, +0.3, -0.7, +0.1]——策略会提高前两个(正确且简洁)的概率、降低第三个(错误)的概率,第四个"正确但冗长"只获得很小的正向信号。

question = "What is 48 + 24?"
answers  = ["48 + 24 = 72. Final Answer: 72",   # 正确
            "48 + 24 = 72. Final Answer: 72",   # 正确
            "48 + 24 = 70. Final Answer: 70",   # 错误
            "Let me think... 72. Final Answer: 72"]   # 正确但冗长
rewards = [1.0, 1.0, 0.0, 0.8]
avg_reward = sum(rewards) / len(rewards)            # 0.7
relative_rewards = [r - avg_reward for r in rewards]  # [+0.3,+0.3,-0.7,+0.1]

这段在干什么:把"绝对奖励"翻译成"组内相对奖励"。它的作用不是选出最好的答案,而是让模型学"比平均水平更好"——这既降低了奖励方差,也提高了训练稳定性。

4.4 KL 散度惩罚:为什么它会防止能力遗忘

KL 散度定义为:

\[D_{KL}(\pi_\theta \parallel \pi_{\text{ref}}) = \mathbb{E}_{s,a \sim \pi_\theta}\left[ \log \frac{\pi_\theta(a|s)}{\pi_{\text{ref}}(a|s)} \right] \]

实践中按 token 计算再求和:

\[D_{KL} = \sum_{t=1}^{T} \log \frac{\pi_\theta(a_t \mid s, a_{<t})}{\pi_{\text{ref}}(a_t \mid s, a_{<t})} \]

KL 越大说明当前策略与参考模型差异越大。目标函数里加 \(-\beta \cdot D_{KL}\) 就是限制策略更新幅度,避免"遗忘"SFT 阶段学到的知识。kl_coef (\(\beta\)) 的取值必须权衡:太小(0.01)策略可能偏离太远,输出格式混乱或质量下降;太大(0.5)更新受限、学习缓慢、难以超越 SFT 模型;建议 0.05~0.1。

4.5 GRPO 超参:生成 / 优化 / 奖励三类

生成参数:num_generations 每个问题生成几个答案(典型 4-8,越多信号越多样但越贵);max_new_tokens(建议 256-512,太少截断、太多浪费);temperature(GRPO 建议 0.7-1.0,保持探索性;0 是贪婪解码,1 是标准采样)。

优化参数:learning_rate 通常比 SFT 更小,建议 1e-6~1e-5——因为不想偏离 SFT 模型太远,且小模型上学习率过大(如 5e-5)可能导致策略坍塌;kl_coef 建议 0.05-0.1;clip_range 建议 0.2。

奖励参数:reward_type 可取 "accuracy"、"length_penalty"、"step"、"combined";reward_config 传额外配置。原文的完整 GRPO 配置可作模板:从 ./models/sft_full 起步,num_epochs=3、batch_size=4、learning_rate=1e-5、warmup_ratio=0.1、num_generations=4、max_new_tokens=512、temperature=0.8、kl_coef=0.05、clip_range=0.2、lora_rank=16、lora_alpha=32,奖励用组合式:accuracy 权重 1.0、length_penalty 权重 0.5(target_length 200)、step 权重 0.3(step_bonus 0.1)。

4.6 训练监控与四大失败模式

要盯的四个指标:平均奖励应逐渐上升;KL 散度应保持在 0.01~0.1(>0.5 说明偏离太远,需增大 kl_coef 或降低学习率;<0.001 说明策略几乎没更新,需减小 kl_coef 或增大学习率);准确率应逐渐提升;生成质量需人工抽样检查格式与推理清晰度。

监控工具有三种:Weights & Biases(wandb,推荐),通过 WANDB_PROJECT、WANDB_LOG_MODEL 环境变量启用,自动记录 train/reward、train/kl、train/loss、train/learning_rate、train/epoch;TensorBoard,日志写在 output_dir 下,用 tensorboard --logdir=... 启动并访问 6006 端口;离线日志,形如 Epoch 1/2 | Step 100/500 | Reward: 0.45 | KL: 0.023 | Loss: 1.234。

四大失败模式与处置表(这是本章最实用的工程清单):

失败模式 根因 处置
奖励不上升 学习率太小 / KL 惩罚太大 / 奖励函数不合理 / SFT 模型太差 lr 1e-5→5e-5;kl 0.1→0.05;查奖励;重训 SFT
KL 爆炸(>0.5~1.0,格式混乱) 学习率太大 / KL 惩罚太小 / 奖励过于激进 lr 5e-5→1e-5;kl 0.05→0.1;调奖励;梯度裁剪
生成质量下降(准确率升但格式乱) 奖励只看准确率 / KL 太小偏离 SFT / 过拟合 改组合奖励;增大 kl_coef;减轮数或加数据
OOM 显存不足 GRPO 要比 SFT 高(多答案生成 + 参考模型输出) num_generations 8→4;batch 4→2;max_new_tokens 512→256;梯度检查点 + 混合精度

5. 模型评估与分析(11.5)

只看准确率是不够的,一个好的评估体系要多维度,分三类指标。

准确性指标:准确率 \(\text{Accuracy} = \frac{\text{正确答案数}}{\text{总问题数}}\),简单直观但无法区分"接近正确"与"完全错误";Top-K 准确率 \(\text{Accuracy@K} = \frac{\text{至少有一个正确答案的问题数}}{\text{总问题数}}\),反映多次采样能找到正确答案的"潜力";数值误差 \(\text{Error} = \frac{1}{N}\sum_{i=1}^{N}|y_i - \hat{y}_i|\),能区分"预测 72.5 / 真实 72"与"预测 100 / 真实 72"。

效率指标:平均长度 \(\text{Avg Length} = \frac{1}{N}\sum_{i=1}^{N}|y_i|\)(直接对应推理成本与响应速度);推理步骤数 \(\text{Avg Steps} = \frac{1}{N}\sum_{i=1}^{N}s_i\)(2~5 步说明能系统分解问题,过多则属冗余);推理时间(影响部署体验)。

质量指标:格式正确率 \(\text{Format Correctness} = \frac{\text{格式正确的答案数}}{\text{总答案数}}\)(格式是最低门槛,格式乱的结果即使对也不可用);推理连贯性与可解释性(步骤之间是否逻辑连贯、是否易于验证,需人工或专门评估模型)。

错误分析是评估的重点,模型错误分四类:计算错误(推理步骤对但算错,如 48/2=25,说明数值计算弱)、推理错误(逻辑错导致思路不对,如先加后除,说明逻辑推理弱)、理解错误(没读懂题,如问"总共"却只算了一部分,说明语言理解弱)、格式错误(答案对但缺 Final Answer: 等标记,说明格式学习不足)。

原文给出的实测分布很有代表性:总错误 76 个,其中计算错误 32(42.1%)、理解错误 22(28.9%)、推理错误 18(23.7%)、格式错误 4(5.3%)——计算错误是最大短板,格式错误极少说明 SFT 效果良好。

按难度分层同样关键:简单(1-2 步)78.50%(85 样本)、中等(3-4 步)58.30%(96 样本)、困难(5+ 步)31.60%(19 样本)。结论清晰:模型在简单题上已可用,多步推理能力是瓶颈。

由此形成改进闭环:训练 → 评估 → 分析错误 → 确定问题 → 选择改进方向 → 重新训练,迭代提升。


6. 完整训练流程与工程要点(11.6)

6.1 端到端六阶段

完整流程是:数据准备 → SFT 训练 → SFT 评估 → GRPO 训练 → GRPO 评估 → 模型部署。工程上把它封装成一个流水线类(原文 AgenticRLPipeline),每个阶段一个方法,结果统一 json.dump 保存,并用配置文件驱动。参考配置:base model Qwen/Qwen3-0.6B;数据 max_samples=1000;SFT num_epochs=3, batch_size=8;GRPO num_epochs=3, batch_size=4;评估 max_samples=200 且设 sft_accuracy_threshold=0.40(SFT 准确率门槛,未达标就不该进 RL);监控开 TensorBoard。

三条上线前必做:从小规模开始(先用 100-1000 样本验证流程和参数,再扩大规模);数据质量检查(查必需字段是否存在、是否有空值、是否有重复样本);数据增强(改写问题但答案不变、生成相似问题、反向翻译)——注意任何增强都不能引入噪声。

6.2 超参数调优:三种方法怎么选

方法 做法 优缺点
网格搜索 遍历参数组合,如 lr [1e-5,5e-5,1e-4] × rank [8,16,32] × kl [0.05,0.1,0.2] 简单、可达全局最优;成本高,参数多时不可行
随机搜索 随机采样 N=10 次;lr 对数均匀 1e-6~1e-4,rank ∈{4,8,16,32,64},kl∈[0.01,0.5] 效率高、适合大空间;可能错过最优
贝叶斯优化 用 Optuna,suggest_loguniform/suggest_categorical/suggest_uniform,n_trials=20 样本效率高;实现复杂,需额外库

6.3 分布式训练:方案选择与两个缩放公式

方案选择规则:单机多卡(2~8 卡)用 DDP,简单高效;大模型(>7B)用 DeepSpeed ZeRO-2 或 ZeRO-3;多节点集群用 DeepSpeed ZeRO-3 + Offload。配置入口是 accelerate config,生成文件在 ~/.cache/huggingface/accelerate/default_config.yaml。

三条落地细节:

  • DDP:distributed_type: MULTI_GPU、num_processes: 4、mixed_precision: fp16;启动 accelerate launch --config_file multi_gpu_ddp.yaml train_script.py,训练脚本一行都不用改。
  • ZeRO-2:zero_stage: 2、gradient_accumulation_steps: 4、gradient_clipping: 1.0、offload 全为 none;ZeRO-3:zero_stage: 3、offload_optimizer_device: cpu、offload_param_device: cpu、zero3_init_flag: true。ZeRO 通过分片优化器状态、梯度、模型参数降低显存。
  • 多节点:num_processes: 16(4 节点 × 4 GPU)、num_machines: 4、main_process_ip: 192.168.1.100、main_process_port: 29500,各节点改 machine_rank 后分别启动。

两个必记公式:总 batch size \(= \text{per\_device\_batch} \times \text{num\_gpus} \times \text{gradient\_accumulation\_steps}\);学习率用线性缩放 \(\text{lr}_{\text{new}} = \text{lr}_{\text{base}} \times \sqrt{\frac{\text{total\_batch}_{\text{new}}}{\text{total\_batch}_{\text{base}}}}\)。例:基准单 GPU、batch=16、lr=5e-5;换成 4 GPU、batch=64,则 lr \(= 5\text{e-}5 \times \sqrt{64/16} = 1\text{e-}4\)。调试用 ACCELERATE_LOG_LEVEL=INFO、NCCL_DEBUG=INFO、watch -n 1 nvidia-smi。

6.4 生产部署三步

导出:把 LoRA 权重合并回基础模型,避免线上多加载一个适配器——

from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B")
model = PeftModel.from_pretrained(base_model, "./models/grpo_model")
merged_model = model.merge_and_unload()          # 合并 LoRA 权重
merged_model.save_pretrained("./models/merged_model")

这段在干什么:merge_and_unload() 把 \(BA\) 写回 \(W\),产出与普通模型无异的独立权重,部署时不再依赖 PEFT。

推理优化:load_in_8bit=True + device_map="auto" 加载,生成参数 max_new_tokens=512、temperature=0.7、do_sample=True。服务化:用 FastAPI 暴露 POST /generate,启动 uvicorn api:app --host 0.0.0.0 --port 8000。


7. 高频考点 & 易错点速查

  1. SFT 与 RL 的分工:SFT 学格式、建基线、缩小探索空间;RL 通过试错超越训练数据质量。跳过 SFT 直接 RL 往往失败——这是最常见的错答。
  2. PPO 目标函数的两个组成部分:最大化奖励模型评分 + 减去 \(\beta \cdot D_{KL}\);会解释 \(\pi_\theta\)、\(\pi_{\text{ref}}\)、\(r_\phi\)、\(\beta\) 各自的角色。
  3. GRPO 为什么不需要 Value Model:用组内相对奖励 \(r(s,a)-\bar{r}_{\text{group}}\) 替代优势函数 \(A(s,a)\);模型数从 4 个降到 2 个。
  4. 相对奖励为什么更稳:减去组均值 = 只看"比平均好多少",直接降低奖励方差;注意它奖励的是相对水平而非绝对高分。
  5. KL 惩罚的双向风险:太小(0.01)会跑偏、格式崩坏、遗忘 SFT 能力;太大(0.5)学不动、追不上 SFT。建议区间 0.05~0.1。
  6. 学习率不能照搬:SFT 用 5e-5,GRPO 必须更小(1e-6~1e-5);小模型上用 5e-5 可能策略坍塌。
  7. 奖励稀疏 vs 奖励欺骗:二值准确率奖励梯度太稀;而长度/步骤奖励若设计不当,会让模型学会"凑步数""写短错误答案"这类作弊(reward hacking)——所以长度与步骤奖励都只在答案正确时才生效。
  8. 数据格式与 mask:SFT 的 \(\mathcal{L}_{\text{SFT}}\) 只对 completion 计算损失(prompt 仅作条件);RL 格式必须只给 ground_truth 不给过程,否则模型只会背答案。
  9. 必背超参与基准值:GSM8K 7473/1319;num_generations 4-8;max_new_tokens 256-512;temperature 0.7-1.0;clip_range 0.2;LoRA rank 8/16、alpha 为 rank 的 2 倍;Qwen3-0.6B 在 GSM8K 上 SFT 40-50%、RL 60-70%。
  10. 梯度范数区间 0.1~10:>100 梯度爆炸、<0.01 梯度消失;KL 健康区间 0.01~0.1。
  11. 章末习题的考点映射:①PBRFT 与 Agentic RL 的状态空间差异及影响、把"代码调试助手"映射到 RL 四要素(考 MDP 建模);②LoRA 为何用 0.16% 参数达到近似效果、何时该用 LoRA、GRPO 相对 PPO 的优势与迁移到代码生成/对话的调整(考参数高效微调与算法对比);③设计部分奖励、多目标任务奖励、以及奖励黑客的防御机制(考奖励工程);④GSM8K 的适用边界、泛化能力评估、在线学习与灾难性遗忘(考数据与泛化);⑤工具学习方案、分层 RL(高层规划/低层调用)、课程学习(考多步与工具方向)。

8. 与前后章节的衔接

前面章节解决的是"怎么把智能体搭起来"——记忆、规划、工具、多智能体与通信协议,它们决定了智能体的结构与行动空间;本章则回答"怎么让策略本身变强":把 LLM 当作可学习策略,用 SFT 建基线、用 GRPO 做试错优化,训练信号从单轮质量升级为多步轨迹的累积回报。本章产出的模型可以反过来替换前面各章中"直接用现成 LLM"的位置,让同一条 Agent 循环具备更强的推理与工具使用能力;而本章反复使用的奖励设计、轨迹回报、多步决策这套语言,也正是理解后续更复杂训练范式(长程推理、工具学习、多智能体协同训练)的公共基础。


9. 课后练习

在线试卷:https://md-quiz-online.app.workbuddy.host/

posted @ 2026-09-28 17:09  测试小罡  阅读(10)  评论(0)    收藏  举报