🧑💻 面试官:同一个大模型,问一句“你好”很快就回复,上传长报告让它总结,却等了半天才开始输出。为什么?
🙋♂️ 我:报告更长,模型需要处理的输入更多,所以开始回答之前要花更多时间。
🧑💻 面试官:那让它只总结一句话,等待时间就能明显缩短吗?
🙋♂️ 我:输出会变短,但报告还是要处理,前面的等待不一定能省下来。
🧑💻 面试官:模型不是有 KV Cache 吗?既然有缓存,为什么还慢?这个缓存存的是报告,还是答案?
这道题要把两段时间分开:模型先处理已经拿到的输入,再一步步生成后面的内容。KV Cache 主要是在这个过程中,保留能够重复使用的注意力计算结果。
面试速答(60 秒版)
常见的自回归大模型推理,可以分成 Prefill 和 Decode 两个阶段。
Prefill 处理输入内容。例如,我们发给模型一份报告,它需要先计算这段输入对应的表示。输入越长,通常需要处理的工作就越多。
Decode 则是在已有内容的基础上,继续生成后面的 Token。普通逐 Token 生成时,后一步依赖前一步的结果,所以要求回答得更长,通常也会增加生成时间。
KV Cache 保存的是前面 Token 在各层注意力计算中的 Key 和 Value。生成后续内容时,可以复用它们,不必每一步都重新计算整个前缀。但缓存会占用显存,也没有消除读取历史信息的成本。
因此,排查慢请求时,要分别看输入处理、生成速度和服务排队。页面迟迟没出字,不能直接认定都是 Prefill 慢,还可能有网络、调度或输出前的其他处理。

知识点详解:从发出报告,到答案一个字一个字出现
模型开始输出前,在处理什么?
假设咱们给一个阅读助手上传了报告,要求它总结本季度的销售变化。这里先不讨论上传和 PDF 解析,假设后端已经拿到了文字,准备调用模型。
模型实际收到的输入,不只有“帮我总结”这几个字,还可能包括系统提示、报告正文和历史对话。这些内容会先变成 Token,再进入模型计算。
在常见的 Transformer 推理里,Prefill 会处理这一段已知输入。因为输入已经齐了,可以利用并行计算,不需要像生成答案那样,等生成一个 Token 才知道下一个位置放什么。随后,系统从最后位置的输出中选出第一个新 Token。NVIDIA 的推理原理说明区分的就是这两个阶段。
所以,“只总结一句话”和“写一篇长分析”虽然输出要求不同,只要两次都把完整报告发过去,输入这部分工作仍然存在。缩短回答,主要减少的是后面的生成工作,不能保证前面立刻变快。
不过,也别反过来认为,输入长一倍,等待就一定长一倍。模型、硬件、批处理和缓存方式都在影响耗时,需要在相同条件下比较。
开始回答以后,为什么还不能一次把答案全部吐出来?
普通的自回归生成,是根据已有内容预测后面的 Token。
假设模型正在输出“本季度销售额有所增长”。生成“增长”之前,它已经拿到了前面生成的内容;生成下一段时,又要基于刚刚扩展的前缀继续计算。
这里说的是 Token,不是中文字。一个 Token 与一个字并不总是一一对应。
这也就解释了两种不同的“慢”:
- 一直等不到开头:要查请求排队、输入处理,以及第一个可见内容出现前发生了什么。
- 开头出来很快,后面慢慢往外蹦:更需要关注生成阶段的速度、输出长度和服务负载。
有些推理方案会用推测解码等方法减少逐步生成的开销,不能拿最基础的流程套住所有实现。但面试时,先把普通生成过程讲清楚,再补这层边界就够了。
KV Cache 到底省了哪一步?
说到这里,很容易产生一个疑问:每生成一个新 Token,前面的报告是不是都要重新算一遍?
如果完全不复用中间结果,确实会重复很多工作。KV Cache 就是为减少这部分重复计算准备的。
注意力机制里,每个 Token 都会得到对应的 Query、Key 和 Value。这里不展开矩阵公式,先记住:当前 Token 要结合前面的内容继续计算,会用到前面 Token 的 Key 和 Value。
前面的内容没变,它们已经算出的 K、V 就可以留着。处理新 Token 时,只计算新位置需要的内容,把新的 K、V 加入缓存,再结合缓存中的历史 K、V 完成注意力计算。Transformers 的缓存说明展示了这个逐步追加的过程。
例如,报告已经处理完,模型也已经生成了一小段总结。下一步计算时,可以继续使用报告和已有总结对应的 KV,不用把整个前缀从头重算。
但它缓存的不是“这份报告的标准答案”,也不是模型权重。换一个问题,不能因为有 KV Cache 就直接取出正确回答。

有了缓存,为什么长请求仍然贵?
因为省下重复计算,并不等于后面的计算不用看历史了。
在常见的全注意力模型中,新 Token 仍然需要结合历史 K、V。历史越来越长,要保存和读取的数据也会增加;并发请求多时,每个请求又都需要自己的缓存空间。
这时候,显存压力可能反过来影响能同时服务多少请求。缓存具体怎样增长,还取决于模型是否使用滑动窗口,以及服务是否采用量化、卸载等策略,不能只用“Token 数乘一个固定常数”估所有模型。
如果要验证优化是否有用,可以固定模型和服务配置,做两组对照:一组保持输出要求相同,改变报告长度;另一组保持输入相同,改变输出长度。记录首 Token 时间、后续生成速度、总耗时,同时把排队时间单独列出来。
这样才能知道,删掉一半报告、缩短输出,或者调整并发,究竟改善了哪一段。
面试官继续追问
多轮聊天,是不是只发新问题就能复用 KV?
不一定。对话产品保存历史消息,和推理服务保留 KV,是两件事。
是否支持跨请求复用、怎样识别相同前缀、缓存多久,由服务实现决定。很多接口仍然需要提交历史消息;后端能不能命中前缀缓存,还要看对应服务的规则,不能由应用自行假定。
流式输出能让模型本身算得更快吗?
流式输出主要是把已经产生的内容尽快交给用户,不必等整段生成完。它能改善等待体验,但不会因为用了 SSE,就自动减少模型的计算量。模型推理和内容传输要分开看。
首字延迟高,第一步应该改哪里?
先看时间记录,而不是马上删提示词。如果大量时间花在排队,缩短提示词未必解决主要问题。
另外,有些模型在可见答案之前还会生成内部推理内容。应用看到的“第一个字”,不一定是服务生成的第一个 Token。指标要先说明口径,才能比较。
面试速记卡
- Prefill:处理已经给到模型的输入。
- Decode:基于已有内容,继续生成后续 Token。
- KV Cache:复用历史 Token 的 Key 和 Value,不是缓存最终答案。
- 性能边界:缓存省重复计算,但仍占显存,也仍有历史读取成本。
- 排查方法:把排队、首 Token、后续生成和总耗时分开看。
