一个常见的现场:白天用户一多,对话框里的字就一个一个往外蹦;到了夜里,同一套服务又显得利落起来。硬件没动,模型没动,变的只是同时说话的人数。这个时候谈推理优化,比谈换一个更大的模型更贴近问题。
先分清两种慢
用户感到的慢,其实是两件事。一种是按下回车后迟迟不见第一个字;另一种是字出来了,但流得慢。前者卡在预填充阶段,模型要把整段上下文读进去,计算密集;后者卡在逐字生成阶段,每吐一个词都要把权重和缓存过一遍,更像是被显存带宽牵着走。成因不同,用同一套办法去治,往往只能治住一半。
批处理的两面
提升吞吐的常见做法,是把多个请求拼成一批送进去,让加速器一次多做点事。代价是排队:后来的请求要等前面凑够数量,或者等一个时间窗口关闭。吞吐上去了,单次请求的等待未必下降,长尾甚至更明显。所以动手之前得问清楚,这个业务在意的是单位时间服务多少人,还是每个人等多久。这两个目标经常互相拉扯,方向答错,优化就变成了看板上的数字游戏。
显存是一道硬约束
长对话里,KV 缓存会随上下文增长,占住的显存不释放,能同时容纳的请求数就被压住。围绕这一点,常见思路是分页管理、前缀复用、把暂时不用的缓存挪到别处。听起来琐碎,实际效果有时比换一个更小的模型更直接——因为瓶颈不在算力,而在能装下多少“正在进行的对话”。
量化与投机:省下来的和赔进去的
量化把权重和激活压到更低的位宽,换来显存和带宽,代价是数值分布上的细微偏移。在长输出、格式要求严格的任务里,这种偏移会被放大,需要单独验证。投机采样则让一个小模型先猜几个词,再由大模型一次性校验,猜对就白赚,猜错就回退。它在输出可预测的业务里收益明显,换成开放式写作,稳定性就没那么好说了。
被忽略的重复劳动
系统提示词、工具说明、固定的知识片段,几乎每次请求都在重复。前缀缓存能让这部分内容只算一次。真正落地时,收益常常来自这类重复被消掉,而不是某个算法上的巧思。这也解释了为什么同一个模型,两家团队跑出来的体感差得很远:差别往往在请求怎么组织。
收益有前提
值得提醒的是,推理优化的效果高度依赖流量形态。请求稀疏时,批处理凑不满,缓存命中率低,很多手段收效有限;只有在并发足够、重复足够多的场景里,前面那些工作才会显出价值。反过来,如果业务对首字延迟格外敏感,可能得主动牺牲一部分吞吐去换响应速度。判断之前,最好先把三件事量出来:
- 峰值并发与请求到达的分布;
- 上下文长度的平均水平和长尾;
- 用户对首字延迟的实际容忍度。
这三项不清楚,就很容易把预算花在看不见的地方:加了机器,延迟没降;换了框架,账单反而涨。做推理优化之前,先确认瓶颈落在排队、带宽还是显存上,比追新方法更管用。