调查研究-221 KV Cache:LLM 推理服务真正的显存黑洞
TL;DR场景高并发、长上下文、RAG 与 Agent 场景下的 LLM Serving 显存压力排查与容量规划结论模型权重只是入场券KV Cache 才是动态显存账本并发、上下文、输出三项 workload 共同决定系统能不能稳定跑产出KV Cache 大小估算公式 8 类常见故障速查卡 7 条工程优化方向 vLLM / SGLang / TensorRT-LLM 版本矩阵版本矩阵功能状态说明PagedAttentionKV 分页管理✅ 已验证vLLM 提出论文 arXiv:2309.061802023-09借鉴 OS 虚拟内存分页vLLM docs 明文支持 block 组织 KVRadixAttentionradix tree 前缀复用✅ 已验证SGLangLMSYS Blog 2024-01-17 发布用 radix tree 跨请求复用前缀 KVTensorRT-LLM paged KV cache✅ 已验证NVIDIA TensorRT-LLM 官方支持思路与 PagedAttention 一致与 in-flight batching 协同Continuous / In-flight Batching✅ 已验证vLLM/HF 文档明文支持TensorRT-LLM 称为 in-flight batching核心思想一致Prefix CachingAutomatic Prefix Cache✅ 已验证vLLM 0.4 支持使用 hash-based radix treeSGLang RadixAttention 同源KV Cache FP8 量化✅ 已验证vLLM--kv-cache-dtype fp8fp8_e4m3 / fp8_e5m2实测可省约 50% 显存但需硬件支持Disaggregated Prefilling✅ 已验证vLLM 官方 docs 列入生产能力prefill / decode 分到不同资源池需解决 KV 跨节点传输KV Cache offloadCPU/NVMe/远端⚠️ 待验证多框架支持雏形传输延迟与带宽成本需结合 workload 实测PyTorch 原生连续分配 KV Cache❌ 反模式LLaMA-13B 单序列 KV 占约 1.7GB连续分配极易碎片化已被 PagedAttention 取代只看显存总占用不监控 KV 指标❌ 反模式显存总量足够不代表 KV 形状够必须监控 used/free blocks、prefix hit rate、preemptionLLM Serving 的核心瓶颈很多时候不是模型权重而是 KV Cache。模型权重是固定的。一个 14B 模型用 BF16 大约 28GB 权重部署前就知道要占多少显存。但 KV Cache 是动态增长的请求越多、上下文越长、输出越长它越大。在线高并发时系统真正容易失控的就是这部分。理解 KV Cache是理解 vLLM、PagedAttention、prefix caching、RadixAttention、disaggregated serving 的前提。如果把 GPU Serving 当成“模型权重放进显存然后请求来了就 generate”很快会遇到一个现实问题权重没变显存却越来越紧并发一上来长上下文一增多系统开始排队、抢占、拒绝请求或者流式输出变慢。很多时候那个正在吞掉系统稳定性的东西就是 KV Cache。一、为什么需要 KV CacheTransformer 自回归生成时每生成一个 token都需要基于前面所有 token 的上下文做 attention。如果没有 KV Cache生成第 1000 个 token 时模型需要重新计算前面 999 个 token 的 Key 和 Value。生成第 1001 个 token 时又要重新计算前面 1000 个 token。这样会产生大量重复计算。KV Cache 的作用就是前面 token 的 Key 和 Value 已经算过了就存下来。后续生成新 token 时只需要计算新 token 的 Q/K/V然后用新 token 的 Query 去和历史 KV 做 attention。这会极大降低 decode 阶段的重复计算让自回归生成变得可用。所以 KV Cache 本质是用显存换时间。它让模型不用反复计算历史 token但代价是每个请求都要占用一份不断增长的缓存。可以把它理解成一份“历史上下文账本”。每个请求一开始进入 prefill系统会为输入 prompt 建立账本进入 decode 后每生成一个 token账本就追加一行直到请求结束、取消、到达最大输出长度或者被系统淘汰账本才有机会释放。二、KV Cache 到底有多大一个简化估算公式KV Cache 显存 ≈ 层数 × token 数 × batch size × KV 维度 × 2 × 单元素字节数这里的2代表 Key 和 Value 两份缓存。单元素字节数取决于精度比如 FP16/BF16 是 2 字节FP8 是 1 字节。注意几个变量。层数越多KV Cache 越大。上下文 token 越长KV Cache 越大。并发请求越多KV Cache 越大。输出越长KV Cache 也越大因为生成 token 也会追加进入缓存。这就是长上下文和高并发难以共存的原因。一个 32K 上下文请求可能消耗大量 KV Cache多个 32K 请求同时在线会迅速吃掉显存。更麻烦的是KV Cache 的占用不是静态配置项而是 workload 的结果。用户今天问短问题显存看起来很宽松明天 RAG 开始塞长文档Agent 开始多轮调用P95 上下文长度上来显存压力就会突然变成服务问题。因此做容量规划时不能只问“模型权重占多少”。还要问问题为什么重要平均上下文长度是多少影响常态 KV Cache 占用P95 / P99 上下文长度是多少决定尾部请求是否挤爆显存最大输出长度是多少decode 越久缓存越大同时 running sequence 有多少并发直接放大 KV Cache是否有共享前缀决定 prefix cache 是否有价值三、为什么 Decode 经常是 memory-boundPrefill 阶段通常是大块矩阵计算。prompt 很长时模型可以并行处理多个输入 token因此更容易形成大规模计算。Decode 阶段每轮只生成一个 token。每个请求每 step 的计算规模很小但需要访问模型权重和历史 KV Cache。随着上下文变长读取 KV Cache 的成本越来越高。这导致 decode 阶段经常不是算力不够而是显存带宽和内存访问效率不够。表现出来就是GPU Util 看起来可能不低但 tokens/s 上不去batch size 增大后TPOT 迅速变差长上下文请求进入系统后所有人的流式输出变慢显存占用没有马上 OOM但 KV block 已经接近上限queue time 和 preemption 开始上升。这类问题不能只靠加线程解决也不能只靠扩大 batch 解决。必须管理 KV Cache 的布局、复用、淘汰和调度。很多人第一次做 LLM Serving会把注意力放在算力上GPU 型号、TFLOPS、quantization、batch size。但在线生成的体验常常卡在另一条线上每个 decode step 都在读历史 KV。上下文越长这份历史越重并发越高这份历史账本越多。四、KV Cache 的生命周期很复杂一个请求的 KV Cache 不是一次性申请、一次性释放那么简单。请求进入 prefill 后需要为输入 prompt 建立 KV Cache。进入 decode 后每生成一个 tokenKV Cache 增加一点。如果请求流式输出持续很久它的 KV Cache 会一直占用显存。如果用户取消请求系统要尽快释放对应缓存。如果请求生成到max_tokens系统要释放缓存。如果多轮对话使用相同前缀系统可能希望复用前面的 KV Cache。如果 beam search 或并行采样多个分支可能共享一部分前缀 KV Cache然后在分叉后各自增长。所以 KV Cache 是一个动态对象。它有创建、增长、共享、分裂、释放、淘汰等状态。粗糙管理会造成大量浪费。显存碎片化也来自这里。传统思路里可以为每个请求分配一段连续显存来存 KV Cache。但 LLM 请求长度不确定这种方案很容易碎片化。假设系统中有三个请求请求最终缓存长度风险A1000 token中等缓存生命周期可能很短B200 token如果预留太大会浪费C4000 token如果预留太小需要扩容如果一开始不知道它们最终长度就很难一次性分配刚刚好的连续显存。分少了要扩容分多了浪费。请求结束时间也不一致释放后会留下大小不一的空洞。碎片化的结果是显存总量看起来还够但找不到足够合适的连续区域或者为了避免扩容系统过度预留导致实际可并发请求数下降。PagedAttention 正是为了解决这个问题不要求 KV Cache 连续存储而是像操作系统分页一样把缓存拆成 block 来管理。vLLM 文档中也明确把 key/value cache 拆成固定 token 数的 block 来组织每个请求通过 block 映射来访问自己的上下文。五、KV Cache 复用从省计算到省延迟很多 LLM 场景有共享前缀。聊天机器人有固定 system prompt。Agent 有固定工具描述。RAG 可能多次使用同一份文档前缀。代码助手有重复仓库上下文。多轮对话中前几轮历史经常保持不变。如果每次请求都重新 prefill 这些相同 token就会浪费计算也会拉高 TTFT。Prefix caching 的价值就在这里相同前缀的 KV Cache 可以复用后续请求从已有缓存继续计算。SGLang 的 RadixAttention 更进一步把共享前缀组织成 radix tree让不同请求可以复用公共前缀的 KV Cache。对于系统 prompt 重复、few-shot 示例重复、Agent 模板重复的 workload这类缓存复用很有价值。缓存复用的收益不只是省算力也是在省首 token 延迟。对于在线交互来说TTFT 直接决定用户感知对于 Agent 链路来说多次 LLM 调用会把 TTFT 放大成整体等待。但要注意prefix caching 不是万能的。如果每个请求 prompt 都完全不同缓存命中率就低。缓存系统本身也有元数据管理、淘汰策略和显存占用成本。因此做 prefix caching 前要先看 workloadworkload 特征缓存价值固定 system prompt 多高工具 schema 重复高同一批文档被反复问中到高用户 prompt 完全随机低prompt 模板不稳定命中率容易下降六、KV Cache 和 RAG / Agent 的关系RAG 系统经常把检索到的文档塞进 prompt。这样会显著增加 prefill token 数也会扩大 KV Cache。如果每次检索内容都不同prefix cache 命中率可能不高。如果业务中有大量用户围绕同一批文档提问比如企业知识库、固定产品手册、代码仓库文档那么文档前缀可能有复用价值。RAG 系统优化不能只看召回质量还要看 token 成本。文档越长prefill 越慢KV Cache 越大TTFT 越差。很多时候压缩上下文、重排文档、减少冗余段落比换更强 GPU 更有效。Agent 场景比普通聊天更依赖 KV Cache 管理。一个 Agent 请求可能包含系统提示词、工具列表、工具 schema、历史状态、用户问题、规划过程、工具返回结果。工具调用几轮后prompt 迅速膨胀。如果每一步都重新 prefill 完整上下文延迟会被放大。一次用户请求可能调用模型 5 次每次 TTFT 增加 500ms整体体验就会多等几秒。Agent 还经常有共享模板。比如相同系统 prompt、相同工具描述、相同输出格式约束。这些都是 prefix caching 的潜在命中点。所以面向 Agent 的 Serving 不能只关注单请求吞吐还要关注多轮调用中的 KV 复用、上下文裁剪和 prompt 结构稳定性。七、KV Cache 的常见优化方向KV Cache 的优化方向可以分成两类减少占用提升复用。第一分页管理。把 KV Cache 拆成固定大小 block避免连续显存分配和碎片浪费。这是 PagedAttention 的核心思路之一。第二prefix caching。复用相同前缀降低 prefill 成本改善 TTFT。第三KV Cache quantization。用更低精度存 KV降低显存占用但可能影响质量或速度需要实测。第四cache eviction。显存不足时淘汰低价值缓存比如很久不用的 prefix。第五offload。把部分 KV Cache 放到 CPU 内存、NVMe 或远端 KV 存储但会带来传输延迟。第六context compression。减少进入模型的 token本质上是从源头减少 KV Cache。第七prefill/decode 分离。不同 GPU 池处理不同阶段但需要解决 KV Cache 跨节点传输问题。生产系统里必须直接监控 KV Cache而不是只看显存总占用。建议关注KV cache used blocksfree blocksblock allocation failureprefix cache hit rateeviction countpreemption count平均上下文长度P95 上下文长度running sequenceswaiting sequences。如果 KV Cache 使用率长期接近上限系统会频繁拒绝请求、抢占请求或者排队变长。如果 prefix cache hit rate 很低说明缓存策略没有命中 workload或者 prompt 不稳定。如果 P99 TTFT 很高同时长 prompt 比例上升说明 prefill 和 KV 分配可能是瓶颈。如果 TPOT 变差同时上下文长度变长说明 decode 阶段 KV 读取压力上升。八、核心结论KV Cache 是 LLM Serving 的核心资源。模型权重是固定成本KV Cache 是动态成本。高并发、长上下文、长输出、多轮 Agent、RAG 文档都会放大 KV Cache 压力。系统是否能稳定服务大量请求很大程度取决于它是否能高效管理 KV Cache。vLLM 的 PagedAttention、SGLang 的 RadixAttention、TensorRT-LLM 的 paged KV cache本质上都在围绕这个问题做工程优化。如果要自研 GPU ServingKV Cache Manager 不是附属模块而是核心模块。它决定了系统能同时容纳多少请求也决定了 TTFT、TPOT 和尾延迟能否稳定。可以把这篇文章压缩成一句话模型权重决定你能不能把模型放进显存KV Cache 决定你能不能把服务稳定跑起来。参考资料vLLM Documentation: https://docs.vllm.ai/vLLM Paged Attention: https://docs.vllm.ai/en/latest/design/paged_attention/vLLM Blog, Easy, Fast, and Cheap LLM Serving with PagedAttention: https://vllm.ai/blog/2023-06-20-vllmPaper, Efficient Memory Management for LLM Serving with PagedAttention: https://arxiv.org/abs/2309.06180NVIDIA TensorRT-LLM Documentation: https://nvidia.github.io/TensorRT-LLM/NVIDIA TensorRT-LLM Memory Usage: https://nvidia.github.io/TensorRT-LLM/reference/memory.htmlNVIDIA Developer Blog, KV Cache Reuse Optimizations in TensorRT-LLM: https://developer.nvidia.com/blog/introducing-new-kv-cache-reuse-optimizations-in-nvidia-tensorrt-llm/LMSYS Blog, Fast and Expressive LLM Inference with RadixAttention and SGLang: https://www.lmsys.org/blog/2024-01-17-sglang/SGLang Documentation: https://sgl-project.github.io/错误速查卡症状根因定位修复长 prompt 进入后排变长 / TTFT 飙升KV block 接近上限新请求分配失败监控 KV used/free blocks、block allocation failure启用 PagedAttention、扩大 KV 预算、上 prefill/decode 分离流式输出节奏变慢 / TPOT 变差长上下文让 decode 阶段显存带宽成为瓶颈监控 P95 上下文长度、KV read 占比context compression、chunked prefill、KV FP8 量化GPU Util 不低但 tokens/s 上不去Decode 是 memory-bound 不是 compute-bound对比 GPU Util 与 tokens/s看 KV 读取时延收窄 max-num-seqs、prefix cache 复用、控制并发度prefix cache hit rate 持续偏低prompt 模板不稳定 / 每请求 prompt 都不同 / 没上 RadixAttention看 prompt 哈希分布、workload 特征固定 system prompt 顺序、用 RadixAttention、整理模板突发 OOM / 显存看似没用满但崩溃KV Cache 碎片化连续分配失败看显存总量 vs 最大连续块上 PagedAttention、用 block 管理、限制单序列预留preemption 频繁上升 / waiting 排长队running 序列过多 长输出占用 KV 不释放监控 preemption count、waiting sequences限制 max-num-seqs、调小 max_tokens、加 cache evictionAgent 链路上整体等待秒级多次 LLM 调用 TTFT 累积放大端到端打点每跳 TTFTprefix cache 共享模板、context compression、压缩工具描述高并发长上下文上线后显存被吃光KV 是 workload 乘法结果不是配置项看 P99 上下文长度 × running seqs容量规划按 P99 算、上 disaggregated serving、KV 量化作者武子康的个人博客

