想象一家川菜馆的后厨:大师傅每炒一道新菜,都要把从开店到现在所有客人点过的菜全部重新切一遍、重新备一遍料,才能决定这一勺该放多少盐。你会不会觉得这家店迟早要关门?可惜,很多大模型在“思考”时就是这么干的——每生成一个新的词,都要重新计算前面所有词的位置和含义(Key/Value 向量),重复劳动量大得吓人。 KV Cache 就是给后厨装上的“备菜架”:把每道菜已经切好的配菜(Key 和 Value 向量)留在案板上,新菜只切自己的部分,旧配菜直接拿来用。可问题来了:菜越点越多,案板(显存)不够用了。于是工程师们出了三招——把案板换成“分格置物架”(PagedAttention),让同样锅底的客人“共享一锅高汤”(Prefix Caching),以及让聊了很久的客人“续桌加菜不重做”(多轮对话共享)。这三招,就是大模型推理优化里最值钱的 KV Cache 工程。

岗位关联

KV Cache 优化是大模型推理部署的核心功课,掌握它,意味着你能用更少的显卡扛住更高的并发,这也是推理框架与 ML Infra 岗位面试的必考点。

目录
  1. 可视化演示
  2. 1. KV Cache 原理:备菜架与长记性的厨师
  3. 2. 显存瓶颈:案板不够用了
  4. 3. PagedAttention:分格置物架
  5. 4. Prefix Caching:共享一锅高汤
  6. 5. 多轮共享策略:续桌加菜不重做
  7. 6. 工程实践权衡:后厨的管理智慧
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

1. KV Cache 原理:备菜架与长记性的厨师

川菜馆后厨里,一位真正的大师傅炒新菜前,总要回味最近几道菜的味道——这一勺盐放多重、辣椒下几克,全都取决于前面的菜。Transformer 生成每一个新词,也是同样的“尝菜”过程:新词必须跟前面所有词逐一比对,才能决定自己是什么。如果每生成一个词,都把前面所有词从零开始重新“切一遍”(重新计算它们的键和值),那后厨的刀工再快也跟不上客人点菜的速度。

自回归生成模型逐字输出,生成第 N+1 个字时,注意力层需要用到前 N 个字各自的 Key(键)和 Value(值)向量。最朴素的做法是每步都把整套历史 K、V 重算一遍,计算量随序列长度平方级爆炸。于是工程师发明了 KV Cache:把已经算好的 K、V 原样放在显存里,后续步骤直接取用,只计算新字自己的 K、V。

缓存并没有改变注意力本身的数学定义,它省掉的只是“重复计算”。注意力公式如下:

有了备菜架,大师傅的刀工从“每天重切所有旧菜”变成“只切新菜”。账本越来越厚,但每一页都写得明明白白——这就是 KV Cache 的全部智慧:把重复劳动变成查表。

Attention(Q,K,V)=softmax(QK⊤dk)V\displaystyle \text{Attention}(Q,K,V)=\text{softmax}\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V
通俗理解:注意力就是“新菜尝旧菜的味道”。Q 是现在这道菜的诉求,K 是每道旧菜的标签,V 是旧菜备好的食材。把 K、V 提前备好放上架,就不用每次重切。
  1. Q 是当前查询Q 来自最新生成的 token,代表“现在这道菜想要什么味道”,每个新 token 都有自己的 Q,无法复用。
    Q∈R1×dkQ \in \mathbb{R}^{1 \times d_k}
  2. K 是历史键K 是历史 token 的“菜牌标签”,缓存后无需重算,直接取出与 Q 做点积。
    K∈Rn×dkK \in \mathbb{R}^{n \times d_k}
  3. V 是历史值V 是历史 token 的“备好的食材”,按注意力权重聚合出最终结果,同样被缓存。
    V∈Rn×dvV \in \mathbb{R}^{n \times d_v}
  4. softmax 加权融合Q 与 K 点积后除以根号 d_k 缩放,再取 softmax,得到对每个历史 token 的注意力权重。
    softmax(QK⊤dk)∈R1×n\text{softmax}\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)\in \mathbb{R}^{1 \times n}

2. 显存瓶颈:案板不够用了

备菜虽好,案板却有限。后厨每切一份菜都占一块板面,客人越点越多,还没炒完,案板先堆满了,新菜没处落刀。KV Cache 也一样——它不占“模型体重”,却占“工作台面积”:对话越长,显存占用越高,而且是一条直线往上走。

