Lecture 4 · 测试时计算:采样、投票、验证器与搜索 · Test-Time Compute: Sampling, Voting, Verifiers, and Search

Advanced Large Language Models Research Seminar · Lecture 04。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应 Maps to:CS486 课程描述的 “enhance LLM reasoning”——推理部分(第 3–7 讲)的第二讲:在推理时多花计算换更好的答案。 依据说明:CS486 没有公开的日程或讲义。本讲依据测试时计算的主要文献(Chen et al. 2021 的 pass@k、Cobbe et al. 2021 的验证器、Wang et al. 2023 的自洽性、Lightman et al. 2023 的过程监督、Gao et al. 2023 的奖励过度优化、Brown et al. 2024 的重复采样、Snell et al. 2024 的计算最优扩展等)来写。§2–§7 的实验是本讲义自己设计的,数字全部来自配套代码的实际输出。 配套代码 Code:code/lecture04/(PyTorch;3 个脚本 + 1 个模块;第一次运行约 4 分钟——并行训练 3 个验证器、采样约 4 万条推理链;之后每个脚本 20–70 秒) 预计阅读时间:4 小时(含运行代码)


0. 本讲导航 · How to read this lecture

0.1 学习目标 Learning goals

学完这一讲,你应该能够:

  1. 区分测试时计算的几种花法(并行采样 + 选择、逐步搜索、串行的长思维链、潜在空间里的循环),说出它们各自依赖什么。
  2. 区分覆盖率(pass@N:答案在不在样本里)和选择(能不能把它挑出来);会用无偏估计计算 pass@k;解释温度怎样在两者之间权衡。
  3. 解释多数投票(自洽性)什么时候有用、什么时候没用——它依赖”正确答案比任何一个错误答案都多”,而不是”正确率 > 50%“;知道系统性错误为什么投不掉。
  4. 说出结果奖励模型(ORM)和过程奖励模型(PRM)的区别;理解生成–验证的不对称;知道过程标签的定义决定了验证器能看见什么错误。
  5. 解释 best-of-N 的过度优化:为什么一个 AUC 0.95 的验证器在 N 增大时反而选得更差;“验证器也是模型,best-of-N 在主动搜索它的错误”。
  6. 设计验证器引导的逐步搜索,解释为什么只用验证器排序会失败、加上策略模型的概率才有效。
  7. 理解计算最优分配的思想,以及它为什么依赖难度估计。
  8. 在实验里分清”测试时计算”和”利用结构知识”(例如强制在第 k 步停下)带来的收益。

0.2 先修与本讲范围 Prerequisites & scope

默认你已经会 Assumed本讲不展开 Not covered
第 1 讲:cot_L2 和长度泛化失败(n = 12 的长题面)用强化学习训练模型生成长思维链(第 5 讲)
第 2 讲:AUC、配对比较、“一次运行不足以下结论”自我纠错与反思(第 7 讲)
第 3 讲:串行深度;循环模型”多想几轮”思维树、MCTS 等更复杂的搜索(第 9 讲)

0.3 本讲地图 Map

§1  为什么要在测试时花计算:o1 的"测试时扩展";四种花法;本讲的实验台
§2  采样与覆盖率:温度、pass@k 的无偏估计;覆盖率随 N 增长;成功率的两极分布          ← 代码 01
§3  投票(自洽性):什么时候有用;"错在哪里":查找 vs 何时停下;系统性错误投不掉       ← 代码 01
§4  验证器:ORM 与 PRM;过程标签的定义;生成–验证的不对称                              ← 代码 02
§5  best-of-N 与过度优化:没有空间时验证器无用;N 越大选得越差;骗过验证器的样本        ← 代码 02
§6  逐步搜索:只看验证器会失败;策略概率 + 验证器;计算量                               ← 代码 03
§7  计算最优分配:难度估计决定一切;结构知识 vs 测试时计算                              ← 代码 03
§8  串行 vs 并行:长思维链、预算强制;测试时计算 vs 更大的模型
§9  现状与开放问题
§10–14  小结、常见误区、练习、延伸阅读、下一讲预告

1. 为什么要在测试时花计算 · Why spend compute at test time

1.1 一条新的扩展轴

扩展律(scaling laws)讲的是训练时的计算:更大的模型、更多的数据、更多的训练 FLOPs 换来更低的损失。2024 年 9 月 OpenAI 发布 o1 时展示了另一条轴:测试时花的计算越多(让模型想得越久),准确率越高,而且大致随计算量的对数线性增长。这引出了一个实用的问题:给定一个模型,怎样在回答一个问题时最有效地花掉额外的计算?

1.2 四种花法

花法做什么依赖什么本课
并行采样 + 选择同一道题采样 N 次,投票或用验证器挑一个样本的多样性;一个选择机制本讲 §2–§5
逐步搜索每一步生成几个候选,用验证器打分,只保留好的能给”部分解答”打分的验证器本讲 §6;第 9 讲
串行地想得更久生成更长的思维链:检查、回溯、换一种方法模型会利用额外的长度(通常要靠 RL 训练)本讲 §8;第 5、6 讲
在潜在空间里循环同一组层多跑几轮循环结构和合适的训练第 3 讲 §6