相关新闻

10亿元,最大一笔融资!快造科技C轮落定,加速布局消费级3D打印市场

10亿元,最大一笔融资!快造科技C轮落定,加速布局消费级3D打印市场

在消费级3D打印牌桌上,快造更有底气了。2026年7月8日,快造科技(snapmaker)宣布完成10亿元C轮融资,成为近两年一级市场消费级3D打印领域最大规模的单笔融资。本轮融资由凯辉基金领投,好未来战投跟投&#xf…

2026/7/9 16:17:42阅读更多 →
基于TB6593FNG与PIC32的直流电机控制系统设计

基于TB6593FNG与PIC32的直流电机控制系统设计

1. 项目背景与核心器件选型在工业自动化和精密控制领域,直流电机因其优异的调速性能和转矩特性一直是关键执行元件。这次我们要探讨的是基于TB6593FNG驱动芯片和PIC32MX675F256L微控制器的定制化直流电机控制系统,这个组合特别适合需要高动态响应和精确位…

2026/7/9 16:17:42阅读更多 →
如何实现Navicat Mac版无限试用:技术原理与实战指南

如何实现Navicat Mac版无限试用:技术原理与实战指南

如何实现Navicat Mac版无限试用:技术原理与实战指南 【免费下载链接】navicat_reset_mac navicat mac版无限重置试用期脚本 Navicat Mac Version Unlimited Trial Reset Script 项目地址: https://gitcode.com/gh_mirrors/na/navicat_reset_mac 还在为Navica…

