PTTS:规划式测试时扩展如何省下一半推理算力

发布时间:2026/10/26 5:36:56
PTTS:规划式测试时扩展如何省下一半推理算力

做推理评测这一年多,我最大的感触是:模型能不能做对越来越不是瓶颈,测试时算力才是。为了把数学benchmark的准确率从72%推到78%,我把每条请求的采样次数从16调到了64,精度确实上去了,但每次请求都等于跑了64遍完整生成,GPU账单肉眼可见地涨,线上p95延迟也飙到了一分钟开外。那段时间我盯着成本曲线,脑子里反复出现的一个词就是:重复采样。

问题在于,这64次采样里有相当一部分是浪费的。同一个错误思路反复出现四五遍,简单问题也在烧和难题一样的算力,有些样本中途已经明显走歪了,却依然被完整生成完再丢掉。最近我在看PTTS(Planning for Test-Time Scaling,规划式测试时扩展)这类方向,核心就一句话:把“规划”和“执行”分开,先想清楚往哪些方向走,再集中预算去采样,而不是让采样在错误方向上自我复制。按公开结果和我自己的复现情况看,它在相同精度下把测试时算力省下一半,是真实可做到的。

这篇文章写给正在做推理优化、test-time scaling落地,以及给Agent和长链路任务调预算的工程师。我会先拆解“规划-执行分离”到底怎么省算力,再对比它和Best-of-N、self-consistency、MCTS这些主流策略的取舍,最后把我复现时踩过的坑和评估方法一起放出来,希望能帮你少走一段弯路。

1. 重复采样为什么越来越“烧钱”:从投票策略说起

1.1 测试时算力的价值与代价

在训练侧算力增长逐渐放缓之后,测试时算力成了新的扩展维度。像o1那一类reasoning模型出现后,大家发现一个规律:给模型更多推理时间、更多采样次数,它就能在数学、代码、逻辑推理上拿到更高分数。这个思路本身没问题,问题出在实现方式上太粗暴。

最常见的做法就是N次采样加投票。让模型针对同一个问题生成N条完整回复,再用多数投票、self-consistency或者一个结果奖励模型来选最终答案。这个策略在不少benchmark上有效,但代价是成本线性增长:N=16的时候,一次请求等于16次完整推理;N=64的时候,一次请求等于64次完整推理。如果是长上下文或者多轮Agent任务,这个放大效应会更明显。

我见过很多团队把采样次数当成一个“旋钮”,精度不够就往上拧。但真正上生产环境时,算力预算、延迟上限、并发吞吐都是硬约束,不会因为采样次数能提分就无限放宽。所以问题的关键不是“要不要测试时算力”,而是怎么让每一份算力都花在刀刃上。

1.2 均匀烧算力的三个隐藏浪费

如果你把一个问题的64条采样结果铺开看,会发现至少有三种浪费。

第一种是思路自复制浪费。LLM在采样时并不是均匀地遍历所有解法,它更容易在模型先验里“概率较高”的那条路上反复生成。比如一道几何题,模型可能在“设坐标建系”这个方向上连续生成30条相似但不完整的推导,真正尝试“辅助线”或“向量法”的只有很少几条。最后的投票结果看似是“多数一致”,其实只是同一个错误方向上的自我重复。

第二种是难度不区分浪费。简单问题可能采样4到8次就能稳定收敛到正确答案,但它依然和难题一样烧64次。中等难度的问题可能需要20次,难题需要50次。均匀采样完全不管这个差异,就像一个不看菜谱、每道菜都炖两小时的厨师,时间花了不少,效果并不均匀。

第三种是中途路径浪费。很多样本在前几步就偏离了正确方向,后面的推导完全是在一条死路上越走越远。传统做法是把这条路整条生成完,然后交给最终答案投票去否决。相当于让一个已经迷路的人继续往前走完整个行程,再回来告诉你“这条路不通”。如果能在中途就判断出这个方向没戏,把后面的算力腾出来给其他方向,成本会低很多。

