推理模型思考 token 导致首 token 时间几乎失去意义,实际用户体验取决于思考 token 与生成 token 的比例,而非传统预填充+输出模型。
对于普通补全任务,首 token 耗时(TTFT)告诉你用户何时开始阅读,token 生成速率告诉你后续的节奏。在答案前面插入一千到一万五千个 token 的思考过程,前者就变得几乎毫无意义,而后者几乎变成一切。
普通补全任务大致是 total = prefill + output_tokens / rate,用户在 prefill 完成后看到第一个 token。推理补全则在可见输出之前插入了一个项:
total = prefill + (thinking_tokens + answer_tokens) / rate
visible_start = prefill + thinking_tokens / rate # 如果 trace 隐藏
= prefill # 如果 trace 流式输出
代入数字。以每秒 60 token 的生成为速率,这在当前服务硬件上运行中等规模模型是个不起眼的数字;prefill 400ms,trace 5000 token,答案 250 token。总时间 = 0.4 + 5250/60,约 88 秒。如果 trace 是隐藏的,用户会盯着空白 84 秒,然后阅读 4 秒。
这就是全部要点,以下每一条运营结论都来自这一道算术题。
注意哪个项是你能影响的。速率由提供商决定;prefill 大致与提示词成正比,但很少是问题所在。思考 token 数是你能控制的唯一大项,而你通过 effort 或 budget 设置来控制它,而不是通过提示词的任何内容。这使得推理模型的延迟调优比传统模型简单得多——本质上只有一个旋钮,而且它直接以精度为代价进行 trade-off。
首 token 耗时曾是一个好指标,因为它同时关联两件事:服务有多快,以及用户还要等多久。在推理模型上这两者完全解耦了。
如果提供商流式输出思考过程,TTFT 保持很小,但无法告诉你答案何时到来。如果提供商隐藏思考过程,TTFT 膨胀成一个主要衡量模型觉得这个问题有多难的数字——所以在你的 TTFT 看板表现更差的模型,可能只是被赋予了更难的提示词组合。无论哪种情况,它都已经不再是一个服务健康信号。
用两个能存活的指标替代它:到首个可见答案 token 的时间,这是人类真正的体验;以及总请求时间,这是你的基础设施必须承受的。两者都按 p95 和 p99 追踪。这里的均值是无用的,原因与均值在长尾分布上总是无用的一样:尾巴不是噪声,它是最难的问题,而你部署推理模型正是为了处理那些最难的问题。
传统模型的响应长度由你的指令和 max_tokens 决定,分布相当紧凑。思考长度由 budget 和模型自己的判断决定,而分布一点都不紧凑:同一个提示词模板,在简单样本上可能产生 300 token 的 trace,在困难样本上产生 12000 token 的 trace。
所以基于均值的容量规划以一种特定方式失败。你按 20 秒均值来规划工作池,一批真正困难的输入一起到来——它们确实会这样,因为难度与导致这批输入的因素相关——然后每个 worker 同时被占用两分钟。它们后面的队列现在比你设置的任何超时都长。按 p95 时长来规划容量,并将每个 worker 的并发数限制为一;一个推理请求保持连接打开的时间远超其代表的 CPU 工作量,所以过度提交的那些常见理由在这里并不适用。
重试值得一个专门的警告。标准弹性模式——超时或 5xx 时重试一次——是针对一秒或两秒内失败的调用设计的。应用到九十秒的请求上,会产生三分钟的最坏情况,并为两次调用付费,包括你丢弃的那一次的所有思考 token。如果真的要重试推理调用,用更低的 effort 级别重试;永远不要在你自己设定的 deadline 上重试:你自己的超时到期并不是提供商失败的证据,重新发出完全相同的昂贵请求是最不可能修复它的方式。
长请求与那些默认值冲突,那些默认值是在慢 API 调用意味着三秒的年代选择的。要检查的具体数字,全部由各自的供应商记录:
最有效的缓解措施是流式输出,即使你缓冲 token 到最后才显示。流式输出把一段漫长的沉默变成持续的字节涓流,上面列表中几乎每个超时都是空闲超时而不是总超时。同一决策在 UX 层面的考量见流式部分思考。
从人倒推。决定用户能容忍什么,减去你自己的开销,把剩余部分按你观察到的速率转换成 token 数,然后把思考 budget 设成那个数字。从你看着顺眼的 token 数推导出来的 budget,在遇到 p99 时就撑不住了。
把超时设成一个真正的 deadline,而不是猜测。如果 30 秒后答案就没有价值了,就在 30 秒时取消并降级。等 90 秒等一个没人会看的东西是能发生的最坏结果:你得为那些 token 付费。
把它移出请求路径。如果任务确实需要一分钟的思考,它就是一个任务。返回一个标识符,完成时通知,然后别再试图让一个 HTTP 请求存活它根本不该承受的时长。
由于快项和慢项现在属于不同的问题,Multigrid 将首 token 耗时和总请求时间记录为独立的序列,并在 p95 汇报两者,这是唯一能看到总时间上升是来自更长的 trace 还是来自更慢的提供商的方式。
流式输出部分思考:模型思考 40 秒时的 UX
什么是推理模型?一个可以验证的定义
在推理模型和快速模型之间路由