跳转至

推理时计算

推理时计算(test-time compute)是在参数固定时,为当前问题增加采样、反思、验证、搜索或工具执行预算。目标不是最大化生成 token,而是在给定成本下最大化正确完成概率:

\[ \max_{\pi} \mathbb E[\operatorname{utility}(y)] \quad \text{s.t.}\quad \mathbb E[\operatorname{cost}(\pi,x)]\le B. \]

单轨迹与多轨迹

Chain-of-Thought Prompting 展示了显式中间步骤可以改善部分算术、符号和常识推理任务。它改变的是生成轨迹;轨迹更长本身不保证更正确。

增加计算有两种基本方向:

  • 纵向:让单条轨迹更长,允许修正、工具调用或分层求解;
  • 横向:生成多条不同轨迹,再聚合或选择。

GLM-5 区分同一轮中的 interleaved thinking,以及跨轮是否保留先前 reasoning 与工具结果两种上下文协议

Figure 7 把“让模型多想一会儿”拆成两种状态机制。interleaved thinking 在同一轮内让 reasoning 与 tool call 交替;preserved thinking 决定下一轮是否继续携带先前的 reasoning、调用与结果。二者会同时改变 token 成本、可用证据和后续动作分布,因此 effort 评测必须记录上下文协议,而不只是最终输出长度。图源:GLM-5: from Vibe Coding to Agentic Engineering, Figure 7, p. 10;Copyright © 2026 GLM-5 Team,CC BY 4.0;已裁去原始 caption 与周围正文。

纵向依赖模型能否利用额外步骤,横向依赖样本多样性和选择器。两者都可能在错误模式高度相关时迅速饱和。

Self-consistency

Self-Consistency 从多个随机推理轨迹提取最终答案并投票:

\[ a^\star = \arg\max_a \sum_{i=1}^{N} \mathbf 1[ \operatorname{extract}(y_i)=a ]. \]

关键不在多数表决本身,而在两个接口:

  1. 采样应产生有意义的解法多样性;
  2. extract 应把数学等价、格式差异和单位表达归一为同一答案。

若答案是自由文本,可先聚类语义等价候选,再按簇大小与可信度选择;直接比较原始字符串会严重低估一致性。

聚合器应接收显式的答案归一函数,并把票数一起返回,便于实现预注册的停止阈值。下面还给出无放回 pass@\(k\);它只衡量候选覆盖,不能复用作最终选择准确率。

import math
from collections import Counter
def self_consistency(samples, normalize):
    answers = [normalize(sample) for sample in samples]
    if not answers or any(answer is None for answer in answers):
        raise ValueError("every sample needs an extractable answer")
    counts = Counter(answers)
    answer, votes = max(counts.items(), key=lambda item: (item[1], item[0]))
    return answer, votes, counts
def pass_at_k(n, correct, k):
    if not 0 <= correct <= n or not 1 <= k <= n:
        raise ValueError("invalid counts")
    if n - correct < k:
        return 1.
    return 1 - math.comb(n - correct, k) / math.comb(n, k)
normalize = lambda text: text.strip().lower().replace("4.0", "4")
answer, votes, counts = self_consistency(["4", " 4.0 ", "5"], normalize)
assert answer == "4" and votes == 2 and sum(counts.values()) == 3
assert pass_at_k(10, 0, 3) == 0
assert pass_at_k(10, 2, 9) == 1

平票规则在这里按规范化答案字典序固定,避免依赖并发完成顺序;实际系统可改用 verifier,但必须预先声明。生产归一器需要覆盖单位、数值容差、集合与代码语义,并把 parse failure、timeout 和取消分支与错误答案分开计数。

Best-of-\(N\)

给定 verifier \(v(x,y)\):

\[ y^\star = \arg\max_{1\le i\le N} v(x,y_i). \]

若单样本独立成功率为 \(p\),理想 oracle 选择器的覆盖率为

\[ P(\text{至少一次成功}) = 1-(1-p)^N. \]

这只是上界直觉。实际候选通常相关,且 verifier 会产生 false positive/false negative。真实 selected accuracy 由候选覆盖率与选择准确率共同决定。

Pass@\(k\) 与选择准确率

代码或可自动判定任务常报告 pass@\(k\)。若从 \(n\) 个样本中有 \(c\) 个正确,均匀无放回抽取 \(k\) 个至少一个正确的估计为

\[ \operatorname{pass@}k = 1- \frac{\binom{n-c}{k}}{\binom nk}. \]

pass@\(k\) 衡量候选集合覆盖,不代表系统能从中选出正确答案。还需报告:

\[ \operatorname{selection\ accuracy} = P(y^\star\text{ correct}\mid \mathcal Y\text{ contains a correct candidate}). \]

自适应预算

固定给每个问题 \(N\) 个样本会浪费容易样本,并低估困难样本。设第 \(i\) 个问题分配预算 \(B_i\),成功概率为 \(P_i(B_i)\):

\[ \max_{\{B_i\}} \sum_iP_i(B_i) \quad \text{s.t.}\quad \sum_iB_i\le B. \]

理想策略按边际收益

\[ \Delta_i(b) = P_i(b+\delta)-P_i(b) \]