要精确知道占多少,可以套一个简单公式。它由四个因素决定:每份 KV 有两套向量(K 和 V)、Transformer 每一层都要一份、每个 token 的向量维度、以及总共缓存了多少个 token。

举一个具体数字:模型 32 层、隐藏维度 4096,处理 2048 个 token,用 FP16,一条序列的 KV 就要 2×32×4096×2048×2 ≈ 1.07 GB。这还只是一个人!如果同时服务 8 个用户,光 KV 就是 8GB,一张 24GB 的消费级显卡瞬间告急。更麻烦的是,传统内存分配要求整块连续案板,序列一长就要换更大的板并整体搬菜(拷贝),剩下的边角料还放不下一整份菜(碎片)。案板满了,后厨只能“赶客”——降低并发。

Mcache=2×L×H×N×b\displaystyle M_{\text{cache}}=2 \times L \times H \times N \times b
通俗理解:显存占用 = 菜的数量 × 每份菜占的地方。上下文翻倍,占的地方就翻倍,躲不掉。
  1. 因子 2 与层数 LK、V 各一份(×2),Transformer 每一层都各有一份 KV 缓存(×L)。
    2×L2 \times L
  2. 隐藏维度 H每个 token 的 K、V 向量长度为 H,多头只是把 H 拆分,总量不变。
    HH
  3. token 总数 NN = batch_size × 序列长度,上下文越长、并发越高,占用越大。
    N=batch×seq_lenN = \text{batch} \times \text{seq\_len}
  4. 精度字节数 bFP16 是 2 字节,FP32 是 4 字节,换更低精度的量化能直接减半显存。
    b∈{2,4}b \in \{2, 4\}

3. PagedAttention:分格置物架

为什么非要一整块大案板?聪明的后厨改成统一尺寸的“分格置物架”:每份菜按固定分量装进一格,格子可以放在后厨任何一个空闲角落,不必连成一片。哪个格子放着哪道菜,记在索引牌上就行。

这就是 vLLM 提出的 PagedAttention 的核心思路,灵感来自操作系统虚拟内存的分页:KV 不再按“连续大块”分配,而是切成固定大小的 block(如 16 个 token 一块),物理块可以散落各处。

置物架让边角碎料全都用上了,索引牌一查就知道菜在哪。后厨的“案板面积”利用率接近满格,能同时接待的客人瞬间翻倍。

Btotal=⌈Nblock_size⌉,Malloc=2×L×H×Btotal×block_size×s\displaystyle B_{\text{total}}=\left\lceil \frac{N}{\text{block\_size}} \right\rceil, \qquad M_{\text{alloc}}=2 \times L \times H \times B_{\text{total}} \times \text{block\_size} \times s
通俗理解:一格格标准尺寸的置物盒,多少份菜就订多少盒,盒子可放在任意空位,索引牌(块表)负责记住位置。
  1. 块数计算ceil 向上取整,序列切成固定大小的逻辑块,最后不足一块也要占一格。
    Btotal=⌈Nblock_size⌉B_{\text{total}}=\left\lceil \frac{N}{\text{block\_size}} \right\rceil
  2. 分配总量实际显存按块分配,可能略多于实际 token 数,用少量冗余换取消灭碎片。
    Malloc=2×L×H×Btotal×block_size×sM_{\text{alloc}}=2 \times L \times H \times B_{\text{total}} \times \text{block\_size} \times s
  3. 块表映射逻辑块号经 block table 找到物理块号,物理块之间不必连续。
    phy_id=table[logical_id]\text{phy\_id} = \text{table}[\text{logical\_id}]
  4. 引用计数共享多个序列可指向同一物理块(如并行采样),写时才复制,靠引用计数维护安全。
    ref_count[phy_id]>1\text{ref\_count}[\text{phy\_id}] > 1

4. Prefix Caching:共享一锅高汤

火锅店最大的聪明,不是每桌现熬锅底,而是提前煨一大锅高汤。谁来点鸳鸯锅,直接舀一勺汤底,再涮各自的菜。请求大模型也是这样:大量请求前面都挂着同一段“服务须知”。

