上线评审会上,产品经理问了一句很朴素的话:为什么点了发送,要等两秒才看见第一个字?工程团队的回答同样朴素——模型太大、显存不够、请求太密。于是讨论自然转向一个词:推理优化。
这个词常被当成“调参数”,其实它更像在一条流水线上重新分配时间。而要判断一次优化值不值得做,先得弄清楚用户到底在等什么。
两个延迟,两种病
一次生成大致分两段:先把整段输入读完,再一个字一个字往外吐。前者决定首字多久出现,后者决定读完一段要多久。第一段吃算力,第二段更吃显存带宽。瓶颈不同,手法也不同。
很多团队把这两件事混在一起谈。结果是对着吞吐量使劲,首字延迟纹丝不动;或者把首字压得很短,长回答中途还是卡。度量没有分开,讨论就容易变成各说各话。
手段背后的代价
- 批处理能把硬件喂饱,吞吐上去了,排在队伍后面的请求却要等更久,尾延迟随之变难看。
- 量化压缩权重、节省显存、提升速度,但对数值敏感的任务未必扛得住,需要自己验证,而不是照搬结论。
- 缓存复用减少重复计算,前提是请求之间确实存在可复用的前缀,否则只是多占一块内存。
投机解码这类思路也类似:小模型先猜、大模型再验,能不能赚到取决于猜测命中率,而命中率与具体业务的文本分布强相关。别人测出来的加速比,搬到你的场景里可能接近于零。
所以推理优化真正难的部分不在技术本身,而在于判断这项收益在“我这儿”是否成立。同一套方法,在离线批处理和在线对话里几乎是两件事。
被忽略的成本
加速往往用复杂度换时间。多一个缓存层、多一套量化流程、多一条降级路径,就多一处需要监控和回归的地方。上线之后模型没变,系统变了,出问题时排查路径长了一倍。
还有一种更隐蔽的成本:为了压延迟而悄悄缩短上下文、限制输出长度、降低检索质量。用户感受到的不是“更快”,而是“变笨了”。这种交换如果没被明确记录,几个月后没人说得清当初为什么这么定。
它解决不了的事
推理优化能让答案更快抵达,但不能让一个本就不该由模型回答的问题变得该由模型回答。产品定义错了,优化只是让错误更早送到用户面前。反过来,如果链路上真正的开销来自一次不必要的二次调用,或者一段串行的外部请求,那么再精细的推理优化也只是在修饰边角。
更实际的做法是先画一条时间线:请求从进来到返回,每一段各占多少。看清之后再决定动哪里。多数性能争议在拿到这条线之后会自动消失。
我的判断是,它正在从“炫技”变成“基本功”。当模型能力彼此接近,用户感知到的差别常常落在等待和稳定上。但它终究是工程手段,不是产品能力。把它放回该在的位置——服务体验的一部分,而不是全部——大概才是它最有用的状态。