第 3 讲的循环模型和第 1 讲的思维链都是”串行”地加深计算;本讲主要研究”并行”地多试几次、再加上”挑选”和”搜索”。

1.3 本讲的实验台

策略模型是第 1 讲的 cot_L2。它在训练分布(n ≤ 8)上已经 100% 正确,测试时计算无处发挥;所以我们把它放在它不完美的地方:n = 12 的长题面(第 1 讲 §4.4 的长度泛化失败),k = 3、4、5、6 各 50 道,共 200 道题。


2. 采样与覆盖率 · Sampling and coverage

2.1 温度与 pass@k

温度采样:每一步从 softmax⁡(logits/T)\operatorname{softmax}(\text{logits}/T) 里抽一个 token。T→0T \to 0 是贪心;T=1T = 1 按模型的原始概率;T>1T > 1 把分布压平,更可能抽到低概率的 token。

pass@k:从 kk 个样本里至少有一个正确的概率。Chen et al.(2021,Codex 论文)给出了一个无偏估计:对每道题采样 n≥kn \ge k 次,其中 cc 次正确,

pass@k=1−(n−ck)(nk)\text{pass@}k = 1 - \frac{\binom{n-c}{k}}{\binom{n}{k}}

(从 nn 个样本里不放回地挑 kk 个,全挑到错的概率是 (n−ck)/(nk)\binom{n-c}{k}/\binom{n}{k}。)它比”只看前 kk 个样本”方差小得多,因为用上了全部 nn 个样本。

2.2 覆盖率 vs 选择

两件事要分开:

  • 覆盖率(coverage)= pass@N:正确答案在不在这 N 个样本里。
  • 选择(selection):不知道正确答案时,能不能把它挑出来——靠投票、靠验证器。

Brown et al.(2024,Large Language Monkeys)发现,覆盖率随采样次数增长得很稳定,常常近似对数线性:在 SWE-bench Lite 上,一个开放的代码模型采样 1 次能解决 15.9% 的问题,采样 250 次时至少有一次解决的比例达到 56%——超过了当时单次尝试的最好成绩 43%。但他们也强调:在没有自动验证器(比如单元测试)的领域,选择才是瓶颈。

2.3 实验:温度与覆盖率

代码 01_sampling_and_coverage.py,每道题采样 32 次:

解码方式单次准确率(pass@1)pass@8pass@32多数投票@32
贪心29.5%———
温度 0.529.4%31.3%32.0%31.5%
温度 1.029.3%32.7%35.0%34.0%
温度 1.527.1%36.6%46.5%36.5%
  • 温度越高,单个样本越差(29.4% → 27.1%),但覆盖率越高(32.0% → 46.5%):样本更多样,“碰到”正确答案的机会更多。多样性和质量之间有权衡。
  • 投票只把覆盖率的一部分”挑”了出来:温度 1.5 时覆盖率 46.5%,投票只有 36.5%。

按跳数分开看(温度 1.0,“覆盖 / 投票”):

Nk = 3k = 4k = 5k = 6
184% / 84%0% / 0%32% / 32%1% / 0%
886% / 84%1% / 2%41% / 40%2% / 2%
3286% / 84%4% / 2%48% / 48%2% / 2%

奇怪的是 k=4k = 4 和 k=6k = 6 几乎是 0,比更”难”的 k=5k = 5 还差。§3.3 解释原因。

2.4 成功率的两极分布

每道题 32 个样本里对的比例(温度 1.0):

成功率0(从没对过)(0, 0.25](0.25, 0.5](0.5, 0.75](0.75, 1)1(每次都对)
题数比例65.0%4.5%1.0%1.5%5.5%22.5%

分布是两极化的:大部分题要么从来不对、要么每次都对,中间的题很少。测试时计算真正起作用的只有中间那部分。对”从没对过”的题,再多采样、再好的选择方法都没用——测试时计算放大的是模型已有的能力,不能凭空创造能力。(这和 Snell et al. 2024 的发现一致:测试时计算主要帮助”中等难度”的题,对模型根本不会的题帮助很小。)


3. 投票(自洽性) · Majority voting

3.1 自洽性

Wang et al.(ICLR 2023,Self-Consistency Improves Chain of Thought Reasoning):对一道题采样多条推理链,取最终答案的多数。想法是:正确的推理路径虽然各不相同,但会汇聚到同一个答案;错误的路径会散落到不同的答案上。它在数学和常识推理基准上带来了大幅提升,而且不需要任何额外的模型。

3.2 投票依赖什么

一个常见的误解是”投票要求正确率超过 50%“。实际上它要求的是正确答案的票数比任何一个错误答案都多(相对多数,plurality)。代码 01 演示 4:

  • 有 9 道题,正确答案的得票不到一半,却仍然胜出——因为错误答案足够分散。
  • 有 2 道题有正确的样本,却输给了一个集中的错误答案(这些题里正确答案平均得票 14.1%,得票最多的错误答案平均 73.4%)。