2026/7/9 16:17:42阅读更多 →
有色金属微观金相检测应用解析 —— 苏州恒商工业一体化金相显微镜解决方案

有色金属微观金相检测应用解析 —— 苏州恒商工业一体化金相显微镜解决方案

一、铜合金、铝材微观金相检测的行业应用价值 有色金属的力学性能、耐腐蚀能力、加工稳定性均由内部显微组织决定,金相微观分析是来料质检、工艺验证、失效溯源的核心手段。 重点:铝合金检测需观察晶粒大小、共晶硅形态、粗晶环、析出相分布&#xff1b…

2026/7/9 17:28:39阅读更多 →
ISOM8710与PIC18LF47K40在高压隔离系统中的应用

ISOM8710与PIC18LF47K40在高压隔离系统中的应用

1. 项目背景与核心需求 在工业控制、医疗设备和电力监测等领域,高压安全隔离是确保系统可靠性和操作人员安全的关键技术。传统的光耦隔离方案存在速度慢、寿命有限等缺陷,而ISOM8710这款3.75kVRMS高速单通道数字隔离器与PIC18LF47K40微控制器的组合&…

2026/7/9 17:28:39阅读更多 →
支持定制的许可证管理方案,满足企业个性化需求

支持定制的许可证管理方案,满足企业个性化需求

