想象你在一座巨大的图书馆里写一篇论文。每写一段话,你都要回头核对之前引用过的所有书籍。如果没有手边书架,你每写一个字都得跑到总书库,把之前看过的书全部重新搬一遍——越写越慢,直到整个下午都耗在搬书上。大语言模型生成文字时也一样:每生成一个新词,都要“回顾”之前所有的词。好在模型有一个聪明的习惯——它把看过的内容放在一张“手边书架”上,随取随用。这个书架,就叫 KV Cache(键值缓存)。 可问题来了:书架是房间里的固定设施,书越写越多,书架迟早塞不下。于是人们想出了一个办法——给书“瘦身”。把精装大开本换成平装本,再把平装本换成口袋书,甚至把书里的地图页单独复印保留、其余部分压缩成索引卡片。这就是 KV Cache 量化的本质:把原本用 16 位浮点数(FP16)存储的键值对,压缩成 INT8、INT4 或 FP8 格式,让同一块 GPU 能服务更长的上下文。今天,我们就用这座“图书馆”来拆解这套显存优化方案。

岗位关联

掌握 KV Cache 量化,你就能用同一块 GPU 服务两倍上下文长度的请求——这是大模型推理优化中最直接、最省钱的“扩容量”技能。

目录
  1. 可视化演示
  2. 认识KV Cache:从“手边书架”说起
  3. 量化基础概念:给书“瘦身”的数学
  4. 量化方案对比:INT8、INT4 与 FP8
  5. 按头量化:分类管理书架
  6. 异常值保护:护住关键书页
  7. 收益与权衡:省出的空间
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示INT4/INT8/FP8量化如何降低KV Cache显存占用,揭示不同量化精度在长上下文推理中的显存节省效果。

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

KV Cache量化 FP16:基线精度,16位浮点存储 FP8/INT8:8位量化,显存减半 INT4:4位量化,显存降至1/4 Memory = Layers × Hidden × Context × Bits / 8 量化精度与显存占用的权衡关系

认识KV Cache:从“手边书架”说起

回到那座图书馆。你写论文时需要不停查阅自己已经引用过的段落。如果没有手边书架,每写一句话都要去总书库把所有书重新翻一遍——这就相当于大语言模型不缓存 Key 和 Value 时的状态:每生成一个新 token,注意力机制都要重新计算之前所有 token 的 K、V 与当前 Query 的匹配。上下文一长,计算量呈平方级爆炸,推理慢得无法接受。于是模型在显存里搭了一个“手边书架”——KV Cache,把每个已生成 token 的 Key(检索标签)和 Value(内容信息)存下来,之后只需要增量计算新 token 的 K、V,再与缓存做注意力运算。

这个书架的大小有明确的数学公式。假设模型有 L 层,每层有 H 个注意力头、每个头维度为 d,每个数值用 b 比特存储(FP16 时 b=16),那么存储一个 token 的 KV 需要:

假设一个 13B 模型有 40 层、每层 40 个头、头维度 128,上下文 8192 个 token,FP16 下 KV Cache 可达 40×40×128×8192×2×2 ≈ 13.4 GB——比模型权重本身还大。当上下文扩展到 32K 甚至 128K 时,这个“书架”直接撑爆显存。瓶颈不在书本身,而在于书架放不下。

MKV=2×L×H×d×b8\displaystyle M_{KV} = 2 \times L \times H \times d \times \frac{b}{8}
  1. K 和 V 各算一份公式开头的系数 2 表示每个 token 既要缓存 Key 也要缓存 Value,两者缺一不可。
    ×2\times 2
  2. 乘上模型层数Transformer 每一层都有独立的注意力机制,每层都有自己的 K、V,必须逐层累加。
    ×L\times L
  3. 乘上每层的头数与维度多头注意力把每层拆成 H 个头,每个头有 d 维向量,这就是单位 token 的总维度。
    ×H×d\times H \times d
  4. 除以 8 完成字节换算b 的单位是比特(bit),除以 8 换成字节(Byte)。FP16 时每个数值占 2 字节。
    ×b8\times \frac{b}{8}

量化基础概念:给书“瘦身”的数学

