Skip to content

项目: 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。其主要量化算法分为三组:

text
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。设一个权重块为 w,线性量化先用 scale s 和 zero-point z 将浮点权重映射到离散整数,再由相同参数重建:

qi=clip(⌊wis⌉+z,qmin,qmax),w^i=s(qi−z).

量化器选择量化参数和离散值,使块内重建误差 ∑i(wi−w^i)2 尽可能小。对称量化固定零点,只保存 scale;仿射量化还保存 min 或等价的 zero-point,以覆盖偏移的权重分布。

Legacy 格式把权重切成 32 个一组 的 block,每个 block 一个 scale:

格式量化值块级参数重建形式
Q4_04 bitscalew^=sq
Q4_14 bitscale、minw^=sq+m
Q5_05 bitscalew^=sq
Q5_15 bitscale、minw^=sq+m
Q8_08 bitscalew^=sq

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 为例:

text
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

设第 b 个 sub-block 的 6 bit scale 和 min 为 (sb,mb),super-block 的两个浮点 scale 为 (d,dmin),则 Q4_K 的重建形式为:

w^b,i=dsbqb,i−dminmb,qb,i∈{0,…,15}.

这形成两级参数层次:sub-block 参数拟合局部动态范围,super-block 参数压缩这些局部参数的存储开销。因此,格式的实际 bpw 还包括 scale、min 等元数据,不等于量化值本身的位宽。

各 K-Quant 块编码的结构如下:

块编码sub-block 划分权重位宽sub-block 参数有效 bpw
Q2_K16×162 bit4 bit scale + 4 bit min2.625
Q3_K16×163 bit6 bit scale3.4375
Q4_K8×324 bit6 bit scale + 6 bit min4.5
Q5_K8×325 bit6 bit scale + 6 bit min5.5
Q6_K16×166 bit8 bit scale6.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 编码。这个过程可以写成:

tj=arg⁡mint∈TEj(t)s.t.∑jCj(tj)≤B,

其中,tj 是 tensor j 采用的块编码,Ej 是其量化误差,Cj 是存储成本,B 是总 bit 预算。llama.cpp 的预设用基于 tensor 类型和模型结构的规则近似这一混合精度分配,而不是在量化时显式求解上述优化问题。

四、I-Quant:重要性加权与码本量化 ​

I-Quant 不是一种固定块布局,而是一组面向低 bit 数的编码。它的共同思路有两层:先用 Importance Matrix 构造加权重建误差,再用非均匀标量码本或向量码本限制候选量化值。

1. Importance Matrix ​

设一行权重为 w,输入 activation 为 a,线性层输出为 y=wTa。量化误差 e=w−w^ 引起的输出误差为:

Δy=eTa,E[(Δy)2]=eTE[aaT]e.

完整的 E[aaT] 是输入协方差矩阵。llama.cpp 只收集其对角项:

ci=E[ai2],Ldiag=∑ici(wi−w^i)2.

源码中的 imatrix 因而是每个输入通道的 activation 平方均值,而不是完整的二维矩阵。ci 越大,该通道上的权重误差对输出影响越大。量化器在搜索 scale、量化值或码本索引时,优先减小这些位置的误差。

具体实现还把权重幅值纳入局部搜索。对块内权重 wi,多种 IQ 编码使用近似权重:

ui=ciσw2+wi2,

再最小化 ∑iui(wi−w^i)2。这里 σw2 是当前 super-block 的权重均方值,用于避免只由单个大权重主导搜索。Importance Matrix 也能传给部分 Legacy 和 K-Quant 量化器;它是误差权重,不是 I-Quant 块格式本身。

2. 非均匀标量码本:IQ4_NL 与 IQ4_XS ​

IQ4_NL 每 32 个权重共享一个 FP16 scale。每个权重不再映射到均匀整数,而是保存一个 4 bit 索引 li,指向固定的 16 值码本:

V=(−127,−104,−83,−65,−49,−35,−22,−10,1,13,25,38,53,69,89,113),w^i=dVli,li∈{0,…,15}.

给定 scale d 时,每个 li 选择使 |wi−dVli| 最小的码本值;给定索引后,scale 的加权最小二乘解为:

d=∑iuiVliwi∑iuiVli2.

量化器在若干候选 scale 上交替更新索引与 scale。一个 IQ4_NL block 包含 16 字节索引和 2 字节 scale,因此实际占用为 18×8/32=4.5 bpw。

IQ4_XS 复用同一个非均匀码本,但把 256 个权重分成 8 个 32-weight sub-block。每个 sub-block 有一个 6 bit scale,该 scale 再由 super-block 的 FP16 scale 统一缩放:

w^b,i=dsbVlb,i.

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 维向量。量化过程依次执行:

  1. 分离每个权重的符号与幅值,并将符号压缩为受约束的 sign pattern。
  2. 将 8 个幅值组成向量,在预定义 grid 中查找最近的合法码字。
  3. 若直接取整结果不在 grid 中,则在邻接表中搜索加权误差最小的码字。
  4. 根据选定码字重新计算 sub-block scale,再把码本索引、符号和 scale 打包。

这种方法量化的是一个小向量的联合模式,而不是 8 个彼此独立的 2 bit 标量。IQ2_XXS 的 256 个权重使用 64 字节索引、符号和局部 scale,再加 2 字节 FP16 scale,总计 2.0625 bpw。

常见 I-Quant 块结构如下:

块编码block 大小主要表示有效 bpw是否要求 imatrix
IQ2_XXS256向量码本 + sign pattern + 分层 scale2.0625是
IQ2_XS256向量码本 + sign pattern + 独立局部 scale2.3125是
IQ2_S256更完整的索引、符号与局部 scale2.5625是
IQ3_XXS2563 bit 向量码本3.0625是
IQ3_S2563 bit 码本 + 独立符号与 scale3.4375否
IQ4_NL3216 值非均匀标量码本4.5否
IQ4_XS256非均匀码本 + 6 bit sub-block scale4.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 格式的统一实验也体现了这一点:相同或相近名义位宽的格式,仍可能因块结构和混合策略不同而产生明显差异。

参考资料 ​

  1. llama.cpp K-Quant PR #1684
  2. llama.cpp ggml-common.h
  3. llama.cpp ggml-quants.c
  4. Importance Matrix PR #4861
  5. 2-bit I-Quant PR #4897
  6. Which Quantization Should I Use? arXiv:2601.14277