什么是 KV 缓存?为什么 AI 聊得越久越吃显存,一次讲明白(2026入门)

去年我第一次在自己机器上用 Ollama 跑 8B 模型,发现一件怪事:同一个会话,第一句回答飞快,聊到几十轮之后,字往外蹦的速度肉眼可见地慢了下来。

一开始我以为是机器老了。后来翻资料才知道这是个普遍现象,背后的主角,就是今天要说的 KV 缓存。这个名字在推理框架的文档、模型发布页、API 定价说明里到处都是,很多人被它劝退,其实拆开看一点都不玄。

AI 写字的方式:每个新字都要回头看前文

之前写过一篇讲注意力的入门文章,Transformer 生成文字的方式,是让当前这个 token 「回头看」前面所有的 token,判断谁跟谁有关系,再决定下一个字输出什么。token 要是觉得陌生,就理解成「字或者词的一小块」,怎么切、怎么算钱,之前那篇 token 科普里算过账。

「回头看」落到实现上,是拿当前 token 跟前面每个 token 的 Key、Value 做运算。Key 和 Value 可以粗暴理解成每个 token 的两份档案:Key 用来被查询,Value 是等着被取走的内容。每个 token 都有,而且模型每一层都有一套。

笨办法:每写一个字,把前文全部重算

假如不做任何优化,生成第 1000 个 token 的时候,为了算注意力,前面 999 个 token 的 Key 和 Value 得全部重算一遍;写第 1001 个的时候,又是 1000 个。前文的档案每次推倒重来,一份都不复用。序列越长浪费越狠,计算量按平方往上涨。

市面上没有哪个推理系统真的这么干,因为谁都用不起。

KV 缓存:算过的档案留着别扔

实际的做法很直白。每个 token 的 Key 和 Value,算完一次不删,就放在显存里。生成新 token 时只算它自己的 Key 和 Value,加到队伍末尾,前面的直接取用。

这就是 KV 缓存的全部。名字唬人,思路跟写代码时「中间结果存下来别重复算」是同一个想法。

代价也直白:档案要占地方。缓存越滚越大,显存越吃越多。更要命的是,每生成一个新字,GPU 都要把整条缓存从显存里读一遍。队伍越长,读得越多,速度自然就慢下来。MQA 那篇论文专门讲了这个瓶颈,说反复装载巨大的 Key、Value 张量,开销全压在显存带宽上。

这笔账有多大:拿 Qwen3-8B 算给你看

空讲没感觉,算一笔。Qwen3-8B 的官方配置文件里写着:36 层,32 个注意力头,8 个 KV 头,每个头 128 维。每存一个 token 的 KV,就是 36 层乘 8 个头乘 128 维,再乘 2(Key 和 Value 各一份)乘 2 字节(FP16 存放),等于 147456 字节,正好 144KB。

一个 token 144KB,听着不起眼,乘起来吓人。4K 上下文约 576MB,32K 约 4.5GB。模型权重本身,80 亿参数按 FP16 算要 16GB 上下。也就是说,对话拉到 32K 长度时,光 KV 缓存就要再吃掉 4.5GB,接近权重本身的三分之一。

这就解释了一件常见的事:为什么不少本地模型明明标着支持 128K 上下文,你的显卡却根本撑不到那里。不是模型撒谎,是显存放不下那条越来越长的档案。

显存不够,工程师想了两头的办法

一头是少存。上面算式里那个「8 个 KV 头」就是成果。最早的 Transformer,32 个注意力头各存一套 KV;2019 年的 MQA 论文让所有头共用一套,速度快了,但论文自己也承认质量会掉一点;后来的 GQA 取了个中间值,几个头搭伙共用一套。Qwen3-8B 的 32 个头配 8 套 KV 走的就是 GQA 路线,缓存直接少存四分之三,论文的说法是质量接近全量方案、速度接近 MQA。现在主流开源模型基本都跟着这条路走。

另一头是管好浪费。vLLM 那篇 2023 年的论文开头就点名,各家推理系统里 KV 显存被碎片和重复复制糟蹋得厉害。它借了操作系统管内存的分页机制,把 KV 缓存切成小页来管理,论文的说法是浪费接近零,同样的卡吞吐提升 2 到 4 倍。这套叫 PagedAttention 的技术,现在是自托管推理服务绕不开的名字。

还有一条路,不省显存,省的是重复计算。API 服务商把公共前缀的 KV 存下来,后面的请求直接复用,这就是上下文缓存。之前写过它的计费门道,命中部分能便宜一个数量级。当时没细说的是,它省掉的其实就是「这批 KV 不用重新算」这一步。系统提示词放在开头为什么能省钱,到这里也通了。

这跟你有什么关系

几件日常琐事,到这里都有了解释。

API 按 token 计费,长对话越聊越贵,因为每一轮都要把前面全部内容再处理一遍;本地模型标 128K 你跑不动,是 KV 缓存把显存吃光了;自建服务并发上不去,多半也是 KV 显存把批量卡死了。

本地跑模型的话还有个实操建议:如果客户端允许调上下文长度,别无脑拉满。用不上 128K 的场景,把上下文压到 8K 甚至 4K,KV 缓存的占用跟着线性下降,省出来的显存给模型本身或者并发请求,都比闲置着强。

我自己因此养成了一个习惯:特别长的会话,隔段时间就开个新窗口,让 AI 把前面的要点总结成一段带过去。省 token 钱,也顺便绕开另一个坑,长上下文中间的内容容易被模型忽略,那篇有实验数据。

KV 缓存本身没什么可操作的,但弄明白「AI 每一次快问快答,都是拿显存和时间换的」,再去看 API 定价页,或者对比显卡的显存参数,很多数字忽然就对上号了。

发表评论