过去十几年,企业软件资产管理的重心一直在从"有没有管"向"管得好不好"转移。随着研发型组织规模扩大、IT架构混合化,标准化的盒子产品越来越难匹配复杂的业务场景——不同部门对许可池的争夺规则不同、跨区域子公司的合规口径不同、…

2026/7/9 17:28:39阅读更多 →
C语言 static/volatile 关键字:嵌入式开发中 3 个易错场景与内存优化实战

C语言 static/volatile 关键字:嵌入式开发中 3 个易错场景与内存优化实战

C语言 static/volatile 关键字:嵌入式开发中的3个实战陷阱与内存优化技巧 在嵌入式系统的世界里,每个字节的内存和每个时钟周期都弥足珍贵。作为嵌入式开发者,我们常常需要在有限的资源下实现复杂的功能,而C语言中的 static 和 …

2026/7/9 17:28:39阅读更多 →
统信UOS部署Burp Suite全攻略:Java环境配置与安全测试工具集成

统信UOS部署Burp Suite全攻略:Java环境配置与安全测试工具集成

1. 项目概述:为什么要在统信UOS上部署Burp Suite? 如果你是一名安全研究员、渗透测试工程师,或者正在学习Web应用安全,那么Burp Suite这个名字对你来说一定如雷贯耳。作为Web安全测试领域的“瑞士军刀”,它集代理、爬…

