采风全网
达观天下

用户等的那三秒,推理优化究竟在动哪一层

敲下一句话,回车,光标闪了几下,字才一个一个往外跳。中间那几秒,用户习惯说成“模型在想”,而在工程侧,它由几个相当具体的环节拼起来。

等待发生在两个不同的地方

一次生成大致分两段。前一段把整段输入读进去,建立上下文状态,计算密集,常被称作预填充;后一段一个词一个词往外吐,每步都要把之前的中间结果读一遍,更受显存带宽牵制。两段瓶颈不同,能用的手段也不同。把它们混在一起谈加速,容易得到看似成立、落地却无效的结论。

还有一处常被忽略:排队。请求到达时若并发已经打满,用户等的那几秒里,可能有相当一部分时间还没轮到计算。

批处理填满的是机器,不一定是耐心

提高吞吐的常见做法是把多个请求拼成一批一起算,让硬件少有空转。连续批处理进一步允许新请求在生成途中插进来。机器利用率上去了,队列管理却变复杂:一个长输出请求占着位置,短请求可能被压在后面。平均数字看着平稳,尾部体验未必如此。

于是推理优化绕不开一个选择:盯吞吐,还是盯尾延迟。线上真正被感受到的是后者——用户不会记住平均响应,只会记住转圈的那几次。

缓存要按命中率算账

把注意力计算中的中间结果缓存下来,可以避免重复劳动。多轮对话里,前面几轮的前缀能复用,收益比较直接。但如果每次请求都换了系统提示、换了随请求附带的文档,命中率低,占用的显存反倒成了负担。它更像需要按实际流量结构去配置的东西,而不是开关一开就见效。

用更少的计算换接近的结果

降低数值精度是另一条路。权重和激活压到更低位宽,显存访问量随之减少,代价是可能带来精度损失,需要按具体任务验证,不宜一概而论。

投机解码的思路略有不同:先用一个轻量模型快速起草若干词,再由目标模型一次性校验,通过的部分就省掉了逐词生成的开销。它的收益高度依赖起草被接受的比例,而这一比例与任务类型强相关,代码补全和开放式写作的差别往往不小。把参数照搬过来,效果可能对不上。

先量清楚,再动手

动手之前值得先分清几件事:用户感知的是首字时间,还是整段输出完成的时间;是稳定负载,还是时不时来一波高峰;输出长度是可预期的,还是完全由模型自己决定。对应的观察指标也应当分开——首字时间、每个词的时间、端到端的分位数,各自指向不同环节。只盯着单个算子的耗时,常常看不出问题出在排队还是出在解码。

它也有做不到的地方

上下文变长,缓存占用上升,能腾挪的空间随之收窄;并发忽然涌来,再精巧的调度也只能缓解;输出长度不受控时,延迟预算本身就难以给准。这些都不是调参能抹平的,更多要靠产品层面的设计去承接,比如先给出一段可读的开头,或者把长任务拆成可感知的阶段。

我的看法是,推理优化更像一连串有代价的取舍,而不是一次性的开关。预填充和解码要分开看,吞吐和尾延迟要分开看,缓存的收益要按命中率算,精度的损失要按任务验。真正难的不是把某个指标压下去,而是先弄清楚用户等的那三秒,究竟落在哪一段里。

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:用户等的那三秒,推理优化究竟在动哪一层
文章链接:https://tech.cfdanews.com/ai/747.html