在真实服务里,几乎每个请求都带相同的系统提示词,比如“你是客服助手,请用礼貌语气回答……”。如果每个请求都从头把这 500 个 token 的 KV 算一遍,就是在每桌重新熬汤。Prefix Caching 专门缓存公共前缀的 KV。

实现上,对前缀 token 序列做哈希,命中则把 KV 直接接进新请求的缓存,只计算前缀之后的差异 token。汤底越浓,翻桌越快。把企业客户的合规前缀缓存下来,成千上万个请求都在同一锅高汤里舀,GPU 的火力全用在涮新菜上。

hit_ratio=LcommonLtotal,saved=Mcache×hit_ratio\displaystyle \text{hit\_ratio}=\frac{L_{\text{common}}}{L_{\text{total}}}, \qquad \text{saved}=M_{\text{cache}} \times \text{hit\_ratio}
通俗理解:一锅高汤千桌用。前缀越长、请求越相似,能省下的“熬汤时间”越多。
  1. 公共前缀长度L_common 是两条请求从头开始完全相同的 token 数,通常来自系统提示词或固定指令。
    LcommonL_{\text{common}}
  2. 总长度L_total 是请求完整 token 数,包含前缀与各自差异部分。
    Ltotal=Lcommon+LdiffL_{\text{total}} = L_{\text{common}} + L_{\text{diff}}
  3. 命中率命中率反映有多少 KV 可以直接复用,越高省得越多。
    hit_ratio=LcommonLtotal\text{hit\_ratio}=\frac{L_{\text{common}}}{L_{\text{total}}}
  4. 节省量节省的显存与计算量等于总缓存乘以命中率。
    saved=Mcache×hit_ratio\text{saved}=M_{\text{cache}}\times \text{hit\_ratio}

5. 多轮共享策略:续桌加菜不重做

客人边吃边聊,突然招手:“再加一份毛肚。”后厨绝不会把桌上已上的菜收回重做,只做新点的毛肚。多轮对话也一样:第 5 轮提问时,前 4 轮的问答已经端端正正“摆在桌上”。

朴素实现每轮都要把完整对话历史重新编码,等于每加一道菜就把整桌菜重做一遍。合理做法是:把多轮历史 token 的 KV 留在显存里,新的一轮只对新增 token 计算 K、V 再追加进缓存。

这意味着第 t 轮推理的 KV 成本只与“这一轮新增了多少 token”成正比,与总历史长度解耦。续桌经济学,越聊越省。长对话 Agent 之所以能跑起来,靠的就是这个增量策略。

ΔM=Mt−Mt−1=2×L×H×ΔN×s\displaystyle \Delta M = M_t - M_{t-1} = 2 \times L \times H \times \Delta N \times s
通俗理解:续桌只做新菜,旧菜全部留桌。这一轮花了多少“刀工”,只跟这轮点了多少新菜有关。
  1. 本轮总缓存M_t 是第 t 轮结束时总 KV 显存占用。
    Mt=2×L×H×Nt×sM_t = 2 \times L \times H \times N_t \times s
  2. 上一轮缓存M_{t-1} 是上一轮已经算好并留在显存里的 KV,数学上完全精确,可直接复用。
    Mt−1=2×L×H×Nt−1×sM_{t-1} = 2 \times L \times H \times N_{t-1} \times s
  3. 增量计算只算本轮新增 token 的 K/V,ΔN 是两轮 token 数之差。
    ΔM=2×L×H×ΔN×s\Delta M = 2 \times L \times H \times \Delta N \times s
  4. 零重复代价历史部分全部命中,每轮复杂度从 O(N_t) 降为 O(ΔN)。
    ΔN=Nt−Nt−1\Delta N = N_t - N_{t-1}

6. 工程实践权衡:后厨的管理智慧

置物架和高汤不是万能的。高汤一直煨着要占灶眼(缓存占用显存),每桌菜也不能无限堆(显存预算),共享汤底还得防串味——万一两个客人的过敏原不同呢(数据隔离)。

工程上需要在命中率与显存开销之间取舍:缓存按 LRU/FIFO 淘汰,太短的公共前缀不值得缓存;多租户场景按前缀隔离缓存空间,防止 A 租户的数据被 B 租户的请求读到。

如果公共前缀太短导致命中率只有 10%,缓存反而白占显存、拖累并发。好的后厨,不是菜越堆越多,而是用最少的案板做出最高的翻桌率。KV Cache 优化最终拼的,就是对“空间、时间、隔离”这三本账的平衡。