图书馆想多放书,最简单粗暴的办法是换更小的开本——把精装书变成口袋书。KV Cache 量化做的就是这件事:用更少的比特数表示原来的数值。FP16 用 16 个比特表示一个浮点数,INT8 用 8 个比特表示一个有符号整数,INT4 用 4 个比特。比特数少了,内存占用自然降下来。

但直接截断比特会丢失信息——就像把书里的插图全删了。量化用了一个聪明的补偿机制:缩放因子(scale)。先把原始浮点张量的取值范围映射到目标整数范围。对于对称量化,假设张量绝对值的最大值为 max|x|,目标整数范围是 [-2^(b-1)-1, 2^(b-1)-1](INT8 为 [-127, 127],INT4 为 [-7, 7]),缩放因子为:

推理时,KV 会先用 scale 反量化回近似浮点值再参与注意力计算。比如 INT8 的 scale=0.01,量化值 42 反量化后就是 0.42,与原值 0.418 只差 0.002——相当于把精装书里的文字缩小印刷,虽然字小了点,但内容基本还能看清。量化的艺术,就是找一本“字足够小但还看得清”的版本。

s=max⁡i∣xi∣2b−1−1,xq=round⁡(xs)\displaystyle s = \frac{\max_{i}|x_i|}{2^{b-1} - 1}, \qquad x_q = \operatorname{round}\left(\frac{x}{s}\right)
  1. 取绝对值最大值max|x_i| 是整个张量中离零最远的那个值,它决定了量程的“标尺”长度。
    max⁡i∣xi∣\max_{i}|x_i|
  2. 算出整数上限2^(b-1)-1 是为符号位预留后的最大整数值,INT8 是 127,INT4 是 7。
    2b−1−12^{b-1} - 1
  3. 得到缩放因子把浮点范围除以整数范围,得到“每 1 个整数刻度对应多少浮点数值”,这就是 scale。
    s=max⁡∣x∣2b−1−1\displaystyle s = \frac{\max|x|}{2^{b-1} - 1}
  4. 取整映射用 x 除以 scale 后四舍五入到最近的整数,完成从浮点到整数的压缩。
    xq=round⁡(xs)x_q = \operatorname{round}\left(\frac{x}{s}\right)

量化方案对比:INT8、INT4 与 FP8

书架上的不同区域,可以选择不同厚度的书。INT8 是“平装本”:每 2 字节的 FP16 被压缩成 1 字节,显存直接降一半;INT4 是“口袋书”:进一步压到 0.5 字节,显存降到原来的四分之一;FP8 则是近年硬件新支持的“特种纸平装本”——同样是 1 字节,但采用浮点表示。三种方案的压缩比由位宽直接决定:

FP8 值得多说一句:它不是整数而是浮点格式,常见配置是 1 位符号 + 4 位指数 + 3 位尾数(E4M3)。因为保留了指数位,FP8 的动态范围远大于 INT8,能更自然地表达“极小值”和“极大值”并存的 KV 张量。代价是尾数精度低——就像口袋书把字体缩到极小,容易把相近的字看混。实践中 INT4 的压缩收益最大,但直接全量 INT4 会带来明显的质量损失;INT8 稳妥但只省一半;FP8 则是“动态范围优先”的折中方案。选哪本“书”,取决于你手边的书架到底有多挤,以及书的收藏价值(任务精度要求)有多高。

R=bFP16bquant\displaystyle R = \frac{b_{FP16}}{b_{quant}}
  1. 分子是原精度位宽FP16 的 b=16,这是压缩前的“精装本厚度”。
    bFP16=16b_{FP16} = 16
  2. 分母是量化位宽INT8 为 8,INT4 为 4,FP8 也是 8。
    bquant∈{8,4}b_{quant} \in \{8, 4\}
  3. 相除得到压缩比INT8 是 16/8=2 倍压缩,INT4 是 16/4=4 倍压缩。显存占用与位宽成正比,压缩比越高,占位越小。
    168=2,164=4\frac{16}{8} = 2, \quad \frac{16}{4} = 4

按头量化:分类管理书架