所以投票的效果取决于错误是否相关:如果模型在一道题上总是犯同一个错误,投票只会把这个错误放大。Chen et al.(2024,Are More LLM Calls All You Need?)进一步发现,投票的准确率随调用次数不一定单调:在一批难易混合的题上,容易的题越投越好,难的题(正确答案不是最多数的)越投越差。

3.3 错在哪里:查找,还是何时停下?

k=4k = 4 和 k=6k = 6 为什么几乎全错?代码 01 演示 5 把温度 1.0 的全部样本按失败类型分类:

跳数正确查找都对,但走过头了查找都对,但停早了有一步查找错了
k = 383.9%0.0%0.0%16.1%
k = 40.2%70.0%0.0%29.8%
k = 532.1%25.9%0.0%41.9%
k = 61.1%45.6%0.2%53.1%

k=4k = 4 时 70% 的样本每一步查找都是对的,只是没有在第 4 步停下:在比训练时长的题面上,模型”数不清”自己走了几步(很多时候一直走到长度上限也没写出 |)。这和第 1 讲 §4.4 的发现呼应:模型的”何时停下”和题面里的数字、题面的长度纠缠在一起,长度一变就乱了。

这种错误是系统性的——模型很确定地继续往下走——所以多采样、投票都救不了它。代码 03 的一个对照把这一点说得更清楚:只要强制贪心解码在第 kk 步停下,准确率就从 29.5% 跳到 84.5%。这不是测试时计算,而是利用了”要走 k 步”这条结构知识;但它提醒我们:在花大量计算之前,先弄清楚模型错在哪里。


4. 验证器 · Verifiers

4.1 ORM 与 PRM

验证器(verifier,也叫奖励模型 reward model)给一个解答打分,用来挑选或引导搜索。

  • 结果奖励模型(ORM,outcome reward model):只看最终答案对不对。Cobbe et al.(2021,GSM8K 论文)训练了一个验证器给候选解答打分、挑最高的,在小学数学题上的提升相当于把生成模型放大约 30 倍。
  • 过程奖励模型(PRM,process reward model):给推理的每一步打分。Lightman et al.(2023,Let’s Verify Step by Step)用人工标注的 80 万个步骤标签(PRM800K)训练 PRM,发现在 MATH 上用它做 best-of-N 明显优于 ORM(他们报告的最好结果是 MATH 一个代表性子集上的 78%)。
  • 自动的过程标签:人工标注每一步很贵。Math-Shepherd(Wang et al. 2024)等工作用”从这一步出发多次续写、看最终答案对的比例”来自动估计每一步的质量。我们的世界里每一步都可以被机械地检查,所以过程标签是精确的。

4.2 我们的三个验证器

代码 02_verifiers.py 训练三个验证器——结构和策略模型相同的 2 层小 Transformer,加一个”对 / 错”的输出头(104,385 个参数)。训练数据都是策略模型自己在 n ∈ [4, 12]、k ∈ [1, 7] 的题上以温度 1.0 采样的 8000 条推理链,用求解器自动标注:

验证器在哪里读出标签
ORM答案位置最终答案对不对
PRM推理链每个字母这一步的查找对不对(以上一步写的字母为起点)
PRM-full推理链每个字母 + `` 处查找对、并且还没超过 k 步;`` 处:在这里停下对不对

训练数据里错的步骤很少(PRM 约 2%),不处理的话验证器会学会”永远说对”——准确率 98%,毫无用处(编写时的原型就是这样)。所以用类别平衡的损失:错的样本按比例加权。

注意 PRM 和 PRM-full 的区别:§3.3 发现大量失败是”查找都对、只是走过了头”。PRM 的标签只看查找,这类推理链在它眼里每一步都对。过程监督能看见什么错误,取决于”过程”是怎样定义的。

4.3 生成–验证的不对称

验证器的质量(AUC,0.5 = 抛硬币,1 = 完美):

PRMPRM-fullORM
逐步 AUC,留出数据(n = 4–12)0.8290.9920.991(按答案)
逐步 AUC,n = 12 测试样本0.7350.9660.960(按答案)
整条推理链 AUC(区分最终对错),n = 12,温度 1.00.8520.9460.960

策略模型在 n = 12 的长题面上大多做错,而一个同样大小的验证器能以 0.95 左右的 AUC 认出这些错误。原因是任务本身的结构:生成推理链是串行的(第 ii 步依赖第 i−1i-1 步,第 1、3 讲);检查推理链的每一步”x>y 在不在题面里”可以对所有步骤并行完成——一次前向就够了。这就是很多测试时计算方法赖以成立的生成–验证不对称:验证比生成容易。(它并不总是成立:对开放式写作、对需要复现整个推理才能验证的问题,验证可能和生成一样难。)

只看查找的 PRM 整条链 AUC 只有 0.852:它看不出”走过头”的推理链。


5. best-of-N 与过度优化 · Best-of-N and over-optimization

5.1 没有空间时,验证器帮不上忙

