项目: llama.cpp前置阅读: 大模型量化源码依据: K-Quant PR #1684 · Importance Matrix PR #4861 · 2-bit I-Quant PR #4897实验参考: Which Quantization Should I Use? arXiv:2601.14277
一句话总结: llama.cpp 的 GGUF 量化不是单一算法,而是一组 weight-only PTQ 格式:Legacy 使用基础块量化,K-Quant 通过 super-block 和跨 tensor 混合精度降低误差,I-Quant 再用 Importance Matrix、非均匀码本等机制支持更低 bit 量化。
一、量化算法总览
llama.cpp 对权重矩阵逐行分块量化,并将量化值、scale、min 或码本索引一起写入 GGUF。其主要量化算法分为三组:
Legacy → 以 32 个权重为一组,保存量化值和 block 级 scale/min
K-Quant → 以 256 个权重组成 super-block,再细分 sub-block
I-Quant → 引入重要性加权和非线性码本,面向更低 bit 数Q4_K、IQ4_NL 等名称表示块编码;Q4_K_M 中的 M 则表示在整个模型上组合多种块编码的量化预设。两者需要分开理解。
二、共同基础:Block-wise Affine 量化
Legacy、K-Quant 和 I-Quant 都属于 weight-only PTQ。设一个权重块为
量化器选择量化参数和离散值,使块内重建误差
Legacy 格式把权重切成 32 个一组 的 block,每个 block 一个 scale:
| 格式 | 量化值 | 块级参数 | 重建形式 |
|---|---|---|---|
Q4_0 | 4 bit | scale | |
Q4_1 | 4 bit | scale、min | |
Q5_0 | 5 bit | scale | |
Q5_1 | 5 bit | scale、min | |
Q8_0 | 8 bit | scale |
Legacy 格式的关键限制是每 32 个权重只共享一组块级参数。块内局部范围差异越大,同一 scale 同时覆盖所有权重时产生的舍入误差越大。
三、K-Quant:Super-Block + 跨 Tensor 混合精度
K-Quant 由 PR #1684 引入。它在 256 个权重的 super-block 内再划分 sub-block,并对 sub-block 的 scale 和 min 做二次量化。
1. Super-Block 结构
K-Quant 把 256 个 weight 组成一个 super-block,再切成若干 sub-block。以 Q4_K 为例:
Q4_K super-block(256 weights)
├── 8 个 sub-block,每个 32 weights
├── 每个权重保存 4 bit 量化值
├── 每个 sub-block 保存 6 bit scale 和 6 bit min
└── super-block 保存两个 FP16 scale,用于还原上述 scale 和 min设第
这形成两级参数层次:sub-block 参数拟合局部动态范围,super-block 参数压缩这些局部参数的存储开销。因此,格式的实际 bpw 还包括 scale、min 等元数据,不等于量化值本身的位宽。
各 K-Quant 块编码的结构如下:
| 块编码 | sub-block 划分 | 权重位宽 | sub-block 参数 | 有效 bpw |
|---|---|---|---|---|
Q2_K | 2 bit | 4 bit scale + 4 bit min | 2.625 | |
Q3_K | 3 bit | 6 bit scale | 3.4375 | |
Q4_K | 4 bit | 6 bit scale + 6 bit min | 4.5 | |
Q5_K | 5 bit | 6 bit scale + 6 bit min | 5.5 | |
Q6_K | 6 bit | 8 bit scale | 6.5625 |
2. 块编码与模型量化预设
Q4_K 定义单个权重块如何编码;Q4_K_S、Q4_K_M 则定义整个模型的 tensor 如何选择编码。后缀 S、M、L 表示不同的跨 tensor 混合策略,不会改变 Q4_K 块本身的布局。
以 Q4_K_M 为例,量化器以 Q4_K 为主体,并把部分误差敏感的 tensor 提升到更高位宽的 K-Quant 编码。这个过程可以写成:
其中,
四、I-Quant:重要性加权与码本量化
I-Quant 不是一种固定块布局,而是一组面向低 bit 数的编码。它的共同思路有两层:先用 Importance Matrix 构造加权重建误差,再用非均匀标量码本或向量码本限制候选量化值。
1. Importance Matrix
设一行权重为
完整的
源码中的 imatrix 因而是每个输入通道的 activation 平方均值,而不是完整的二维矩阵。
具体实现还把权重幅值纳入局部搜索。对块内权重
再最小化
2. 非均匀标量码本:IQ4_NL 与 IQ4_XS
IQ4_NL 每 32 个权重共享一个 FP16 scale。每个权重不再映射到均匀整数,而是保存一个 4 bit 索引
给定 scale
量化器在若干候选 scale 上交替更新索引与 scale。一个 IQ4_NL block 包含 16 字节索引和 2 字节 scale,因此实际占用为
IQ4_XS 复用同一个非均匀码本,但把 256 个权重分成 8 个 32-weight sub-block。每个 sub-block 有一个 6 bit scale,该 scale 再由 super-block 的 FP16 scale 统一缩放:
256 个 4 bit 索引占 128 字节,8 个 6 bit scale 占 6 字节,FP16 super-block scale 占 2 字节,总计 136 字节,即 4.25 bpw。
3. 向量码本:IQ2 与 IQ3
在 2–3 bit 下,逐权重独立选择标量会留下过大的索引和 scale 开销。IQ2_XXS、IQ2_XS、IQ3_XXS 等格式把连续多个权重组成小向量,再用一个索引指向预先构造的合法向量集合。
以 IQ2_XXS 为例,一个 256-weight super-block 被分成 8 个 32-weight sub-block,每个 sub-block 再拆成 4 个 8 维向量。量化过程依次执行:
- 分离每个权重的符号与幅值,并将符号压缩为受约束的 sign pattern。
- 将 8 个幅值组成向量,在预定义 grid 中查找最近的合法码字。
- 若直接取整结果不在 grid 中,则在邻接表中搜索加权误差最小的码字。
- 根据选定码字重新计算 sub-block scale,再把码本索引、符号和 scale 打包。
这种方法量化的是一个小向量的联合模式,而不是 8 个彼此独立的 2 bit 标量。IQ2_XXS 的 256 个权重使用 64 字节索引、符号和局部 scale,再加 2 字节 FP16 scale,总计 2.0625 bpw。
常见 I-Quant 块结构如下:
| 块编码 | block 大小 | 主要表示 | 有效 bpw | 是否要求 imatrix |
|---|---|---|---|---|
IQ2_XXS | 256 | 向量码本 + sign pattern + 分层 scale | 2.0625 | 是 |
IQ2_XS | 256 | 向量码本 + sign pattern + 独立局部 scale | 2.3125 | 是 |
IQ2_S | 256 | 更完整的索引、符号与局部 scale | 2.5625 | 是 |
IQ3_XXS | 256 | 3 bit 向量码本 | 3.0625 | 是 |
IQ3_S | 256 | 3 bit 码本 + 独立符号与 scale | 3.4375 | 否 |
IQ4_NL | 32 | 16 值非均匀标量码本 | 4.5 | 否 |
IQ4_XS | 256 | 非均匀码本 + 6 bit sub-block scale | 4.25 | 否 |
4. 三类算法的差异
| 算法族 | 离散表示 | 参数层次 | 主要误差目标 |
|---|---|---|---|
| Legacy | 均匀标量 | 32-weight block scale/min | 块内重建误差 |
| K-Quant | 均匀标量 | sub-block scale/min + super-block scale | 分层块内重建误差 |
| I-Quant | 非均匀标量码本或向量码本 | block/sub-block scale + 索引与符号 | Importance Matrix 加权误差 |
名义 bit 数只描述权重索引的主要位宽,无法单独决定实际 bpw 和量化误差。scale、min、符号、码本索引以及跨 tensor 混合策略都会改变最终结果。arXiv:2601.14277 对多种 GGUF 格式的统一实验也体现了这一点:相同或相近名义位宽的格式,仍可能因块结构和混合策略不同而产生明显差异。