第4章 推理期扩展
资料说明:本章依据已核验的原始论文、官方文档和中文教材展开,来源—论点映射先于本轮扩写建立;重点算法于 2026 年 11 月 1 日续核。数值手算、预算表和任务案例均为本书教学构造,非服务实测。
后训练可以把模型塑造成更守指令的协作组件,却不能保证它在复杂问题中一次生成就走对路径。大模型的“推理”不是一个单独的神经网络模块,而是模型、提示、搜索、验证器和推理预算共同形成的过程。自回归模型每次只预测下一个 token,但复杂任务需要先拆解问题、保留中间状态、比较候选路径、检查结果,再决定是否继续。于是,推理算法要回答两个问题:如何从概率分布中生成更好的轨迹,如何用额外计算换取更高的任务成功率。
本章的判断是:推理期扩展以时间、token 和验证成本交换复杂任务成功率;它提升的是候选答案质量,而不是替代事实来源、权限控制或 Serving 可靠性。后训练改变默认行为,推理期扩展决定当前任务如何使用计算,两者必须在任务可验证性和预算约束下协同选择。
本章把“推理能力”和“推理服务”分开。采样、解码、CoT、Self-Consistency、Tree of Thoughts、推理期验证、test-time scaling 和 speculative decoding 属于算法层;RLVR 和验证器训练见第 3 章 3.6 节,GPU 显存、KV cache 分页、continuous batching 和分布式 serving 见第 10 章“推理服务与资源调度”。本章说明这些能力的接口,但不把训练方法或系统吞吐优化冒充推理期算法。
4.1 从一次生成到推理期计算
flowchart LR
A["输入与固定模型"] --> B["产生候选"]
B --> C["比较或验证"]
C --> D{"预算与目标"}
D -->|继续| B
D -->|完成| E["输出与证据"]
\(x\) 作为输入时,语言模型定义一个条件分布:
\[ P(y\mid x)=\prod_{t=1}^{T}P(y_t\mid x,y_{<t}). \]
常见的基础生成策略可以只取最大概率 token,或者用 beam search 在有限候选中寻找高概率序列。GPT-3 展示了模型可以通过上下文示例执行多种任务 [1],但也暴露了一个事实:单次 greedy 生成的局部最优,不一定对应全局正确答案。模型可能在早期选错一个前提,后续所有 token 都流畅地围绕错误继续。
Chain-of-Thought 通过示范中间步骤,让模型把复杂答案展开成一串可观察的推理文本 [2]。Zero-shot CoT 进一步发现,简单的“逐步思考”提示也能诱导某些模型生成中间过程 [3]。Self-Consistency 不再只取一条思路,而是独立采样多条推理轨迹,再对最终答案做多数投票 [4]。这尝试缓解单次采样的偶然失败,但成本随样本数增加。
随后出现了显式搜索、工具调用和验证器:Tree of Thoughts 把中间思路组织成可回溯的树 [5],Graph of Thoughts 允许不同思路合并和循环 [6],ReAct 把推理与行动交替连接到外部环境 [7]。在数学、代码和形式化任务中,结果验证器和过程验证器让“好思路”不再完全依赖主观评价 [8][9]。
传统规模化主要增加参数和训练 token,reasoning model 则在推理时增加计算预算。模型可以生成更多 reasoning token、采样多个候选、调用验证器、进行搜索或重试。DeepSeek-R1 把强化学习与可验证奖励结合,展示了模型通过更长推理和自我反思提升数学、代码等任务的路线 [10]。
Test-time scaling 的关键不是“思考越长越好”,而是把预算分配给有价值的分支。Snell 等人的研究指出,在一定条件下,合理增加推理时计算可能比增加模型参数更有效 [11]。新限制也随之出现:推理成本、延迟、错误累积、验证器漏洞和停止条件,成为算法与产品必须共同设计的对象。
把生成器、选择器与事实来源分开
历史上的方法名称很多,但一次请求中的变化可以归到三个位置。第一处是候选分布:改变提示、提供中间状态或根据反馈修订,可能让模型更容易提出有效答案。第二处是候选集合:固定模型和提示,采样更多完整轨迹,或在某个中间状态分叉,增加可供比较的路径。第三处是选择规则:使用投票、奖励模型或程序检查,从已有候选中挑选输出。三处都可能消耗计算,却不是同一种改进。Snell 等人的 proposer 与 verifier 视角帮助区分候选提出与候选选择;本书进一步把外部事实获取单独列出,以免把新增证据的收益算成纯搜索收益。[11]
例如某道教学题要求根据两段条款计算应付金额。生成器可能没有提出“优惠不可叠加”的解释,也可能已经提出正确解释而被选择器错选。前一种情况下,多候选或更好的分解有机会增加覆盖;后一种情况下,仅增加同质量候选未必有用,需要修正判断条件。如果输入根本没有提供优惠条款,两个组件都不能可靠地凭计算恢复未知业务事实,应先补材料。这里的分类由输入、候选和选择结果决定,不依赖猜测模型是否在“认真思考”。
设事件 \(G\) 表示候选集合中至少存在一个有效答案,事件 \(S\) 表示选择器最终挑中有效答案。如果系统只允许从候选中选输出,则 \(S\) 必须以 \(G\) 为前提,因而有 \(P(S)=P(G)P(S\mid G)\)。这是本书用于分析流水线的概率恒等式,不是假设两个事件独立。它提示我们分别报告候选覆盖与条件选择成功率:只给最后准确率,会把提出能力与辨别能力混成一个数字。
用一组教学假设可以看到这种混淆。某策略在一百道题中有八十道生成过正确候选,却只在其中六十道选中,最终成功率为六成;另一策略只覆盖七十道,但选中六十三道,最终成功率更高。前者更需要检查排序器,后者更需要提高生成覆盖。这里的一百道、八十道等均是演算用计数,并非实测。若选择器还可以改写答案,它本身又成为新的生成阶段,此时要把改写后的集合与检查单独记账,不能继续套用“只能选择”的简化定义。
同样的分解能够澄清几个常被混用的指标。单次成功率描述一次完整策略的结果;至少一个候选通过的比例描述集合覆盖;最佳候选得分描述选择器目标;被最终接纳的比例还受拒答与输出约束影响。高覆盖不保证高选择准确率,高接纳也不保证低错误率。比较论文或服务实验时,要先问被统计的事件是什么,再问采样次数是否相同。
| 改动位置 | 教学操作 | 可直接观察的对象 | 不能直接推出的结论 |
|---|---|---|---|
| 候选分布 | 加入可检验的子问题与反馈 | 有效候选出现频率 | 权重已永久更新 |
| 候选集合 | 独立采样或局部分叉 | 覆盖、重复与分支成本 | 多数一定真实 |
| 选择规则 | 投票、评分或执行测试 | 条件选择成功率 | 测试之外全部正确 |
| 信息条件 | 查询新版本文档或工具状态 | 新增证据与适用范围 | 模型结构更强 |
| 执行方式 | 保分布的投机采样 | 延迟与分布一致性 | 答案质量自然提升 |
推理期策略还应区分串行和并行计算。延长同一条轨迹,让后一步使用前一步的结果,增加的是串行依赖;同时生成多条完整轨迹,主要增加并行候选宽度。两者消耗相同总 token,也可能有不同墙钟延迟、上下文成本和错误传播方式。一条错误中间状态可能影响其全部后续,而多个独立候选保留了另起路径的机会;但并行候选之间没有自动共享后来发现的反例。这些差别来自依赖图,不能通过一个“推理预算”标量完全表达。
还要把任务目标与语言模型分数分开。模型分布衡量的是在其训练和条件输入下某段文字有多可能,任务验收衡量的是这段文字是否满足题目约束。二者可以相关,但通常不相同。对事实任务,常见表达可能陈旧;对程序任务,常见代码模板可能漏掉边界;对开放创作,最常见的文本又可能缺少新意。搜索算法如果只改善了自身分数,必须进一步证明这种改善能转化为目标任务的收益。
4.2 概率分布与可控解码
flowchart LR A["词表分数"] --> B["温度变换"] B --> C["语法可行集再截尾"] C --> D["归一化与选择"] D --> E["更新文本和解析状态"] E --> A
Logits、softmax 与温度
模型在每一步输出词表大小的 logits \(z_i\)。温度采样先把 logits 除以 \(\tau\),再计算:
\[ p_i=\frac{\exp(z_i/\tau)}{\sum_j\exp(z_j/\tau)}. \]
当 \(0<\tau<1\) 时,概率分布更尖锐,输出稳定但可能重复;当 \(\tau>1\) 时,低概率 token 获得更多机会,输出更有多样性但错误率可能上升。温度不是“创造力旋钮”这么简单,它改变的是整个生成分布,可能影响事实、格式、代码和安全边界。
采样实现还要处理数值稳定性,通常先减去最大 logit 再做 softmax;低温下要避免概率下溢,高温下要避免尾部噪声占据过多质量。中文、代码和结构化输出的 token 分布不同,不能用一套参数覆盖所有任务。
温度对分布的影响可以量化。设两个候选的 logit 差为 \(\Delta z\),温度 \(\tau\) 下它们的概率比为 \(\exp(\Delta z/\tau)\)。温度实际上是在放大或压缩 logit 差:\(\tau<1\) 让差距放大,最高概率项迅速主导;\(\tau>1\) 让差距压缩,尾部候选进入采样范围。这解释了为什么温度改变的不只是“多样性”,还包括概率集中程度。正温度不改变 logit 排序,因而不改变理想 argmax;高温压缩概率差距,但不使有限温度下不同分数严格等概率。
先把温度作用手算一次。假设有限词表只有三个候选,logits 为 \((\log 4,\log 2,0)\)。温度为一时,概率为 \((4/7,2/7,1/7)\);温度减到二分之一,相当于对原指数项平方,得到 \((16/21,4/21,1/21)\)。候选的次序没有改变,但第一项相对第三项的概率比从四变为十六。若第一项恰是事实错误的续写,低温只会更集中地选择这个错误,不能把集中程度解释成正确率。
温度与熵之间还可给出一个有限支持集上的推导。记 \(\beta=1/\tau\)、\(Z=\sum_i e^{\beta z_i}\),则熵 \(H=\log Z-\beta E_p[z]\)。由 \(dE_p[z]/d\beta=\operatorname{Var}_p(z)\),得到 \(dH/d\tau=\operatorname{Var}_p(z)/\tau^3\geq0\)。这里固定的是同一组 logits 和可用项,变化的只有正温度;它不描述生成下一 token 后,随着前缀改变而产生的新分布,也不证明某任务的质量随熵单调变化。
Greedy 每步选择最高概率token;固定数值实现与并列裁决时选择规则确定,适合部分代码补全和固定格式,但容易陷入重复或早期错误。Top-k 只保留概率最高的 k 个 token,在截尾后重新归一化的有限候选中采样,Fan等在故事生成中采用过这种方案[12];k 太小接近贪心,k 太大又会引入低质量尾部。Top-p,也称 nucleus sampling,保留累计概率达到 p 的最小 token 集合,候选数量随分布形状动态变化 [13]。
Top-p 适合语言模型概率分布变化较大的自然语言生成,但不是质量保证。一个错误前提可能拥有很高概率,top-p 只会在错误附近增加多样性。代码、SQL、JSON 和函数调用最好结合语法约束、schema 或验证器;单纯调低 temperature 不能把不可靠输出变成可靠输出。
top-k 与 top-p 的差别在于候选集合由什么决定。top-k 的集合大小固定:在平坦分布下,较小的 k 会删掉许多同样合理的候选;在尖锐分布下,较大的 k 可能为填满固定名额纳入无用尾部。top-p 的集合大小随分布自适应:分布越尖锐,需要的 token 越少;分布越平坦,纳入的 token 越多。可以用一个教学例子说明:若分布为 \((0.5,0.3,0.15,0.05)\),\(p=0.9\) 会保留前三项;若分布为 \((0.9,0.05,0.03,0.02)\),\(p=0.9\) 只保留第一项。后者接近贪心,前者保留了一定探索空间。这也是同一组 top-p 参数在不同任务上效果不同的原因:它依赖分布形状,而分布形状随任务、语言和上下文变化。
截尾与约束的组合顺序也改变结果。假设原概率为 \((0.6,0.25,0.15)\),第一项被语法禁止,top-p 阈值取教学值零点七。若先选 nucleus,保留前两项,再删除第一项,只剩第二项;若先屏蔽非法项并归一化,得到第二项与第三项的概率分别为零点六二五与零点三七五,为达到阈值就必须保留二者。两条路径最后的支持集不同,因此复现策略时应记录处理顺序,而不只是温度和阈值数字。
这个例子还说明“有效候选”有不同层次。词表截尾按模型分数删除尾部,语法掩码按形式约束删除不可能完成合法文本的项,业务规则可能要等整个字段或整个动作生成后才能检查。前两者能在生成过程中交替执行,后者却不总能被有限的局部掩码准确表达。比如金额字段可以被约束为一个数字,但金额是否超过订单余额,需要外部状态。把外部事实硬编码成一次固定词表屏蔽,可能在状态更新后过期。
本章示意采用先形成语法可行集、再截尾的顺序。若合法集合为空,应报告约束冲突或终止失败;若仅因截尾造成空集,可按事先声明的规则放宽截尾并重新归一化,不能静默放开语法约束。回退策略改变了分布,也是请求配置的一部分。
随机种子、低温与版本化请求记录
公式要求 \(\tau>0\);服务把temperature设零时,通常需按接口定义切换greedy等路径,不能直接除以零。即使采用greedy,也可能因并列logits、低精度舍入、算子实现、批次形状或模型版本变化而改变输出。PyTorch复现说明明确指出,不保证跨发布版、提交和平台完全复现,CPU/GPU在相同seed下也可能不同。[14] 这不能反过来证明某托管API有或没有seed支持;实际参数必须按其版本文档核验。
因此低温用于改变分布集中程度,seed用于控制一部分随机源,二者都不是事实正确率或跨环境逐字复现的保证。比较方案应固定输入及制品,并重复采样报告分布;需要严格回放时,保存已生成输出和环境证据,比事后只给一个seed更有解释力。
以下为本书服务内部的教学记录规约,不是任何厂商API,也未实际发出请求;占位版本应在实验执行时解析为真实哈希。
{
"record_kind": "teaching_example_not_measured",
"model_revision": "<resolved model revision>",
"tokenizer_template_hash": "<input protocol hash>",
"prompt_hash": "<exact final input hash>",
"generation": {"temperature": 0.2, "top_p": 0.9, "seed": 123},
"accepted_parameters": "<parameters actually accepted by backend>",
"budget": {"candidates": 3, "verifier_calls": 3, "deadline_ms": 10000},
"runtime": "<backend, kernels, dtype, device and batch policy>",
"verifier_revision": "<frozen verifier revision>",
"result": {"stop_reason": "<actual reason>", "output_hash": "<actual output>"}
}
执行时分别保存请求参数和后端实际接受的参数;不支持或被忽略的字段不能算已控制变量。候选编号与停止原因需关联同一记录,并区分重试使用相同随机状态还是重新采样。示例中的候选数和时限都是教学假设,没有压测或质量结论。
重复可能来自高概率 token 的自强化:模型生成一个短语后,历史上下文使同一短语继续变得可能。repetition penalty 在解码时降低已经出现 token 的分数,简单有效,但可能误伤合法重复,例如代码中的变量名或诗歌中的韵脚。Unlikelihood training 从训练目标出发,显式惩罚不希望出现的候选,尝试让模型减少重复模式 [15]。
推理时还可以限制重复 n-gram、设置最小长度、引入 stop sequence 或使用语法约束。每种方法都可能产生副作用:过强惩罚会让模型刻意换词、破坏术语一致性或生成不自然文本。应该用真实任务的重复率、正确率和格式通过率共同评估。
重复惩罚同样应该被当作显式分布变换。它可能依赖整个前缀中某个 token 是否出现,也可能依赖出现次数或局部窗口。于是即便基础模型 logits 相同,历史计数不同也会得到不同的最终采样分布。评估投机采样或前缀复用时,这些状态必须随前缀一起保存;只缓存模型内部状态而忘记惩罚计数,会在算法外部引入不可见差异。对代码变量名、列表分隔符等合法重复,应使用任务断言评估惩罚副作用,而不是仅追求重复率下降。
| 任务 | 待评估的策略起点 | 额外控制 |
|---|---|---|
| 事实问答 | 低温或近贪心 | 检索、引用和事实校验 |
| 创意写作 | 中高温度、top-p | 长度和重复控制 |
| 代码生成 | 低温或多候选采样 | 编译、单元测试和安全沙箱 |
| JSON/函数调用 | 低温 | grammar/schema constrained decoding |
| 数学推理 | 多轨迹采样 | verifier、多数投票 |
| 规划任务 | 分支采样 | 状态检查与回滚 |
采样参数应纳入版本管理和评估记录。模型版本相同,只改变 temperature、top-p 或 stop 条件,也可能造成明显的行为变化。
Beam Search 与长度偏差
Beam search 每一步保留概率最高的 \(K_{beam}\) 条前缀,扩展后再裁剪。它比 greedy 能探索更多路径,但原始序列概率、结束符建模与任务目标可能产生长度偏差。实际系统常使用长度归一化或长度惩罚,但惩罚过强会生成冗长答案。
Beam search 在机器翻译等条件生成任务中有历史价值,但在开放式聊天中不一定优于采样。模型的概率高低未必等于人类偏好,beam 可能产生安全、流畅但空泛的候选。解码算法必须与训练目标匹配,不能假设最大 likelihood 就是最佳任务答案。
长度偏差可以量化。序列 \(y\) 的对数概率是各步对数概率之和,\(\log p(y)=\sum_t\log p(y_t\mid y_{<t})\)。同一前缀继续延伸时概率非增,但这不意味着任意完整长序列都比任意完整短序列概率低:完整候选还包含不同条件下的结束符概率。是否偏向过短输出,应结合模型和终止评分观察。常见修正是长度归一化 \(\frac{1}{|y|^{\alpha}}\log p(y)\),\(\alpha\) 控制惩罚强度:\(\alpha=0\) 回到原始对数概率,\(\alpha=1\) 按长度平均。\(\alpha\) 过大时,beam 会倾向生成冗长、重复但每一步概率都不低的文本。因此长度惩罚必须与任务可接受的长度范围一起调,评估中要分别报告长度分布,而不是只看最终分数。
束搜索可以用一个很小的概率树解释为何优于贪心仍不等于全局保证。假设第一步候选甲的概率为零点六,乙为零点四;从甲出发最好的后继概率只有零点五,从乙出发最好的后继概率为零点九。贪心选择甲后得到路径概率零点三,而保留两个前缀就有机会找到乙分支的零点三六。这个例子只证明局部最大不必组成路径最大;若正确路径在更早阶段已被束宽限制删除,后续扩展无法恢复它。
中文教材《动手学深度学习》的束搜索章节把贪心、穷举与固定束宽放在同一框架中比较。[16] 在本书推导中,还需明确活跃前缀与已终止候选的区别:活跃前缀可继续扩展,遇到结束符的候选应进入完成集合。若完成集合与活跃集合混用长度分数,短候选可能过早挤占所有位置;若从不保留完成集合,又可能在继续搜索时丢掉已经获得的较好答案。停止条件应根据所用评分规则设计,不能用“出现第一个结束符”代替所有束搜索的结束规则。
长度归一化的方向容易被负号掩盖。假设短序列总对数概率为负二、长度为二,长序列总对数概率为负三、长度为四。按原始对数概率,负二较大;按平均对数概率,前者为负一,后者为负零点七五,排序逆转。除以较大长度会让负值更接近零,因此它可以补偿长序列的累计惩罚,而不是再惩罚一次长度。这里同样是教学分数;是否应该逆转排序,最终仍取决于任务目标和结束符建模。
结构化生成可以通过有限状态机、上下文无关文法、JSON schema 或词表屏蔽限制候选 token。每一步只允许仍然可能形成合法输出的 token,能显著提高 JSON 和函数参数的解析成功率。它解决的是语法正确性,不解决字段值正确性;一个结构合法的 SQL 仍然可能查错表,一个字段类型正确的 API 调用仍然可能越权。
约束解码要处理 tokenizer 边界、Unicode、转义、空白、停止条件和流式输出。schema 版本变化后,旧约束不能继续复用。生产系统应在模型输出之后再次解析和校验,不能把解码器视为唯一防线。
约束解码常通过词表屏蔽实现:将语法编译成状态机或下推自动机,依据当前解析状态判断合法续接,把非法 token 的 logit 置为负无穷。token 与语法边界并不重合,合法续接可能一次跨越空白、引号和部分键名;下面按完整字节串检查,而不是限制单个字符。
约束解码需要维护解析状态,而不仅是识别某个字符。假设要求输出只含一个整数金额的对象,模型已产生开括号、键名和冒号,下一 token 可能同时包含空白、数值开头甚至后续标点。解析器必须判断 token 的整个字节串接到当前前缀后是否仍可完成一个合法对象。若只检查 token 的首字符,就可能放过非法后缀;若要求单个 token 独立构成完整语法单元,又会错杀跨边界的合法编码。XGrammar 对 token 与语法边界的错位及栈状态处理给出了一手实现讨论。[17]
还有一种重要区别是“当前前缀没有违反语法”和“在剩余预算内能够完成”。一个未闭合字符串可以是合法前缀,但如果只剩一个 token,而任何可用 token 都无法关闭它,当前策略已经不可能按时产生完整对象。语法引擎通常负责语言可达性,长度预算则是额外约束;若需要严格完成保证,必须联合检查终止可达性,或预留结束空间。达到长度上限后返回截断文本,应记为不完整,而不是因为每一步都通过了局部掩码就算成功。
这些机制在一条请求中会相互作用:温度改变概率质量,截尾改变支持集,语法状态过滤路径,束搜索比较多条前缀,停止规则决定何时交付。合理的最小复现实验应先固定其中大部分,只改变一个因素,检查支持集、归一化结果和完整输出。仅比较最终字符串很难定位哪一层改变了行为;记录局部分布与状态转移,才有可能解释相同模型为何在不同解码配置下表现不同。
4.3 分解、轨迹采样与有界修订
flowchart LR A["固定问题"] --> B["轨迹一"] A --> C["轨迹二"] A --> D["轨迹三"] B --> E["答案规范化"] C --> E D --> E E --> F["聚合或外部验证"]
CoT 解决什么问题
直接让模型从问题跳到答案,容易在多步任务中丢失中间变量。CoT 通过显式生成中间步骤,把一个长映射拆成多个局部映射:理解题意、列出条件、执行运算、检查结论。Wei 等人的实验显示,足够大的模型在提供推理示范后,复杂算术、常识和符号任务的性能明显提高 [2]。
从算法角度看,CoT 增加了计算轨迹和可利用的中间状态;从工程角度看,它增加了 token 成本和泄露风险。输出的“思考过程”也不一定是模型真实的因果过程,可能是事后合理化。Turpin 等人通过偏置输入研究CoT解释可能不忠实的问题,提醒不能把可读的步骤直接当作忠实解释 [18]。
CoT 为什么有效,可以从两个角度理解。其一是计算角度:自回归模型每个 token 经过固定网络深度的一次前向,但注意力工作量仍随上下文和结构变化,较短的直接答案通常只提供较少的显式串行生成步骤;显式写出中间步骤,等于把一部分计算移到 token 序列上,用更长的序列换取更多串行计算。其二是状态角度:中间步骤充当可复用的中间状态,后续步骤可以引用前面已经算出的量,而不必在一个隐藏向量里同时保存所有条件。这也划出了 CoT 的边界:如果任务本身不需要多步组合,或者中间步骤没有真正承载可复用的状态,增加 token 未必带来收益。
不忠实的 CoT 是另一个独立问题。输入偏置可能影响最终答案,解释却没有披露这一影响,甚至为受偏置影响的答案提供合理化论述。关键不是解释是否随答案变化,而是它是否忠实反映影响答案的因素。因此可见步骤可以作为待核查材料,却不能单独证明决策依据,结论仍需独立检查。
“逐步思考”一类的提示可以在没有任务专用示范时诱导分步推理 [3]。但效果依赖模型规模、任务类型、语言和提示位置。对代码、数学和规划任务,提示可以明确要求先列约束、再生成候选、最后检查;对敏感任务,不应要求模型公开所有内部思考,而应要求输出可审计的结论、依据和验证状态。
Self-ask研究了先显式提出并回答子问题,再合成总答案的方式;能答对各个子问题却合成失败,说明知识召回与组合推理不是同一能力。[19]
好的分解不是把答案机械拆成更多句子。它应减少依赖、暴露可验证中间量、允许失败后回溯。例如 SQL 任务可以先识别实体和范围,再生成查询,执行只读检查后返回结果;代码任务可以先列修改文件和测试,再生成补丁,运行测试后决定是否提交。
分解是否有效,可以用一个不需要外部知识的教学计算检验。假设订单有三件商品,每件标价八十元,先按商品总额打九折,再收十二元运费;优惠不作用于运费。直接跳到总额时,候选可能把运费也打折。可检查的分解应保留三个量:商品原额二百四十元,优惠后商品额二百一十六元,最终应付二百二十八元。每个量都有单位和前提,错误可以定位到优惠基数,而不是只得到“答案不对”的整体反馈。
这个例子不是要求模型公开不可见的内部推理,而是要求输出或内部工作记录包含足以验证的中间结果。中间结果可以是表格、表达式或程序输出,不必是一大段自然语言。若子问题只写成“先认真理解,再认真计算”,没有暴露任何可检验量,就没有建立更强的验收接口。相反,若细分到每个字符都调用一次模型,调度与上下文开销又会超过收益。合适粒度是能独立判断的事实或状态变化。
分解也会引入新的接口错误。第一步输出“折扣后金额”却没有说明是否含运费,第二步便可能再次加运费;一段中间文本正确,合成答案仍然错误。为避免这种组合失败,状态应至少保留对象、数值、单位和适用条件。若使用工具求值,还应区分表达式来自哪里、计算器验证了什么:计算器能证明给定表达式的算术结果,却不能证明表达式正确代表题意。
多轨迹采样
Self-Consistency 对同一问题采样多条 CoT,再聚合最终答案 [4]。一致性提供的是答案分布信息;只有正确答案在相应聚合规则下占优等条件成立时,增加样本才可能提高正确率。共享错误前提也可能使错误答案稳定占优。采样温度、轨迹数量、答案规范化和投票规则都会影响效果。
聚合不能总是使用字符串多数票。数学答案需要解析等价表达式,代码需要执行测试,开放问答需要 judge 或证据检索。可以把每条轨迹映射为 (answer, evidence, cost),先过滤验证失败的轨迹,再按答案聚合。这样“多数”建立在可接受候选集合上,而不是所有文本一视同仁。
多轨迹聚合可以沿同一个例子展开。假设五条教学候选分别输出二百二十八、二百二十八元、二二八、二百二十六点八和“信息不足”。前三条文本不同,但在题目单位明确且解析规则预先固定时可以归入同一答案桶;第四条反映了把运费也打折的错误;最后一条应保留为拒答或未完成状态。规范化不能把无法解析的文本强制映射到某个常见数字,也不能忽略币种、正负号和数量级。
如果答案规范化需要由另一个模型完成,它便成为整个策略的一部分,需要自己的版本、成本和错误检查。对可解析的数值,优先采用确定的规则;对代数表达式,要在题目定义域内检查等价,而不是只比较显示文本;对程序,行为等价通常更难,不能把在一组小测试上的相同输出当作全面等价。规范化越强,越可能降低无意义的票数分散,也越可能错误合并本来不同的答案。
在固定题目与固定采样策略下,令每条独立轨迹正确概率为 \(p\)。对奇数 \(n\),严格多数正确的概率为 \[ \sum_{k=(n+1)/2}^{n}\binom{n}{k}p^k(1-p)^{n-k}. \] 例如教学假设 \(p=0.6,n=3\),结果为 \(3(0.6)^2(0.4)+(0.6)^3=0.648\)。若 \(p=0.4\),同样计算得到零点三五二,反而低于单条正确率。这个模型把所有错误合为一类,并限定奇数样本以避开平票处理;偶数样本若要求严格过半,新增一条样本不保证比前一个奇数样本更好。
实际答案往往不止两类。假设正确答案概率为零点四,两个错误答案各为零点三;随着独立样本数增加,正确答案可以越来越稳定地成为众数,即使它没有超过二分之一。若一个错误答案本身占零点六,众数投票则会更稳定地选择错误。由此可见,二元多数的条件不能直接套到多类别众数上;需要观察错误质量是分散在许多答案上,还是集中到一个系统性错误。
轨迹独立性与错误机制也必须分开。固定问题和提示后,独立随机抽样可以产生条件独立轨迹,但这些轨迹都来自同一有偏分布。若混合很多难度不同的问题后计算相关性,困难题会让多个样本同时失败,这不证明单题条件采样必然依赖。另一方面,先抽一条随机前缀再复制到多个分支,或让后续候选读前一个候选的结论,确实改变了联合分布。报告采样实验时应说明随机性在哪一级独立、哪些状态被共享。
候选覆盖率提供另一个更弱但有用的上界。在上述独立固定概率假设下,至少生成一个正确候选的概率为 \(1-(1-p)^n\)。当教学值 \(p=0.2,n=5\) 时,它约为零点六七二;这不等于投票正确率,更不等于一个不完美验证器的最终选择率。增加候选能使覆盖提高,却可能让选择问题更困难。应同时保存每题候选集与最后被选项,才能分清没有生成正确答案和生成后没有选中。
Self-Refine 与迭代修正
Self-Refine 让模型先生成答案,再根据反馈批评和改写,多轮迭代改善输出 [20]。它原研究以同一模型生成反馈并迭代,不要求外部验证器;本书生产设计进一步建议用规则、测试或明确rubric交叉检查。没有独立反馈时,模型可能只是重复自己的偏差;迭代次数太多还会造成答案漂移和成本爆炸。
修订则与独立采样不同。新候选以旧答案和反馈为条件,目标是有方向地改变分布,而不是再抽一张互不相关的票。反馈若包含明确反例,可以排除某类错误;若只说“再想想”,模型可能把原本正确答案改错。Huang 等人在所测推理任务中讨论了缺乏外部反馈时内在自纠错的困难;这与 Self-Refine 在其他任务与反馈设置中的结果并不矛盾,比较时必须保留任务和反馈条件。[21]
在订单例子中,第一轮把全部金额乘折扣后得到二百二十六点八;反馈应指出“运费不参与折扣”这一约束,并给出能区分两种公式的输入,而不是只公布期望答案。下一轮若改成二百二十八,还需要验证商品数量变化和零运费等情况。公开反馈中的测试负责指导搜索,最终留出的测试负责估计泛化;不能每轮向候选暴露最终测试答案,再把最终通过率当作独立证据。
为避免修订漂移,状态应保存当前最优且已验证的候选,而不是永远用最新文本覆盖它。若新候选使一个先前通过的边界重新失败,应回退或保留两个分支待比较;若两轮反馈完全相同而候选没有结构性变化,应消耗停止预算,而不是将改写措辞算作进展。这些规则是本书对有界修订的工程设计,实际收益仍应与同预算的独立多候选策略比较。
设想一次代码修复任务要修复“金额为负时仍可提交”的校验,允许范围只有本地补丁和测试。以下是设计轨迹,非已运行结果。先冻结失败用例和原始代码,设最多三轮补丁候选、三次测试与十秒教学时限。成功条件由外部测试和差异范围检查定义,不由模型的一句“现在正确了”定义。
第一轮候选把金额改成取绝对值。模型自评可能认为“已不再为负”,外部断言却要求拒绝负金额;测试返回明确反例,反思输入只需包含该断言、补丁差异与相关约束,不需要索取隐藏思维链。第二轮候选改成非负判断,还要检查零值、小数、缺失值和不允许修改的文件。若外部检查均通过,停止生成,并交付补丁与测试证据,不因还能“再完善”而自动扩大修改。
若三轮都未通过,停止原因为budget_exhausted,保留最后验证失败的状态,返回缺少的证据或请求人工;若上一轮候选的外部状态未知,先核对再继续,不把重复生成当成反思;若发现用例要求本身不明确,停止原因为needs_clarification,不在两个相同前提间循环自证。下一轮不得把上轮模型自评当作新增事实。
| 信号 | 可以怎样使用 | 不能推出什么 |
|---|---|---|
| 模型指出一个可能错误 | 生成待验证假设 | 错误已经被证明 |
| 测试给出稳定反例 | 缩小修订范围并复测 | 未覆盖情况全部正确 |
| 任务断言及范围检查通过 | 按既定门禁结束候选循环 | 已获准发布或产生业务副作用 |
| 候选意见一致 | 风险或搜索收敛线索 | 事实已经得到独立证实 |
这个案例继承Self-Refine的迭代思路,但外部停止与预算是本书工程设计,不能写成论文保证。记录初稿、具体反馈、改动和外部判定,才能区分修复了错误、只改了措辞和掩盖了失败。反思收益应与单次生成、多候选但不反思等基线比较,包含全部测试与重试成本。
4.4 搜索状态与验证器
flowchart TD A["状态与约束"] --> B["扩展候选"] B --> C["启发式评分"] C --> D["保留分支"] D --> B D --> E["终止候选的独立检查"] E --> F["有效结果或反例"]
Tree of Thoughts
Tree of Thoughts 把推理看成搜索:在每个状态生成若干思路,使用评估器筛选 promising 分支,继续扩展或回溯 [5]。它适合需要规划、组合搜索或中间状态可评价的任务,例如数值游戏、路线安排和多步证明。搜索策略可以是 breadth-first、depth-first、best-first 或 beam-like pruning。
树搜索的难点是状态表示和启发式评估。状态太粗,无法区分不同前提;状态太长,评估成本高;启发式不准,搜索会把预算花在错误分支;分支太多,组合爆炸。实际系统通常需要限制深度、宽度、每步 token、总 verifier 次数和超时,并保存可回放轨迹。
某些推理任务不是树,而是多个思路可以合并、比较和循环。Graph of Thoughts 允许把生成的思路作为图节点,执行聚合、变换和反馈 [6]。例如多个候选计划可以先各自提出,再让模型抽取共同约束,形成一个更稳的综合计划。
要让搜索可执行,先把“思路”定义成能够改变问题状态的操作。以下用教学任务“用给定数字和四则运算构造目标值”作局部例子。状态包含尚未使用的数字、多步表达式以及每个中间值的来源;动作选择两个已有值和一种运算,将结果放回集合。终止条件不是文本声称“完成”,而是所有原数字恰好使用规定次数、表达式合法、求值等于目标。这样生成器只负责提出动作,状态转移与终止检查可以由确定的程序执行。
如果状态只保存当前数值而丢掉来源,两个同为六的中间量可能使用了不同的原数字,错误合并后会重复用数。若只保存完整自然语言,又很难判断两条路径是否等价。一个可用表示需要同时保留规范化数值和表达式来源;交换律能减少部分重复,但除法、减法的顺序不能被随意交换。这个例子说明状态去重首先是语义设计,哈希只是最后的存储手段。
再看剪枝的教学反例。根状态扩展甲、乙两条路线,启发式分别给零点九和零点六;甲在下一步被约束证明不可行,乙却能到达目标。全局束宽为一时,乙在第一轮已经消失;束宽为二时才有机会保留。增大束宽的价值来自保留启发式暂时低估的路径,而不是让每个候选本身更正确。如果启发式对所有可行路线都持续误判,单纯加宽可能只延迟失败,需要改变评价信息。
| 搜索对象 | 必须保存的内容 | 可以提前检查的约束 | 失败后的处理 |
|---|---|---|---|
| 部分数值表达式 | 剩余数字、表达式来源、精确数值 | 使用次数、除零、运算合法性 | 丢弃非法动作或回到分叉 |
| 局部代码补丁 | 基线版本、差异、反馈测试结果 | 修改范围、语法、已知反例 | 保留基线与已验证候选 |
| 证据综合节点 | 来源版本、适用条件、依赖节点 | 引用存在、条件兼容 | 撤销依赖该错误节点的结论 |
| 计划节点 | 未满足目标、资源与已执行动作 | 前置条件、资源冲突 | 区分逻辑回溯与外部补偿 |
这一框架也解释树与图的差别。树保留每条路径的独立历史,便于追踪但可能重复计算;图尝试让多个路径共享同一中间结论,减少重复,却要求证明这些路径对该结论具有相同前提。若一个节点后来被修正,其后继不能自动沿用旧验证结果。逻辑图可以有反馈环,但一次具体执行中的每次读取、修订和检查应带版本,避免“结论依赖自己”在记录中伪装成外部支持。
结果验证器
结果验证器只判断最终结果是否满足条件。代码题可以运行用于搜索反馈的可见测试,最终留出测试应另行隔离,数学题可以检查数值或符号答案,SQL 可以在只读数据库比较结果,规划任务可以检查环境状态。Cobbe 等人的研究训练 verifier 来区分数学答案 [8];本节把训练完成并冻结版本的 verifier 当作推理期组件,用于候选过滤、排序和停止判断。验证器的训练、奖励构造与防投机要求见第 3 章 3.6 节。
结果验证的优点是信号清晰、成本可控;缺点是不能解释中间过程,也可能存在测试盲区。一个能通过不完整单元测试的代码不一定正确,一个答案数值正确的推导不一定逻辑有效。验证器的覆盖率、误报率和版本必须纳入模型评估。
过程验证器对中间步骤给分。Let’s Verify Step by Step 比较了结果监督与过程监督,并用逐步反馈训练过程奖励模型 [9]。进入推理阶段后,这类已训练的过程验证器可以为搜索状态打分、决定优先扩展或剪枝;它的分数只表示验证器偏好,不能当作步骤正确性的证明。
推理时可以组合两种信号:过程分用于引导搜索,结果检查用于筛选最终候选;如果两者冲突,须回到任务的验收定义:证明题不能用最终答案相同覆盖错误证明,代码也不能用少量可见测试覆盖缺失的需求条件。发布或执行有副作用的动作仍需独立门禁,不能由 verifier 分数直接授权。
验证器本身也会失败,常见形态有四种。覆盖不足:测试集没有覆盖边界条件,错误的候选通过了验证。解析漏洞:验证器只比较最终数值,不检查约束,候选可以满足格式却违反语义。搜索利用漏洞:当搜索反复以同一验证器分数挑选候选时,最终可能选中钻过测试盲区的答案。版本漂移:验证器、测试集或业务规则更新后,旧结论不再成立。因此推理记录必须绑定 verifier 版本,保存误报率、漏报率和覆盖范围,并定期用人工样本抽查。
SelfCheckGPT 利用多个采样结果之间的一致性,检测事实陈述可能存在的幻觉 [22]。如果相同问题的独立样本对一个事实说法差异很大,说明采样输出不一致,可作为风险线索;但一致性不代表真实,一个模型可以稳定重复错误。Ji 等人的综述梳理了自然语言生成中的幻觉问题与检测研究 [23];本书在诊断时另行记录事实错误、依据缺失和上下文冲突,避免将不同失败混作同一指标。
更可靠的做法是让模型引用检索证据、调用事实工具或通过程序检查,并把“不确定”作为合法输出。采样一致性可以作为风险信号,不能单独作为事实验证器。高风险领域要把证据来源、时间、权限和版本纳入判定。
过程分如何汇总也会改变排序。Lightman 等人的附录比较了取最小分与分步分数乘积等方案,并在该研究中采用乘积。[9] 这是一种评分设计,不能未经校准就解释成整条证明客观正确的概率。假设一个候选有两个步骤,各得零点九,乘积为零点八一;另一候选将同样论证细分为四步,各得零点九五,乘积约为零点八一四五。细分后排序可能变化,表明分数依赖步骤划分与评分器,而不只依赖数学有效性。
取最小分强调最薄弱步骤,却可能忽略许多中等风险累计;取乘积更容易惩罚长轨迹;取平均可能让一个关键错误被许多容易步骤冲淡。选择聚合方式时,应固定步骤切分协议,在验证集上比较排序准确率与长度偏差。若候选可以自由拆分或合并步骤,搜索器还可能通过改变表达形式提高分数,而没有改变推理质量。这是评价接口的一部分,不能只调一个最终阈值。
验证器的错误率也要放在搜索强度下理解。假设一组确定错误的候选独立地以概率 \(f\) 被误接纳,则 \(n\) 个错误候选至少一个通过的概率为 \(1-(1-f)^n\)。教学值 \(f=0.01,n=100\) 时,这个概率约为零点六三四。它不是任何实际服务的事故率:自适应搜索通常不满足独立同分布,候选之间也可能共享漏洞;这个演算只是说明很小的单候选漏检并不自动意味着大规模筛选安全。
奖励过优化研究进一步提醒,持续优化一个不完美代理分数可能损害真正目标;Gao 等人的研究用合成 gold/proxy 奖励设置考察了这一现象,不能把其中的 gold 模型说成真实人类真值。[24] 对本书的搜索器而言,直接推导出的设计要求是区分用于引导搜索的可见评分和用于最终估计质量的留出评估。若每次失败都把留出答案反馈给生成器,该集合已经成为训练或搜索条件,应建立新的独立评估。
一个有用的失败记录应同时包含生成器是否提出有效路线、搜索器是否保留它、验证器是否正确判断,以及最终选择是否遵守判断。只记录“失败”无法知道预算该加在何处。若有效候选被早剪,改进启发式或增加有限宽度更相关;若全部候选都有相同错误前提,应补输入或改变提出策略;若错误候选绕过测试,扩大搜索可能放大测试盲区,也可能发现真正有效的候选,净收益仍取决于覆盖改善与选择错误。这个因果分解把搜索算法从反复调用模型变成可以审查的决策过程。
搜索复杂度与剪枝策略
如果每个状态扩展 \(b\) 个候选,搜索深度为 \(d\),最坏情况下节点数为 \(O(b^d)\)。这也是为什么“让模型多想一些”很快会变成成本问题。剪枝的目标是在不丢失高质量路径的前提下减少节点,包括保留 top-k 状态、设置上限、去除重复状态、优先扩展高价值节点,以及在验证失败时尽早停止。
剪枝器可以使用模型分数、规则分数、检索证据、程序测试和历史成功率。单一模型分数容易把流畅错误排在前面;单一规则又可能误杀创造性路径。组合评分要注意尺度校准,避免某个分数因为数值范围更大而完全支配决策。对高风险任务,宁可保留少量候选等待人工,也不能用不可解释的启发式直接丢弃所有替代路径。
复杂度必须区分逐父节点限宽与全层固定束宽。完整 b 叉树深度 d 的节点总数为几何和,量级为 O(b^d);每个父节点减少子分支才有相应指数缩减。若每层全局仅保留 K 个状态、每状态扩展 b 个候选,候选扩展量约为 O(dKb),不是 O(b^d)。较小的 K 节省预算,也可能过早删掉正确路径;应记录剪枝位置与反例,而不能把两种限宽规则混用。
搜索不是候选越相似越好。若所有分支都继承同一个含有未纠正错误的前缀,投票和搜索可能放大该偏差;若候选完全随机,验证成本会很高。可以在早期使用较高温度或 diverse sampling 获取不同计划,再在后期降低温度并使用 verifier 收敛。多样性应在“不同有效策略”之间,而不是错误格式和无意义改写之间。
对代码任务,可以让候选使用不同算法或边界处理,再通过测试筛选;对数学任务,可以要求不同证明路径或不同变量消元顺序;对规划任务,可以改变资源约束和执行顺序。多样性设计必须与任务结构结合,不能简单把 temperature 调高后宣称探索更充分。
CoT 数据、过程奖励和搜索轨迹会改变模型的先验,但不意味着上线时必须暴露同样长的思考。训练可以让模型学会提出更有价值的候选,推理时再根据难度选择短答、单轨迹、少量采样或完整搜索。相反,如果训练没有学会可验证的中间结构,仅靠 runtime 反复采样可能得到更多相似错误。
因此评估应比较四种配置:基础模型单次生成、后训练模型单次生成、后训练模型加采样、后训练模型加验证或搜索。这样才能知道收益来自训练、额外计算还是验收机制。DeepSeek-R1 展示了强化学习形成推理行为的路线,但生产系统仍需要按预算和风险动态决定是否启动外部搜索 [10]。训练侧的可验证奖励和 GRPO 见第 3 章 3.6 节。
4.5 投机解码的分布与成本
flowchart LR
A["已接受前缀"] --> B["草稿连续提出候选"]
B --> C["目标模型并行评分"]
C --> D{"逐项接受"}
D -->|首次拒绝| E["丢弃后缀并从残差补采"]
D -->|全部接受| F["目标分布再采一项"]
E --> A
F --> A
Speculative Decoding
投机解码用一个较小的 draft model 先生成连续候选,再由 target model 一次验证多个 token。若 target 接受候选,就减少逐 token 的大模型调用;若在某个位置拒绝,就从 target 的校正分布继续生成。Leviathan 等人的方法给出了在保持目标分布的条件下加速自回归解码的框架 [25];speculative sampling 进一步讨论了随机采样下的接受与修正 [26]。
关键条件是 draft 与 target 足够相似,且验证多个 token 的并行计算成本低于逐 token 生成。接受率低时,draft 的额外开销更可能超过节省;draft 太大时,节省的成本又会消失。速度收益还受 batch、上下文长度、GPU kernel 和传输影响,因此要用真实请求分布测量,而不是只看理论接受率。
Speculative decoding 改善的是生成速度,不自动改善答案质量。严格的接受—修正算法可以保持 target 分布,但如果 target 本身错误,最终仍然错误。工程上需要同时监控接受率、tokens/s、TTFT、TPOT、显存和输出一致性。
正确性条件可以用接受概率写清。设 draft 分布在位置 \(t\) 给出概率 \(q(x)\),target 给出 \(p(x)\)。采样一个 draft token \(x\sim q\),以概率 \(\min(1,p(x)/q(x))\) 接受;被拒绝时,从残差分布 \(\operatorname{norm}(\max(0,p-q))\) 重新采样。这样最终采样分布恰好等于 target 分布 \(p\)——加速不改变目标分布,这是它区别于“用小模型近似大模型”的关键。在其他成本不变的简化条件下,较高接受率通常增加有效输出;\(p\) 与 \(q\) 接近时接受率高,差异大时接受率降低,草稿成本可能超过节省,具体仍取决于块长和草稿、验证的实际成本。所以选择 draft 模型要看它在目标任务分布上的接受率,而不是它在通用基准上的质量。
逐 token 的接受规则可以直接证明,而不必凭“两个模型通常相同”来解释。以下推导固定一个已经接受的前缀,并把其条件记号暂时省略。草稿提出某个 token 的概率是 \(q(x)\),它被接受并输出的概率质量因此为 \(q(x)\min(1,p(x)/q(x))=\min(p(x),q(x))\)。把所有 token 的这部分质量加起来,得到本步接受概率 \(A=\sum_x\min(p(x),q(x))\)。尚缺的目标概率质量恰好是 \(p(x)-\min(p(x),q(x))=\max(0,p(x)-q(x))\),总和为 \(1-A\)。拒绝发生的概率也是 \(1-A\),因此从这个差额归一化后的分布补采,就逐项补足了目标分布。这个证明讨论分布,不讨论单个候选是否在语义上正确。[25]
用一个本书构造的三项词表手算。设目标分布为 \((0.5,0.3,0.2)\),草稿分布为 \((0.7,0.2,0.1)\)。第一项的接受概率是 \(5/7\),第二、三项必然接受。最终经接受路径输出的质量是 \((0.5,0.2,0.1)\),总接受率为 \(0.8\);拒绝率为 \(0.2\),残差分布为 \((0,0.5,0.5)\)。拒绝路径于是分别向第二、三项补上 \(0.1\),合计恢复 \((0.5,0.3,0.2)\)。若拒绝后直接按目标分布重采而不使用残差,结果会变成 \((0.6,0.26,0.14)\),第一项反而被重复计算。这一反例说明“拒绝后让大模型随便重新生成”缺少了关键的概率校正。
边界情形也必须显式处理。若某项 \(q(x)=0\),草稿不会提出它,不应计算零分母的接受比;目标给它的质量通过拒绝后的残差获得。若 \(p=q\),所有候选均接受,残差总质量为零,程序不能尝试归一化这个零向量。在有限精度下,如果非常小的差额被舍入,理论上的非负性、和为一以及采样实现都需要一致的数值处理;不能先随意截断概率,再继续声称实现与理想算法完全一致。零温贪心可被视为确定性目标分布的特例,但具体实现通常直接检查草稿 token 是否等于目标的贪心选择,并固定并列裁决规则。
这里的 \(p\) 和 \(q\) 必须是实际采样用的分布。若目标请求启用了温度、top-p、重复惩罚或语法约束,目标分布就是这些处理按约定顺序完成并归一化后的结果;若草稿也有采样处理,接受率分母则必须来自其真正提出 token 时的分布。不能用原始 softmax 概率去校正已经截尾的草稿,也不能在接受后再静默换一个温度。尤其在状态化约束下,语法状态和重复计数必须对应同一个已接受前缀。候选分布可以不同,证明不要求二者具有相同支持集;但支持差异会影响接受率与实现成本。
把单步证明扩展到一个块时,条件前缀成为重点。假设草稿连续提出三项。目标模型可以通过因果掩码,在一次前向中计算这些假设前缀对应的三个条件分布,并获得完整草稿后再下一项的分布。它不是把三个 token 当成相互独立的结果一起决定;各位置仍然条件于此前的草稿项。验证必须从左向右进行。只有前面的项都接受,当前位置所用的假设前缀才与最终输出前缀一致。遇到首次拒绝后,残差补采得到新的 token,后面的草稿及其概率就属于另一个历史,必须丢弃。
例如草稿提出“甲、乙、丙”,第一项接受,第二项拒绝并补成“丁”,第三项的目标概率是在“甲、乙”之后计算,不能拿来决定“甲、丁”后的输出。即使丙字面上仍然很合理,也必须重新计算条件分布。缓存处理同样遵循这一因果关系:保留已接受前缀的有效状态,截断拒绝位置及其后的假设缓存,再把补采项纳入后续计算。若三项全接受,可以从已得到的目标下一项分布再采一项;它没有草稿提出过程,不再应用同一轮的草稿接受比。遇到合法终止符时则直接结束,不为凑满块继续生成。
“保持分布”也不等于“相同随机种子输出逐字相同”。直接目标采样与投机算法消耗随机数的次数、顺序和用途不同:后者还为接受判断和残差采样使用随机数。两种算法可以拥有相同的输出分布,却在同一个种子下得到不同的一条文本。验证实现应先用可枚举的小词表检查概率质量,再在固定条件下比较统计分布;逐字一致测试只适用于额外规定了随机数耦合方式的实现,不能替代一般正确性要求。这个区分也解释了为什么速度测试与任务质量测试应分开:同分布算法不会凭空提高目标模型的数学正确率。
从接受率到账面收益
下面用简化成本模型理解速度条件,不把它当作硬件实测。令一次目标逐 token 调用的时间为 \(T\),草稿生成一项为 \(cT\),每轮草稿长度为 \(\gamma\)。假定每个位置独立以相同概率 \(\alpha\) 被接受,并假定目标并行验证整块仍花约 \(T\)。一轮可输出的期望项数是 \(1+\alpha+\alpha^2+\cdots+\alpha^\gamma\),其中至少输出的一项来自首次拒绝的补采,或全部接受后的追加项。因此理想速度比为该几何和除以 \(1+\gamma c\)。这与原论文的简化分析一致,其独立性和目标成本假设不能直接照搬到生产。[25]
取教学参数 \(\gamma=3,\alpha=0.8,c=0.1\),期望输出为 \(2.952\) 项,成本为 \(1.3T\),理想速度比约为 \(2.27\)。若接受率仍为 \(0.8\),但草稿成本升为 \(0.6T\),速度比就只约为 \(1.05\)。再若目标验证整块实际需要 \(1.6T\),后一个配置会变为 \(2.952/(1.8+1.6)\),约为 \(0.87\),比直接解码更慢。三个数字组合只是模型演算,却足以说明高接受率不是加速的充分条件。
块长也不是越大越好。后部 token 只有在前面连续接受时才可能被保留,增加一项的期望收益在这一模型中按 \(\alpha^\gamma\) 衰减,而草稿成本仍然增加。在真实请求中,接受率还会随着题材、上下文和生成位置变化;拒绝可能集中发生在格式切换、罕见标识符或数字处。一个全局平均接受率可能掩盖长串连续接受与频繁早拒绝两种完全不同的情况,因此需要记录每轮有效输出长度、首次拒绝位置和实际验证时长。
硬件层还存在与算法证明正交的约束。目标模型原本受权重读取限制时,一次读入权重并计算多个位置可能较有利;若批处理已经充分占用计算资源,额外验证位置可能消耗本可用于其他请求的算力。草稿自身占用显存、缓存和调度时间,还可能改变并发容量。因而单请求延迟降低、总吞吐提高、总浮点运算减少是三个不同命题,投机解码不同时保证三者。上线比较必须固定目标采样语义与业务请求分布,分别观察用户等待、服务容量和资源消耗,不能只报告最顺利文本上的连续接受长度。
Blockwise 与并行预测
Blockwise parallel decoding 让模型尝试一次预测一个 token block,再用后续计算验证,目标是减少串行深度 [27]。这类方法与 speculative decoding 有相似目标,但候选产生方式、模型结构和验证过程不同。它们的共同限制是:自回归依赖仍然存在,真正可并行的部分取决于候选正确率和验证成本。
4.6 预算分配与任务验收
flowchart TD
A["输入与初始预算"] --> B["估计难度与策略开销"]
B --> C["分配生成与验证预算"]
C --> D["运行并观察"]
D --> E{"目标或停止条件"}
E -->|继续| C
E -->|完成或耗尽| F["交付结果及停止状态"]
预算的组成
推理预算不只是生成 token 数,还包括候选数量、搜索深度、验证次数、工具调用次数、上下文长度和 wall-clock 时间。可以把一次任务的预算写为:
\[ \mathbf{C}=(N_{gen},N_{score},N_{verify},N_{tool},T_{GPU},T_{wall}). \]
各分量分别记录生成和评分 token、验证与工具次数、计算时间和墙钟时间。只有明确单价或归一化权重后才能合成成本标量;墙钟截止时间还应作为独立约束,避免重复计费。
不同任务的最优分配不同。一些简单问答的候选收益可能很快饱和,仍需按任务测量;数学题可能需要多条轨迹和 verifier;代码题可能更适合少量候选加真实测试;长任务需要把预算留给中间观察与重试。Snell 等人提出的 compute-optimal test-time scaling 视角,正是要寻找模型规模、样本数和验证计算之间的平衡 [11]。
何时增加模型,何时增加推理
如果错误来自输入中缺失的事实,单纯增加闭卷采样不能可靠补足它;如果错误来自搜索路径、算术步骤或偶然采样,增加预算可能有效;如果验证器不可靠,更多候选的覆盖收益可能被选择错误抵消,同时增加验证成本;如果任务本身没有可判定目标,长 CoT 可能只是生成更多解释。
固定策略增加预算的成功率不保证单调或凹:修订可能把正确候选改错,选择压力可能利用验证盲区。因此应测量每个策略的成功率—成本曲线,并区分它与“预算内可选择策略的最优包络”。部署只能根据可观测特征估计下一步收益,不能假装知道尚未产生候选的真值。
可用一个小实验估计收益曲线:固定模型和提示,逐渐增加 reasoning token、候选数和 verifier 次数,记录成功率、单位成功成本、p95 延迟和失败类型。当收益曲线很快饱和时,继续扩大预算不划算;当成功率持续增长但延迟超限时,可以做路由,让简单请求走短路径、困难请求走长路径。
Reasoning RL、GRPO、PPO 和蒸馏属于训练方法:DeepSeekMath 提出 GRPO,并在其强化学习实验中使用训练得到的奖励模型;这不同于直接用规则验证器产生奖励 [28],DeepSeek-R1 展示了冷启动、强化学习与蒸馏的组合路线 [10],PPO 提供更通用的策略优化基础 [29]。这些目标和训练风险由第 3 章负责,本章只讨论训练后模型在一次请求中怎样使用采样、搜索和验证预算。
训练后的模型可能用较少候选产生更有效的轨迹,也可能继续生成稳定但错误的路径。因此部署评估要把模型版本与推理策略拆开比较:固定推理预算比较不同训练版本,再固定模型比较单次生成、多候选、验证和搜索。只有这样才能判断收益来自权重变化还是额外推理计算。
复杂任务通常不是“多生成几个 token”就能解决,而是需要把目标拆成相互依赖的子目标。组合性研究指出,模型可能分别会做两个简单操作,却无法稳定地把它们组合到一个新任务中 [19]。因此推理算法要显式表示任务结构:先识别对象和约束,再决定步骤顺序,最后把子结果合成为答案。
层次生成把规划和表面实现分开。高层规划先产生章节、步骤、动作或子问题,低层生成再把每个计划展开为自然语言、代码或工具参数。Hierarchical Neural Story Generation 说明,长文本生成可以先规划更高层的内容,再逐步生成细节 [12]。在代码修复任务中,高层计划可以是“定位调用链—修改接口—补测试—运行回归”,低层模型负责每一步的具体 patch。
分解的关键是边界。子任务太大,仍然需要长链推理;子任务太小,调度和上下文开销会吞掉收益。每个子任务最好有输入契约、输出契约和完成条件。完成条件可以是一个字段完整、测试通过、数据库状态改变或 verifier 接受。没有完成条件的分解只是把一段自由文本拆成几段,不能真正降低错误传播。
把推理过程形式化为状态 \(s_t\)、动作 \(a_t\) 和转移 \(s_{t+1}=f(s_t,a_t)\),可以更清楚地设计搜索器。状态包含已知事实、已完成步骤、候选答案和剩余预算;动作可以是生成下一步、调用工具、请求澄清、回退或终止;代价包含 token、时间、工具费用和风险。搜索器的目标不是最大化文本概率,而是在约束下找到成功状态。
回溯是搜索区别于普通 CoT 的重要能力。普通生成一旦写出错误前提,后续 token 通常继续围绕错误展开;搜索可以保留多个候选,在验证失败时退回最近的分叉点。回溯需要保存状态快照和依赖关系,不能简单把错误文本追加到上下文后要求模型“重新想一遍”。回溯保存的是算法状态;它不会撤销真实世界里已经发生的动作。
把前面的方法组合成一次请求的策略时,先判断错误的来源,再选择对应手段。格式类错误用约束解码与 schema 校验;可验证的推理错误用多候选加验证器;知识缺失用检索;搜索路径错误用采样与搜索;预算或延迟受限时用路由与预算控制。
| 任务特征 | 首选策略 | 成功证据 | 不应由它承担的责任 |
|---|---|---|---|
| 格式固定、字段可检查 | 约束解码与 schema 验证 | 解析率、字段准确率 | 事实时效 |
| 数学、代码、规划且结果可验证 | 多候选搜索加验证器 | 测试通过率、结果正确率 | 替代独立测试 |
| 开放式解释与创作 | 低预算采样与引用约束 | 忠实度、任务完成率 | 伪造唯一正确答案 |
| 高风险或不可逆判断 | 受限推理加人工复核 | 复核与规则证据 | 自主决定执行边界 |
采样和搜索帮助生成候选,验证器决定候选是否满足可检查约束;三者都要在明确的预算与停止条件下运行,并把停止原因写入记录。
预算优化可以写成一个受约束的决策问题。给定任务可观测特征 \(x\),策略 \(\pi\) 决定生成、验证、检索与停止动作;希望最大化成功概率,同时满足费用和截止时间约束。这里的“成功”必须由事先冻结的验收定义,而不是由策略自己输出的自信分数决定。若把成功收益与费用合成效用,也要声明错误代价、超时损失和计费权重。对数学练习,错一题与晚一秒的权重可能较低;对自动修改生产配置,两者的代价完全不同。不存在脱离任务损失函数的统一最优推理长度。
考虑一个本书构造的折扣计算服务。输入包含商品数量、单价、折扣作用范围和运费,输出包含最终金额与可核验表达式。服务有三条候选路径:一次生成后检查表达式;生成三个候选再检查并选择;先查询缺失的活动规则,再生成并检查。第一条路径解决常见输入,第二条增加候选覆盖,第三条补足缺失事实。它们不是从便宜到昂贵的单一能力阶梯:缺少折扣范围时,第二条即使采样很多次也只是猜测规则;规则完整但偶发算错时,第三条反而重复获取已有信息。
假设开发集中的一百个任务被人工核验为三类:六十个规则完整且计算简单,二十五个规则完整但组合复杂,十五个缺少规则。以下表中全部数字都是教学假设,用于展示算账方式,不代表任何模型测量。单位成本统一指已经按内部单价换算后的费用,不包含墙钟时间。
| 任务组 | 单次生成加验证 | 三候选加验证 | 补规则后生成 |
|---|---|---|---|
| 六十个简单任务 | 成功五十七个,单位成本一 | 成功五十八个,单位成本三 | 成功五十七个,单位成本二 |
| 二十五个复杂任务 | 成功十五个,单位成本一 | 成功二十二个,单位成本三 | 成功十五个,单位成本二 |
| 十五个缺规则任务 | 成功三个,单位成本一 | 成功四个,单位成本三 | 成功十三个,单位成本二 |
全量单次策略的成功数是七十五,费用是一百;全量三候选成功八十四,费用三百。若有一个暂且假设完美的路由器,让三组分别走第一、第二、第三条路径,成功数为九十二,费用为一百六十五。这不是证明实际路由一定有效,而是说明额外计算应与错误类型匹配。这里是忽略类别识别错误与探测成本的理想分组对照,不是所有策略的成功率上界;部署也不能直接看到任务真实类别。实际路由器只看到字段是否缺失、表达式结构、初次验证结果等特征,其误判和额外成本都要计入。
进一步假设路由器把五个简单任务错分到三候选路径,把三个缺规则任务错分到单次路径。前一种错误主要增加费用,后一种错误则可能直接失去关键事实。两个分类错误在混淆矩阵中都算一次,但对任务成功和成本的影响不同。因此路由优化不能只追求类别准确率;应在独立评估集上按最终任务效用比较完整链路。若某条路径的成功率只是从很小的开发样本估计,路由器还可能过拟合偶然差异,需要报告不确定范围,而不是把表中的一个百分点差距视为确定收益。
Snell 等人的研究说明,按问题难度与方法特点分配计算具有研究价值;但研究中的难度估计不能不加成本地复制到在线服务。其一种预测难度分析使用大量样本的过程奖励均值,并在该分析中忽略这项估计开销,作者也讨论了更便宜预测器的必要性。[11] 本书据此强调:所谓“先判断难度”本身是一个算法调用。若为了省下两条轨迹,先生成了几十条轨迹估计难度,账面上的节省就可能消失。线上应使用能够获得的特征,并将预测器的时间、费用和错误纳入同一预算。
预算还存在时间结构。三个候选若串行执行,墙钟时间接近各路径之和;若并行执行,理想情况下接近最慢路径,但总 token 和验证费用并未相应减少,并发资源不足时还会排队。先检索后生成属于数据依赖,不能简单通过并行绕过;与问题无关的独立资料预取可以并行,却可能做无效工作。因此总成本是各操作的累加,关键路径延迟则由依赖图决定,把二者合成一个“计算量”会掩盖最重要的取舍。
一个可执行的截止时间策略应从验收动作倒推。假设请求总时限为十秒,表达式验证和结果封装预留两秒,那么生成器不能一直运行到第十秒再开始检查。若第一条候选在第四秒生成,验证发现单位错误,剩余时间是否足够修订取决于实际尾延迟;不能仅用平均耗时判断。下一步动作的预计成本超过剩余预算时,可以交付已验证候选、返回缺少规则的明确状态,或终止本次任务。停止状态应与“结果正确”分开记录,预算耗尽但未验证的文本不能自动升级为成功答案。这些时限仍是教学设定,真实预留量应由目标服务测量决定。
自适应停止也会影响评估。在“看到验证通过就停止”的策略中,成功样本通常消耗较少,困难失败样本可能一直用完预算。只统计成功请求的平均成本,会把失败探索的费用排除,导致单位成功成本被低估。正确的账本应把所有请求的费用相加,再除以成功请求数,并另报失败和超时分布;若还要研究单次成功的用户体验,可以同时报告成功条件下的延迟,但不能把两种统计混为一谈。
另一方面,保留当前最好候选并不保证真实正确率随预算单调。它只能保证被使用的选择分数不下降,前提还是比较规则固定;如果验证器把某个漏洞打成高分,更多搜索可能替换掉原来正确的答案。对强制性约束,可以先采用解析、类型、可见测试等硬门槛,再在合格候选中按质量排序;对无法完整形式化的质量目标,则要承认验证器仍有误差,并用独立留出集测量实际收益。预算曲线应分别展示候选覆盖、验证器选择成功率和端到端成功率,才能分辨瓶颈在哪里。
评估协议还应防止在同一数据上反复挑选最好的预算。先用开发集调整温度、候选数、束宽、验证阈值与停止规则,再冻结方案到留出测试集比较。若测试结果又用于修改策略,这份测试集便承担了开发反馈作用,需要新的留出评估。比较不同模型时应固定或明确换算费用、延迟与资源约束;“每个请求同样采样三次”并不意味着模型间计算预算相同。对于上下文缓存、共享前缀和并行验证,还要说明采用的是实际计费、设备时间还是理论运算量,避免同一张曲线横轴含义不断变化。
最后,任务切片应保留失败的具体原因。金额案例中,缺规则、选错折扣对象、算术错误、输出解析失败和验证器误放行分别对应不同改进方向。只记录“答错”会促使团队盲目增加候选;只记录“验证通过”又会掩盖验证器自己的盲区。将输入事实、采用的规则版本、候选表达式、可见验证反馈、最终结果和停止状态连接起来,才能复现某一次预算决策。这里需要的是短而可核查的证据链,不是要求公开冗长的内部思考文本。
语言与格式的差异
中文、英文、代码和数字混合输入会产生不同的 token 化和概率形状,采样参数不能直接照搬英文自然语言。中文长文可能需要保留段落、标题和引用边界;代码推理需要维护缩进、括号、类型和测试状态;SQL 需要区分表名、字段名和用户输入;数学表达式需要保留符号结构。中文教材对概率建模与优化的基础解释有助于理解这些差异 [30]。
评估时应按语言和格式切片,而不是把所有任务合成一个平均准确率。一个模型可能英文数学推理较强、中文题目较弱;可能自然语言解释很好、代码执行较差;可能单轮输出正确、多轮状态错误。推理算法的收益只有在目标语言和目标格式上重复验证,才具有工程意义。
本章小结
生成算法从 greedy 和 sampling 发展到 CoT、Self-Consistency、显式搜索、验证器和 test-time scaling,核心变化是从“选择一个最可能的下一个 token”转向“在预算内寻找并验证一条可接受的任务轨迹”。投机解码和预算路由可以改善执行效率或成本,但它们与推理质量相关而不等价。
面对一个具体任务,先判断错误来自知识、搜索、验证还是格式,再选择对应方法。能程序化验证的任务优先使用执行器和 verifier;需要多路径探索的任务使用采样和搜索;需要实时事实的任务使用工具和检索;需要低延迟的任务使用路由、草稿模型和预算控制。这样,推理能力才会从论文中的 benchmark 变成可观察、可控制、可回滚的工程组件。
参考资料
- Brown, T. B., et al,Language Models are Few-Shot Learners,2020。核验日期:2026-10-31。
- Wei, J., et al,Chain-of-Thought Prompting Elicits Reasoning in Large Language Models,2022。核验日期:2026-10-31。
- Kojima, T., et al,Large Language Models are Zero-Shot Reasoners,2022。核验日期:2026-10-31。
- Wang, X., et al,Self-Consistency Improves Chain of Thought Reasoning in Language Models,2023。核验日期:2026-10-31。
- Yao, S., et al,Tree of Thoughts: Deliberate Problem Solving with Large Language Models,2023。核验日期:2026-10-31。
- Besta, M., et al,Graph of Thoughts: Solving Elaborate Problems with Large Language Models,2024。核验日期:2026-10-31。
- Yao, S., et al,ReAct: Synergizing Reasoning and Acting in Language Models,2023。核验日期:2026-10-31。
- Cobbe, K., et al,Training Verifiers to Solve Math Word Problems,2021。核验日期:2026-10-31。
- Lightman, H., et al,Let’s Verify Step by Step,2023。核验日期:2026-11-01。
- Guo, D., et al,DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning,2025 / v1。核验日期:2026-10-31。
- Snell, C., et al,Scaling LLM Test-Time Compute Optimally can be More Effective than Scaling Model Parameters,2024。核验日期:2026-11-01。
- Fan, A., et al,Hierarchical Neural Story Generation,2018。核验日期:2026-11-01。
- Holtzman, A., et al,The Curious Case of Neural Text Degeneration,2020。核验日期:2026-10-31。
- PyTorch contributors,Reproducibility,2.14 documentation; checked 2026-10-31。核验日期:2026-10-31。
- Welleck, S., et al,Neural Text Generation with Unlikelihood Training,2020。核验日期:2026-10-31。
- Zhang, A., et al,动手学深度学习:束搜索,中文在线版。核验日期:2026-10-31。
- Dong, Y., et al,XGrammar: Flexible and Efficient Structured Generation Engine for Large Language Models,MLSys,2025。核验日期:2026-11-01。
- Turpin, Michael, Perez, Bowman,Language Models Don’t Always Say What They Think: Unfaithful Explanations in Chain-of-Thought Prompting,2023 / v2。核验日期:2026-10-31。
- Press, O., et al,Measuring and Narrowing the Compositionality Gap in Language Models,2022。核验日期:2026-10-31。
- Madaan, A., et al,Self-Refine: Iterative Refinement with Self-Feedback,2023。核验日期:2026-10-31。
- Huang, J., et al,Large Language Models Cannot Self-Correct Reasoning Yet,ICLR,2024。核验日期:2026-10-31。
- Manakul, P., Liusie, A., & Gales, M,SelfCheckGPT: Zero-Resource Black-Box Hallucination Detection for Generative Large Language Models,2023。核验日期:2026-10-31。
- Ji, Z., et al,Survey of Hallucination in Natural Language Generation,2023。核验日期:2026-11-01。
- Gao, L., Schulman, J., & Hilton, J.,Scaling Laws for Reward Model Overoptimization,2022。核验日期:2026-10-31。
- Leviathan, Y., Kalman, M., & Matias, Y,Fast Inference from Transformers via Speculative Decoding,2023。核验日期:2026-10-31。
- Chen, C., et al,Accelerating Large Language Model Decoding with Speculative Sampling,2023。核验日期:2026-10-31。
- Stern, M., et al,Blockwise Parallel Decoding for Deep Autoregressive Models,2018。核验日期:2026-10-31。
- Shao, Z., et al,DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models,2024。核验日期:2026-11-01。
- Schulman, J., et al,Proximal Policy Optimization Algorithms,2017。核验日期:2026-11-01。
- Zhang, A., Lipton, Z. C., Li, M., & Smola, A. V,动手学深度学习:softmax回归,中文在线2.0.0。核验日期:2026-10-31。