Speedup=NtotalNnew=11−hit_ratio\displaystyle \text{Speedup}=\frac{N_{\text{total}}}{N_{\text{new}}}=\frac{1}{1-\text{hit\_ratio}}
通俗理解:命中率越高,需要新做的菜越少,翻桌越快。但缓存本身也占地方,命中率太低就得不偿失。
  1. 总 token 数N_total 是请求中全部参与注意力计算的 token 数量。
    NtotalN_{\text{total}}
  2. 新增 token 数N_new 是实际需要新计算 KV 的 token,等于总数量减去命中部分。
    Nnew=(1−hit_ratio)×NtotalN_{\text{new}} = (1 - \text{hit\_ratio}) \times N_{\text{total}}
  3. 加速比定义无缓存工作量除以有缓存工作量,比值越大越划算。
    Speedup=NtotalNnew\text{Speedup}=\frac{N_{\text{total}}}{N_{\text{new}}}
  4. 命中率形式用命中率直接表达,命中 80% 时加速 5 倍。
    Speedup=11−hit_ratio\text{Speedup}=\frac{1}{1-\text{hit\_ratio}}

AI 应用场景

在线大模型推理服务

阶段:模型推理与部署

解决的问题:传统推理框架每条请求从头算 KV,全局并发低、显存碎片多,遇长上下文频繁 OOM。PagedAttention 让 KV 显存利用率接近满格,配合 Prefix Caching 让系统提示词共享,吞吐可提升数倍。

具体案例:某客服机器人接入微调后的 7B 模型,每用户携带 2000 token 系统提示词。优化前 8 卡 A100 仅撑 60 并发,改用 vLLM 后并发提升到 200+,单 token 延迟基本不变。

多轮对话与 Agent 应用

阶段:模型推理与上下文管理

解决的问题:Agent 每轮工具调用后都要重新发送完整历史,朴素实现重复编码导致延迟随轮数线性恶化。多轮 KV 共享把历史 KV 留在显存,每轮只算增量,长对话成本骤降。

具体案例:某代码助手的多轮会话平均 20 轮,使用会话级 KV 缓存后,平均每轮推理时间从 1.8s 降到 0.5s,GPU 成本下降约 60%。

企业私有化 LLM 网关

阶段:模型推理与资源调度

解决的问题:多租户共享固定 system prompt 和安全审核前缀,重复计算浪费严重。网关按前缀哈希做 Prefix Caching,并隔离各租户的缓存空间,既提升命中率又保证数据隔离。

具体案例:某金融企业网关统一注入“合规风控指令”500 token,日均请求 100 万次,前缀命中率约 70%,KV 计算量减少七成,首 token 延迟降低 40%。

Python 演示

python47 行
"""KV Cache 优化极简模拟:对比无缓存与分块缓存的工作量"""class PagedCache:    """分块管理的 KV 缓存,模拟 PagedAttention 的块表"""     def __init__(self, block_size=4, total_blocks=10, occupied=(1, 5, 8)):        self.block_size = block_size        self.free_blocks = [b for b in range(total_blocks) if b not in occupied]        self.block_table = []        self.kv_store = {}     def append_kv(self, token_id, kv):        """为新 token 分配物理块(按需扩容)并保存 KV"""        block_id = token_id // self.block_size        if block_id == len(self.block_table):            if not self.free_blocks:                raise RuntimeError("OOM: 物理块用完,需要淘汰或扩容")            self.block_table.append(self.free_blocks.pop(0))        self.kv_store[token_id] = kv     def has_kv(self, token_id):        return token_id in self.kv_store  def simulate():    cache = PagedCache()    naive_work = 0    cached_work = 0    rounds = (3, 5, 7, 9)    pos = 0    for r, cnt in enumerate(rounds, 1):        added = 0        for _ in range(cnt):            if not cache.has_kv(pos):                cache.append_kv(pos, (pos, pos))                added += 1            naive_work += pos + 1            cached_work += 1            pos += 1        print(f"第{r}轮: 新增{added} KV, 序列{pos} token, "              f"无缓存累计{naive_work}, 有缓存累计{cached_work}")     print(f"\n块表(逻辑->物理): {cache.block_table}")    print(f"无缓存总工作量 {naive_work} ≈ O(N^2)")    print(f"有缓存总工作量 {cached_work} = O(N)")  simulate()
目的:用 20 行核心逻辑模拟多轮对话中“无缓存 vs 有缓存”的工作量差异,以及 PagedAttention 分块分配物理块的过程。
  1. self.free_blocks = [b for b in range(total_blocks) if b not in occupied]初始化时把被其他请求占用的物理块剔除,剩下的才是可用的空闲格,对应显存的空闲块表。
  2. if block_id == len(self.block_table):只有逻辑块号超出当前块表长度时才分配新物理块,旧块直接命中,这就是“按需分页”。
  3. self.block_table.append(self.free_blocks.pop(0))从空闲池取一个物理块,它很可能不连续,块表负责记住逻辑到物理的映射。
  4. naive_work += pos + 1无缓存时每生成一个 token 要把前面所有历史 PV 重新算一遍,工作量持续累加。
  5. cached_work += 1有缓存时每步只算新增 1 个 token 的 KV,历史全部复用。
  6. print(f"块表(逻辑->物理): {cache.block_table}")输出逻辑块到物理块的映射表,直观呈现 PagedAttention 的“索引牌”。

