train_snapshots 以每 10 步为一段调用 arl.train_rl,每段结束后保存一份冻结副本。每次调用都会重启 Adam 优化器并使用自己的随机种子,这与一次不间断的 80 步训练略有不同,但对本章要测量的东西没有影响。
17.1 通过率估计的是什么
评测估计的是策略在某个评测框架下的性质。评测框架 指权重之外的一切:任务集、提示模板、环境及其预算(轮数、编辑次数、上下文长度)、采样温度,以及成功判据。对任务 ,记 基准的 pass@1 是任务平均 。除非每个任务的回合(episode)数相同,否则它并不是“通过的回合所占比例”;它也不是权重单独具有的性质:改变 ,每个 都会改变。这里的成功判据是第 4 章为评测固定下来的那一个,与任何训练奖励无关:智能体提交了答案,并且所有隐藏测试都通过。 因此,一次评测的原始数据是每个任务的成功次数:在 个任务上各采样 个回合,记录成功的次数 。本章其余内容(pass@1、pass@、区间、配对检验)都是向量 的函数。sample_counts 用训练时的评测框架 cfg、通过训练所用的同一个 sample_groups 来产生它,这样模板、重命名、编辑预算、轮数预算和温度就不会悄无声息地出现差异。
under_cap 是 32 次中 17 次,speed 是 32 次中 1 次。单个数字掩盖了一个任务基本未被解决的事实;下面的统计会表明,决定训练后智能体得分不确定性的,正是这种异质性,而不是回合数。
17.2 pass@ 及其无偏估计量
编码系统通常允许多次尝试:在有验证器(verifier)的前提下,采样 个补丁并保留一个通过的。pass@ 是 次独立尝试中至少一次成功的概率,再对任务取平均: 它需要一个能挑出通过尝试的预言机,因此衡量的是覆盖率,即任何选择器所能达到的上界,而不是可部署的成功率(第 20 章将它与 Best@ 区分开)。 代入估计量是有偏的。 最直接的估计是用 替代 。当 时,映射 在 上严格凹,因此由 Jensen 不等式,只要 ,就有 :代入估计会系统性地低估 pass@, 越小、 越大,低估越严重。 无偏估计量。 Chen et al. (2021) 采样 个样本,并对它们提出另一个问题:如果从 个样本中无放回地均匀随机挑出 个,它们全部失败的概率是多少?若有 个成功,该概率为 ,于是 无偏性一行即可证明。对任意固定的 个样本下标集合 ,事件“ 中每个样本都失败”的概率为 ,因为样本相互独立。估计量中的失败项是该事件指示函数在全部 个集合 上的平均。期望是线性的,所以它的期望恰好是 。(它是一个 U 统计量,即由样本构造的最小方差无偏估计量。)无偏性对每个任务成立,对任务取平均后依然成立。 数值稳定的形式。 远在 变大之前,二项式系数就会让浮点数溢出: 有 600 位数字。把两个系数写成阶乘并约分, 当 时,这是 个落在 内的因子之积。当 时,每个 元子集都包含一个成功,估计值恰好为 1。17.3 置信区间
没有区间的通过率无法与任何东西比较。三种区间覆盖了本书遇到的情形。单个任务的二项区间
对 个成功概率为 的独立回合, 的标准误为 。Wald 区间 代入了 ,而它恰恰在智能体评测所处的区域失效:当 或 时宽度为零,靠近边界时覆盖不足。Wilson 区间不做代入,而是反转检验:它收集得分检验不会拒绝的所有 ,即 。两边平方得到关于 的二次方程,其根为 区间中心被拉向 1/2,宽度永不坍缩,这正是小 所需要的。自助法,以及该重采样哪个单元
**自助法(bootstrap)**通过在从观测数据中有放回重采样得到的数据上重新计算统计量,来估计该统计量的抽样分布。百分位区间取重算值的 和 分位数。这里首先要检查:被重采样的单元是否可以看作从目标总体中独立抽取。样本量过小等问题仍会影响区间的可靠性。bootstrap_ci 接收每个单元一个值;paired_bootstrap_diff 为两个系统重采样相同的单元。
bootstrap_ci 应用于每个任务的通过率。
哪种区间正确取决于问题,Miller (2024) 针对语言模型评测强调了这一点。“这个检查点在这 10 个任务上表现如何?”是以任务为条件的,只有回合采样是随机的。“它在类似的任务上会表现如何?”则把任务视为一个样本。讨论对新任务的泛化时,应回答第二个问题。一个总体已知的模拟可以把两者分开:任务通过率从 U 形的 Beta(0.4, 0.3) 分布中抽取(大多数任务几乎总是或几乎从不被解决,与智能体基准中的情形一样),共 10 个任务,每个任务 32 个回合。
17.4 比较两次训练
把两个数字区分开的随机性有两种。评测噪声来自从固定检查点采样回合,更多回合能缩小它。训练噪声来自训练的随机种子(任务顺序、采样的组、小批次顺序),它是训练配方的性质:同一配方的两次训练会停在不同的检查点。训练噪声是否应计入误差棒,取决于所做的论断。“检查点 B 优于检查点 A”是关于两个固定检查点的论断。“配方 B 优于配方 A”是关于检查点分布的论断,它的重复单元是随机种子。 我们用默认配方再训练三个随机种子,各 30 步——此时训练尚未饱和——并对四个第 30 步检查点各做两次相互独立的评测(每次 320 个回合)。重复评测衡量评测噪声;跨种子的离散则包含两种噪声。配对比较
当两个系统在相同任务上运行时,应逐任务比较。每个任务的差 消去了两个系统共享的任务难度,因此 协方差项在任务难度差异大时很大,而非配对比较恰恰丢掉了它。我们在相同的 10 个任务上比较第 60 步和第 80 步的检查点,并让两者使用同一个随机数生成器。两个相似的策略在相同随机数驱动下往往采样出相同的回合,这进一步提高了它们结果之间的相关性。这就是仿真中的公共随机数(common random numbers)技术;它可以降低配对差值的方差,也正因如此,当目标是测量评测噪声时(如上一个代码块),不能重复使用同一个生成器。需要多少任务或随机种子?
功效分析(power calculation)把比较反过来:给定我们想检测的效应 ,需要多少个单元?对显著性水平 、功效 的双侧检验, 个配对差(每单元标准差为 )的均值必须满足 ,因此 对两个独立组(非配对的任务,或各用一组种子的两个配方),两均值之差的每单元标准差为 ,公式给出的是每一组的大小。生产实践。 同样的算术决定了真实基准的规模。在 SWE-bench Verified 的 500 个任务上,若每个任务尝试一次,通过率在 0.4 附近时的二项标准误约为 0.022,因此两次独立的单次尝试运行之差的标准误约为 0.031,2 个百分点的差距完全落在其内。逐任务配对、每任务多次尝试(如 DeepSWE 取 16 次运行的平均,见第 20 章),以及多个训练种子,是可用的手段。这是由二项公式算出的结果,不是测量。
17.5 评测框架定义了这个数字
评测框架选择是指权重之外任何会改变 的设置。如果训练与评测之间、或被比较的两次评测之间有一项不同,那么比较测到的就是评测框架。我们在训练评测框架以及七种单字段改动下评测同样的两个检查点。贪心评测与采样评测
贪心解码(温度 0)评测的是每一步都选择最高概率 token 时的表现;这不保证整段序列的概率全局最高。在训练温度下采样,评测的才是训练所优化的随机策略,也是使用相同采样配置的 best-of- 系统会采样的分布。二者回答不同的问题,逐任务计数显示了区别所在。compare 和 zero 任务上、且只对部分函数名是对的;而它的采样行为则分散在全部五种修复操作上。对训练后的智能体,贪心解码消除了大多数任务上的残余错误(under_cap 从 25 升到 30),并把训练后智能体偶尔能成功的 speed 变成了彻底的零。对于贪心解码的部署,贪心 pass@1 是正确的数字。对于采样部署或 best-of- 系统,它是错误的数字,而且它恰好掩盖了 17.7 节 pass@ 之争所关注的那些低概率成功。本书的默认做法是在训练温度下做采样评测,并报告所用温度。
17.6 留出划分与泄漏
留出集回答的是一个泛化问题,而这个问题取决于留出了什么。第 4 章的默认划分留出的是变体:每种缺陷类型六个变体中的两个,函数名、常数和测试都不同。它衡量的是智能体能否在训练过的 bug 的不同表面形式之间泛化。留出一种缺陷类型,问的则是它能否泛化到一类从未因修复而获得奖励的 bug。我们在zero(缺少除零保护)以外的四种缺陷类型上训练 30 步,然后在全部六个 zero 任务以及其他缺陷类型的八个留出变体上评测。
build_tokenizer(make_tasks('all'))),因此留出任务中的词都有嵌入;一个从未在训练中出现的词保持随机初始化,这对答案无害,但属于词表泄漏。基座智能体只在训练任务上做了行为克隆。第三条渠道就是第 9 章练习 3 指出的那一条:randomize_names 从全部 30 个函数名中抽取,所以留出任务的函数名会作为随机名字出现在训练回合中。下面的代码块测量这种情况出现的频率,然后把重命名池限制为只含训练函数名或只含留出函数名进行评测,以检验它是否有影响。
17.7 强化学习是否让分布变窄?TinyAgent 上的 pass@
第 20 章总结了一场公开争论。Yue et al. (2025) 报告,在数学基准上,经 RLVR 训练的模型在小 时占优,但“base models achieve a higher pass@k score when k is large”(大 时基座模型的 pass@k 更高),并将此解读为强化学习只是让基座模型的分布更尖锐,而非增加了能力;ProRL (2025) 则报告,在加入参考策略重置、训练更长时间后得到了相反的结论。两者都是作者在数学任务和大模型上报告的结果,本书没有复现。用本章的工具,这项测量本身并不昂贵:用每个任务相同的 64 个回合,在留出任务上计算基座智能体和强化学习检查点的无偏 pass@。我们加上一条参考曲线:在五种修复操作中均匀随机猜测,每次尝试的通过概率为 0.2。speed。基座智能体在 64 个回合中解决它 10 次,20 步检查点 13 次,80 步检查点 3 次。因此 80 步检查点在 speed 上的 pass@32 约为 0.88,而基座智能体基本为 1,大 处的全部差距都来自这一个任务。训练在这个任务上做了什么?
speed 同时包含乘法和整数除法;它的 bug 是缺少除零保护。基座智能体在它上面的第一次编辑分散在全部六种编辑操作上,add_zero_guard 出现在 64 个回合中的 13 个。训练后的智能体在 64 个回合中有 59 次使用 fix_comparison,用对操作的只有 4 次。在第 20 步到第 80 步之间的某个时候,策略从源码到操作的映射对这个任务变得自信而错误,正确操作的概率从约 0.2 降到了 0.06。这正是那场争论中精确意义上的变窄:强化学习把概率集中到其他经验所奖励的行为上,并从一个偶尔有效的替代方案中拿走了大部分概率质量。图 17.3 展示了平均曲线和 speed 任务。
证据。 本书测得:一个 158k 参数模型的一次 80 步 GRPO 训练,10 个留出任务,每个检查点每个任务 64 个回合。文献报告:Yue et al. 与 ProRL(数学任务、大模型;见第 20 章)。这个小规模结果说明了测量方法和一种变窄机制;它不能作为这场争论中任何一方在大规模上的证据。
17.8 不碰测试集地选择检查点
每一个通过查看数字做出的选择,都会把那个数字变成训练信号。选择测试分数最高的检查点、再报告这个分数,报告的是多个带噪声估计中的最大值,它是向上有偏的:这就是赢家诅咒(winner’s curse)。若有 个真实水平相同的检查点、评测噪声为 ,期望最大值约为 ,当 时为 。解决办法与超参数相同:把留出任务划分为用于每一个决策的验证集,以及只在最终报告时评测一次的测试集。只有 10 个留出任务,我们只能五五分,每一侧包含每种缺陷类型的一个变体。speed,验证那一半不包含:每个划分只有五个任务时,划分的构成决定了水平。按验证选择会选中第 80 步,其测试分数 0.744 对所选检查点是无偏估计,因为测试集没有参与选择。按测试选择会选中第 70 步,报告 0.762。从一次评测无法看出这个具体数字是否被高估。赢家诅咒是关于这一选择流程期望值的陈述,所以我们通过重复这个流程来测量它:做 10 次小规模测试评测(每个任务 8 个回合),每次用来挑选一个检查点,再用另外 9 次没有参与挑选的评测给所选检查点打分。
17.9 实践中的设计问题
问题:评测噪声大于效应。 现象: 消融表中各组相差几个百分点,周期性评测曲线呈锯齿状,或者一次“胜出”在重跑后消失。 原因: 在正确单元上计算的评测标准误(17.3 节)与效应一样大,而比较是非配对或没有重复的。train_rl的周期性eval_pass每个任务用 4 个回合,在留出集上共 40 个;下面的代码块以这个规模对同一个检查点重复评测八次。 可选方案: (a) 增加每个任务的回合数,这在任务项 占主导之前有效;(b) 增加任务数,这是减小该项的唯一办法;(c) 在相同任务上做配对比较,比较检查点时使用公共随机数;(d) 当论断针对配方时,增加训练种子数。 建议做法: 在做消融之前,先从一次试点评测计算配对标准差,并用required_units确定规模;在任务级别报告区间。
问题:评测框架漂移。 现象: 同一检查点的数字在两个监控面板之间不一致,复现论文时差了几个百分点,或者改进恰好出现在评测代码改动之时。 原因: 依赖于评测框架,而某个评测框架字段不同了:温度、预算、模板、环境规则或成功判据(17.5 节)。当被改动的字段是弱策略可以利用的字段时,漂移最危险。下面的代码块运行一个没有技能的策略——它按固定顺序施加三种操作然后提交——分别在训练评测框架下和允许无限编辑的普通BugFixEnv下运行。第 15 章的pass_rate辅助函数在普通环境中评测,这与第 15 章自己的训练设置一致,但与第 9 章起的默认设置不一致,所以两者的数字不能直接比较。 可选方案: (a) 从训练配置对象构建评测,就像sample_counts(..., cfg)那样,使每个字段在构造上就是共享的;(b) 为评测框架加版本号,并随每个数字一起记录;(c) 让一个固定的参考策略(脚本策略或一个冻结的检查点)经过每一次评测框架改动,并要求它的数字保持不变。 建议做法: (a) 和 (c)。一个分数已知的金丝雀策略能捕捉到的漂移,无论怎样审视被评测的模型都发现不了。
问题:评测复用了训练奖励。 现象: 训练奖励和评测数字一起上升,而背后的行为并不是预期的技能。 原因: 当评测用策略被优化所针对的同一个函数来计算成功时,它会继承优化器找到的每一个缺陷:可以被特判的公开测试、可以被讨好的评判模型、不解决任何问题也能满足的格式检查(第 11 章)。下面的代码块让第 4 章的脚本化投机策略(它对公开测试的输入做特判)分别在公开测试奖励和隐藏测试奖励下运行 gym。 可选方案: (a) 用比训练奖励更强的留出验证器评测(隐藏测试、更多测试、不同的测试生成器);(b) 人工或借助行为统计抽查通过的轨迹;(c) 把训练奖励与留出验证器之间的差距作为监控面板指标来跟踪。 建议做法: 始终采用 (a),并以 (c) 作为警报。无论cfg.reward是什么,sample_counts都用隐藏测试打分,所以即使强化学习是在可投机的奖励上训练的,评测仍然是诚实的。
问题:用测试集选择检查点。 现象: 报告的测试分数再也没有被重现过,无论是重跑、新的测试集还是用户。 原因: 每一个通过查看测试数字做出的决策(检查点、解码温度、提示、报告哪一次训练)都是在噪声上做选择,报告的最大值大约向上偏 (17.8 节中为 0.03 到 0.04)。 可选方案: (a) 用验证集做所有决策,测试集只用一次;(b) 任务太少无法划分时,报告预先登记的最终检查点,而不是最好的那个;(c) 报告在测试集上评测过的模型数量,让读者判断选择偏差可能有多大。 建议做法: (a),并在测试评测之前写下选择规则。对于长期使用的基准,要定期更新测试集,因为即使每个决策都很谨慎,团队累积的决策仍会泄漏进去。
小结
- 评测估计的是 ,即某个评测框架下每个任务的成功概率,其原始数据是每个任务的成功次数。
sample_counts用训练配置生成这些数据,并且无论训练奖励是什么,都用隐藏测试打分。 - pass@ 需要无偏估计量 ,以乘积形式计算;在 时,代入估计 把 pass@5 低估了 0.04 到 0.08。
- 同一任务的回合是相关的。对训练后智能体这样异质的任务,设计效应为 20,任务级区间的宽度是回合级区间的 4.4 倍;在模拟评测中,对回合重采样只在 38% 的情况下覆盖总体均值。单个任务用 Wilson 区间,基准用任务级自助法。
- 在相同任务上比较:配对把检查点差异的标准误从 0.132 降到 0.023。用功效分析确定比较的规模(检测 5 个百分点需要 17 个配对任务,非配对时每组 533 个),并用相互独立的评测测量种子方差;在这里第 30 步时,它与评测噪声无法区分。
- 评测框架的一个字段就让训练后智能体的留出通过率最多变化 0.13,一个更宽松的环境让无技能策略的分数变为三倍。留出变体(0.93)和留出类型(0.03)对同一个检查点给出了相反的结论。
- 基座智能体在 时反超 80 步检查点(0.998 对 0.988),原因是强化学习把一个任务上正确操作的出现次数从 64 次中的 13 次压到了 4 次;当 足够大时,五种操作空间中的猜测者能覆盖一切。在测试集上做选择把报告分数抬高了约 0.03;应在验证集上决策,在测试集上只报告一次。
练习
- 利用 是完备充分统计量这一事实,证明 是基于 个伯努利样本的 的最小方差无偏估计量。然后通过模拟计算 、、 时它的方差,并与 时比较。
- 改变一个假设:以每个任务 个回合、 最大到 128 重跑 17.7 节,并加入第 40 步检查点。交叉点会移动吗?除
speed之外,是否还有其他任务失去覆盖?绘制所有检查点的逐任务成功次数,找出speed开始下降的步数。 - 实现任务级自助法的贝叶斯替代方案:每个任务一个 Beta 先验,任务通过率采用层次模型,在 torch 中用简单的 Gibbs 采样或重要性采样求解。在 17.1 节的计数上,将其区间与
bootstrap_ci比较。 - 对五种缺陷类型中的每一个,重复 17.6 节的留出类型实验。跌到基座智能体猜测率以下的现象是否普遍?把结果与未见过的缺陷类型回合开始时第一次编辑的熵联系起来(第 10 章)。
- 编写一个评测框架金丝雀:一个函数,让一组固定的脚本策略(
oracle、blind、17.9 节的stacker)通过make_env(cfg)运行,并断言它们的通过率。它能检测出RLConfig中哪些字段的改动,又会漏掉哪些? - 公共随机数:比较第 60 步与第 80 步差异的配对标准误,一种是两个检查点使用同一个生成器,另一种是使用不同的生成器。用 17.4 节的方差公式解释其差别。
- 设计评审:一位同事报告,一种新的优势估计量把 SWE-bench Verified 的 pass@1 从 41.0% 提升到 43.4%,每组只有一次训练、每个任务只采样一次,而且检查点是“最后五个中最好的那个”。运用本章内容,列出你在接受这一论断之前会要求补充的内容,分别在非配对和配对分析下估计所报告差异的标准误,并说明你会要求多少个随机种子和多少次采样。