一、为什么大模型「说话」这么慢?
用过 ChatGPT 的人都有这种体验:第一个字总是等得最久,之后每个字蹦得飞快,但速度还是比不上真人打字。为什么一个能把文章写得行云流水的模型,说话却总是「一个字一个字往外挤」?
答案藏在 Transformer 的自回归(autoregressive)机制里——模型一次只能生成一个 token,然后把这个 token 拼进输入,再预测下一个。而大模型部署的每毫秒都在烧钱,各大厂每年投入数十亿美元优化推理成本。本文要讲的 KV Cache、PagedAttention(vLLM)、Flash Attention 三件套,就是这场「提速军备竞赛」中最核心的三板斧,也是目前大模型推理领域最值得学的技术主线。
二、KV Cache:用内存换时间的第一个秘密
先理解大模型生成的两个阶段:
- Prefill(预填充):把你的整段 prompt(比如「帮我写一篇关于……的文章」)一次性并行喂进所有层,所有 token 互相做注意力计算。此时算力开销巨大,这就是「第一个字等得久」的原因。
- Decode(解码):每次只生成 1 个新 token,它逐层穿过网络,跟之前所有 token 的 Key/Value 向量做注意力计算。
关键洞察来了:如果没有缓存,生成第 t 个 token 时,前 t-1 个 token 的 K/V 向量都要重新计算一遍。生成 1000 个 token 的序列复杂度是 O(t²),其中大量计算完全重复。而 KV Cache 的做法简单粗暴:在 Prefill 阶段就把每个 token 每层的 K、V 向量存进显存,Decode 阶段直接读取,只计算新 token 自己的 Q/K/V 投影。
这里有个常被问到的细节:为什么只缓存 K 和 V,不缓存 Q?因为 Q 代表「当前 token 想问什么」,每个新 token 的 Q 都是全新的;而 K、V 代表「已有 token 提供的键和值」,一旦算好就不会变,所以值得缓存。推理阶段是纯前向传播、模型权重固定,缓存里已有的 K/V 永远不会被修改,只会追加新内容——这本质上是用显存换算力。
代价也很明显——KV Cache 极其吃显存。经验公式:
KV Cache 大小 ≈ 2 × L × H × D × 序列长度 × 字节数
其中 L 是层数、H 是头数、D 是头维度。LLaMA-7B 用 fp16 精度、序列长 2048 时,每个并发请求就要吃掉约 1GB 显存。为此业界提出了 MQA(Multi-Query Attention)和 GQA(Grouped-Query Attention)——让多个 Query 头共享同一组 K/V 头,大幅压缩缓存体积。LLaMA 2/3、Mistral 等主流模型均已采用 GQA。
三、PagedAttention:把操作系统虚拟内存搬进 GPU
KV Cache 解决了「重复计算」,但带来了新问题:怎么在显存里装下成百上千个并发请求的缓存?传统做法是为每个请求预分配一整块连续的最大长度显存,结果惨不忍睹——vLLM 论文实测,仅三种「内存浪费」就吃掉了 KV 缓存预算的 60%~80%:
- 内部碎片:请求只生成了 100 个 token,却占着 2048 个 token 的坑;
- 外部碎片:不同长度的请求按任意顺序结束,显存被切成大小不一的「洞」,新请求塞不进去;
- 预留浪费:生成过程中,已分配区间未用到的部分被锁死,别的请求借不走。
PagedAttention 的灵感来自操作系统虚拟内存:既然进程内存可以用「固定大小页 + 页表」解决碎片问题,KV Cache 为什么不行?它把显存切成固定大小的块(block,默认可装 16 个 token 的 K/V),每个请求通过一张 Block Table 记录自己的逻辑位置映射到哪些物理块。需要多少块就分配多少块,请求结束立即归还——利用率从 20% 左右飙到 90%+。
更妙的是它还支持 Copy-on-Write(写时复制)前缀共享:所有请求都带相同的系统提示词,那就让它们指向同一批物理块,只在某个请求「分叉」时才复制一份——这跟 Unix 的 fork() 是同一个思路。系统提示词越长、共享收益越大,实际部署里常能再省一半显存。这个技术的落地实现就是 vLLM,如今已是开源大模型部署的事实标准。
四、Flash Attention:让注意力计算本身变快
前两个优化管的是「K/V 怎么存、怎么管理」,Flash Attention 管的则是注意力计算本身怎么算得更快。它解决的问题是显存带宽瓶颈:
标准 Attention 分三步:Q×Kᵀ 算分数 → softmax 归一化 → 乘 V 得输出。其中间结果——N×N 的注意力分数矩阵——要写回显存 HBM,再读出来做 softmax,IO 开销是 O(N²)。序列越长,这个中间矩阵越爆炸(8K 上下文就是 6400 万个元素)。而 GPU 算力增长远快于显存带宽,瓶颈根本不在这几万亿次乘法,而在数据搬运。
Flash Attention 的核心是 分块(tiling)+ 在线 softmax:把 Q、K、V 切成小块,全部塞进 GPU 的高速缓存 SRAM 里,按块完成「乘法→softmax→乘 V」的全流程,中间的大矩阵从不落盘。虽然总浮点运算量一模一样(数学结果完全不变),但 HBM 读写从 O(N²) 降到 O(N),实测端到端加速 2~4 倍,还顺带省下了中间矩阵的显存——长上下文训练和推理几乎都靠它才能跑起来。
五、量化与推测解码:优化全景的另外两块拼图
除了上面三件套,推理优化还有两个高频词汇值得了解:
- 量化(Quantization):把模型权重/激活从 BF16 压到 INT8、INT4、FP8,显存占用和每步访存量直接腰斩再腰斩。KV Cache 同样可以量化(如 2~4 bit),精度损失可控。
- 推测解码(Speculative Decoding):让一个小模型快速「起草」一串候选 token,大模型并行验证、一次性接受多个正确结果,减少 Decode 步数,无损加速 2~3 倍。
六、全景总结:它们如何协作
这四项技术并不孤立,它们沿着同一条主线演进:先缓存 K/V(KV Cache)→ 管好内存(PagedAttention)→ 压缩体积(量化)→ 让计算本身更快(Flash Attention),四者可以同时叠加使用。一个典型的 vLLM 部署就是:Flash Attention 做注意力内核、PagedAttention 管缓存分页、量化压权重和 K/V。每一层解决不同问题,彼此互不冲突。
这背后的启示值得每个 AI 学习者咀嚼:大模型时代的性能革命,往往不来自新的网络结构,而来自「理解硬件、借用经典系统思想」——分页是操作系统 50 年前的老办法,如今在大模型推理里焕发新生。搞懂这些,你就迈进了「不只是会用模型,而是懂模型怎么跑起来」的进阶门槛。想深入的同学,建议按「KV Cache → Flash Attention → PagedAttention → vLLM 源码」的顺序系统学习,收益最大。