温度 1.0、每道题 32 个样本,用前 N 个做选择:

选择方法N = 1N = 4N = 16N = 32
随机挑一个29.0%29.1%29.3%29.3%
多数投票29.0%31.0%33.0%34.0%
ORM 加权投票29.0%31.0%33.0%33.5%
ORM 选最高29.0%30.5%30.5%29.5%
PRM 选最高29.0%31.5%33.0%33.0%
PRM-full 选最高29.0%31.0%33.0%32.5%
覆盖率(上限)29.0%31.5%34.0%35.0%

覆盖率上限只有 35.0%,多数投票已经拿到了 34.0%——可挑的空间只有 1 个点。验证器偶尔把错的排在对的前面,就已经输给了投票。ORM 选最高甚至和随机挑一个差不多。我原本以为”好的验证器总比投票好”;在这个设定里不是。

5.2 N 越大,选得越差

温度 1.5 时覆盖率高得多:

选择方法N = 1N = 4N = 16N = 32
多数投票27.5%34.0%36.0%36.5%
ORM 加权投票27.5%31.0%34.5%35.0%
ORM 选最高27.5%27.0%19.5%14.0%
PRM 选最高27.5%31.0%28.0%24.0%
PRM-full 选最高27.5%32.0%30.0%24.0%
覆盖率(上限)27.5%35.5%41.5%46.5%

覆盖率从 27.5% 一路升到 46.5%,可是验证器”选最高”随 N 增大反而变差:ORM 从 27.0% 掉到 14.0%,PRM-full 从 32.0% 掉到 24.0%。同时多数投票和 ORM 加权投票稳步上升。

这就是 best-of-N 的过度优化。Gao, Schulman & Hilton(ICML 2023,Scaling Laws for Reward Model Overoptimization)系统地研究了这个现象:用一个代理奖励模型做 best-of-N,随着 N 增大,代理奖励一直上升,而真实奖励先升后降。直觉:

  • 验证器的 AUC(温度 1.5 时 ORM 是 0.925)描述的是平均的排序能力:随机挑一对正负样本,它大概率排对。
  • best-of-N 取的是 N 个样本里的最高分——它只关心分布的尾部。N 越大,越可能出现一个”恰好骗过验证器”的错误样本,它的分数比所有正确样本都高。

Stroebl et al.(2024,Inference Scaling fLaws)在代码生成上得到了类似的结论:验证器不完美(例如单元测试有漏洞)时,重复采样的收益会撞上一个天花板,再多的样本也补不回来。

5.3 什么样的样本骗过了验证器?

代码 02 演示 4:温度 1.5、N = 32 时,ORM 在 93 道”有正确样本”的题里选错了一部分,其中 10 道选中的是”推理链完全正确,但 | 后面的答案抄错了”,48 道是有一步查找错了。一个例子:

题面          o>g;e>o;c>k;d>e;k>h;i>j;l>c;a>l;m>i;g>m;h>d;j>a;3?i
正确          jal|l
ORM 选中      jal|e     (打分 0.984)

验证器是在温度 1.0 的样本上训练的,那里答案几乎总是等于推理链的最后一个字母——它从没学过检查这一点。高温采样恰好大量制造这种它没见过的样本,而”选最高分”会主动把它们找出来。

一般的教训:验证器也是一个模型,在它的训练分布之外会犯错;best-of-N 和搜索是在主动搜索它的错误。 这是 Goodhart 定律(“一个指标一旦变成优化目标,就不再是好指标”)在测试时计算里的版本,也是第 5 讲用 RL 优化奖励模型时”奖励黑客”的前身。

5.4 对策

  • 聚合而不是取最大:投票、加权投票对少数离群的高分样本不敏感(本实验中最稳健)。
  • 让验证器的训练数据覆盖测试时的采样方式:练习 3 用温度 1.5 的样本重新训练 ORM——温度 1.5、N = 32 时从 14.0% 升到 21.0%,但仍然随 N 下降、仍然不如投票。只靠”补数据”很难追上所有的分布外情况。
  • 限制 N、校准分数、用多个验证器的集成。
  • 改进验证器的目标:让它检查真正的正确性条件(这里是”答案等于最后一个字母”、“每一步查找正确”),而不只是拟合策略模型自己的错误分布(§6.2)。

6.1 思想

best-of-N 只在最后挑一次。逐步搜索在推理的每一步都让验证器看一眼:每一步从几条”束”出发各生成几个候选,用 PRM 给”到这一步为止的推理”打分,只保留最好的几条(束搜索)。更复杂的版本有前瞻搜索、蒙特卡洛树搜索(MCTS)、思维树(Tree of Thoughts,第 9 讲)。Snell et al.(2024)和 Wu et al.(2024,Inference Scaling Laws)都发现,在较小的计算预算下,PRM 引导的搜索比 best-of-N 更有效。