1.3 从盲目穷举到目标导向

人遇到难题时是怎么做的?先列几个可能的方向,挑一两个最靠谱的深入推演;推不通再回头换方向。而不是把每个可能的方向都从头到尾写十遍。那为什么模型在测试时扩展上要选择后者?

一方面是历史原因:early stopping、过程奖励模型这些手段在训练阶段用得很多,但在测试时阶段,大家为了流程简单,习惯一次性并行采样后投票,不愿意在中间做任何干预。另一方面是工程惯性:并行采样在GPU上很好实现,服务端只要把batch size调大就行,而“中途评估”需要额外的模型调用和逻辑控制,看起来更麻烦。

PTTS做的事情,其实就是把“先规划”这个环节加回来。它不要求你在token级别逐字打分,只需要在“方向级别”做一次判断:哪些路径值得走,哪些路径可以直接放弃。然后用一套预算分配策略,把原先均匀分布在N条采样上的算力,集中到少数的潜力路径上。这个改变听起来不复杂,但拆开看,省算力的逻辑非常清晰,而且落地时只需要改很小的服务端逻辑。

2. PTTS的核心机制:先规划路径,再按需执行采样

2.1 两个阶段的分工

PTTS把整个测试时计算过程拆成两个阶段:规划阶段和执行阶段。

规划阶段的任务是“决定做什么”。输入是原始问题,输出不是最终答案,而是一组候选路径,以及每条路径的价值估计。比如对一道数学题,规划阶段可能给出三条路径:路径A是“设未知数列方程”,路径B是“用几何性质快速排除”,路径C是“尝试特殊值反推”。每条路径后面附带一个分数,表示这条路径有多大希望能通往正确答案。

执行阶段的任务是“把决定好的事情做好”。它只对规划阶段筛选出的路径做采样生成,不再从头到尾无差别采样。每个路径可以根据自己的价值分数分到不同的采样预算:高分路径多采几次,低分路径少采几次甚至直接不采。最后把各路径的生成结果统一聚合成最终答案。

用软件工程类比的话,规划阶段相当于做架构设计和方案评审,执行阶段相当于写代码和测试。以前的做法是每个候选方案都完整实现一遍再统一验收,PTTS是先做一次低成本评审,再集中资源实现少数方案。评审本身也要花成本,但和完整实现相比小得多,这就是它能省算力的根源。

2.2 规划阶段到底在算什么

规划阶段的核心是给路径算价值分,这一步决定了后续预算怎么分配。

价值估计通常有三个来源。第一种是过程奖励模型(PRM)。PRM可以对生成的每一步打分,把路径上各步的分数累加或取最小值,就能得到这条路径的整体价值。PRM的好处是可解释性强,能告诉你“这条路径坏在第几步”,缺点是需要额外训练或外部模型,在找不到合适PRM的场景下不太方便。

第二种是轻量模型或浅层评估。用一个比执行模型小很多的模型来评估路径,或者让执行模型只在短前缀上生成“思路骨架”,然后直接对这个骨架打分。因为规划阶段不需要完整生成,只需要看到“方向雏形”,所以成本可以压得很低。我实测下来,判断一个方向可不可行,往往只需要前几步推导就足够了,后面一大半token都是在既定的方向上做重复计算。

第三种是搜索启发式,比如类似UCT、LCB这类在探索与利用之间做平衡的策略。它们不直接给路径打分,而是维护一个“不确定性区间”,对不确定性太高的路径降低预算,对“看起来有希望但还没充分验证”的路径保留探索机会。这种方法适合和树搜索配合使用。

有一个工程细节值得强调:规划阶段的生成长度可以大幅缩短。比如执行阶段每条路径要生成800个token,规划阶段只需要生成前150到200个token做方向判断。这150个token就是“分歧点”所在的位置,过了这个位置,路径基本定型,后面只是细节推导。在分歧点之前做判断,等于用不到三分之一的成本完成了大部分方向筛选。

