技术深潜 · 推理架构

云厂商部署开源模型服务, KV Cache 缓存 是怎么实现的?

显存是有限的,token 是无限的。开源大模型推理服务的吞吐与成本,一半押在 KV Cache 上。

vLLM PagedAttention SGLang 2026.09
KV CACHE FOOTPRINT

KV Cache 显存有多夸张
一组数字看懂瓶颈

0.5MB
LLaMA-2-7B
每个 token 的 KV 占用
2GB
4096 上下文
单个请求的 KV Cache
8×
GQA 压缩
70B 模型 KV 体积缩小
01

为什么 KV Cache
是推理服务的命门

大模型是自回归生成:预测第 N 个 token 时,必须"看"到前面 N-1 个 token。而 Transformer 的核心是注意力机制——每个 token 都要和所有前序 token 计算相关性。

如果不做任何缓存,每生成一个新 token,都要把前面所有 token 的 K、V 重新算一遍。序列越长,计算量按平方级膨胀,长上下文推理会慢到完全不可用。

KV Cache 的思路非常朴素:把每一层注意力产生的 K、V 矩阵缓存进显存;生成下一个 token 时,只算当前这一个新 token 的 K/V,再拼到缓存尾部,旧 token 直接复用。于是计算量从"每步重算全序列"降为"每步只算 1 个 token"。

但代价是显存——它随"序列长度 × 并发数"线性增长,很快成为推理服务第一大显存消耗项,甚至超过模型权重本身。谁更会管理、压缩、复用这块显存,谁就能在吞吐和成本上拉开差距。

KV head 数,是决定 KV Cache 体积的核心变量之一。

— 开源模型推理 · 关键洞察
02

KV Cache 显存
到底有多大

先记住一个公式:KV Cache = 2(K和V) × 层数 L × 序列长度 S × KV head 数 × head_dim × 每参数字节数。

以 LLaMA-2-7B 为例(fp16 精度,2 字节/参数):层数 L = 32,KV head 数 = 32,head_dim = 128。每个 token 的 KV 占用约 0.5 MB;4096 上下文就是 2 GB,而 7B 权重本身 fp16 只有 14 GB。并发 8 个请求,光 KV Cache 就要 16 GB 显存——"小模型 + 长上下文 + 高并发"才是真正的瓶颈。

KV head 数是决定体积的核心变量之一,由此引出两类结构级瘦身方案:

MQA
1 个 KV head
所有 query head 共享同一个 KV head,体积压到极限,质量略有损失
GQA
8× 体积缩小
query head 分组共享 KV head,质量与体积折中,新一代开源模型标配

LLaMA-2-70B 采用 GQA,把 64 个 KV head 压到 8 个,KV Cache 体积直接缩小 8 倍。Mistral、Gemma、Qwen 等新一代模型也已普遍默认 GQA。

03

缓存的
三个层次

实际部署中"KV Cache"常被泛化,其实分三层,越往上越接近应用:

层次缓存对象命中粒度典型技术
张量级 KV Cache每一层的 K/V 矩阵逐 tokenPagedAttention、FlashAttention
前缀缓存共享前缀的 KV 段逐 promptRadixAttention、前缀缓存
语义缓存相似问题的最终答案逐请求Embedding 相似度 + 向量库

张量级解决"每步重算全序列";前缀缓存让重复的 system prompt、长文档前缀只算一次;语义缓存直接返回相似问题的答案。三层叠加,才是云厂商"高缓存命中率"的完整图景。

04

架构方案演进
从单卡到集群

01

单机单卡

单张 GPU 装下权重 + KV Cache。缺点是显存有限,长上下文和高并发只能二选一,适合轻量场景。

02

单机多卡(张量并行)

权重按层/头切分到多张卡,KV Cache 也随之切分,单机显存容量翻倍;代价是每步都有跨卡通信,需 NVLink 高速互联支撑。

03

PD 分离(Prefill-Decode Disaggregation)

把推理拆成两个独立服务:Prefill 吃下整个 prompt 一次性算出 KV Cache(计算密集);Decode 逐 token 生成、反复读写 KV(显存密集)。两者独立扩缩容,vLLM 的 disaggregated prefill、SGLang 均落地了这一思想。

04