我们的束搜索(ttc_lab.beam_search):每一步在”16 个字母 + |”里取策略模型概率最高的 ee 个候选(| 表示停下,所以模型自己决定何时结束),候选的分数 = 之前的分数 + wπ⋅log⁡Pπ(候选)w_\pi \cdot \log P_\pi(\text{候选}) + wV⋅log⁡V(这一步)w_V \cdot \log V(\text{这一步}),保留最好的 bb 条。

6.2 实验:只看验证器会失败

代码 03_search_and_budget.py,同样 200 道 n = 12 的题:

方法准确率每题策略前向每题验证器打分
贪心29.5%9.80
贪心,强制走 k 步就停(结构知识)84.5%4.50
束搜索 4×4:只用策略概率44.5%31.00
束搜索 4×4:只用 PRM-full9.0%31.0124.0
束搜索 2×2:策略概率 + PRM-full48.0%16.032.0
束搜索 4×4:策略概率 + PRM-full55.5%31.0124.0
best-of-4(PRM-full 选最高)31.0%39.34
best-of-32(PRM-full 选最高)32.5%313.332

(“每题策略前向”:策略模型做了多少次”生成一个 token”的计算;best-of-N 那一行是生成的 token 总数。)

我第一次实现束搜索时只用 PRM-full 排序,结果是 9.0%——比贪心差得多。原因在演示 1b:

题目正确第一步的分数(中位数)错误第一步的分数(中位数)
n = 8,k = 41.0001.000
n = 12,k = 40.9970.995

PRM-full 完全分不出”错误的第一步”。它的训练数据是策略模型自己的样本,而策略模型几乎从不在第一步犯错——验证器从没见过”错误的第一步”,在那里是”瞎”的。它的高 AUC(§4.3)是在策略模型的样本上测的;而只用验证器排序的搜索会把策略模型几乎不会写出的字母也拿来比较,正好落进验证器的盲区。

加上策略模型的概率之后(55.5%),候选就被限制在”模型认为合理”的范围里,验证器只负责在其中挑——这和”从策略模型采样候选、再用 PRM 挑选”(Snell et al. 的做法)是同一个思路。在这个范围内,验证器的信号是可靠的,而且用在了每一步:束搜索 4×4 每题约 31 次策略前向就到了 55.5%,best-of-32 用了约 313 个 token 只有 32.5%。

编写时我还试过一个补救:给验证器的训练数据加入人为制造的离策略错误(把某一步换成随机字母,再从错的字母继续走)。它让 n = 8 的题上”错误的第一步”得分降到 0,但 n = 12 上仍然分不开,和策略概率结合后的束搜索也没有更好(54.5% vs 55.5%),所以没有放进正式代码。让验证器在离策略的候选上也可靠,是一个开放问题。

6.3 一个歪打正着?

只用策略概率的束搜索也比贪心好很多(44.5% vs 29.5%)。我的第一个猜测是:束搜索的分数是各步对数概率之和,偏爱更短的完整答案,恰好抵消了模型”走过头”的倾向。练习 5 检验了这个猜测:束搜索的答案确实更短(平均 5.0 步,贪心 7.9 步,真实平均 4.5 步),但按长度归一化之后准确率几乎不变(43.0%)——猜测基本被推翻。更可能的原因是:束搜索在每一步都把”停在这里”作为一个完整的候选保留下来比较,而贪心一旦错过停下的时机,就再也回不来了。


7. 计算最优分配 · Compute-optimal allocation

7.1 思想

Snell et al.(ICLR 2025,Scaling LLM Test-Time Compute Optimally Can Be More Effective than Scaling Parameters for Reasoning)的两个主要结论:

  1. 按难度分配:不同难度的题适合不同的测试时策略(容易的题适合让模型自己修改答案,难一些的题适合搜索),每道题花多少计算也应该不同。按估计的难度自适应地分配,比 best-of-N 基线的计算效率高 4 倍以上。
  2. 测试时计算 vs 更大的模型:在 FLOPs 相同的比较下,在小模型有一定成功率的题上,测试时计算可以胜过一个大 14 倍的模型;但在小模型几乎不会的难题上,换更大的模型更划算。

关键前提是难度估计:你得在花大量计算之前,先知道一道题”难但有希望”还是”没希望”。

7.2 实验:难度估计决定一切

代码 03 演示 2:温度 1.5,多数投票作答,每道题先采 4 个样本,然后比较三种分配方式:

平均每题预算平均分配按一致性自适应(前 4 个不一致的题加预算)按真实难度分配(上限:只给”有时对”的题加预算)
434.0%34.0%34.0%
835.0%33.5%35.5%
1636.0%32.5%37.5%

我预期”把预算集中给没把握的题”会更划算;结果它反而比平均分配更差。前 4 个样本意见不一致的 63 道题里,有 27 道 32 次采样一次都没对过——“不一致”既可能是”难但有希望”,也可能是”没希望”,额外的预算有很大一部分浪费在了后者身上。即使用”看不到的真实难度”来分配,收益也只有 0.5–1.5 个点:多数投票本身限制了能从额外样本里挑出多少(§5)。

