量化与算子
上一章减少了每个词元需要的目标模型周期数,本章讨论剩余每个周期的成本。量化减少权重、激活或 KV 缓存的表示字节数,IO 感知内核减少数据在内存层次中搬运的字节数。两者可以相互配合,但任何一方都不能单独保证服务更快。压缩工件需要能够直接读取其确切布局的内核,运行时还必须针对工作负载产生的形状派发这个内核。
本章的组织原则就是把数值契约、内核实现与服务结果分开。这条区分解释了为何同一个四位模型在一种引擎中很快,在另一种引擎中却可能很慢;为何 FP8 路径对预填充的帮助可能大于对解码的帮助;也解释了为何更小的文件可能节省容量,却不改善延迟。
从字节数算起
设模型存储了 个参数,平均每个权重使用 个比特,那么权重占用约为
这里, 表示存储字节数, 是参数量, 是每个参数平均使用的数据比特数, 则包括缩放因子、零点、填充、张量头,以及以其他精度保留的权重。因此,一个 700 亿参数模型若全部采用 FP16,按十进制单位计算,FP16 完整存储约需 140 GB。名义上的四位表示只有 35 GB 权重数据,但真实工件更大,因为元数据和混合精度张量也占空间。
容量只是第一项约束。小批量解码时,许多线性层对每次载入的权重利用不足,无法让加速器的算术单元饱和。若一步执行从设备内存读取 字节,实际达到的高带宽内存速率为 ,那么带宽给出的时间下界为
其中, 是一个解码步的耗时, 是真正到达高带宽内存的流量, 是这个内核与工作负载的实测带宽,而不是设备标称峰值。权重量化可以同时降低常驻占用与 ,但只有实际执行的内核能高效读取压缩表示时,它才会降低延迟。节省容量并不自动等于降低延迟。
同一个判断也可以写成 roofline 下界。若某项操作执行 次浮点运算,并通过设备内存搬运 字节,其算术强度为 ,则
这里, 表示针对确切操作数类型与累加器类型实测或受支持的计算速率。增大批量可以提高权重复用,从而提高 ;长时间解码会增加 KV 流量;混合专家模型只读取被激活的专家;分布式执行则可能受限于通信。因此,受内存限制的解码是一种常见运行区间,不是一条定律。
注意力也有相近但依赖形状的流量问题。设查询长度为 、键长度为 ,单个注意力头的分数张量为
这里, 包含查询, 包含键, 是头维度。完整序列的预填充或训练中, 与 都可能等于序列长度,物化 会产生二次规模的中间张量。普通解码时,一个新查询只关注已经保留的键,因此 往往为一,而 随上下文增长。解码不会在每个解码步都新建一个完整的 分数矩阵,但仍能从融合注意力操作、避免不必要读写与内核启动的实现中受益。
这两类成本模型对应三个不同问题:
- 哪些张量占用容量并穿过内存接口?
- 哪种数值表示能够保持所需质量?
- 目标硬件是否拥有适配这种表示与形状的内核?
量化是一份数值契约
整数量化用整数编码以及重建近似值所需的元数据代替实数。对分配到缩放组 的元素 ,一般的仿射规则为
这些公式中的每个符号都属于存储下来的数值契约:
- 是原始实数, 是重建值。
- 是存储的整数编码,其范围由 与 限定。
- 是组 的缩放因子, 是该组的整数零点。
- 可以标识整个张量、单个通道或一小组相邻数值,这项选择称为量化粒度。
- 把数值映射到整数, 则把整数限制在可表示范围内。
若 位于可表示范围内,并采用最邻近编码取整,则
截断会带来超过该界限的误差。更细的粒度通常会缩小每组的取值范围,从而减小步长,但也会增加元数据,并可能需要更专用的内核。真实存储成本还包括元数据与填充,因此,四位是一组布局,而不是完整的格式说明。
缩放粒度还会改变元数据开销。这里, 表示每个值的数据位宽, 表示每组的数值个数, 表示缩放因子宽度, 表示零点宽度。若每组存储一个缩放因子和一个零点,那么不计填充与高精度张量时,理想的有效载荷为
比特每值。若 128 个四位值共用一个 FP16 缩放因子且不存储零点,则每个值使用 4.125 个理想比特,相对 FP16 的载荷缩减约 3.88 倍,而不是整整四倍。全零的对称量化组需要明确约定,例如存储 并把所有编码设为零,以避免除以零。
对称量化是 的常见特例。缩放因子可以由组内最大绝对值确定,但生产配方也可能用校准数据优化缩放因子或截断阈值。浮点格式使用符号位、指数位与有效数位,不采用均匀整数网格,因此动态范围更宽;块缩放格式则为一个小块增加共享缩放因子。每项选择都会同时改变数值误差和硬件可高效执行的路径。
离群值使粒度变得重要
多个经过研究的模型系列中,Transformer 激活都存在幅度远高于其他通道的少数通道 (Dettmers et al. 2022)。若整个张量共用一个缩放因子,离群值会拉宽可表示范围,使普通数值使用的网格变粗。每通道或每组缩放可以隔离这部分范围,但会增加元数据与内核成本。这类激活行为推动了 SmoothQuant 等方法;权重专用量化方法则利用校准激活判断哪些权重误差更重要 (Xiao et al. 2023; Lin et al. 2024)。
下面的可运行示例使用特意构造的小型合成向量。它不是实测的激活分布,只展示共享的对称缩放因子如何响应一个较大数值。
def quantize(values, bits=4):
qmax = 2 ** (bits - 1) - 1
maximum = max(abs(v) for v in values)
scale = maximum / qmax if maximum else 1.0
codes = [max(-qmax, min(qmax, round(v / scale))) for v in values]
return [scale * q for q in codes], scale
bulk = [0.7, -0.4, 0.9, -0.8, 0.3, -0.6, 0.5, -0.2, 0.75, -0.5, 0.6]
cases = [("no outlier", bulk), ("one outlier", [7.0] + bulk)]
for name, values in cases:
reconstructed, scale = quantize(values)
original_bulk = values if name == "no outlier" else values[1:]
quantized_bulk = reconstructed if name == "no outlier" else reconstructed[1:]
error = sum(abs(a - b) for a, b in zip(original_bulk, quantized_bulk)) / len(bulk)
print(f"{name:12s} scale={scale:.3f} bulk mean abs error={error:.3f}")
权重、激活与 KV 状态是三类不同目标
W4A16 之类的记法表示权重大约使用四个数据比特,激活采用 16 位格式。它没有说明组大小、缩放因子类型、零点、截断规则、累加器精度或内核布局,而这些细节都属于数值契约。
| 目标 | 常见简写 | 直接节省 | 内核要求 | 主要质量检查 |
|---|---|---|---|---|
| 仅权重 | W4A16、W8A16 | 权重容量与权重读取流量 | 读取打包权重,在矩阵乘附近反量化,并安全累加 | 任务质量与层输出误差 |
| 权重与激活 | W8A8、FP8 | 权重与激活流量;可能加快矩阵乘 | 使用原生或优化的低精度矩阵乘,并采用合适的累加精度 | 校准覆盖、溢出与任务质量 |
| KV 缓存 | FP8 KV、INT8 KV | 每个保留词元的缓存字节与注意力读取流量 | 量化写入,并在注意力内反量化或直接读取缓存值 | 长上下文与生成质量 |
权重专用量化通常适合受带宽限制的小批量解码。内核读取打包权重,在载入压缩块后反量化,再用较高精度的激活与累加器执行乘法。权重与激活量化可以使用原生低精度矩阵乘,这对大型预填充或高吞吐批次可能更重要。KV 缓存量化会改变 第 32 章 中的状态记账,也会改变注意力读取的输入。权重专用量化、权重与激活量化、KV 缓存量化是三项独立选择,并不是同一个开关由弱到强的三个档位。
这里, 表示层数, 表示 KV 头数, 表示头维度, 表示每个键或值元素的存储字节数。每个保留词元的逻辑 KV 载荷为
其中,因子二分别计入一个键和一个值。把每元素两字节的 BF16 或 FP16 改成每元素一字节,会在计入缩放元数据之前把逻辑元素载荷减半,但不会让总接纳批量自动翻倍,因为权重、工作区、分配器尾部、预留和其他状态仍会占用容量。KIVI 还发现缓存键与缓存值的分布行为不同,因此在其评估的二位方案中采用了不同量化粒度 (Liu et al. 2024)。缓存格式、缩放因子、模型版本与位置策略必须属于缓存身份,否则复用块可能按错误的数值契约解码。
GPTQ、AWQ 与 SmoothQuant 解决的问题不同
GPTQ 与 AWQ 产生权重专用工件,SmoothQuant 则为 W8A8 执行准备权重和激活。它们的名称不能互换为格式标签。
三者都是训练后量化(PTQ)方法:它们从训练完成的权重出发,使用小型校准集选择缩放因子,或估算候选权重带来的误差。量化感知训练(QAT)则让优化过程接触模拟或真实的低精度效应,并继续更新模型参数。激活缩放因子可以是静态的,由校准数据估计;也可以是动态的,根据当前输入在运行时计算。动态规则可以适应范围变化,但动态规则的归约与缩放工作也要计入延迟。
GPTQ 最小化层输出重建误差。 设 表示校准输入, 表示该层的权重矩阵, 表示所有可表示量化矩阵的集合,其局部目标为
该方法使用近似二阶信息,按顺序量化权重,同时更新剩余权重,以补偿已经引入的误差。论文实验表明,超大规模模型可以实际采用三位与四位训练后量化 (Frantar et al. 2023)。结果仍取决于校准输入、布局、模型和运行时内核。
AWQ 利用激活证据保护显著权重的误差。 AWQ 论文观察到,把约百分之一的显著权重保留为高精度可以大幅降低误差,但这种混合精度表示只是提出方法的依据。AWQ 并不会把那百分之一的权重存成 FP16。它转而搜索每通道缩放因子,在保持硬件友好的权重专用布局时,降低显著权重的量化误差。它需要校准数据,但不需要反向传播或逐层重建 (Lin et al. 2024)。
SmoothQuant 在激活与权重之间转移缩放。 对正的逐输入通道因子 ,有
这里, 是激活矩阵, 是权重矩阵, 是由通道缩放因子构成的对角矩阵,等号右侧两个因子的内维相容。SmoothQuant 不改变全精度层的代数结果。它把一部分激活范围转移到相应的权重行,使激活通道更容易量化,再应用 W8A8 量化。缩放因子由校准统计量确定,通常还带有一个平衡激活范围与权重范围的参数 (Xiao et al. 2023)。
这些方法都不会让量化变成无损操作。它们只是选择把近似误差放在哪里,以及使用哪类校准证据。
格式不等于执行路径
模型目录中经常并列出现的标签,其实描述了技术栈的不同层次:
- INT4 与 INT8 描述整数元素位宽,但没有规定组大小、元数据、打包方式或累加行为。
- FP8 通常指 E4M3 或 E5M2 编码。E4M3 给有效数分配更多比特,E5M2 给指数分配更多比特 (Micikevicius et al. 2022)。硬件支持取决于具体设备。
- MXFP4 与 NVFP4 是采用块缩放的四位浮点方案。微缩放格式让窄元素共享一个块缩放因子 (Rouhani and others 2023)。在支持的 NVIDIA 硬件上,NVFP4 使用更小的缩放组,以及块级和张量级缩放构成的层次 (NVIDIA 2025)。
- GGUF 是容器,不是数值精度。 GGUF 文件存储张量与模型元数据,其中的张量可以采用多种量化类型。llama.cpp 生态为多种 CPU 与加速器后端提供内核,但不同类型和后端的支持程度与性能并不相同 (GGML project 2023)。
可部署路径包含三份契约:工件、内核与运行时。
运行时可能接受某个工件,却退回通用转换或通用内核。这只是功能兼容,并不能证明它会加速。支持不等于快。转换前,应核对引擎当前的兼容性矩阵,确认确切的模型架构、量化配方、设备代际、张量并行布局与注意力后端。经常更新的引擎文档适合做这项部署检查,论文结果不能充当兼容性保证。
FlashAttention 不再物化中间结果
传统注意力可以由多个独立内核完成:把分数块写入高带宽内存,读回后计算 softmax,再写入概率,最后再次读回并与值相乘。FlashAttention 改用分块计算,让查询、键和值的块能够装入快速的片上 静态随机存取存储器(SRAM)。它在线更新 softmax 与输出,不在高带宽内存中物化完整分数张量。它在浮点舍入误差范围内计算精确注意力,不是稀疏或近似注意力规则 (Dao et al. 2022)。
对一行查询,把键和值分为 个块。对第 个块,定义
这里, 是查询行; 与 是第 个块中的键行和值行; 是该块第 行的分数; 是运行中的最大值; 是运行中的 softmax 分母; 是未归一化的输出累加器; 是最终注意力输出。初始状态为 、、。后续块若提高最大值,指数因子会把先前的分母与累加器重新缩放到新的数值基准。这正是朴素分块 softmax 所缺少的步骤。
后续版本延续同一项 IO 感知原则,但改变了工作划分与硬件映射。FlashAttention-2 减少非矩阵运算,并改进 A100 级硬件上的并行度 (Dao 2024)。FlashAttention-3 在 Hopper 上重叠数据搬运与矩阵计算,并增加 FP8 路径 (Shah et al. 2024)。FlashAttention-4 则针对 Blackwell 在张量吞吐、共享内存流量与特殊函数方面的不同平衡重新设计流水线 (Zadouri et al. 2026)。它们报告的加速只属于所声明的硬件、精度、形状与基线,不是可以迁移的常数。
重要的融合并不只有 FlashAttention。量化线性内核通常会融合权重解包、缩放应用、矩阵乘,有时还融合偏置或激活计算。服务运行时还可能融合归一化、旋转位置更新、缓存写入或采样操作。融合可以减少流量与内核启动开销,但更大的融合内核也可能遭遇寄存器压力、占用率不足、形状不支持或额外编译成本。因此,应测量实际执行的路径。
选择并验证部署方案
从工作负载出发,不要从格式名称出发。
- 记录基线。 固定模型版本、词元器、采样策略、引擎版本、内核后端、硬件、张量并行方式、提示词长度分布、输出长度分布、并发量与服务级目标。
- 定位约束。 测量常驻权重、KV 占用、分配器余量、实际内存带宽、算术单元利用率与内核耗时。把预填充和解码分开,并检查有代表性的矩阵形状。
- 选择张量目标。 当权重容量或解码读取占主导时,使用权重专用量化;当受支持的低精度矩阵乘占主导时,考虑权重与激活格式;当保留上下文限制容量或注意力流量时,量化 KV 状态。
- 记录完整数值契约。 包括方法、位宽、元素格式、组大小与分组轴、缩放因子与零点类型、截断规则、校准数据、累加器精度、未量化张量和工件版本。
- 证明目标路径确实执行。 确认运行时在预填充与解码中都选中了目标内核。分析解包、反量化、格式转换、计算图中断、编译与回退内核。
- 在相同接纳负载下比较。 报告首词元时间、每输出词元时间、词元间延迟、端到端延迟、请求与词元吞吐、有效吞吐、设备内存峰值,并在相关时报告能耗或成本;中位数与尾部行为都要覆盖。
- 重新运行质量评估。 困惑度在合适时可以使用,但还要检查任务特定质量、长上下文表现、结构化输出有效性、安全检查以及产品关键切片。使用相同提示词、解码规则和评判器版本。对量化多语种模型的评估已经发现,任务与语言相关的变化可能被单个聚合分数掩盖 (Marchisio et al. 2024)。
- 保留回滚路径。 当质量、兼容性、延迟尾部或运行稳定性没有达到声明阈值时,退回实测基线。
不仅要测试正常路径,也要测试故障。覆盖不支持的层、奇数矩阵形状、接近最大上下文的序列、混合提示词长度、缓存压力、张量并行边界、取消请求和引擎重启。加载时必须拒绝不兼容的元数据,不能静默误读。还要保证回退能在指标中被观察到,因为未被察觉的回退可能保持正确性,却抹掉预期加速。
GPTQ、AWQ、SmoothQuant、FP8、MXFP4、NVFP4 与 GGUF 量化类型不存在脱离硬件的统一排名。它们甚至不属于同一类别:有些是校准方法,有些是数值格式,还有一个是容器。质量与速度取决于模型、校准集、组大小、内核、设备、批量和序列形状。“四位无损”或“FP8 更快”之类的断言,只有在给出这些条件与实测指标后才完整。
量化会改变 logits 与 KV 值,融合内核则可能改变浮点归约顺序。因此,服务系统必须交付两类结果:本章的系统测量,以及来自 第 47 章 与 第 50 章 的能力测量。也就是说,系统测量与能力测量缺一不可。下一章会加入结构化解码与长上下文缓存策略,两者都可能改变形状、内核选择和系统对 KV 量化的敏感度。应分析并评估组合后的执行路径,不能把彼此独立测得的加速倍数直接相乘。
收益与边界
量化降低表示成本,融合与 IO 感知算法减少数据搬运和内核启动开销。只有工件、内核、运行时、工作负载与质量阈值彼此一致,这些收益才会到达用户。完整路径才是部署单位。
延伸阅读
- Frantar et al., “GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers,” 2023. arXiv:2210.17323GPTQ 是一种基于近似二阶信息的训练后量化方法,可在数小时内将 OPT-175B 等大语言模型压缩至每权重 3-4 比特,困惑度损失可忽略,并首次实现在单张 GPU 上运行 175B 参数模型的生成推理。
- Lin et al., “AWQ: Activation-aware Weight Quantization for On-Device LLM Compression and Acceleration,” 2024. arXiv:2306.00978AWQ 提出基于激活感知的逐通道权重缩放,实现对大语言模型硬件友好的低比特(W4A16)量化,精度接近混合精度 FP16 且无需反向传播,配套 TinyChat 推理框架在边缘 GPU 上实现超过 3 倍加速。
- Xiao et al., “SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models,” 2023. arXiv:2211.10438SmoothQuant 通过数学等价的逐通道缩放变换将激活离群值迁移至权重,从而为大语言模型实现无需训练的 W8A8 训练后量化。
- Micikevicius et al., “FP8 Formats for Deep Learning” (E4M3 与 E5M2 格式,以及包含 175B 参数语言模型的实验), 2022. arXiv:2209.05433本文规定 E4M3 与 E5M2 两种 FP8 交换格式,并在多类神经网络上评估相应训练方案。
- Dao et al., “FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness” (把「数字节」当作一个算法思想), 2022. arXiv:2205.14135FlashAttention 是一种 IO 感知的精确注意力算法,通过分块(tiling)与重计算减少高带宽显存(HBM)访问次数,实现更快的实际训练速度并将显存占用降至序列长度线性级别。
- Rouhani & others, “Microscaling Data Formats for Deep Learning” (OCP MX 格式), 2023. arXiv:2310.10537OCP 微缩放(MX)提案由 AMD、Arm、Intel、Meta、Microsoft、NVIDIA 与 Qualcomm 联合提出,让窄浮点或整数元素类型共享一个块级 scale,并证明包括 MXFP4 在内的 MX 格式能以极小的精度损失用于推理与训练。
- Dettmers et al., “LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale,” 2022. proceedings.neurips.ccLLM.int8() 将逐向量 INT8 矩阵乘法与激活离群维度的高精度路径结合,用于论文所评估的大型 Transformer。
- Liu et al., “KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache” (按通道量化键缓存并按词元量化值缓存), 2024. proceedings.mlr.pressKIVI 研究 KV 缓存的分布,并在所评估的 Llama、Falcon 与 Mistral 部署中对键和值采用不同的二比特粒度。
- Marchisio et al., “How Does Quantization Affect Multilingual LLMs?,” 2024. aclanthology.org在论文评估的多语言模型中,不同语言与任务受量化影响不均,自动指标低估了人类评估者观察到的部分变化。
评论
登录后评论