你以为整个图书馆只能统一换一种开本?其实不然。仔细想想,画册需要大图,小说可以用小字。KV Cache 也类似——现代 Transformer 的多头注意力中,每个注意力头的数值分布和敏感度都不一样。有些头负责捕捉精确的语法关系,对量化误差极其敏感(敏感头);有些头只起到平滑作用,即使量化得很狠也不影响质量。

按头量化(Per-Head Quantization)的思路是:给每个头单独计算一个缩放因子,敏感的头用更高位宽(如 FP8 或 INT8),不敏感的头用 INT4。第 h 个头的缩放因子只取决于该头自己的数值范围:

那么如何判断哪些头敏感?通常的做法是在一小部分校准数据上跑一遍推理,观察每个头输出的注意力分布:如果量化后该头的注意力得分与 FP16 版本差异大,就标记为敏感头并分配更高位宽。效果上,按头量化可以在整体显存压缩 2-3 倍的前提下,把质量损失控制在 1% 以内。图书管理员懂得:画册精装、小说平装、随手笔记用口袋本——同样的道理,好的量化方案是“因头施策”。

sh=max⁡j∣xh,j∣2bh−1−1\displaystyle s_h = \frac{\max_{j}|x_{h,j}|}{2^{b_h-1} - 1}
  1. 按头取范围把第 h 个头中的所有维度值 j 收集起来,找这个头自己的绝对值最大值。
    max⁡j∣xh,j∣\max_{j}|x_{h,j}|
  2. 按头定上限b_h 是分配给这个头的位宽,每个头的 b_h 可以不同,这就是“分类管理”的核心。
    2bh−1−12^{b_h-1} - 1
  3. 每个头一个比例尺s_h 只服务于第 h 个头,量化后的该头数据用 s_h 反量化,误差不会扩散到其他头。
    sh=max⁡∣xh∣2bh−1−1\displaystyle s_h = \frac{\max|x_{h}|}{2^{b_h-1}-1}

异常值保护:护住关键书页

给书瘦身时最怕什么?怕的是整本书里有一张地图折页,展开后比书本身还大,硬塞进口袋本里会把书皮撑坏。KV Cache 的张量中同样存在这种“异常值”:注意力计算后的数值分布虽然整体集中在小范围,但总有少数维度出现绝对值极大的离群点。如果不处理,量化时 scale 会被这些异常值撑大,导致绝大多数正常值被压缩到很小的整数区间,细节全部丢失——就像为了让地图折页塞进口袋本,把正文字体缩成了蚂蚁大小。

解决方案是裁剪(clipping):先统计张量绝对值分布的 P99.9 分位数作为阈值 α,然后强行把所有超出阈值的值截断到 α 或 -α:

除了裁剪,另一种保护是混合精度保护:把异常值所在的少数维度单独提取出来,用 FP16 原样存储,剩余的多数维度做低位宽量化。这相当于把地图折页拆下来单独复印,装进一个透明文件袋——书变薄了,地图也没丢。好的量化方案,不是平均用力地压,而是把关键的几页护住,其余尽情压缩。