常见误区

误区我一开始以为 KV Cache 是模型训练好的参数,像 Transformer 的权重一样存在模型文件里,加载模型时就有了,不用自己管理。

正解KV Cache 是推理时动态计算出来的“中间产物”。每输入一段文本,都要在显存里重新算一遍 K/V 并缓存;换一段输入,缓存就完全换掉。它不写进模型文件,也不属于权重,而是像后厨“今天切好的配菜”一样,属于一次性备菜。

为何常见:K/V 名字听起来像“模型学到的知识”,容易和注意力层的可学习权重混淆。

误区8B 模型 FP16 权重 16GB,我觉得显存大头就是模型权重,上下文长短影响很小,KV 缓存那点内存不值一提。

正解推理时权重不管处理多少 token 都占固定一份,但 KV 随上下文线性增长。32 层、4096 维下,2048 token 的 KV 就约 1GB;若 batch 和并发大,KV 会远超权重。这就是为什么长上下文服务常常先 OOM 在 KV 上。

为何常见:很少人实际算过 KV 显存公式,被“模型大小”先入为主,忽略了推理时的显存大头其实在动态缓存。

误区PagedAttention 只是更“省内存”,对单请求的生成速度没帮助,所以重要性一般。

正解省内存本身就是加速:能塞下更多并发请求,GPU 利用率上升,端到端吞吐显著提升;同时避免了连续分配时整体搬移的拷贝开销,还支持多序列共享前缀块。vLLM 发布时吞吐可提升数倍,靠的就是这套“分格置物架”。

为何常见:把“省内存”和“省时间”对立起来,忽略了部署场景下吞吐才是核心指标。

误区凡是公共前缀,不管多长都缓存,反正能复用,缓存越多越好。

正解前缀缓存要占显存;如果公共前缀短、命中率低,缓存本身会挤占可用显存,反而降低并发。工程上要设前缀长度阈值、按 LRU 淘汰,在收益与成本之间做权衡。

为何常见:只看到复用好处,没看到缓存也有“机会成本”——占着灶眼就不能炒别的菜。

误区缓存了历史 KV,模型会不会“记不清”或回答质量下降?感觉缓存就像图片压缩,会丢信息。

正解KV Cache 是精确缓存,不是近似压缩。复用的 K/V 与重新计算完全一致,注意力输出逐位相同,生成质量毫无损失。唯一的风险是显存放不下时被淘汰,那属于容量问题,不是精度问题。

为何常见:把“缓存”类比成图像压缩或人脑遗忘,忽略了它本质上是无损的中间结果暂存。

面试题

Q1. KV Cache 中的 K 和 V 分别指什么?

单选题 · easy

  • A.损失值与梯度更新
  • B.注意力中键与值向量← 正确答案
  • C.词表编号与词频统计
  • D.学习率与动量参数

答案:B。注意力计算用 Q 去匹配 K,再按权重取 V,K、V 是 token 经矩阵变换得到的向量(B)。A/D 是训练动态概念,C 是词频统计,都与注意力无关。

Q2. KV Cache 主要解决什么问题?

单选题 · easy

  • A.减少参数并压缩显存
  • B.复用历史键值防重算← 正确答案
  • C.提升训练集准确精度
  • D.加速梯度反向传播