分配下一单位预算。实际系统可用以下信号近似困难度或剩余收益:

  • 候选答案是否已经稳定一致;
  • verifier margin 是否足够大;
  • 轨迹间是否出现新策略而非措辞改写;
  • 工具执行是否提供了可判定反馈;
  • 已用 token、时间和错误次数;
  • 基础模型对任务类型的历史校准。

停止规则

常见停止条件包括:

  • 同一答案达到阈值票数;
  • top-1 与 top-2 verifier score 的 margin 足够大;
  • 连续若干扩展没有产生新答案或更高分;
  • 可执行检查通过;
  • 达到 token、时间、费用或工具调用上限;
  • 风险策略要求人工确认。

停止规则必须在评测前固定。观察到正确答案后再决定停止会引入 oracle 信息。

生成多样性

横向扩展需要区分“文本多样”与“解法多样”。可控制:

  • temperature 与 top-\(p\);
  • prompt 中要求不同分解或不同工具;
  • 不同草稿模型或角色;
  • 对已探索前缀施加去重;
  • 在搜索树的不同状态继续展开。

温度过低会重复同一错误;过高会增加无效或不可解析候选。应以正确候选覆盖率和错误相关性选择采样参数,而不是最大化表面差异。

Effort 是复合干预,不只是 token 上限

产品接口常把推理时计算压成 low、high、max 一类 effort 档位,但档位可能同时改变 context cap、system instruction、thinking envelope、采样次数、工具预算与停止规则。它不是一个跨模型天然可比的物理量。

DeepSeek-V4 公开了一个可拆解的例子:Non-think 直接进入答案,Think High 使用常规 thinking envelope,Think Max 还增加强调穷尽路径、边界与反例的 system instruction;评测时三档 context cap 分别为 8K、128K、384K。因而 High \(\rightarrow\) Max 的差异至少混合了 预算 与 elicitation,不能把分数增量全部归因于更多 token。

报告中的结果也说明 effort 不保证逐项单调:Flash 的 MMLU-Pro 在 Max 略低于 High,Pro 的 MCPAtlas Public 也略低于 High;HLE、竞赛代码、Apex 与 BrowseComp 则明显受益。合理的评测应把每个档位写成一份完整 intervention card:

项目 至少记录
生成预算 context cap、最大输出、平均实际 token、截断率
提示干预 system prompt、输出 envelope、工具说明
横向扩展 samples、并发宽度、selection/verifier
工具资源 调用上限、超时、搜索或执行环境
停止策略 正常终止、预算终止、early stop
代价 延迟、accelerator time、价格、失败重试

只有固定其余变量、单独改变一项时,才能估计该项的边际收益。若比较的是发布档位,就应诚实地把它当作端到端策略,而不是纯粹的“思考长度实验”。

成本模型

对并行采样,token 成本近似

\[ C_{\text{token}} = \sum_{i=1}^{N} \left( T_{\text{prefill},i} + T_{\text{decode},i} \right). \]

共享 prefix cache 可以减少重复 prefill 计算,但不会减少所有 decode 成本。并行执行降低 wall-clock,不降低总 accelerator time;串行自适应可以早停,却增加尾延迟。

比较方案时至少报告:

  • input、visible output 与隐藏 reasoning token;
  • prefix cache 是否复用;
  • 并行宽度与硬件数量;
  • verifier/工具额外成本;
  • 平均、P95 和 P99 最终答案延迟。

实现契约

  1. 候选 ID、随机种子和 sampling 参数可追踪;
  2. answer extractor 在生成前冻结版本;
  3. 等价答案归一规则覆盖单位、浮点、集合和代码;
  4. verifier 不读取参考答案或其他候选的真值;
  5. budget 同时约束 token、时间、费用和调用次数;
  6. 取消的分支停止生成并释放 cache;
  7. 并发失败和超时不会被静默当作错误答案;
  8. 评测按问题聚合,不能把同题多个样本当独立测试样本。

失效模式

  • 候选相关:\(N\) 增大但只是重复同一错误。
  • Verifier Goodhart:生成器学会提高评分而非正确性。
  • 长度偏置:长答案因形式完整获得更高分。
  • 答案解析错误:等价答案被拆分,错误字符串被误归一。
  • 预算反分配:难题耗尽预算,简单题仍固定过度采样。
  • 延迟隐藏:只报告并行 wall-clock,不报告总计算。
  • 测试泄漏:verifier 或 prompt 包含 benchmark 特征。
  • 不单调:更长轨迹产生自我干扰或错误修正。

验证矩阵

维度 对照
候选覆盖 pass@1、pass@\(k\)、unique answer 数
选择能力 oracle、随机选择、verifier、majority
相关性 同种采样与多策略采样
预算 固定 \(N\) 与自适应早停
成本 相同 token、时间、费用预算
稳健 extractor 扰动、超时、部分工具失败
校准 verifier score 分桶后的真实正确率
泛化 不同任务、难度与分布外切片

Scaling LLM Test-Time Compute Optimally 给出了按问题难度选择计算策略的实证框架;DeepSeek-R1 深读把可验证奖励、在线 RL、多阶段数据与蒸馏的公开证据拆开。对开放和闭源系统,都应把可观察的预算—质量曲线与未披露训练机制分开。

本节的边界与阅读顺序见推理与推理时计算总览,搜索与 verifier 的计算图见搜索与验证,底层采样见解码,紧凑实现与测试见测试时计算手撕实现。

Reference