α=P99.9(∣x∣),y={α,x>αx,−α≤x≤α−α,x<−α\displaystyle \alpha = P_{99.9}(|x|), \qquad y = \begin{cases} \alpha, & x > \alpha \\ x, & -\alpha \le x \le \alpha \\ -\alpha, & x < -\alpha \end{cases}
  1. 统计异常值边界P99.9(|x|) 表示有 99.9% 的绝对值都小于这个数,用它作为“关键页”的裁剪线。
    α=P99.9(∣x∣)\alpha = P_{99.9}(|x|)
  2. 上界截断大于 α 的值被强制拉回 α,不让极端值撑大 scale。
    α,x>α\alpha, \quad x > \alpha
  3. 中间保持原样在 [-α, α] 区间的绝大多数值原样保留,它们才是量化的主体。
    x,−α≤x≤αx, \quad -\alpha \le x \le \alpha
  4. 下界对称截断小于 -α 的值同样拉回 -α,保证对称分布,方便后续对称量化。
    −α,x<−α-\alpha, \quad x < -\alpha

收益与权衡:省出的空间

书架换了一批小开本书后,能多放多少书?答案是几乎按比例翻倍。给定可用显存 M_avail,能服务的上下文长度大致为:

以 13B 模型为例:FP16 下 24GB 显存只能支撑约 8K 上下文;换成 INT8 后约 16K;INT4 则突破 30K。但收益背后有隐藏成本——每存一个 token 都要额外保存每个头的 scale 因子(以及裁剪阈值 α),这些元数据也要占显存;同时量化/反量化操作会增加少量计算开销。因此实际落地时,INT8 常用于“无损优先”的生产环境,INT4 更常配合按头量化和异常值保护一起使用。省下的是书架空间,付出的是管理精力和一点点速度——聪明的图书管理员,总是先算清这笔账再决定换哪套书。

Lserved=Mavail×8b×2×nlayers×nheads×dhead\displaystyle L_{\text{served}} = \frac{M_{\text{avail}} \times 8}{b \times 2 \times n_{\text{layers}} \times n_{\text{heads}} \times d_{\text{head}}}
  1. 可用显存换成比特分子上的 M_avail × 8 把 GB 等显存单位换算成比特,因为位宽 b 是按比特计算的。
    Mavail×8M_{\text{avail}} \times 8
  2. 乘 2、乘层数、乘维度分母完整还原了“K+V 双份 × 层数 × 每层 KV 总维度”的结构,这部分上一节已经拆解过。
    2×nlayers×nheads×dhead2 \times n_{\text{layers}} \times n_{\text{heads}} \times d_{\text{head}}
  3. 除以位宽b 从 16 降到 8 或 4,分母变小,L_served 变大。INT4 理论上是 FP16 的 4 倍容量。
    1b\frac{1}{b}

AI 应用场景

长上下文 LLM 服务扩容

阶段:模型推理部署与性能优化

解决的问题:传统 LLM 服务中,长上下文请求的 KV Cache 占满显存,导致并发数极低、响应超时。使用 INT8/FP8 量化后,单卡可服务的上下文长度接近翻倍,用户上传长文档也能流畅对话。

具体案例:某知识库问答产品基于 vLLM 部署 70B 模型,原始 FP16 下只能支持 4K 上下文和 8 路并发。对 KV Cache 做 INT8 量化并启用按头缩放后,上下文扩展到 8K,并发提升到 16 路,首 token 延迟下降 40%,且人工评测回答质量几乎无差异。

边缘设备本地模型推理

阶段:端侧模型部署与资源优化

解决的问题:笔记本、手机等设备显存带宽有限,运行 7B 级本地模型时,KV Cache 稍长就触发内存换页。INT4 量化让 KV Cache 缩减到四分之一,配合异常值裁剪,让 8G 内存设备也能流畅运行长对话。

具体案例:某 AI 助手 App 在 MacBook Air(8GB 内存)上运行量化版 Llama-3-8B,未量化前对话超过 20 轮即卡顿;对 KV Cache 做 INT4 + 混合精度保护后,连续对话 100 轮仍响应流畅,端侧首 token 延迟小于 300ms。

高并发多租户推理集群

阶段:集群资源调度与成本控制

解决的问题:多租户场景下,每个请求占用显存大小直接决定单卡能塞多少请求。KV Cache 量化后,单位显存可承载更多并发,GPU 资源利用率提升,摊薄单次请求成本。

具体案例:某 AI 创业公司用 A100 集群托管多个客户模型,启用 KV Cache INT8 量化后,单卡并发从 4 路提升到 9 路,月均 GPU 成本下降约 45%,SLA 达标率反而提高。

Python 演示

python59 行
"""KV Cache 量化演示:INT8/INT4 如何压缩显存并近似还原"""import random  def symmetric_quantize(tensor, bits):    """对称量化:用缩放因子将浮点张量映射到有符号整数"""    qmax = (1 << (bits - 1)) - 1          # 例如 bits=8 时 qmax=127    max_abs = max(abs(min(tensor)), abs(max(tensor)))    scale = max_abs / qmax if max_abs > 0 else 1.0    quantized = [max(-qmax, min(qmax, round(x / scale))) for x in tensor]    return quantized, scale  def dequantize(quantized, scale):    """反量化:用缩放因子还原为近似浮点值"""    return [q * scale for q in quantized]  def mse_error(orig, recon):    """计算还原前后的均方误差"""    n = len(orig)    return sum((a - b) ** 2 for a, b in zip(orig, recon)) / n  def simulate_kv_cache(seq_len, head_dim, bits):    """模拟一层注意力头的 KV Cache 量化全过程"""    random.seed(42)    keys = [random.uniform(-1.0, 1.0) for _ in range(seq_len * head_dim)]    values = [random.uniform(-1.0, 1.0) for _ in range(seq_len * head_dim)]     if bits >= 16:        print(f"FP16 原始精度:不量化,显存占用无压缩")        return     q_keys, scale_k = symmetric_quantize(keys, bits)    q_values, scale_v = symmetric_quantize(values, bits)    recon_keys = dequantize(q_keys, scale_k)    recon_values = dequantize(q_values, scale_v)     fp16_bytes = seq_len * head_dim * 2 * 2          # K 和 V 各 2 字节    quant_bytes = seq_len * head_dim * (bits // 8) * 2    key_err = mse_error(keys, recon_keys)    value_err = mse_error(values, recon_values)     print(f"量化位宽 {bits}bit: "          f"显存 {fp16_bytes}B -> {quant_bytes}B "          f"(节省 {1 - quant_bytes / fp16_bytes:.1%}) | "          f"K 还原误差 {key_err:.5f} | V 还原误差 {value_err:.5f}")  def main():    print("=== KV Cache 量化模拟 ===")    seq_len, head_dim = 128, 64    for bits in (16, 8, 4):        simulate_kv_cache(seq_len, head_dim, bits)  if __name__ == "__main__":    main()
目的:演示 KV Cache 量化的核心机制——对称量化计算缩放因子、量化取整、反量化还原,并量化展示位宽与显存压缩比、还原精度的关系。
  1. qmax = (1 << (bits - 1)) - 1计算有符号整数的最大可表示值,INT8 为 127,INT4 为 7,这是映射的“整数刻度上限”。
  2. scale = max_abs / qmax if max_abs > 0 else 1.0用张量绝对最大值除以整数上限得到缩放因子,这是整个量化的“比例尺”。
  3. quantized = [max(-qmax, min(qmax, round(x / scale))) for x in tensor]将每个浮点数除以 scale 后四舍五入取整,再用 min/max 做裁剪,防止超出整数范围。
  4. dequantize(quantized, scale)把整数乘以 scale 还原为近似浮点值,体现“压缩后仍可恢复”的关键特性。
  5. mse_error(keys, recon_keys)用均方误差衡量量化造成的精度损失,数值越小代表还原得越准。
  6. quant_bytes = seq_len * head_dim * (bits // 8) * 2计算量化后的 KV 总字节数,其中 bits // 8 把位宽换算成字节数,直观展示压缩比例。

常见误区

误区“INT4 每个数值占 4 个比特,FP16 占 16 个比特,所以 INT4 一定把 KV Cache 显存降到原来的四分之一,比 INT8 省两倍。”

正解位宽确实决定了数值本身的存储量,但落地时还需额外存储缩放因子、裁剪阈值等元数据。按头量化下每个头都要保存一个 scale,这些开销在高并发小 batch 场景下可能占 KV Cache 总显存的 5%-15%。因此 INT4 实际节省通常为 3.2-3.7 倍,而非理论上的 4 倍。就像书变小了,但每本书的书签(元数据)还是得有。

为何常见:很多人只关注公式里的位宽比例,忽略了量化方案本身引入的额外存储结构。

误区“量化就是把精度砍掉,等于是给模型'降智',输出质量肯定明显变差。”

正解注意力机制的 K、V 张量内部存在大量数值冗余,合理的量化(按头缩放 + 异常值裁剪 + 校准)可以把质量损失控制在 1% 以内,甚至在一些任务上完全无损。这就像把精装书换成排版紧凑的平装本——读者几乎察觉不到内容差异。真正导致质量崩坏的,往往是“一刀切”地全量 INT4 且不做异常值保护。

为何常见:早期量化方案不成熟,确实出现过明显掉点,形成了“量化=降智”的刻板印象。

误区“量化方案应该全网统一,INT8 就全部 INT8,INT4 就全部 INT4,这样实现简单。”

正解不同层、不同头对量化误差的敏感度差异极大。靠近输出层的注意力头通常更敏感,负责句法位置编码的头被量化后误差会被后续层放大。按头量化正是针对这一现象:敏感头用 FP8/INT8,非敏感头用 INT4,整体收益远好于统一位宽。图书管理员不会把画册和便签纸印成同一尺寸——对症下药才是最优解。

为何常见:实现“统一位宽”的工程成本最低,很多人没有意识到混合位宽的收益远大于额外开销。

误区“FP8 和 INT8 都占 1 字节,压缩比一样,用哪个都行。”

正解虽然存储空间相同,但两者的数值分布能力差异显著。INT8 的 256 个整数刻度均匀分布,适合范围集中、分布均匀的数值;FP8 采用“1 符号 + 4 指数 + 3 尾数”,刻度在零附近更密、在远处更疏,动态范围更大。KV Cache 中异常值的存在使 FP8 往往比 INT8 更稳定。但 FP8 的尾数精度只有 3 位,对分布极其集中的张量反而误差更大。

为何常见:只看“位宽相同”这个表层属性,忽略了浮点与整数在数值分布机制上的本质差异。

误区“显存占用小了,带宽占用也小了,推理速度自然更快。”

正解量化主要解决的是显存容量瓶颈,而非速度问题。每次读取量化后的 KV,都需要先反量化回浮点才能参与注意力计算,这增加了额外开销;如果量化位宽导致需要频繁解包、对齐,甚至可能让延迟略微上升。真正的延迟收益来自“显存换出减少”和“batch 增大”的间接效果。省下的房间可以放更多书架,但取书时反而要多一道拆封工序。

为何常见:将“显存优化”直接等同于“速度优化”,忽略了反量化计算本身的开销。

面试题

Q1. KV Cache 主要存储的是什么?

单选题 · easy

  • A.模型的全部权重参数
  • B.已生成词的 Key 和 Value← 正确答案
  • C.训练数据中的梯度信息
  • D.每层输出的中间激活值

答案:B。KV Cache 缓存的是注意力机制中每个已生成 token 的 Key(检索标签)和 Value(内容信息),避免重复计算。权重参数在模型加载时就固定了,不需要也不应该放进 KV Cache;梯度信息只在训练阶段存在;中间激活值则是前向传播过程中的临时产物,不属于 KV Cache 的职责范围。

Q2. 使用 INT8 量化 KV Cache 后,数值存储相比 FP16 大约节省多少?

单选题 · easy

  • A.约 25% 的显存
  • B.约 50% 的显存← 正确答案
  • C.约 75% 的显存
  • D.约 90% 的显存

答案:B。FP16 每个数值占 16 比特(2 字节),INT8 占 8 比特(1 字节),因此单个数值存储量降为原来的一半,对应显存约节省 50%。如果考虑缩放因子等元数据开销,实际略低于 50%,但主体压缩比由位宽决定。

Q3. 为什么直接对 KV Cache 做 INT4 量化可能显著损伤生成质量?

单选题 · mid

  • A.整数运算容易溢出导致程序崩溃
  • B.数值表示范围被压缩,量化误差变大← 正确答案
  • C.模型必须重新训练才能适配整数格式
  • D.显存占用反而比 FP16 更高

答案:B。INT4 只有 16 个整数刻度(含符号实际有效范围更小),对于取值范围较大的 KV 张量,每个刻度代表的浮点间隔变大,量化误差随之放大。关键注意力头的误差累积会改变生成的 token 分布。程序崩溃是工程问题而非精度问题;KV 量化是推理期优化,不需要重新训练模型;显存占用只会更少,不会更多。

Q4. 按头量化(Per-Head Quantization)的核心思想是什么?

单选题 · mid

  • A.每一层网络使用不同的量化位宽
  • B.每个注意力头单独计算缩放因子← 正确答案
  • C.所有头共享同一个全局缩放因子
  • D.只量化 Value 而完全不量化 Key

答案:B。按头量化认为不同注意力头的数值分布和敏感度不同,应该为每个头独立计算 scale。这样敏感头可以分配更高位宽,非敏感头用较低位宽,整体效果优于全局统一缩放。选项 C 是“全局量化”的做法,选项 A 是“按层量化”,选项 D 忽略了 Key 在注意力得分计算中的关键作用。

Q5. 以下哪些策略可以保护 KV Cache 量化后的精度?

多选题 · mid

  • A.按头缩放因子← 正确答案
  • B.异常值裁剪← 正确答案
  • C.混合精度保护← 正确答案
  • D.直接丢弃所有极小值

答案:ABC。按头缩放让每个头拥有独立的量化比例尺;异常值裁剪用分位数阈值限制极端值对 scale 的干扰;混合精度保护把异常值所在维度单独用 FP16 存储。直接丢弃极小值属于信息丢失,会破坏 Value 中的细粒度信息,因而不是合理的保护策略。

Q6. FP8(E4M3)相比 INT8 在 KV Cache 量化中的主要优势是什么?

单选题 · hard

  • A.每个数值占用的显存更少
  • B.动态范围更大,能容纳异常值← 正确答案
  • C.尾数精度更高,还原更准确
  • D.不需要存储缩放因子

答案:B。FP8 的 E4M3 格式有 4 位指数,可以表示从极小到极大的广泛数值范围,相比之下 INT8 是均匀刻度,遇到异常值容易饱和或浪费刻度。两者都占 1 字节,显存相同;FP8 的尾数只有 3 位,精度反而更低;FP8 同样需要配合缩放或校准使用,并非完全免缩放。

Q7. 对称量化中,缩放因子 scale 的典型计算方式是?

单选题 · easy

  • A.张量均值除以最大值
  • B.张量绝对最大值除以量化上限← 正确答案
  • C.张量方差开根号的结果
  • D.张量最小值减去最大值

答案:B。对称量化用 scale = max(|x|) / (2^(b-1)-1),分子是绝对值最大值,分母是整数表示上限。均值、方差描述的是分布形态而非量程,不能用来做线性映射;最小值减最大值得到的是取值范围宽度,缺少与整数刻度的对应关系。

Q8. 在实际推理系统中落地 KV Cache 量化时,需要考虑哪些额外因素?

多选题 · mid

  • A.每个 token 的动态缩放与反量化← 正确答案
  • B.存储缩放因子的额外显存开销← 正确答案
  • C.与 PageAttention 等显存管理器的兼容← 正确答案
  • D.训练阶段同步执行相同的量化

答案:ABC。KV Cache 量化发生在推理期,每个头/每个 token 的 scale 需要持久化并参与反量化;这些元数据占据额外显存,必须纳入总预算;主流推理引擎的 PageAttention 以 16KB 页为粒度管理 KV,量化后的布局需要与分页机制对齐。训练阶段不需要对 KV Cache 量化,因此 D 错误。

Q9. 为什么 Key 的量化通常比 Value 的量化对注意力质量影响更大?

单选题 · mid

  • A.Key 直接参与注意力得分的点积计算← 正确答案
  • B.Value 的张量维度通常比 Key 小
  • C.Key 中不存在任何数值冗余结构
  • D.Value 只包含无用的填充信息

答案:A。注意力得分是 Query 与 Key 的点积结果,Key 的量化误差会直接影响得分排序——原本该被关注的 token 可能因误差被忽略,改变整个注意力分布。Value 的误差更多是“内容”层面的轻微扰动,通常不会改变关注点。因此 Key 的精度预算往往要高于 Value。

Q10. 关于 KV Cache 量化的收益与代价,以下说法正确的是?

多选题 · hard

  • A.显存占用近似按位宽比例下降← 正确答案
  • B.可服务的上下文长度可接近翻倍← 正确答案
  • C.生成质量在任何情况下都完全不变
  • D.推理延迟一定比 FP16 更低

答案:AB。位宽从 16 降到 8 或 4,KV 的显存占用确实按比例下降;在显存为瓶颈的场景下,可服务的上下文长度会随之翻倍或更多。但质量并非“完全不变”,而是“在合理量化方案下几乎无损”;延迟也不一定更低,因为反量化操作本身有计算开销。因此 C、D 都是绝对化表述,错误。