教训:计算最优分配的价值完全取决于难度估计的质量,而”样本是否一致”这种廉价信号会把”难”和”不可能”混在一起。更好的难度估计(例如用验证器的置信度、或者训练一个专门的难度预测器)是这个方向的关键问题。

7.3 结构知识 vs 测试时计算

回到 §3.3 的对照:强制在第 k 步停下,贪心就从 29.5% 到 84.5%——远超本讲任何测试时计算方法(最好的束搜索 55.5%)。在真实问题里,对应的”结构知识”可能是:答案的格式约束、单元测试、类型检查、物理守恒律、已知的步骤数……把已知的结构放进解码过程(约束解码、工具、外部验证器——第 8、10 讲的 LLM-Modulo)常常比盲目地多采样更有效。


8. 串行 vs 并行,以及测试时计算 vs 更大的模型 · Sequential vs parallel

8.1 长思维链:串行地想得更久

o1、DeepSeek-R1 这类推理模型主要用的是串行的测试时计算:生成很长的思维链,里面有检查、回溯、换方法(第 5 讲讲怎样用 RL 训练出这种行为)。一个简单而有效的控制方法是 预算强制(budget forcing,Muennighoff et al. 2025,s1: Simple Test-Time Scaling):模型想停下时在末尾追加一个 “Wait”,让它继续想;想太久时强制截断。他们只用 1000 条精选的推理样本微调,就让一个 32B 模型在竞赛数学题上随思考长度稳定提升。

串行和并行各有优势:串行的思维链能利用之前的尝试(“刚才那个方法不行,换一个”),并行采样则彼此独立、容易并行化、不怕一条路走到黑。Snell et al. 发现两者可以组合,最优比例随题目难度变化。

8.2 测试时计算 vs 更大的模型

比较测试时计算和”换一个更大的模型”时,要用同样的推理 FLOPs:生成一个 token 的计算量大约正比于模型参数量,所以一个大 14 倍的模型生成 1 次的计算,大约相当于小模型生成 14 次。Wu et al.(ICLR 2025,Inference Scaling Laws)在数学题上发现,小模型配合先进的搜索算法,在很多计算预算下是”计算最优”的选择;Snell et al. 则强调这只在小模型有一定成功率的题上成立(§7.1)。和本讲 §2.4 的观察一致:测试时计算放大能力,不创造能力。


9. 现状与开放问题 · State of the field

  • 测试时计算已经是推理模型的标配:长思维链(串行)+ 多次采样投票(并行)+ 在有自动验证器的领域(代码、数学证明、形式化验证)用验证器选择。
  • 验证器的可靠性是瓶颈:本讲的过度优化、离策略盲区在真实系统里同样存在;在没有自动验证器的开放领域(写作、研究、规划),用 LLM 当验证器又回到了第 2 讲 LLM 当裁判的偏差问题。
  • 过程监督的定义:什么是”一步”?什么样的步骤标签最有用?自动生成的过程标签(基于续写的成功率)有噪声,也会把”策略模型的习惯”编码进去。
  • 难度估计与自适应计算:推理模型”想多久”由它自己决定,常常过度思考(简单题想太久)或思考不足(第 6 讲)。

研究问题:

  1. 怎样训练在离策略候选上也可靠的验证器(第 6.2 节的补救没有成功)?
  2. 能不能检测到 best-of-N 何时开始过度优化,并自动停止增加 N?
  3. 怎样获得廉价而准确的难度估计,区分”难但有希望”和”没希望”?
  4. 串行思维链和并行采样的最优组合怎样随任务变化?

10. 小结 · Summary

  1. 测试时计算的几种花法:并行采样 + 选择、逐步搜索、串行的长思维链、潜在空间的循环。
  2. 覆盖率(答案在不在样本里)和选择(能不能挑出来)是两件事;温度越高覆盖率越高、单个样本越差。
  3. 成功率是两极分布的:测试时计算只对”有时对”的题起作用,放大能力,不创造能力。
  4. 投票依赖”正确答案比任何一个错误答案都多”;系统性错误(这里是”走过头”)投不掉。
  5. 验证器:ORM 看结果,PRM 看过程;过程标签的定义决定验证器能看见什么错误;生成–验证的不对称让一个同样大小的验证器能认出策略模型写不对的推理链。
  6. 没有选择空间时,验证器帮不上忙;有空间时,“选最高”会随 N 变差(过度优化):AUC 描述平均排序,best-of-N 取的是尾部;best-of-N 在主动搜索验证器的错误。
  7. 聚合(投票、加权投票)比取最大稳健。
  8. 只用验证器排序的搜索会落进它的离策略盲区;策略概率 + 验证器的束搜索最好,而且计算量只有 best-of-32 的约十分之一。
  9. 计算最优分配取决于难度估计;廉价的”一致性”信号会把”难”和”不可能”混在一起。
  10. 先弄清楚模型错在哪里:一条结构知识(在第 k 步停下)胜过本讲所有的测试时计算方法。

