云厂商部署开源模型服务,KV Cache 缓存是怎么实现的?
显存是有限的,token 是无限的。开源大模型推理服务的吞吐与成本,一半押在 KV Cache 上。 ark.tokenrize.cn
火山方舟 × 向量云 · 2026.09
一、为什么 KV Cache 是推理服务的命门
大模型(以 GPT 系、LLaMA 系为代表)是自回归生成:预测第 N 个 token 时,必须"看"到前面 N-1 个 token。而 Transformer 的核心是注意力机制——每个 token 都要和所有前序 token 计算相关性。
如果不做任何缓存,每生成一个新 token,都要把前面所有 token 的 Key(K)和 Value(V)重新算一遍。序列越长,计算量按平方级膨胀,长上下文推理会慢到完全不可用。
KV Cache 的思路非常朴素:
-
推理过程中,每一层注意力产生的 K、V 矩阵缓存到显存里; -
生成下一个 token 时,只需计算当前这一个新 token 的 K、V,再把它拼到缓存尾部即可; -
旧 token 的 K、V 直接复用,不再重复计算。
于是,计算量从"每步重算全序列"降为"每步只算 1 个 token"。
但天下没有免费的午餐。KV Cache 的代价是显存——它随"序列长度 × 并发数"线性增长,很快就成为推理服务的第一大显存消耗项,甚至超过模型权重本身。谁能更好地管理、压缩、复用这块显存,谁就能在吞吐和成本上拉开差距。
二、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 = 2 × 32 × 32 × 128 × 2 ≈ 524,288 字节 ≈ 0.5 MB
-
4K 上下文(4096 token):0.5 MB × 4096 ≈ 2 GB -
而 7B 模型权重本身 fp16 只有 14 GB
也就是说,一个 4096 上下文的请求,KV Cache 就占 2GB;并发 8 个请求,光 KV Cache 就要 16GB 显存。这也是为什么"小模型 + 长上下文 + 高并发"的部署,KV Cache 才是真正的瓶颈。
关键洞察:KV head 数是决定 KV Cache 体积的核心变量之一。
GQA / MQA:从结构上直接瘦身
- MQA(Multi-Query Attention)
:所有 query head 共享 1 个 KV head,KV Cache 压缩到原来的 1/头数。 - GQA(Grouped-Query Attention)
:把 query head 分组,每组共享 1 个 KV head,在质量和体积之间折中。
LLaMA-2-70B 采用 GQA,把 64 个 KV head 压到 8 个,KV Cache 体积直接缩小 8 倍。这也是新一代开源模型(Mistral、Gemma、Qwen 等)普遍默认 GQA 的原因。
三、缓存的三个层次
实际部署中,"KV Cache"常被泛化,其实分三层,越往上越接近应用:
|
|
|
|
|
|---|---|---|---|
| 张量级 KV Cache |
|
|
|
| 前缀缓存 |
|
|
|
| 语义缓存 |
|
|
|
- 张量级 KV Cache
(最底层):就是第二节说的显存里的 K/V 张量,解决"每步重算全序列"的问题。 - 前缀缓存
:大量请求共享同一段 system prompt或长文档前缀,把这段公共前缀的 KV Cache 计算一次、复用多次,省掉重复的预填充计算。 - 语义缓存
:对相似问题直接返回缓存答案,严格说不属于 KV Cache,但常被云厂商打包进"缓存命中"的卖点里。
三层叠加,才是云厂商"高缓存命中率"的完整图景。
四、架构方案:从单卡到集群
方案一:单机单卡
最简单,单张 GPU 装下权重 + KV Cache。缺点是显存有限,长上下文和高并发只能二选一,适合轻量场景。
方案二:单机多卡(张量并行)
模型权重按层/头切分到多张卡,KV Cache 也随之切分。好处是单机显存容量翻倍;代价是每步计算都有跨卡通信开销,需要 NVLink/高速互联支撑。
方案三:PD 分离(Prefill-Decode Disaggregation)
这是当前生产级集群的主流做法,把一次推理拆成两个独立服务:
- Prefill(预填充)
:吃下整个 prompt,一次性算出全部 KV Cache。计算密集(compute-bound)。 - Decode(解码)
:逐 token 生成,不断读写 KV Cache。显存/带宽密集(memory-bound)。
两者天然需要不同硬件配比,拆开后可以独立扩缩容:预填充集群用高算力卡,解码集群用大显存卡,KV Cache 通过高速互联在两者间传输。vLLM 的 disaggregated prefill、SGLang 的 PD 分离都是这一思想的落地。
方案四:推理集群 + 缓存亲和路由
在网关/调度层,把前缀相同的请求尽可能路由到同一个实例,让它的前缀缓存被反复命中。这是"高缓存命中率"的最后一块拼图,也是向量云这类接入服务重点优化的能力。
一条生产级链路大致是:网关路由 → 缓存亲和调度 → PD 分离集群 → 张量并行多卡 → 分页 KV Cache。
五、缓存亲和路由的开源实现
前缀缓存只在同一进程内生效。一旦水平扩成多实例/多节点,就会出现尴尬一幕:请求 A 在 worker-1 算好了 system prompt 的 KV,请求 B 带着同样的前缀却被路由到 worker-2,只能重新 prefill 一遍,缓存白搭。
缓存亲和路由,就是让前缀相同(或同一会话)的请求,尽量落到"已经持有对应 KV Cache"的那个 worker。核心就两件事:路由 key 怎么定、决策怎么做。按此,开源方案分三类。
第一类:通用网关的一致性哈希 / 会话粘性
思路最朴素:不关心 KV 内容,只保证"同一个 key 永远去同一个后端"。
|
|
|
|
|---|---|---|
| Envoy |
|
|
| Istio |
|
|
| Nginx |
|
hash $arg_session consistent; |
优点通用、零侵入、成熟稳定;缺点只按"静态 key"亲和,不知道 worker 真实 KV 命中率,扩缩容时命中率骤降,属于入门方案。
第二类:推理框架/网关内置的缓存感知路由
这类会感知每个 worker 实际持有的 KV Cache 状态,把请求发给"前缀命中最多、重算成本最低"的 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 的节点);第三类反过来——“缓存跟着算力走”,把 KV 直接在节点间搬运,从根上解耦路由与缓存位置。
- Mooncake Transfer Engine
:月之暗面开源,Prefill 集群算好 KV 后用 RDMA / GPUDirect 直接搬到 Decode 集群,SGLang 官方已支持其作为 disaggregated serving 后端。 - vLLM disaggregated prefill + KV Connector
:在 prefill/decode 节点间传输 KV,同属"搬运"路线。 - LMCache
:把 KV 卸载到 CPU/磁盘并跨请求复用,可作为亲和路由的兜底层。
对比与选型
|
|
|
|
|
|
|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
一句话总结演进主线:静态哈希粘性 → 缓存状态感知路由(SGLang Router / Dynamo)→ KV Cache 中心化搬运(Mooncake),越往后越接近"缓存即一等公民"的架构。
六、开源组件盘点
vLLM —— PagedAttention 分页注意力
vLLM 把 KV Cache 切成固定大小的 block(页),像操作系统虚拟内存一样分页管理:
-
请求需要新空间时,按页分配,用完回收; -
彻底解决显存碎片化(内部/外部碎片)问题; -
配合 Continuous Batching(连续批处理),请求可随时加入/退出,不必等整批完成; -
内置 Automatic Prefix Caching,自动识别并复用共享前缀。
这是目前事实上的工业标准,绝大多数云厂商的开源推理栈都基于或借鉴它。
SGLang —— RadixAttention 前缀树
SGLang 用 Radix Tree(基数树/前缀树) 组织 KV Cache:
-
树的每个节点代表一段 token 前缀; -
多个请求共享公共前缀时,天然复用同一份 KV Cache; -
尤其适合有长 system prompt、多轮对话、RAG 模板等高前缀重复场景。
RadixAttention 与 PagedAttention 互补:一个强调前缀复用,一个强调显存分页。
FlashAttention / FlashDecoding
严格说 FlashAttention 不是"缓存",而是 IO-aware 的注意力算法:把 attention 分块计算,大幅减少对高带宽内存(HBM)的读写,让长序列 attention 真正跑得动。没有它,KV Cache 方案在长上下文下依然会被显存带宽卡死。配套的 FlashDecoding 专门优化解码阶段。
TGI(Text Generation Inference)
HuggingFace 官方推理框架,内置 PagedAttention + 连续批处理,开箱即用,生态友好,适合快速上线。
TensorRT-LLM
NVIDIA 官方推理引擎,针对自家 GPU 深度优化,支持 KV Cache 复用与量化,性能天花板高,但上手门槛也更高。
LMCache
LLM 推理的 KV Cache 分层存储与复用库:它把 KV Cache 从 GPU 显存**卸载(offload)**到 CPU 内存甚至本地磁盘/分布式存储,突破显存上限以支撑超长上下文,同时支持跨请求的 KV Cache 复用,可与 vLLM 等框架无缝集成,专治"显存不够放长上下文"。
Mooncake
月之暗面(Moonshot AI,Kimi 背后的团队)开源的 KV Cache 中心化分离架构。它把 KV Cache 当作"一等公民",通过专门的 KV Cache Transfer Engine 在 Prefill 与 Decode 节点之间用 RDMA 等高速网络搬运 KV,支撑大规模 PD 分离集群,是 KVCache 中心化服务架构的代表作。
配套优化技术
|
|
|
|
|---|---|---|
| GQA / MQA |
|
|
| KV Cache 量化 |
|
|
| 滑动窗口 / StreamingLLM |
|
|
| 权重 + KV 联合量化 |
|
|
七、向量云如何把 KV Cache 变成省钱能力
对用户而言,KV Cache 优化的最终收益是两个字:省钱。向量云 ark.tokenrize.cn 作为火山方舟官方 API 的优选接入渠道,把上述架构能力落到了账单上:
- 缓存隔离
:独享缓存实例,避免共享缓存被并发请求"污染"而导致命中率骤降; - 高缓存命中率
:前缀缓存 + 亲和路由,让重复的 system prompt 和长文档前缀只算一次; - Token 折扣
:缓存命中的部分按折扣计费,长上下文、多轮对话场景省得最多。
向量云核心优势
-
◆ 官方 API 直连,模型能力完全一致 -
◆ 缓存隔离,高命中率,命中即省 -
◆ 分时段折扣,闲时价格更优 -
◆ 企业级并发承载,稳定可靠 -
◆ 多模型兼容,一站接入主流大模型 -
◆ 按量计费,余额耗尽即停,无欠费风险
平台网址
👉 [ark.tokenrize.cn/#/register?invite_code=VASPC3R3]
注册即享专属 Token 折扣 → [立即注册] [ark.tokenrize.cn/#/register?invite_code=VASPC3R3]
火山方舟 × 向量云 · 官方 API · 缓存隔离 · Token 折扣
本文技术参数参考开源社区(vLLM / SGLang / LMCache / Mooncake / LLaMA 等)公开资料,实际以各框架与控制台为准