集群 + 缓存亲和路由

网关把前缀相同的请求尽可能路由到同一实例,让前缀缓存被反复命中。这是"高缓存命中率"的最后一块拼图。

一条生产级链路大致是:网关路由 → 缓存亲和调度 → PD 分离集群 → 张量并行多卡 → 分页 KV Cache。

05

缓存亲和路由
开源实现方案

前缀缓存只在同一进程内生效。一旦水平扩成多实例/多节点:请求 A 在 worker-1 算好了 system prompt 的 KV,请求 B 带着同样前缀却被路由到 worker-2,只能重新 prefill 一遍,缓存白搭。

缓存亲和路由,就是让前缀相同(或同一会话)的请求,尽量落到"已经持有对应 KV Cache"的那个 worker。核心两件事:路由 key 怎么定、决策怎么做。按此,开源方案分三类。

第一类 · 通用网关的一致性哈希 / 会话粘性:不关心 KV 内容,只保证"同一个 key 永远去同一个后端"。

组件机制典型配置
EnvoyRING_HASH + hash policy按 cookie / header 一致性哈希
IstioDestinationRule 的 consistentHash按 httpHeaderName / cookie
Nginxhash 指令 / stickyhash $arg_session consistent;

优点通用、零侵入、成熟稳定;缺点只按"静态 key"亲和,不知道 worker 真实 KV 命中率,扩缩容时命中率骤降,属入门方案。

第二类 · 缓存感知路由:感知每个 worker 实际持有的 KV 状态,把请求发给"前缀命中最多、重算成本最低"的 worker。

SGLang Router(sgl-router):SGLang 官方开源的轻量 KV 感知网关,对外暴露 OpenAI 兼容接口,worker 支持静态 URL 列表或 Kubernetes EndpointSlice 发现;策略含 cache_aware、cache_aware_zmq,Router 在本地维护 worker 的 Radix Tree 状态,把请求发给前缀命中最高的 worker——注意它是近似决策,非一致性/正确性保证。

NVIDIA Dynamo KV Router:NVIDIA 开源的分布式推理框架(兼容 vLLM / SGLang / TensorRT-LLM),KV Router 把请求路由到最可能已持有其 KV 的 worker,决策同时考虑 decode 成本(已激活 block)与 prefill 成本(需新算 block);配套 KVStorage 可把 KV 卸载到 CPU 内存 / Redis / NIXL。

第三类 · KV Cache 中心化的"搬运"型方案:前两类是"算力跟着缓存走",第三类反过来——"缓存跟着算力走",把 KV 直接在节点间搬运,从根上解耦路由与缓存位置。

Mooncake Transfer Engine:月之暗面开源,Prefill 集群算好 KV 后用 RDMA / GPUDirect 直接搬到 Decode 集群,SGLang 官方已支持其作为 disaggregated serving 后端。vLLM disaggregated prefill + KV Connector 在 prefill/decode 节点间传输 KV,同属"搬运"路线;LMCache 把 KV 卸载到 CPU/磁盘并跨请求复用,可作亲和路由的兜底层。

方案路由依据感知真实 KV复杂度适用场景
Envoy / Istio / Nginx静态 key否低多轮会话粘性、快速起步
SGLang RouterRadix Tree 状态(近似)是(近似)中SGLang 多实例、高前缀复用
NVIDIA Dynamo KV RouterKV overlap + 成本模型是高多机多卡、异构引擎、压成本
Mooncake / KV Connector不路由,直接搬运 KV是(搬运)高大规模 PD 分离、极致吞吐

一句话总结演进主线:静态哈希粘性 → 缓存状态感知路由(SGLang Router / Dynamo)→ KV Cache 中心化搬运(Mooncake),越往后越接近"缓存即一等公民"的架构。

06

开源组件
各司其职

vLLM · PagedAttention:把 KV Cache 切成固定大小的 block(页),像操作系统虚拟内存一样分页管理,彻底解决显存碎片化,配合 Continuous Batching(连续批处理)与 Automatic Prefix Caching,是事实上的工业标准。

SGLang · RadixAttention:用前缀树(Radix Tree)组织 KV Cache,多请求共享公共前缀时天然复用同一份 KV,尤其适合长 system prompt、多轮对话、RAG 模板等高前缀重复场景。

