KV 缓存机制(Key-Value Cache,简称 KV Cache)是 Transformer 架构大语言模型在自回归推理阶段用于消除重复计算的核心优化技术。它将在生成过程中已经计算出的键(Key)与值(Value)向量按层缓存于显存,使每个新 token 只需与历史缓存做注意力计算而无需重新投影全部历史 token,从而将推理延迟从平方级增长压低到近线性增长。随着长上下文与高并发推理成为主流需求,KV 缓存已成为决定显存占用、吞吐量与部署成本的关键瓶颈,相关优化技术(如 PagedAttention、GQA、MLA、前缀缓存等)也被主流大模型(如 腾讯混元、Llama、DeepSeek 等)与推理引擎广泛采用。
大语言模型以自回归方式逐 token 生成文本。在不使用缓存时,每生成一个新 token,都需要对提示词及此前已生成的所有历史 token 重新计算其键、值投影,再以此计算注意力分数。随着序列变长,这种"每步重算全部历史"的做法会让计算量随序列长度迅速膨胀,生成越长的回复,单步开销越大。
KV 缓存的思路是:历史 token 的键与值投影在首次计算完成后即被保留,后续生成新 token 时直接复用。模型只需为新到达的 token 计算一次投影,并让它去查询已缓存的全部历史键、值,即可完成当前步的注意力运算。这意味着每步新增的只是"一个新 token 的计算",历史部分不再重复。
KV 缓存是一种典型的空间换时间策略:它通过占用额外的显存来保存中间状态,换取每步推理计算量的大幅下降。对于多轮对话、长文档生成、批量并发等场景,缓存带来的加速直接转化为更低的延迟与更高的吞吐,是生产级推理不可或缺的基础机制。
自注意力计算中,第 t 个 token 的输出仅依赖于当前 token 的查询(Query)与所有历史 token 的键、值。已生成 token 的键、值一旦算出,就不再随后续 token 的生成而改变——这一"历史表示与未来无关"的数学特性,使得缓存下来的键、值可以被任意后续步安全复用,无需重新计算。
键、值由输入表示经固定的线性投影(乘以权重矩阵 W_K、W_V)得到,是确定性的函数输出。只要输入 token 不变,其键、值就唯一确定,因此缓存具有完全一致的正确性保障,不会因为复用而产生近似误差。
在因果语言建模的注意力中,当前 token 只能关注其自身及之前的 token(因果掩码)。由于查询方向始终是"当前指向历史",历史键、值天然构成可被持续追加与复用的缓存,这正是 KV 缓存在解码阶段成立的数学前提。
每个 token 经投影得到键向量,用于和后续 token 的查询做点积以衡量注意力相关性。键可以理解为该 token 在注意力机制中的"身份与检索标签",决定它在未来被其他 token 关注时的匹配程度。
值向量是注意力聚合时真正被加权求和提取的内容。当某个后续 token 通过查询与历史键匹配上之后,对应的值向量中包含的语义信息会被按权重汇聚到当前表示中,因此值承载的是 token 的实际语义内容。
查询向量只在"当前正在生成的新 token"上被使用,它在计算完自身这一步的注意力后即失去复用价值,因此不参与跨步缓存。由于被持久保存的只是键与值,这一机制被称为 KV 缓存而非 QKV 缓存。
在预填充(Prefill)阶段,模型并行处理用户输入的完整提示词,为其中每一个 token 计算键、值投影,并将全部结果按层写入 KV 缓存。该阶段完成之后,缓存中已经包含了整段提示词的注意力状态,供后续生成直接复用。
在解码(Decode)阶段,模型一次只生成一个新 token。每步先计算新 token 的查询、键、值,将键、值追加进缓存,再让新查询与缓存中全部历史键、值做注意力运算得到输出。生成结束后该步的键、值留在缓存中,供下一步继续使用。
Prefill 负责"批量建缓存",Decode 负责"增量用缓存",二者共享同一套缓存结构。正是这种分工,使得提示词越长,Prefill 越重,而 Decode 每步保持轻量,整体推理效率得以保证。
在不使用缓存时,生成第 n 个 token 必须重新投影此前所有 n-1 个 token 的键、值并重算注意力,单步注意力计算量约为 O(n²)(n 为已生成序列长度)。引入 KV 缓存后,每步只需为新 token 计算一次投影,再与长度为 n 的缓存做注意力,单步复杂度降为 O(n)。
从生成整段长度为 n 的序列看,无缓存时每步 O(n²) 累计约为 O(n³),缓存后每步 O(n) 累计约为 O(n²)。也就是说,KV 缓存将序列生成的总注意力计算从 O(n³) 量级压低到 O(n²) 量级,并消除了随序列长度增长的重复计算。
这一量级下降直接对应延迟的改善:短回复时收益有限,但当序列达到数千乃至数十万 token 时,无缓存方案几乎不可行,而缓存方案使长文本生成保持在可接受的线性增长轨道上。
单个序列的 KV 缓存字节数可用如下一阶公式估算:
KV 缓存大小(字节) = 2 × L × H_kv × D × S × P
其中各参数含义为:2 表示键与值两个独立张量;L 为 Transformer 层数;H_kv 为键值头(KV Head)数量;D 为每个头的维度;S 为上下文长度(token 数);P 为每个元素的字节数(FP16 / BF16 为 2 字节,INT8 为 1 字节,INT4 为 0.5 字节)。
单 token 的缓存大小为 2 × L × H_kv × D × P 字节,它随层数、键值头数、头维度与精度的增加而增加。例如采用多头注意力(MHA)的 LLaMA-2 7B(32 层、32 个键值头、头维度 128、FP16)单 token 缓存约为 512 KiB,在 4K 上下文下约占用 2 GB 显存。
同一模型下,将缓存精度从 FP16 降到 FP8 或 INT4,可直接减半或减至四分之一的单 token 缓存;而采用分组查询注意力(GQA)或低秩压缩(MLA)等架构,则通过减少键值头数或压缩表示维度,从结构上缩小单 token 缓存。
在每个 Transformer 注意力层中,推理引擎为该层维护两组张量:键缓存与值缓存。它们随 token 的生成在序列长度维度上不断追加,常驻于 GPU 显存(HBM)中,是 KV 缓存在物理上的主要载体。
缓存通常组织为四维张量,形状近似为(批大小, 键值头数, 序列长度, 头维度),不同框架在维度排布上略有差异(例如序列长度与头维度的顺序可能互换)。序列长度维度随生成推进而增长,是显存占用随上下文变长的直接来源。
KV 缓存与模型权重、激活值分开管理:权重在推理期间基本不变,而 KV 缓存随每个请求的生命周期动态分配与释放。正因它是动态、随请求增长的数据,才需要专门的内存管理机制来控制碎片与容量。
传统做法按请求可能达到的最大序列长度,预先分配一整块连续显存。多数请求实际长度远小于上限,被预留却未使用的部分形成内部碎片,造成大量显存闲置。
不同请求长度不一,分配与释放交错进行,空闲显存被打散成不连续的小块,难以拼凑出满足新请求所需的整块连续空间,形成外部碎片,进一步降低可用容量。
当多个请求共享同一系统提示词或检索上下文时,连续分配方案会各自独立计算并保存一份前缀的 KV 缓存,无法在请求间复用相同内容,重复占用显存;此外对齐填充也会产生额外浪费。
在解码阶段,每个新 token 都需要把完整模型权重与不断增长的 KV 缓存从显存读入计算单元。由于每读入一批数据对应的实际浮点运算很少,GPU 的计算单元往往处于等待数据的空闲状态,瓶颈落在内存带宽而非算力上。
在批大小较小时,推理的计算强度低,主要受限于显存容量与带宽;只有当批大小足够大、计算强度提升后,算力才逐渐主导。KV 缓存在长上下文下随序列线性膨胀,使显存约束在多数实际场景中先于算力成为限制因素。
短上下文时模型权重是显存主体;上下文变长后,KV 缓存会快速逼近甚至超过权重占用,二者叠加使得单卡能承载的并发数与最大上下文直接受显存上限约束,而非受 GPU 算力约束。
内存容量墙指 KV 缓存总量(单 token 大小 × 上下文长度 × 并发请求数)受限于 GPU 显存上限。当上下文长度与并发数上升时,缓存体积线性增长,超出单卡 HBM 容量后便无法继续服务更多请求或更长上下文,形成容量天花板。
带宽瓶颈指解码每步都要从显存读取模型权重与全部 KV 缓存,系统的吞吐受显存带宽(字节/秒)限制,而非受算力(FLOPs/秒)限制。缓存越长,每步需读取的字节越多,解码速度随之下降,带宽成为实际速率上限。
容量墙决定"能放多少",带宽瓶颈决定"能跑多快"。部署时必须在二者约束下权衡上下文长度、并发数与批大小,这正是 KV 缓存优化(压缩、分页、共享、量化)需要同时应对的两个维度。
PagedAttention(由 vLLM 在 2023 年提出)借鉴操作系统的虚拟内存分页思想,将 KV 缓存切分为固定大小的块(页),并通过块表(Block Table)把请求的逻辑 token 位置映射到物理显存页。物理页可按需分配,不必连续。
当多个请求拥有相同的前缀(如同一系统提示词)时,它们可以指向同一批物理页,仅在某个请求发生分歧、需要写入新内容时才复制出独立副本(写时复制,Copy-on-Write)。这样相同前缀的 KV 缓存只需计算与存储一次,便被多个请求共享。
通过写时复制的页共享,并行采样、束搜索以及共享前缀的批量请求都能复用已有缓存,既减少重复计算,又提升显存利用率与并发吞吐,是不同请求间 KV 缓存共享的核心机制。
标准多头注意力(MHA)中,每个查询头都拥有独立的键、值头,缓存的键值头数与查询头数相同。分组查询注意力(GQA,由 Ainslie 等人于 2023 年提出)让多个查询头组成一组、共享同一组键、值头,从而显著减少需要缓存的键值头数量。
若查询头数为 H、每组包含 g 个查询头,则键值头数降为 H/g,KV 缓存体积相应缩减约 g 倍。以 LLaMA-2 70B 为例,其采用 8 组 GQA(64 个查询头共享为 8 个键值头),相较 MHA 将 KV 缓存缩小约 8 倍,而模型质量损失极小(标准基准上约为 0.2 个百分点)。
由于 GQA 在缓存体积与表达能力之间取得良好平衡,Llama-3 系列等大量生产级模型已普遍采用 GQA 作为默认注意力架构,从源头降低 KV 缓存的显存压力。
滑动窗口注意力(SWA,如 Mistral 7B 所采用)让每个 token 只关注其之前的固定窗口大小 w 个 token,而非整个历史序列。注意力范围被限制在局部窗口内,不再随序列总长的增长而扩展。
由于只关注最近 w 个 token,KV 缓存每层只需保留最近 w 个 token 的键、值,缓存占用被限定为 w × 单 token 大小,与整段序列的总长度无关,从而为显存设置了一个固定上限。
SWA 通过限制单层的直接注意力范围,用可控的内存代价支持更长的表层序列;超出窗口的历史信息可经由多层堆叠的感知野间接传递。其代价是单层无法直连任意远处 token,需在任务效果与内存上限之间权衡。
前缀缓存并非独立于 KV 缓存的另一套存储,而是对 KV 缓存的管理策略:它将多个请求共享的提示词前缀(如系统提示词、检索上下文、少样本示例)对应的 KV 状态计算一次后持久化缓存,供后续共享该前缀的请求直接复用。
KV 缓存是承载键、值的中间状态存储,前缀缓存是在此之上决定"哪些 KV 状态可跨请求保留与共享"的策略。二者是存储机制与调度策略的关系,前缀缓存使 KV 缓存的投入在共享前缀场景中产生更大回报。
vLLM 提供自动前缀缓存(Automatic Prefix Caching),SGLang 通过 RadixAttention 以基数树组织并复用共享前缀的 KV 缓存。它们都建立在 KV 缓存之上,避免对相同前缀反复做 Prefill 计算,从而降低延迟、提升吞吐。
vLLM 以 PagedAttention 为核心,维护一个 KV 缓存块分配器:统一管理空闲块池,按请求增长按需分配物理页,并通过块表记录每个请求的逻辑位置到物理页的映射;请求结束即回收其块,显存利用率接近最优。
借助块表与写时复制机制,vLLM 在共享前缀、并行采样等场景下复用同一批物理页,避免重复存储与重复计算,这也是前文所述跨请求共享的实现基础。
当显存不足时,vLLM 可将部分 KV 块换出到 CPU 内存(块交换)或选择重计算来腾出空间;同时支持 FP8 等低精度 KV 缓存量化以压缩体积。类似地,TensorRT-LLM、SGLang 等引擎也提供了各自的 KV 缓存管理方案,腾讯云 TI-ONE 内置的 TACO 推理加速引擎则在长文本、高并发场景提供 PD 分离部署与 KV 缓存相关优化。
部署规划可基于公式:所需显存 ≈ 模型权重 + 单 token KV 缓存大小 × 最大上下文长度 × 最大并发请求数。先用模型架构参数(层数、键值头数、头维度、精度)算出单 token 占用,再按业务预期的上下文上限与并发上限估计峰值 KV 缓存,据此选择 GPU 显存规格。
在模型选型上,优先采用 GQA、MLA 等本身压缩 KV 缓存的注意力架构,可从源头降低显存压力;同时可对 KV 缓存使用 FP8、INT4 等低精度量化,在可接受的质量范围内将缓存减半或减至四分之一。
实际部署需将并发数与上下文长度控制在单卡显存可承载范围内,避免缓存峰值超出容量墙。使用腾讯云 TI-ONE 等托管训推平台时,其内置的 TACO 推理加速引擎、PD 分离部署与自动扩缩容能力可代为管理 KV 缓存分配、共享与抢占,降低人工调优成本。
上下文从数 K 延伸到 128K 乃至更长时,KV 缓存体积近似线性增长,单个请求的缓存即可达到数十 GB 级别,迅速逼近甚至超过模型权重占用,使单卡可服务的并发数大幅下降。
更长的缓存意味着解码每步需从显存读取更多字节,内存带宽成为更突出的限制,长上下文下的吐字速度往往会明显低于短上下文,需要在架构与引擎层面做针对性优化。
为应对长上下文,工业界发展出缓存驱逐(如 H2O、SnapKV 保留重要 token、淘汰次要 token)、缓存量化(如 KVQuant、KIVI 以低位宽存储)、低秩压缩(MLA)与滑动窗口(SWA)等一整套技术,但激进的淘汰或量化可能在长程依赖任务上带来质量下降,需在效率与效果间权衡。
GQA 通过减少键值头数来压缩缓存,而多头潜在注意力(MLA,由 DeepSeek-V2 于 2024 年提出)换了一条路径:它将键、值联合投影到一个低维潜在空间,每层每个 token 只缓存一个约 512 维的潜在向量与一个约 64 维的解耦 RoPE 键(合计约 576 个浮点数),注意力时再经上投影恢复出各头的键、值。
DeepSeek-V2 论文报告,MLA 相较其采用标准多头注意力(MHA)的前代模型 DeepSeek-67B,将 KV 缓存压缩约 93.3%(即降至原有的约 6.7%)。在 DeepSeek-V2 的 128 头配置下,MLA 每层每 token 的缓存(约 576 个浮点数)约为同等 8 组 GQA 配置(约 2048 个浮点数)的 1/3~1/4,即再小约 3~4 倍。
与 GQA 仅"减少缓存的头数"不同,MLA 进一步"压缩每个表示的维度",因此能做到比 GQA 更大幅度的缓存缩减;DeepSeek 的消融实验显示,在相同参数量下 MLA 的困惑度与下游表现可匹配甚至优于 MHA 与 GQA。这意味着在长上下文、高并发场景中,MLA 相比 GQA 提供了显著更高的 KV 缓存压缩收益。