2.3 执行阶段如何把预算用足

规划阶段做完后,执行阶段要解决的是“预算怎么分”和“结果怎么合”。

预算分配尽量不要均匀分。最简单的策略是top-k选择加比例分配:先选分数最高的k条路径,然后按分数比例分配采样次数。更精细一点可以用动态退出:某条路径在采样过程中已经出现了多个一致答案,那就提前停止,把多余的预算让给其他还没收敛的路径。

结果聚合也要分两层考虑。同一路径内的多个采样结果,可以用self-consistency判断这条路径内部是否稳定;跨路径的采样结果,可以用最终答案的投票数加权,或者用结果奖励模型排序。这里我踩过一个小坑:如果只按路径分数加权投票,低分路径上的正确答案容易被高分路径上的错误多数淹没;如果改成先按答案聚类、再按路径多样性加权,效果会更稳。因为多个独立路径都指向同一个答案,比一条路径内部的多数一致更有说服力。

执行阶段还有一个隐藏的省钱点:路径之间往往共享公共前缀。规划阶段生成的“思路骨架”本身就可以作为生成前缀,不同路径在骨架之后分叉。如果服务端支持prefix caching,这些共享前缀只需要算一次,KV Cache可以直接复用,执行阶段的额外成本就会进一步下降。

2.4 一条拆解“省一半”的估算公式

“省一半”听起来像营销话术,其实可以用一个简单的式子算出来。

假设传统方案是N次完整采样,每次完整采样成本是C_full。那么传统成本是:

C_naive = N * C_full

PTTS的成本由两块组成:规划成本C_plan,以及执行阶段各路径的采样成本之和。

C_ptts = C_plan + Σ K_i * C_path_i

我拿一个具体数字举例。N=64,传统方案成本是64次完整生成。PTTS里,规划阶段只生成路径骨架,假设它等价于4次完整生成的成本;规划出8条候选路径,按价值排序后只选3条高价值路径执行,每条路径分到8到10次采样,总执行次数大约24到30次。加起来是28到34次完整生成成本,正好接近传统方案的一半。

精度为什么没掉?因为原来的64次采样里有大量样本挤在同一条低价值路径上,它们彼此重复,并没有给投票增加实质信息。把它们的预算转移到3条高价值路径上,投票时覆盖到的“有效解题方向”反而变多了。实际跑下来,有些题目PTTS的精度比均匀采样还高了一点——原因是方向多样性增加了,投票不再被单一错误模式主导。这就是“规划-执行分离”最直观的收益:不是压缩了单次生成,而是重新分配了生成资源的去向。

3. 横向对比:PTTS 与 Best-of-N、self-consistency、MCTS 的取舍

3.1 各自的定位

Best-of-N是最轻量的策略:采样N次,用结果奖励模型挑分数最高的那个答案。它省掉了中间所有的评估,但代价是算力不灵活——不管路径好坏都采样N次,而且最终只挑一个,没有利用答案之间的内部一致性。

Self-consistency比Best-of-N多了一步:采样N次后,按最终答案聚类投票。它在可验证答案的任务上效果很好,因为同一个正确答案可能通过不同路径到达,投票能增强这种信号。但它仍然是均匀采样,没有方向筛选。

MCTS则是走到另一个极端:在token级或步骤级做树搜索,每一步都用过程价值模型打分,再回溯更新父节点。它适合数学证明、代码调试这类“逐步可验证”的任务,效果上限高,但工程复杂度也高,搜索过程会产生大量中间节点,token消耗常常比N次采样还要大。

PTTS正好站在中间:它不做token级密集评估,只在路径级做一次规划;它保留了大规模并行采样的优点,但在采样之前先裁剪方向。从实现的复杂度看,PTTS比Best-of-N多了一个规划层,比MCTS简单得多。

3.2 一张表看差异

我把四个策略放在一张表里对比,方便你根据场景快速选择。