11. 常见误区 · Common pitfalls

  1. “pass@N 很高,说明模型会做这道题。” pass@N 是覆盖率;没有可靠的选择机制,用户拿到的是 pass@1 或投票的结果。
  2. “温度越高越好 / 越低越好。” 温度在覆盖率和单个样本质量之间权衡;最优温度取决于选择方法(投票 vs 验证器)。
  3. “投票要求正确率超过 50%。” 它要求的是相对多数;错误答案集中时,正确率 40% 也会输。
  4. “验证器的 AUC 很高,所以 best-of-N 一定有效。” AUC 是平均排序;best-of-N 取最大值,对尾部敏感,N 大时会过度优化。
  5. “过程监督总比结果监督好。” 要看”过程”定义得对不对;只看查找的 PRM 看不见”走过头”。
  6. “N 越大越好。” 有不完美的验证器时,N 越大越可能选到骗过它的样本。
  7. “搜索时用验证器排序就行。” 验证器在策略模型很少产生的候选上可能是瞎的;要和策略的概率结合。
  8. “给没把握的题多分预算,总是更划算。” 只有当难度估计能区分”难”和”不可能”时才成立。
  9. “测试时计算能弥补模型能力的不足。” 它只能放大已有的能力;对模型从来做不对的题无效。

12. 练习 · Exercises

练习 1(pass@k)。一道题采样 10 次,2 次正确。用无偏估计算 pass@3。如果你只看”前 3 个样本里有没有对的”,这个估计的方差为什么更大?

参考答案:1−(83)/(103)=1−56/120≈0.5331 - \binom{8}{3}/\binom{10}{3} = 1 - 56/120 \approx 0.533。只看前 3 个样本时,结果是 0 或 1,取决于这 2 个正确样本恰好在不在前 3 个里;无偏估计等价于对”10 个里挑 3 个”的所有组合求平均,用上了全部 10 个样本的信息。

练习 2(投票与错误的相关性)。一道题,模型每次采样有 40% 的概率答对。三个样本做多数投票(平票时取第一个出现的答案,样本顺序随机)。(a) 如果错误答案总是同一个字母,投票正确的概率是多少?(b) 如果错误答案均匀地分布在 6 个不同的字母上呢?

参考答案:(a) 只有正确答案至少出现 2 次时才赢:3×0.42×0.6+0.43=0.288+0.064=0.3523 \times 0.4^2 \times 0.6 + 0.4^3 = 0.288 + 0.064 = 0.352——比单次采样的 0.4 还低。(b) 除了上面的 0.352,还有”正确答案出现 1 次、两个错误答案不同”的平票情况:概率 3×0.4×0.62=0.4323 \times 0.4 \times 0.6^2 = 0.432,两个错误答案不同的概率 5/65/6,平票时正确答案恰好最先出现的概率 1/31/3,贡献 0.432×5/6×1/3=0.120.432 \times 5/6 \times 1/3 = 0.12;合计 0.472>0.40.472 > 0.4。同样的单次准确率,投票是帮忙还是帮倒忙,取决于错误是否集中。

练习 3(让验证器见过高温样本)。§5.4 说”让验证器的训练数据覆盖测试时的采样方式”。用 ttc_lab.verifier_data(policy, 8000, 1, temperature=1.5) 生成温度 1.5 的训练数据,按 train_verifier 的方法训练一个新的 ORM,比较它和原来的 ORM 在温度 1.0、1.5 的样本上做 best-of-N 的结果。先预测。

参考答案(编写时在草稿目录里的实际运行,约 1.5 分钟):

测试样本验证器N = 4N = 16N = 32
温度 1.0ORM(温度 1.0 数据)30.5%30.5%29.5%
温度 1.0ORM(温度 1.5 数据)31.5%33.0%33.0%
温度 1.5ORM(温度 1.0 数据)27.0%19.5%14.0%
温度 1.5ORM(温度 1.5 数据)31.0%27.5%21.0%

用高温数据训练的 ORM 在两种温度下都更好,在温度 1.5 时过度优化明显减轻(14.0% → 21.0%);但它仍然随 N 下降,仍然不如多数投票(36.5%)。补数据能缩小分布差距,不能消除”取最大值会找到尾部错误”这个结构性问题。

练习 4(计算量怎样比较)。§6.2 的表格里,束搜索”每题验证器打分 124 次”,best-of-32 只有 32 次。为什么这两个数不能直接比较?你会怎样设计一个更公平的计算量口径?

参考答案要点:best-of-N 的一次打分是对一整条推理链做一次前向;束搜索的一次打分是对一个”部分推理链”做一次前向(序列更短),而且同一步的候选可以批量处理、共享前缀。更公平的口径是按处理的 token 数(或 FLOPs)计:策略模型和验证器各自处理了多少 token(有 KV cache 时,共享的前缀只算一次)。在真实系统里还要考虑墙钟时间(束搜索每一步都要等验证器,难以完全并行)。

练习 5(检验一个猜测)。§6.3 猜测”只用策略概率的束搜索更好,是因为它偏爱短答案”。设计并运行一个实验来检验。提示:比较束搜索和贪心答案的平均长度;再把束搜索的排序分数改成”按长度归一化”(除以步数),看准确率会不会掉回贪心的水平。