答案:B。KV Cache 的核心是缓存历史 token 的 K/V,避免自回归生成时每步重复计算前面所有 token 的 K/V(B)。A 混淆了参数压缩,C/D 属于训练阶段的事,与推理缓存无关。

Q3. 关于 KV Cache 显存占用,正确的说法是?

单选题 · mid

  • A.与序列长度完全无关
  • B.随序列长度线性增长← 正确答案
  • C.随序列长度指数暴涨
  • D.只随模型参数变化

答案:B。每个新增 token 都要额外存 2×L×H 个数的 K/V,显存总量与 token 数 N 成正比(B)。指数暴涨是 C 的夸张,A/D 忽略了上下文长度对缓存的影响。

Q4. PagedAttention 借鉴了什么思想?

单选题 · mid

  • A.数据库 B 树索引优化
  • B.操作系统虚拟内存分页← 正确答案
  • C.编译器寄存器分配
  • D.网络拥塞窗口控制

答案:B。PagedAttention 把 KV 切成固定块、用块表做逻辑物理映射、引用计数共享与写时复制,整个框架都来自 OS 虚拟内存分页(B)。A/C/D 是其他领域技术,与分页机制无关。

Q5. PagedAttention 中 block table 的作用是?

单选题 · mid

  • A.保存模型全部权重值
  • B.记录逻辑块物理块映射← 正确答案
  • C.缓存每条训练的样本
  • D.存放注意力分数矩阵

答案:B。块表维护“逻辑块号 → 物理块号”的映射,物理块可分散在显存任意空闲位置(B)。A 是权重存储,C 是数据缓存,D 是注意力中间结果,都不是块表的职责。

Q6. Prefix Caching 最适合哪种场景?

单选题 · mid

  • A.请求间完全无公共前缀
  • B.共享长系统提示词场景← 正确答案
  • C.单 token 短查询占多数
  • D.纯离线批量推理任务

答案:B。前缀复用的收益来自“公共前缀占比高”,长系统提示词正是典型场景(B)。A 没有可复用内容,C 前缀太短收益低,D 离线批处理通常无共享前缀需求。

Q7. 关于无缓存与有缓存的工作量,说法正确的有?

多选题 · hard

  • A.无缓存时生成新词要重算全部历史 KV← 正确答案
  • B.无缓存累计工作量约为序列长度平方← 正确答案
  • C.有缓存后每步仍需重算所有历史
  • D.有缓存每步新增工作量变为常数← 正确答案

答案:ABD。无缓存时每步重扫全部历史,累计工作量 ≈ N(N+1)/2,是 O(N²)(A、B 对);有缓存后每步只算 1 个新 token 的 KV,历史直接命中(D 对),C 恰恰相反,故排除。

Q8. PagedAttention 减少内存碎片的手段包括?

多选题 · mid

  • A.固定大小的块式分配← 正确答案
  • B.逻辑物理块映射机制← 正确答案
  • C.模型参数也进行分页
  • D.块可放入任意空闲位← 正确答案

答案:ABD。固定块分配(A)、块表映射(B)、散落空闲位(D)共同消除碎片。C 错误:PagedAttention 只对 KV 缓存分页,模型权重常驻显存,不走块分配。

Q9. 关于 Prefix Caching 与多轮共享,正确的有?

多选题 · hard

  • A.命中前缀仍要重算历史 KV
  • B.前缀缓存可在请求间复用← 正确答案
  • C.多轮对话只算新增的 token← 正确答案
  • D.复用缓存会降低生成质量

答案:BC。前缀缓存按前缀哈希命中后直接复用(B 对);多轮共享下每轮只算新增 token 的 KV(C 对)。A 与 B 相反,D 错误——KV 缓存是精确缓存,数学上与重算完全一致,不损失质量。

Q10. 某服务通过 Prefix Caching 使公共前缀命中率达到 80%,理想情况下 KV 计算加速比约为?

单选题 · extreme

  • A.约 1.25 倍
  • B.约 2 倍
  • C.约 5 倍← 正确答案
  • D.约 10 倍

答案:C。加速比 = 1 / (1 − 命中率) = 1 / 0.2 = 5(C 对)。A 是把 0.8 直接取倒数(1.25),B/D 数值与公式不符。命中率越接近 1,加速比越恐怖。