策略算力控制粒度是否依赖PRM/价值模型方向多样性工程复杂度典型适用场景主要风险
Best-of-N采样级需要结果奖励模型低低通用问答、候选答案排序方向单一,算力利用率低
Self-consistency采样级不需要中低数学、常识问答、可验证答案简单问题过度采样
MCTS步骤级需要过程奖励模型高高数学证明、代码调试搜索节点多,成本高
PTTS路径级需要轻量规划器或PRM高中长链路推理、Agent任务规划器误剪正确路径

这张表里最容易忽略的是“方向多样性”这一行。传统采样策略默认认为N次采样是iid的,但LLM采样根本不是均匀覆盖,它在高概率方向上会产生大量自相似的样本。PTTS通过显式的路径规划把多样性拉了回来,这是它除了省算力之外的第二个价值。

3.3 什么场景选谁

如果你有训练质量很好的PRM,且问题可以逐步验证,MCTS依然是天花板最高的方案,缺点是工程量大。

如果你没有PRM,只有最终答案可以自动判断对错,那self-consistency是最稳的baseline。PTTS可以在这个基础上叠加,但前提是你有一个还算靠谱的路径价值估计器,否则规划阶段只会帮倒忙。

我的个人倾向是:当问题链条长、方向分叉多、单次采样成本高的时候,PTTS的省算力效果最明显。比如Agent需要多轮工具调用,或者数学题需要多步推导,这些场景下“方向错了再重来”的代价非常大,提前规划的价值就很高。反过来说,如果只是短问答,N=4到8次采样就已经很稳,再加一个规划器收益很小,甚至可能因为多一次模型调用变得不划算。规划-执行分离不是银弹,它是特定成本结构下的最优解——单次生成越贵,规划的价值越大。

4. 落地时最容易踩的坑:实测经验

4.1 规划器太激进,把正确答案提前剪掉

我第一次复现PTTS时,精度不仅没涨,反而比self-consistency baseline跌了3个百分点。查了半天,问题出在规划器上。

现象是:规划阶段用PRM给路径打分,很多“非主流但正确”的路径被打低分,进不了执行名单。比如一道结合了排列组合的问题,PRM的训练数据里大多是枚举法,它就给了枚举法路径高分,把“生成函数法”这条更简洁的正确路径剪掉了。等执行阶段只能沿着枚举法反复采样,效率自然下降。

解决办法有两个。一是别只走top-1,保留top-k路径,我默认至少留3条。二是给低分路径一个最低采样额度,比如每条低分路径至少采样1次,防止被完全剪掉。这个“最低采样额度”就像保险,成本增加不多,但能堵住规划器估计偏差的漏洞。

4.2 规划与执行模型不一致导致的分布漂移

还有一个隐蔽的大坑:规划器用的模型和执行器用的模型不是同一个,或者不是同一套微调数据训练出来的。

我试过一个组合:规划阶段用8B小模型做路径打分,执行阶段用70B大模型生成答案。结果是路径分数很高,但大模型实际执行那条路径时效果很差。后来一分析,8B模型认为“设方程”是好路径,70B模型在同类问题上更擅长“几何变换”,两个模型的先验和擅长方向完全不一样。规划器按自己的偏好选了方向,执行器却按另一个思路工作,两边对不上。

对策是尽量让规划器和执行器同源,至少来自同一个模型家族。如果必须跨模型,先拿一小批验证集做校准:对比不同路径在各执行器下的实际成功率,再调整规划权重。还有一种更稳的办法:让规划器只做“粗裁剪”,比如从8条里排掉2条明显不好的,保留6条。越是大模型,越值得把路径选择权交还给执行阶段。

提示:规划器不是越聪明越好。在分布漂移不可控时,规划器做“粗筛选”比做“精排序”更安全,因为它留给了执行阶段足够的纠错空间。

4.3 KV Cache和prefix复用没设计好,省下的钱又花回去

在工程层面,“省一半算力”能不能落到账单上,最关键的环节是Prefix复用。