参考答案(编写时在草稿目录里的实际运行):贪心的推理链平均 7.9 步,束搜索 5.0 步(真实平均 4.5 步)——束搜索的答案确实更短。但按长度归一化之后,准确率是 43.0%(不归一化 44.5%),平均长度 5.1 步——几乎不变。所以”偏爱短答案”不是主要原因。更可能的解释:束搜索在每一步都把”停在这里”作为一个完整候选放进完成池,和其他完整候选比较总概率;贪心只看当前一步,一旦”继续走”的概率略高于”停下”,就错过了停下的时机、再也回不来。这是一个猜测被实验推翻、然后被修正的小例子。

练习 6(难度估计)。§7.2 的”按一致性自适应”失败了。设计一个更好的难度估计,能区分”难但有希望”和”没希望”。你会用什么信号?怎样在不知道正确答案的情况下验证它?

参考答案要点:候选信号:(1) 验证器对样本的最高分(有把握的题停下;所有样本分数都极低的题可能没希望,也停下);(2) 样本答案的分布形状——“没希望”的题里错误答案常常高度集中(模型很确定地犯同一个错,见 §3.2:输给集中的错误答案),“难但有希望”的题里答案更分散且包含少数正确样本;(3) 推理链的特征(例如是否写出了 |、长度是否合理)。验证:在一个有标签的开发集上训练 / 调整难度估计器,然后在独立的测试集上比较分配策略——不要用测试集来设计规则(第 2 讲的赢家的诅咒)。

练习 7(论文卡片)。用第 1 讲 §8.4 的论文卡片读 Snell et al.(2024)。重点回答:他们怎样估计难度?“比 best-of-N 高效 4 倍”是在什么条件下比较的?哪些结论你在本讲的实验里也看到了、哪些没有?

参考答案要点:难度按”模型在这道题上的 pass@1”分成若干档,可以用真实答案(神谕难度)或用验证器估计(预测难度)。“4 倍”是在同样的生成预算下、在数学题(MATH)上、和 best-of-N 基线比较的。本讲看到了:测试时计算主要帮助中等难度的题(§2.4);PRM 引导的搜索在小预算下比 best-of-N 好(§6.2)。没有看到:自适应分配的收益——我们廉价的难度估计(样本是否一致)不够好(§7.2)。他们也讨论了 PRM 在大预算的搜索下被”利用”的问题,和本讲 §5–§6 一致。


13. 延伸阅读 · Further reading

采样、覆盖率与投票

  • M. Chen et al. Evaluating Large Language Models Trained on Code(Codex,pass@k 的无偏估计). 2021.
  • X. Wang et al. Self-Consistency Improves Chain of Thought Reasoning in Language Models. ICLR 2023.
  • B. Brown et al. Large Language Monkeys: Scaling Inference Compute with Repeated Sampling. 2024.
  • L. Chen et al. Are More LLM Calls All You Need? Towards Scaling Laws of Compound Inference Systems. 2024.

验证器与过程监督

  • K. Cobbe et al. Training Verifiers to Solve Math Word Problems(GSM8K). 2021.
  • H. Lightman et al. Let’s Verify Step by Step. 2023(ICLR 2024).
  • P. Wang et al. Math-Shepherd: Verify and Reinforce LLMs Step-by-Step without Human Annotations. ACL 2024.

过度优化与验证器的局限

  • L. Gao, J. Schulman, J. Hilton. Scaling Laws for Reward Model Overoptimization. ICML 2023.
  • B. Stroebl, S. Kapoor, A. Narayanan. Inference Scaling fLaws: The Limits of LLM Resampling with Imperfect Verifiers. 2024.

搜索与计算最优

  • C. Snell et al. Scaling LLM Test-Time Compute Optimally Can Be More Effective than Scaling Parameters for Reasoning. ICLR 2025.
  • Y. Wu et al. Inference Scaling Laws: An Empirical Analysis of Compute-Optimal Inference for Problem-Solving with Language Models. ICLR 2025.
  • N. Muennighoff et al. s1: Simple Test-Time Scaling. 2025.
  • OpenAI. Learning to Reason with LLMs. 2024.

14. 下一讲预告 · Next lecture

第 5 讲:用强化学习训练推理——从 STaR 到 RLVR、GRPO 与 DeepSeek-R1。 本讲的所有方法都不改变模型,只是在测试时多试几次、挑一挑、搜一搜;它们放大已有的能力,但不能创造能力。下一讲问:能不能把”多试几次、挑出对的”变成训练信号,让模型本身变强?从 STaR(用自己做对的题训练自己)到 GRPO(同一道题的多个样本互相比较),再到 DeepSeek-R1-Zero 里自发出现的长思维链。我们会在指针追踪任务上亲手用 RL 训练一个模型——包括本讲发现的”走过头”问题能不能被奖励修好,以及第 2 讲、本讲反复出现的”优化一个不完美的信号”问题在 RL 里会变成什么(奖励黑客)。

← 返回课程目录