2026/7/9 17:28:39阅读更多 →
JDK25 Windows环境搭建与卸载实战指南(2026 LTS版)

JDK25 Windows环境搭建与卸载实战指南(2026 LTS版)

1. 这不是“又一个JDK安装教程”,而是Java开发者2026年绕不开的实操起点你点开这个标题,大概率正卡在某个关键节点上:可能是刚拿到公司新发的Windows 11开发机,双击IDEA却弹出“Cannot determine java version”;也可能…

2026/7/9 17:23:37阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/9 5:56:19阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/9 9:45:20阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/9 2:47:07阅读更多 →
Three.js 着色器光效教程

Three.js 着色器光效教程

着色器光效 Shader Light ▶ 在线运行案例 案例合集: 三维可视化功能案例(threehub.cn)开源仓库github地址: https://github.com/z2586300277/three-cesium-examples400个案例代码: 网盘链接 你将学到什么 ShaderMaterial 自…

2026/7/9 0:04:37阅读更多 →
如何5分钟掌握CS2智能库存管理:开源工具CASEMOVE终极指南

如何5分钟掌握CS2智能库存管理:开源工具CASEMOVE终极指南

如何5分钟掌握CS2智能库存管理:开源工具CASEMOVE终极指南 【免费下载链接】casemove A dedicated desktop app that enables you to move items in and out of storage units in CS2. 项目地址: https://gitcode.com/gh_mirrors/ca/casemove 还在为CS2存储单…

2026/7/9 0:04:37阅读更多 →
GBase 8a vs MySQL 8.0:ALTER TABLE语法与限制的5点关键差异对比

GBase 8a vs MySQL 8.0:ALTER TABLE语法与限制的5点关键差异对比

GBase 8a与MySQL 8.0:ALTER TABLE语法差异深度解析与实战指南1. 两种数据库的ALTER TABLE能力全景对比在数据库架构设计和运维过程中,表结构变更(DDL操作)是不可避免的需求。GBase 8a作为国产分析型数据库代表,与开源M…

2026/7/9 0:04:37阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/9 9:45:20阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/9 15:50:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/9 14:14:17阅读更多 →