我遇到过一种情况:采样次数确实从64降到了30,但服务端的KV Cache没有做共享。每条路径虽然共享前几步的骨架,但从骨架之后的分叉点开始,每个分支都重新计算了KV Cache,等于把同样的前缀算了好几遍。结果GPU时间和延迟几乎没降下来,只是少了后半段的采样次数。

PTTS天然适合prefix caching。规划阶段生成的路径骨架可以直接作为公共前缀,执行阶段所有同路径的采样都从同一个KV Cache状态继续生成。这个优化在工程上一点都不性感和高深,但实测下来,它能让你真正看到那“一半”的节省——采样次数降了,KV Cache也复用了,账单才会跟着降。

4.4 只报精度不报算力,对比失去意义

最后一个坑不是代码问题,而是评估方法问题。我见过不少方案汇报时说“PTTS精度提升了1个点”,但没提它为了这1个点花了多少token。这种对比没有意义。

正确做法是固定三个维度中的一个,再对比另外两个。要么固定精度,看谁用的算力更少;要么固定算力预算,看谁的精度更高;要么固定延迟上限,看谁的总吞吐更大。我习惯在实验记录里统一标注三个数字:总token数、GPU-seconds、p95延迟。

列一个简单的评估模板:baseline SC-N=64一行,PTTS一行,Best-of-N一行。每个方案记录精度、总token、GPU-seconds、p95延迟,放在同一张表里。这样团队成员一眼就能看出PTTS到底省了多少,而不是被“精度涨了”这四个字带偏。

5. 关于“测试时算力”还能往哪走

5.1 预算随难度自适应

PTTS已经在路径维度上做了自适应,但下一步应该是按问题难度做更粗粒度的路由。简单问题不规划直接执行一次;中等难度问题做一次轻量规划加少量采样;困难问题才上完整的分层规划加充分采样。这种“先分诊、后治疗”的流程,在医疗场景是常识,在推理场景却很少被认真设计。

我在自己的服务上试过一个很粗糙的分级策略:先让模型在短前缀上生成一个“预期难度分”,低于阈值直接返回第一次采样的结果,高于阈值再走规划-执行流程。这个分诊本身成本很低,但能把大量简单请求拦截掉,整体算力节省比单靠PTTS更可观。

5.2 规划器可以更轻

现在PTTS的规划器通常还是独立模型或PRM,未来更值得期待的方向是把它挂到执行模型内部,做成一个可以提前退出的分支。这意味着模型先生成一小段思路骨架,一个轻量的预测头输出“这条路有没有希望”,有希望就继续展开,没希望就换方向。这和early exit、speculative decoding在思想上是一脉相承的,目标都是把有限算力集中在更可能成功的路径上。

这类做法的难点不在模型结构,而在训练信号:你需要在训练阶段让模型学会“识别自己擅长和不擅长的方向”。这和目前主流的RLHF配方不完全一样,可能需要更多过程级监督数据。但一旦做成,测试时算力从“外部策略调参”变成了“模型内生能力”,应用范围会比现在大得多。

5.3 我自己的实操建议

如果你现在就想试PTTS,我的建议是别一上来就搞复杂版本。先在现有数据集上把baseline跑稳:SC-N=16的精度和token数是多少,N=64又是多少。然后做一个最简版的PTTS:用一个已有的轻量PRM或小型同源模型做路径打分,只选top-3路径执行,每条路径分配预算,共享前缀开起来,先看一组对比曲线。

多数场景里,一个能用的PRM加上路径级预算分配,就已经能拿到“省一半”的大部分收益。真正把方案升级到树搜索级别,是在你发现路径之间的交叉和回溯很频繁、简单top-k不够用之后的事。别为了追求架构完整让工程成本吃掉算力收益,这是我在好几个项目里反复验证过的经验:测试时算力的优化,永远是把每一份算力放在最需要它的地方,而不是把策略包得越复杂越好。