长上下文服务最终会将 GPU 内存变成一个调度问题。一个请求可能完成其第一轮交互,但会留下重算成本高昂、当前又不需要保留在 GPU 上的 KV 状态。KV 缓存卸载是一种将可复用缓存块从快速的 GPU 层移至更大、更慢的层级(通常先移至主机 RAM),然后仅在后续请求能够复用这些缓存块时再将其提升回来的技术。
目标并不是让慢速存储看起来像 HBM。目标是将昂贵的 GPU KV 容量留给活跃工作集,同时让高价值前缀在其他位置保持可用。因此,当流量既有长上下文又有显著复用时,KV 缓存卸载最有价值:例如重复出现的系统提示词、RAG 脚手架、多轮会话或重复的文档前缀。
本指南将说明如何判断分层是否合适、当前 vLLM 控制项如何配合、TensorRT-LLM 为主机内存卸载提供了什么,以及如何测试这一变更,避免用尾延迟事故来替代 GPU 内存不足故障。
快速结论
将KV 缓存卸载用作前缀复用的受控扩展,而不是默认的内存修复方案。
| 流量模式 | 起步方案 | 原因 |
|---|---|---|
| 重复的长系统提示词或 RAG 前缀 | GPU 前缀缓存,然后进行 CPU 卸载试点 | 后续请求可以复用缓存的前缀,而无需重新计算。 |
| 存在非活跃时段的长生命周期交互式会话 | GPU + CPU 温层 | 非活跃上下文可以离开 GPU 内存,同时仍可恢复。 |
| 大多为一次性、唯一的提示词 | 优先考虑 GPU 容量和准入控制 | 没有未来复用价值的缓存块在卸载后只会增加传输工作。 |
| GPU 内存紧张,但主机 RAM 可用 | 小规模 CPU 卸载实验 | 卸载可以为活跃 KV 块腾出空间,但提升成本必须保持在 SLO 范围内。 |
| 需要持久的更低层级 | CPU 主层级加上经过测试的次级层级 | 次级层级可以延长保留时间,但不能替代快速的活跃层级。 |
重要约束是局部性。当复用一个已卸载的块时,它必须在注意力机制使用它之前回到 GPU 内存。该传输路径是请求延迟预算的一部分。
KV 缓存层实际存储的内容
在自回归生成期间,注意力层会为已处理的 token 生成键和值张量。保留这些张量可让服务器避免在后续解码步骤或兼容的前缀复用中重新计算已见过的前缀。在 TensorRT-LLM 中,KV 缓存被表示为块池,其中的块保存固定 token 数量的状态;其文档还介绍了跨请求复用、优先级保留和主机内存卸载。TensorRT-LLM KV 缓存系统
一个实用的服务栈通常有三种可能的存储温度:
| 层级 | 典型角色 | 优势 | 成本 |
|---|---|---|---|
| GPU HBM | 热数据、活跃的预填充和解码状态 | 访问延迟最低 | 容量最小且最昂贵 |
| CPU DRAM | 温数据、可复用块 | 容量大得多;可作为第一卸载目标 | 提升到 GPU 会增加传输时间 |
| 文件系统或对象层级 | 冷数据、保留的块 | 持久或共享容量 | 检索成本最高,且有更多运维故障模式 |
vLLM 卸载指南明确说明了顺序:其多层设计使用 CPU 作为主层级,GPU 与次级层级之间的传输通过该 CPU 层级进行暂存。换言之,冷层级命中并不是 GPU 直接读取。vLLM KV 卸载使用指南
promote on a usable cache hit
Request ──> GPU HBM <──────────────────── CPU DRAM
│ ▲
│ evict completed, reusable │ stage
▼ │
active GPU cache ─────────────> secondary storage
hot warm / cold
这个vllm KV 缓存卸载示意图刻意保持简洁:只有 GPU 层级应始终位于关键计算路径上。CPU 和存储层级应服务于可衡量的复用策略。
KV 缓存卸载不是模型权重卸载
这一区别可以避免一种出乎意料的常见错误配置:
- KV 缓存卸载移动由请求创建的注意力状态。它主要改变可用于活跃上下文的内存以及复用路径。
- 模型权重卸载移动模型参数。在 vLLM 中,
--cpu-offload-gb控制项记录在模型权重卸载下,并且可能会给每次模型前向传递增加 CPU–GPU 传输工作。vLLM serve 参数
不要假设某个能让模型加载的设置也会创建更多可用的 KV 容量。请先分离模型权重预算、运行时工作空间和 KV 缓存预算;然后再决定是否值得在 GPU 内存之外保留非活跃 KV 块。
vLLM KV 缓存卸载:从原生 CPU 路径开始
对于当前的 vLLM CLI,相关的vllm kv 缓存卸载标志是 --kv-offloading-size。官方 CLI 参考说明,这是以 GiB 为单位的 KV 卸载缓冲区大小;当张量并行度大于一时,该大小是所有张量并行 rank 的总和。未设置时将禁用卸载。配套的 --kv-offloading-backend 支持原生 CPU 后端和 LMCache。vLLM serve 参数
应使用有界试点,而不是将主机层按所有可用 RAM 进行配置:
vllm serve <your-model> \
--gpu-memory-utilization 0.85 \
--kv-offloading-size 16 \
--kv-offloading-backend native
该示例是一种实验配置形态,而非通用设置。合适的值取决于模型的缓存布局、上下文长度、张量并行配置、主机 RAM 余量、请求组合和延迟目标。在将这些标志投入生产前,请固定 vLLM 镜像版本,并在该镜像中运行 vllm serve --help;服务配置演进很快。
原生路径适合作为首次vllm kv 缓存卸载 CPU试验,因为它使分层问题保持聚焦:CPU 温层能否保留足够多的有用块,从而改善准入或避免 GPU 缓存抖动,同时不恶化 p95 和 p99 表现?
先选择缓存准入策略,再确定缓存容量
保留更多块并不一定意味着保留更多有用块。在增加卸载缓冲区之前,请回答四个问题:
- 哪些前缀在请求之间共享?
- 这些前缀在创建后多久会被再次使用?
- 相对于主机传输预算,一个有用块有多大?
- 哪些块应直接驱逐,因为其复用概率过低?
如果工作负载无法从追踪数据中回答前两个问题,请先测量 GPU 上的前缀复用情况。CPU 层可以保留温缓存状态;它无法为完全唯一的提示词凭空创造复用。
仅在完成 CPU 试点后构建 vLLM 分层路径
vLLM 的 OffloadingConnector 可用于配置 CPU 主层以及可选的次级层。官方指南介绍了适用于单一 CPU 层的 CPUOffloadingSpec,以及适用于带有一个或多个次级层的 CPU 主层的 TieringOffloadingSpec。该指南还将 LRU 和 ARC 记录为内置驱逐策略选项。vLLM KV 卸载使用指南
以下是文档化多层示例中的忠实配置形态。仅在自己的主机上完成测试后,再替换模型、路径、块大小、字节数和线程数:
vllm serve <your-model> \
--kv-transfer-config '{
"kv_connector": "OffloadingConnector",
"kv_role": "kv_both",
"kv_connector_extra_config": {
"spec_name": "TieringOffloadingSpec",
"cpu_bytes_to_use": 10737418240,
"block_size": 16,
"eviction_policy": "lru",
"secondary_tiers": [
{
"type": "fs",
"root_dir": "/mnt/kv_cache",
"n_read_threads": 32,
"n_write_threads": 16
}
]
}
}'
相比复制该代码片段,以下三个运维细节更重要:
cpu_bytes_to_use是跨所有工作进程的 CPU 层总预留,而不是对操作系统的模糊建议。应为进程、操作系统、存储页面缓存以及任何共置服务预留预算。- 配置的块或分块大小决定 I/O 单元。过小的分块可能增加元数据和调度开销;过大的分块则可能提升请求并不需要的字节。请使用真实的前缀长度测试这两种情况。
- 次级层位于 CPU 层的下游。如果 CPU 层太小或已饱和,增加文件系统容量可能会保留更多数据,但无法改善后续命中的延迟。
因此,vllm kv 缓存卸载的目标并不是“保留一切”,而是“保留具有合理且及时复用路径的块”。
将 TensorRT-LLM KV 缓存卸载到主机内存
TensorRT-LLM 通过其 KV 缓存配置提供了相同的基本理念。其文档指出,host_cache_size 会分配用于卸载的主机内存,默认值为零,并允许块保持可复用状态,直到之后从主机内存中被驱逐。在复用时,该块会被复制回 GPU 内存。TensorRT-LLM KV 缓存系统
对于tensorrt-llm kv 缓存卸载主机内存部署,除容量外还应关注保留策略:
| TensorRT-LLM 控制项 | 需要验证的内容 |
|---|---|
host_cache_size |
字节预算经过审慎设定,并留有主机内存余量。 |
| 块优先级 / 保留策略 | 频繁复用的提示词区域优先于可丢弃数据被保留。 |
secondary_offload_min_priority |
低优先级块可以绕过主机卸载并被直接驱逐,从而减少可避免的主机流量。 |
| 跨请求块复用 | 复用保持启用状态,并且可与调度器估算值分开观测。 |
截至本文撰写时,TensorRT-LLM 文档中记录的默认 secondary_offload_min_priority 为 35。应将其视为随版本变化的默认值,而非策略建议:阈值应反映您的服务中观测到的复用价值和传输成本。
保护延迟的上线方法
不要在容量事故期间启用冷层,并在 OOM 停止后就宣布成功。应改为执行受控的步骤序列:
- 采集仅 GPU 的基线。记录上下文长度分布、并发量、首个令牌时间、令牌间延迟、端到端 p50/p95/p99、前缀复用率以及 GPU KV 驱逐行为。
- 预留真实的主机余量。纳入运行时开销和操作系统;不要仅根据可用内存快照来确定 CPU 缓存大小。
- 启用小型 CPU 层。在改变一个缓存维度时,保持模型、批处理策略、流量形态和 SLO 告警稳定。
- 比较命中质量,而不只是命中次数。区分 GPU 命中、CPU 提升、冷层提升,以及触发重新计算的未命中。
- 检查竞争下的尾延迟。运行长短混合请求以及并发爬坡测试。仅看均值的结果会掩盖传输队列问题。
- 仅在保留价值足以证明其合理性时才添加二级层。在广泛上线前,测试缓存丢失、存储压力、重启行为和提升突发情况。
- 设定回滚规则。例如:当 p99 首个令牌时间或令牌间延迟在持续一段时间内超出约定预算时,禁用最新加入的层。
vLLM 指南记录了配置和卸载指标,包括配置信息和 CPU 缓存使用信号。应将它们与应用程序追踪结合使用;没有请求级延迟的缓存指标,难以区分有价值的提升与传输抖动。vLLM KV 卸载使用指南
需要在设计中规避的故障模式
| 故障模式 | 表现 | 更好的应对方式 |
|---|---|---|
| 将所有缓存块都视为有价值 | CPU 层被填满,提升操作增多,延迟恶化 | 根据复用证据而非仅按创建顺序进行准入和保留。 |
| 混淆权重卸载与 KV 缓存卸载 | 模型能够加载,但长上下文并发能力仍然较差 | 分别规划权重、KV、工作区和安全余量预算。 |
| 过度承诺主机 RAM | 主机开始回收内存,或共置服务变得不稳定 | 预留固定预算,并在真实竞争条件下进行负载测试。 |
| 过早添加二级层 | 保留的字节更多,但 SLO 没有实质改善 | 先证明 CPU 层复用的价值;再独立测试冷层。 |
| 忽略传输拓扑 | 实验室结果良好,共享节点上的 p99 却很差 | 在生产环境所使用的确切 GPU、CPU、PCIe/NVLink 拓扑和存储路径上进行基准测试。 |
| 向运维人员隐藏缓存行为 | 事故看起来像随机的延迟波动 | 暴露特定层的命中、提升、驱逐、容量和错误信号。 |
KV 缓存卸载并非正确优化手段的情况
在以下情况下,暂时不要采用 KV 缓存卸载:
- GPU 内存不是限制因素。
- 提示词几乎全都唯一,因此保留的前缀不会再次出现。
- 您的主要 SLO 是极低的尾延迟,且无法证明传输路径能够满足该要求。
- 主机 DRAM 或存储已是生产环境中存在竞争的资源。
- 尚未评估前缀缓存、批处理、上下文限制、模型选择或缓存量化。
在这些情况下,更清晰的第一步可能是审查 GPU 内存预算、采用不同的上下文策略,或变更服务架构。有关拓扑和并行化选择,请参阅 vLLM 多 GPU 推理、vLLM 与 SGLang以及 TensorRT-LLM 与 vLLM。
常见问题
KV 缓存卸载会减少 GPU 内存使用吗?
它可以通过将可复用的非活动 KV 块移出 GPU 层,降低这部分带来的压力。但它不会消除活动注意力计算对 GPU 驻留缓存的需求,并且复用已卸载的块前,必须先将其提升回来。
vLLM 的 KV 缓存卸载标志是什么?
在当前 vLLM CLI 文档中,设置 --kv-offloading-size 会启用 KV 卸载缓冲区,而 --kv-offloading-backend 用于选择后端。请在您固定使用的 vLLM 版本中核实确切的标志。vLLM serve 参数
文件系统层是直接 GPU 缓存吗?
不是。vLLM 文档将 CPU 作为其多层实现的主层;GPU 与二级层之间的传输会经由 CPU 内存进行暂存。因此,二级层测试必须涵盖完整的提升路径。
KV 缓存卸载比购买更大的 GPU 更好吗?
它们解决的是不同的约束。更大的 GPU 可以在没有提升开销的情况下增加热工作集。卸载则可以在现有 GPU 容量下保留有用的温状态或冷状态。应根据工作负载测得的复用情况、延迟 SLO、运维负担和总服务成本,对两者进行比较。
结论:将 KV 缓存卸载视为缓存策略,而非容量技巧
最完善的KV 缓存卸载设计会将活跃状态保留在 GPU 上,将 CPU 内存预留给有证据支持的温数据复用,并且仅当衡量传输成本和故障处理后,保留冷数据仍然具有价值时才添加冷层。先从受限的 CPU 试点开始,按层级监测提升操作和延迟,并且仅推广能够改善生产 SLO 的策略,而不只是增加保留的缓存量。
如果自托管服务栈的运营成本超过了您的工作负载所需控制能力的价值,请在投入更大规模的集群之前,比较采用模型 API 的 GPU 云部署,或探索 Flatkey Compute。



