一个实际问题:同一个模型,回答一句“你好”要半秒,解一道数学题却要十几秒。用户不一定抱怨后者慢,但他会记住那个转圈的时刻。推理优化常被理解成“把速度提上去”,可真正做过部署的人知道,难的是在速度、成本和稳定性之间找到一条不忽快忽慢的线。
变长的输出,把预算表撕开了口子
过去很多服务按请求数估容量,现在这种估法越来越不准。模型开始先写一段思路再给结论,输出长度可能翻几倍,解码阶段的耗时随之上升。输入侧还能靠缓存复用,输出侧却是一个 token 接一个 token 往下走,想快也快不到哪去。推理优化在这里的第一个动作,往往不是换更快的硬件,而是弄清楚:哪些请求真的需要长输出,哪些只是被默认配置带长了。
有些团队会给不同场景设不同的输出上限,或者让简单问题走短路径。这听起来像产品设计,其实是推理优化的一部分。因为容量是按峰值准备的,一个不必要的长回答,占的是所有人的余量。
批处理的甜区,不在最大那一端
把多个请求攒在一起算,能摊薄权重读取的开销,这是常见做法。但批越大,单个请求等待的时间越长,尾部延迟越难看。线上系统里,用户感知的往往不是平均响应时间,而是那几次卡顿。于是不少服务会在延迟和吞吐之间来回调参,白天偏保守,夜里放开一些。
这里有个容易被忽略的点:批处理的效果与请求的相似度有关。长短混在一起,短请求要陪着长请求等;如果能在调度层做一点分组,实际收益可能比单纯调大批量更明显。推理优化做到这一步,已经接近系统调度问题,而不只是模型问题。
缓存能省事,但省不掉判断
前缀缓存、会话复用这类手段,对多轮对话很有效。相同的前文不必重复计算,首字延迟能降下来。但它也带来新的麻烦:缓存命中率成了要盯的指标,缓存失效时的那一次请求会格外慢。更现实的是,缓存让成本结构变得不直观,账面上算力用少了,可内存占用上去了,换算成钱未必便宜。
所以谈推理优化,不能只看一个数字。延迟、吞吐、显存、单位请求成本,这几项经常此消彼长。把一个指标压到极致,通常意味着另一个指标在暗处变差。
边界:不是所有慢都值得优化
有些延迟来自模型本身的能力,比如它需要多步推演才能给出可靠答案。硬把这类请求压短,可能换来更差的正确率,用户返工一次,总时间反而更长。工程上比较稳妥的做法,是区分“可接受的思考时间”和“不可接受的等待”,前者留给模型,后者靠流式输出、进度提示、异步任务来缓解。
还有一种情况是流量波动。为峰值准备太多资源,平时闲置;准备太少,高峰就排队。推理优化在这里的作用不是消除波动,而是让系统在波动中保持可预期。可预期比绝对快更有价值,因为用户和运营都能据此安排预期。
回到开头那个转圈的时刻。它未必能被消灭,但可以被解释、被缩短、被放在合适的位置。推理优化真正要回答的,不是“还能快多少”,而是“哪些慢是可以接受的,哪些慢是不该出现的”。这个问题没有统一答案,每个团队得按自己的场景算一遍账。