FlashAttention / FlashDecoding:严格说是 IO-aware 注意力算法,把 attention 分块计算、减少 HBM 读写,让长序列真正跑得动;没有它,KV Cache 方案在长上下文下仍会被显存带宽卡死。

TGI(Text Generation Inference) 与 TensorRT-LLM:前者是 HuggingFace 官方推理框架,开箱即用;后者是 NVIDIA 官方引擎,性能天花板更高、上手门槛也更高。

LMCache:LLM 推理的 KV Cache 分层存储与复用库,把 KV Cache 从 GPU 显存卸载(offload)到 CPU 内存甚至本地磁盘/分布式存储,突破显存上限以支撑超长上下文,同时支持跨请求复用,可与 vLLM 无缝集成,专治"显存不够放长上下文"。

Mooncake:月之暗面(Moonshot AI,Kimi 背后的团队)开源的 KV Cache 中心化分离架构,把 KV Cache 当作"一等公民",通过专门的 KV Cache Transfer Engine 在 Prefill 与 Decode 节点间用 RDMA 等高速网络搬运 KV,支撑大规模 PD 分离集群,是 KVCache 中心化服务架构的代表作。

配套技术作用代表
GQA / MQA结构层面压缩 KV 体积LLaMA-2-70B、Mistral
KV Cache 量化8bit / 4bit 存 K/VvLLM、TGI、TensorRT-LLM
滑动窗口 / StreamingLLM截断远端 KV,控制上限Mistral、StreamingLLM
07

动手部署,
一行命令开缓存

以 vLLM 为例,启动 OpenAI 兼容服务并开启前缀缓存,只需几条参数:

bash · vLLM
# 启动 vLLM OpenAI 兼容服务,开启前缀缓存 python -m vllm.entrypoints.openai.api_server \ --model meta-llama/Llama-2-7b-chat-hf \ --enable-prefix-caching \ --gpu-memory-utilization 0.9 \ --max-num-seqs 256 \ --max-model-len 8192
python · KV 估算
# KV Cache 显存估算 L = 32 # 层数 num_kv_heads = 32 head_dim = 128 b = 2 # fp16 每参数字节 per_token = 2 * L * num_kv_heads * head_dim * b print(per_token / 1024 / 1024, "MB/token") # ≈ 0.5
向量云 · 官方API优选接入

KV Cache 优化的终点,
是把省钱落到账单上

对用户而言,KV Cache 优化的最终收益只有两个字:省钱。向量云作为火山方舟官方 API 的优选接入渠道,把上述架构能力直接落到账单上:

缓存隔离:独享缓存实例,避免共享缓存被并发请求"污染"导致命中率骤降;高缓存命中率:前缀缓存 + 亲和路由,重复的 system prompt 和长文档前缀只算一次;Token 折扣:缓存命中的部分按折扣计费,长上下文、多轮对话场景省得最多。

官方 API 直连,模型能力完全一致
缓存隔离,高命中率,命中即省
分时段折扣,闲时价格更优
企业级并发承载,稳定可靠
多模型兼容,一站接入主流大模型
按量计费,余额耗尽即停,无欠费风险

平台网址: https://ark.tokenrize.cn (注册即享专属 Token 折扣)

火山方舟 × 向量云

官方 API · 缓存隔离 · Token 折扣

本文技术参数参考 vLLM / SGLang / LMCache / Mooncake / LLaMA 等开源社区公开资料,实际以各框架与控制台为准

常见问题(FAQ)

火山方舟官方 API 与官方 Key 直连 · 向量云 · 按量计费享 Token 折扣

Q1. KV Cache 为什么是推理服务的命门?

A. 它决定显存占用与并发能力,直接限制单卡能同时服务多少请求。

Q2. KV Cache 显存到底有多大?

A. 文中用一组数字说明瓶颈规模:显存占用随上下文长度增长而膨胀。

Q3. 缓存的三个层次是什么?

A. 从显存内的前缀缓存到跨请求复用,分三个层次逐级提升缓存命中率。

Q4. 架构方案是怎么演进的?

A. 从单机单卡,到单机多卡(张量并行),再到 PD 分离(Prefill-Decode Disaggregation)。