arl. 调用前面各章的内容。下一个代码块按第 5 章的方式搭建 gym 和分词器。
15.1 轨迹 SFT 与动作掩码
示范是由我们所训练的策略之外的某个主体产生的轨迹:人类、脚本化的专家或更强的模型。SFT 用最大似然把策略拟合到示范上。对单轮回复来说,这就是普通的下一 token 交叉熵。对智能体轨迹来说,问题在于应当最大化哪些 token 的似然,而答案来自轨迹本身的概率。 把一条示范写成动作与观测交替的序列 ,其中 是提示。在固定环境中、策略 之下,它的概率可以分解为策略的选择与环境的响应: 其中 是动作 之前的历史。每个动作是一个 token 串,所以 是其各 token 对数概率之和(3.1 节)。取对数后,只有中间的乘积依赖 : 因此,在示范上做最大似然恰好就是带掩码的目标:对策略拥有的 token 的对数概率求和,其余部分只作为条件。动作掩码不是一种“避免在工具输出上训练”的经验技巧。它就是轨迹对数似然的梯度,因为环境的概率不含参数。在观测 token 上训练优化的是另一个目标,即环境模型,它会教策略去预测、并最终去编造工具输出。这与让环境动力学从策略梯度中消去的推导(第 6 章)相同,只是从监督学习的一侧来看。sft_loss 在一个 collate 批次上实现它。我们对动作 token 取平均(token 平均)。第 6 章讨论了这一选择如何对长轨迹和短轨迹重新加权。
scripted_rollout 运行,为每个任务给出一条示范。我们在未训练的模型上比较带掩码的损失与覆盖全部预测位置的无掩码损失,并统计无掩码损失会把权重放在哪里。
15.2 热启动:先格式,后技能
SFT 在智能体流水线中扮演两种不同的角色,而 gym 让我们能把它们分开。第一种是教格式:调用语法、停止 token 以及轮次的节奏。第二种是教技能:根据观测到的内容决定发出哪个调用。对真实模型来说,预训练加上通用指令微调提供了前者。我们为 TinyAgent 构造对应物的方法,是在格式正确但没有技能的行为上做 SFT,即第 4 章的 blind 与 random 脚本策略的混合。我们把得到的模型称为弱基座(weak base)。它是本章每种做法的起点。(第 6 章为第二部分构造了一个类似的基座智能体。)sft_train 是一个最小的循环:有放回地采样一个轨迹小批次(minibatch),在 sft_loss 上走一步 AdamW,并可选地每隔几步调用一个钩子,使实验可以在不重启优化器的情况下评估或保存检查点。
rollout_batch 采样回合并对奖励取平均。pass_rate 同时返回轨迹,方便调用者检查;action_entropy 报告一个批次在动作 token 上的平均下一 token 熵(entropy),即 3.2 节的探索统计量。
read 观测(如 min 或 // 这样的关键字)而不是函数名来选择操作,而这条规则能迁移到没见过的函数上。同时要看最后一列的代价:动作熵从 0.25 降到 0.02 nats,降了一个数量级。策略已经几乎是确定性的,一旦接着做 RL,这一点就很关键(15.6 节)。
证据。 本书测得,单个随机种子,每次评估每个任务采样 4 次(训练 80 个回合、留出 40 个回合),所以每个通过率的标准误最高约 0.06。oracle 是完美的,并覆盖每个任务类型。真实示范两者都做不到,15.3 至 15.5 节展示数据来自模型自身时会发生什么变化。
15.3 拒绝采样与专家迭代
示范很贵,验证器(verifier)往往很便宜。拒绝采样微调(rejection-sampling fine-tuning,RFT)用模型自身取代示范者:从当前策略为每个任务采样若干回合,保留验证器接受的那些,然后在保留集上做 SFT。反复执行采样、过滤、微调就是专家迭代(expert iteration);STaR 把这个循环用于推理理由,保留那些导向正确答案的理由(Zelikman et al., 2022),而数学推理上的 RFT 报告说,不同的正确路径越多,收益越大(Yuan et al., 2023)。有意思的问题是它与 RL 是什么关系。RFT 是奖励为 0/1 的策略梯度
设 ,。第 6 章的策略梯度是 因为 在失败时为 0,成功时为 1。右边的期望是从当前策略抽取的成功轨迹的对数似然梯度,这恰好是在保留集上走一步 SFT 所估计的量。因此,在新鲜样本上走一步 RFT,就是学习率除以成功率 的一步策略梯度。实际方法与这个估计量之间有三点差别:- 归一化。 SFT 对保留的 token 取平均,策略梯度对全部采样 token 取平均。当 很小时,RFT 每单位梯度信号走的步子更大。
- 没有负信号。 失败样本不贡献任何东西。带基线 时,策略梯度是 ;RFT 只保留第一项。除了通过 softmax 的间接作用外,没有任何东西把概率推离失败模式。
- 复用。 在固定保留集上跑多个轮次(epoch)是没有重要性校正的 off-policy 更新。把保留集拟合到收敛,求解的是 ,即以成功为条件的旧策略。这就是过滤式行为克隆(filtered behavior cloning),专家迭代的每一轮都是一次这样的投影。
从弱基座开始的专家迭代
我们跑四轮。每轮为每个训练任务采样 16 个回合(共 320 个回合),保留成功的回合,并在其上走 15 步 SFT,从上一轮的模型继续训练。init。保留集中没有它的任何样例,所以这一轮没有直接教会它的成功示范:专家迭代主要强化已经采样到的成功行为,这就是过滤式克隆的覆盖范围的局限。而且大多数保留下来的成功回合是以编辑而不是读取开头的(第 0 轮的 49 个中有 32 个以两种编辑操作之一开头,只有 10 个以读取开头)。它们是碰巧猜对的盲猜,而能复现它们的成本最低规则就是把 issue 中的函数名映射到一个操作。这条规则在训练任务上是准确的,在留出函数上毫无用处,因为模型从没见过这些函数名,所以留出结果停留在猜测水平附近。最终策略只在 30% 的回合中读取文件。RFT 复制的是通过筛选的行为;在这里,许多成功来自盲猜,筛选本身并不区分决策依据。STaR 的“合理化”(rationalization)步骤针对模型失败的问题,在给定正确答案的条件下重新生成理由,它处理的是这个问题中样本覆盖这一部分(Zelikman et al., 2022)。过滤器中没有任何东西处理捷径(shortcut)这一部分。
15.4 面向智能体轨迹的 DPO
RFT 丢弃失败样本。偏好优化则利用它们:给定同一任务上的一对回合,一个被偏好(,chosen),一个不被偏好(,rejected),提高被选回合的相对似然。直接偏好优化(Direct Preference Optimization,DPO)从 KL 正则化的 RL 目标推导出这样的更新,训练时无需采样(Rafailov et al., 2023)。 从 出发。它的最大化解是 ,所以奖励可以通过策略写成 。在 Bradley–Terry 模型 下,配分函数 相互抵消,对观测到的偏好最大化似然就得到 DPO 损失 对于智能体轨迹,还会发生一次抵消。每个 都包含 15.1 节中的环境项,而比值 把它们约掉了,因为两个策略面对的是同一个环境。因此每个对数比值都是只在动作 token 上对 求和。动作掩码进入 DPO 的理由与它进入 SFT 的理由相同。还有两个推论值得指出。两个回合在相同上下文中共享的 token,例如共同的第一次调用,贡献大小相等、方向相反的梯度而相互抵消,所以 这一对样本的 DPO 梯度只来自分叉之后的策略 token。另外,这个损失只在数据集中的轨迹上约束策略;推导它所依据的 KL 正则化从未在策略自己的样本上计算过。dpo_loss 接收求和后的序列对数概率,因此与调用者如何掩码、如何求和无关。
episode_logp 对一个批次的带掩码对数概率求和。
15.5 实验:从同一个弱基座出发的四种做法
现在我们比较几种都从弱基座出发、并以相同方式评估的做法:- 在 oracle 轨迹上做 SFT(15.2 节):20 条示范,60 步。
- RFT / 专家迭代(15.3 节):不用示范,4 轮,每轮 320 个采样回合、15 步。
- 先 SFT 后 RL:第 20 步的 oracle-SFT 检查点(训练通过率 0.80),再跑 40 步 RL。
- 从弱基座直接 RL:60 步 RL,这个对照显示了冷启动带来了什么。
- 有一个完美且覆盖全面的示范者时,SFT 很难被超越。 二十条 oracle 轨迹加 40 步就在训练集上达到 0.99,在留出集上达到约 0.9。冷启动之后的 RL 最终到达同一位置(0.96/0.95),没有超过它:对于一个行为已经最优、且先读后动的示范者,RL 没有什么可以补充的。这就是智能体流水线只要能做到,就会收集或合成示范的原因。
- 从弱基座出发的 RFT 受限于基座。 它提升很快,在基座能解的 16 个任务处进入平台期,并学到了一条无法迁移的捷径。过滤式克隆无法创造采样器从未产生过的行为。
- 冷启动让 RL 奏效。 从第 20 步检查点出发,40 步 RL 在训练集上达到 0.96,在留出集上达到 0.95;而从弱基座出发的 RL 跑了 60 步,只达到 0.36/0.30。在第 20 步,冷启动的策略已经会读文件,成功率约 80%,所以大多数组同时包含两种结果,优势是有信息量的(15.6 节测得 70%)。弱基座很少读取,RL 必须先靠偶然发现读取这个动作。
- 只做 RL 的曲线仍在上升。 它的曲线在末尾仍在上升,第 9 章展示了用调好的训练器跑更长时间能达到什么。这里的要点是固定预算下的排序,而不是渐近值。
证据。 四条曲线都是单随机种子的 CPU 运行,评估分别用 80 和 40 个回合。低于约 0.1 的差异在噪声范围内。只做 RL 与其他做法之间的排序差距远超噪声。
15.6 实践中的设计问题
问题:SFT 在 RL 之前降低熵和探索。 现象: 在一个较强的 SFT 阶段之后,RL 奖励持平不动,大多数组的奖励方差为零,熵曲线从接近零的位置开始。 原因: 把 SFT 训练到收敛会把策略推向示范者的确定性选择(15.2 节测得 0.25 → 0.02 nats)。组基线优势为 ,对于回合全部通过或全部失败的组,其中每个成员的优势都为零,所以近乎确定性的策略几乎不产生梯度,在它做错的任务上也一样。 可选方案: (a) 提前停止 SFT,选一个仍保有熵的检查点,就像第 20 步冷启动那样,代价是起始通过率较低。(b) 在 RL 期间提高 rollout 温度,这会改变行为策略(3.3 节)。(c) 加入熵奖励(第 10 章)。(d) 混入多样化的示范,使 SFT 拟合一个分布而不是一条路径。 建议做法: 依据探针集上奖励方差非零的 RL 组所占比例来选择 SFT 检查点,而不是依据 SFT 损失。下一个代码块在留出任务上测量这个比例。
问题:示范用与 RL 不同的模板渲染。 现象: SFT 损失非常好,而最初的 RL rollout(或第一次评估)远差于 SFT 验证数字所预示的水平。 原因: 示范流水线渲染回合时使用了与 rollout 流水线不同的模板,所以策略是在它从未训练过的前缀上接受评估(5.8 节)。 可选方案: (a) 让所有数据都经由 rollout 自己的Episode代码路径渲染,这是最便宜的修复。(b) 用 RL 模板重新渲染遗留数据。(c) 断言同一段固定对话在两条流水线下的 token 级别完全相等。 建议做法: (a) 和 (c)。下一个代码块模拟一个漏掉了<obs>与</obs>包装 token 的示范流水线,并在其输出上训练。
问题:DPO 的 off-policy 退化。 现象: DPO 的训练损失和奖励准确率稳步改善,而策略自己的 rollout 却越来越差:格式错误的输出更多,回合更长或更怪,留出分数下降。 原因: 损失只在固定的偏好对上计算,而降低 可以通过把概率质量移到数据之外的序列上来实现,那里没有任何约束(15.4 节)。策略离生成这些偏好对的策略越远,偏好对对它当前行为的说明就越少。 可选方案: (a) 在被选回合上加 NLL 项,Iterative RPO 就是这样做的,并报告该项“至关重要”(“crucial”)(Pang et al., 2024),它为被选行为提供锚定。(b) 每隔几百步从当前策略重新生成偏好对(迭代式或在线 DPO),这需要付出采样和标注的成本。(c) 使用更大的 或更少的步数,这会同时限制漂移和学习。 建议做法: 始终采用 (a),策略移动较远时再加上 (b)。下一个代码块以 NLL 权重 1 重跑 15.4 节。
问题:数据混合与去重。 现象: 经过几轮 RFT 后,保留集被少数几个任务或完全相同的回合所主导,模型在它们上过拟合,而其他任务退步。 原因: 不同任务的成功率不同,所以对每个任务采样相同数量的回合,会返回大量容易成功的副本。确定性的策略会返回字面上完全相同的轨迹,这会成倍放大它们在 SFT 损失中的权重。 可选方案: (a) 按动作序列去重,数学推理上的 RFT 以不同路径的价值为这一做法提供了依据(Yuan et al., 2023)。(b) 限制每个任务保留的回合数。(c) 对困难任务采样更多回合。(d) 混入固定比例的示范或早期数据以防遗忘。 建议做法: (a) 加 (b),并在每一轮记录保留集中各任务类型的占比。下一个代码块测量 15.3 节第 1 轮的保留集。
range 和 compare 两个任务类型占原始集合的 72%,因为策略在它们上已经几乎是确定性的,一次又一次地返回同一个回合,而 minmax 的成功回合更多样。去重颠倒了这个顺序,minmax 以 0.43 成为占比最大的任务类型。两行都不是“正确的混合”:去重是一种带有自身偏差的重加权决策,而且它无法加入 init 任务类型,后者在两行中的占比都是 0。去重改变的是权重,而不是覆盖。
问题:在被投机利用的“成功”上做 SFT。
现象: RFT 保留集每轮都在增大,训练奖励趋近 1,而隐藏测试或人工评估却在下降。
原因: 过滤器就是奖励,而只检查智能体能看到的东西的奖励会接受漏洞利用(exploit)。使用 4.5 节的公开测试奖励时,每一个提交了的 hardcode_tests 回合都能通过过滤,随后过滤式克隆以 15.3 节中按 放大的步长忠实地复制它。
可选方案: (a) 用留出测试或隐藏测试过滤,代价是要编写它们。(b) 为已知的漏洞利用模式加一个检测器。(c) 每轮抽查一部分保留回合。
建议做法: 永远不要用策略能观测到的信号做过滤,并记录过滤器通过率与一项独立检查之间的差距。下一个代码块以公开测试为过滤器,从弱基座跑三轮 RFT。
hardcode_tests;到第三轮,这一比例增长到 64%(287 个中的 185 个)。过滤器自身的通过率攀升到 0.97,而隐藏测试通过率停留在 0.35 左右。策略修 bug 的能力并没有变差。它学到的是:漏洞利用是通过过滤器最可靠的方式。
小结
- 轨迹 SFT 最大化示范动作的对数似然。环境的概率不含参数,所以动作掩码是轨迹对数似然的精确梯度,而不是经验技巧。在 oracle 示范中,只有 19% 的预测 token 是动作。
- SFT 分别教授格式与技能。在无技能行为上训练的弱基座掌握了格式(每回合 0.06 个格式错误的调用),但技能只在猜测水平(0.14)。二十条 oracle 示范把它带到训练集约 0.99、留出集约 0.9,同时把动作熵从 0.25 压到 0.02 nats(本书测得)。
- 拒绝采样微调是奖励为 0/1 的策略梯度,步长除以成功率,并且没有负信号。专家迭代是过滤式行为克隆:两轮内从 0.15 升到 0.68,随后停滞在基座能解的 16 个任务之下,并复制了无法迁移的侥幸猜中(留出 0.15)。
- 面向智能体轨迹的 DPO 使用带掩码的动作对数概率,因为环境在策略/参考比值中被约掉。离线训练时,它把被拒对数概率压低了 45 nats,而格式错误的调用增加了三十多倍。在被选回合上加 NLL 项减轻了损害,但没有修复数据。
- 从同一个弱基座出发,oracle SFT 达到 0.99/0.93(训练/留出),先 SFT 后 RL 达到 0.96/0.95,RFT 为 0.74/0.15,只做 RL 在 60 步时为 0.36/0.30。冷启动的价值在于有信息量的组:它 70% 的留出组带有信号,而 SFT 训练更久之后只有 10%。
练习
- 证明 token 平均的 0/1 策略梯度损失与保留回合上 token 平均的 SFT 损失,其梯度之比恰好为(保留的动作 token 数)/(全部动作 token 数),并对序列平均的聚合方式验证这一点。哪种聚合方式会使 RFT 的有效步长依赖回合长度?
- 改变一个假设:把弱基座的 blind 与 random 行为换成只来自
random策略的行为。基座能解的任务集合会如何变化?专家迭代会收敛到什么? - 为 gym 实现 STaR 的合理化:对一轮中没有任何成功的任务,在编辑轮强制使用正确的操作来 rollout 当前模型,保留成功回合,并把被强制的 token 从损失中掩码掉。
init任务类型是否变得可学?结果是否仍是过滤式行为克隆? - 给 RFT 加上组基线:同时在失败回合上训练,每组权重为 。证明这在相差一个比例因子的意义下恢复了带基线的策略梯度,并测量它是否改变了 15.3 节的平台期。
- 改用第 20 步的 oracle-SFT 检查点而不是弱基座来构造 DPO 偏好对,训练 100 步,与 15.4 节比较格式错误的调用数和留出通过率。用这些偏好对中被选回合包含的内容来解释差异。
- 从第 10 步、第 20 步和第 40 步检查点分别测量先 SFT 后 RL 的做法,并画出最终留出通过率与起始时有信息量的组所占比例的关系。
- 设计评审:你的团队有 2,000 条编程智能体的人类示范、一个基于测试的验证器,以及在 RL 之前再做一个阶段的预算。论证应选择在示范上做 SFT、从 SFT 模型出发做 RFT,还是在(示范,模型失败)偏好对上做 DPO,并指出哪个监控面板指标能在一天之内告诉你这个选择错了。