llama.cpp(一):K-Quant 与 I-Quant — GGUF 量化格式全解
项目: llama.cpp — 社区驱动的 C/C++ 推理引擎,GGUF 格式的事实标准
前置阅读: 大模型量化系列 · GPTQ · AWQ
参考: K-Quant PR #1684 · Importance Matrix PR #4861 · 2-bit I-Quant PR #4897 · 统一评测 arXiv:2601.14277
一句话总结: llama.cpp 的 GGUF 量化不是单一算法,而是一套面向本地部署的格式族——Legacy 块量化打底,K-Quant 用 super-block 分层混合精度把 4 bit 做稳,I-Quant 再靠 Importance Matrix 和非线性映射把 2–3 bit 从「不可用」拉到「能跑」。
一、为什么需要单独讲 llama.cpp 量化
大模型量化系列里我们聊过 LLM.int8()、GPTQ、AWQ——它们的目标大多是 W8A8 或 W4A16 的 GPU 推理,评估也集中在 PyTorch 生态。
llama.cpp 走的是另一条路:
1 | 目标:在 CPU / Apple Silicon / 混合 offload 上跑开源 LLM |
Ollama、LM Studio、koboldcpp、text-generation-webui 的 GGUF 后端,底层都是 llama.cpp。你在 Hugging Face 下载的 Q4_K_M.gguf、IQ4_XS.gguf,文件名里的字母组合就是本文要讲的内容。
| 维度 | GPTQ / AWQ | llama.cpp GGUF |
|---|---|---|
| 量化时机 | PTQ,带 Hessian 补偿或 activation-aware 缩放 | PTQ,主要是 block-wise 取整 + 格式工程 |
| 运行时 | 需要 CUDA kernel(AutoGPTQ、vLLM 等) | CPU/GPU/Metal 通用,activation 保持 FP16/FP32 |
| 格式 | 单一 bit-width | 十几种格式,按 tensor 混合精度 |
| 选型依据 | 论文 + benchmark | perplexity + 社区经验 + 近期系统评测 |
这不是说 GGUF 量化「更差」——它在 本地部署、跨硬件、磁盘/内存受限 场景里往往是唯一合理选择。难点在于:名字太多,该选哪个?
二、共同基础:Block-wise Affine 量化
不管 Legacy、K-Quant 还是 I-Quant,llama.cpp 都是 weight-only PTQ:权重离线压成整数,推理时 activation 仍用浮点(部分 kernel 内部会临时量化 activation 做 dot product,但对用户透明)。
每个 weight block 存一组 scale(有时还有 offset/min),反量化公式:
Legacy 格式把权重切成 32 个一组 的 block,每个 block 一个 scale:
1 | Legacy 家族(2023 年初): |
名义上都是 4 bit,但 Q4_0 和 Q4_1 只有 一个 block 级 scale,对 outlier 和跨 block 动态范围差异很敏感。社区很快发现:同样叫「4 bit」,Legacy 和 K-Quant 的质量差距可以很大。
三、K-Quant:Super-Block + 跨 Tensor 混合精度
K-Quant 由 ikawrakow 在 2023 年中通过 PR #1684 引入,是当前 ≥4 bpw 场景的事实默认。
1. Super-Block 结构
K-Quant 把 256 个 weight 组成一个 super-block,再切成若干 sub-block。以 Q4_K 为例:
1 | Super-block(256 weights) |
相比 Legacy 的 32-weight block,K-Quant 多了一层 hierarchy:super-block 管全局动态范围,sub-block 管局部细节。同样 4 bit 名义宽度,重建误差显著更小。
各 K-Quant 变体的 bpw 大致如下(来自社区文档与 Discussion #559):
| 格式 | 有效 bpw | 说明 |
|---|---|---|
| Q2_K | ~2.56–3.0 | 2 bit 为主,部分 tensor 用 3 bit |
| Q3_K_S / M / L | ~3.4 / 3.5 / 3.6 | S=压缩优先,L=质量优先 |
| Q4_K_S / M | ~4.2 / 4.5 | M 是社区最常用默认 |
| Q5_K_S / M | ~5.2 / 5.5 | 接近无损 |
| Q6_K | ~6.5 | 高质量,体积仍比 FP16 小 ~40% |
后缀 S / M / L 不是「模型大小」,而是 同一 bpw 档位内的压缩–质量 trade-off:S 更省空间,L 给敏感 tensor 更多 bit。
2. 跨 Tensor 混合精度(这才是 Q4_K_M 的精髓)
K-Quant 的名字容易让人以为只是「block 结构升级」。真正拉开差距的是:不同 tensor 可以用不同的 K-Quant 子格式。
以 Q4_K_M 为例(Llama-3.1-8B 上约 4.58 GiB,bpw ≈ 4.89):
1 | Q4_K 用于:token_embd、attn_q、attn_k、ffn_gate、ffn_up、attn_output |
直觉上,attn_v 和 ffn_down 对输出质量更敏感——给它们 6 bit,其余 4 bit,整体 bpw 只比纯 Q4_K 高一点点,perplexity 却接近 Q5。
Q4_K_S 则所有 tensor 统一用 Q4_K,文件更小(~4.2 bpw),质量略逊。Q4_K_M 用混合精度换质量,是 bartowski 等量化发布者推荐的默认档。
3. K-Quant 的局限
Super-block 要求 tensor 列数能被 256 整除。早期 Falcon-7B、OpenLLaMA-3B 等模型部分 tensor 不满足,只能回退到 Legacy 格式(Issue #1919)。后续 row-wise 量化(IQ 系列的一部分)部分缓解了这个问题。
四、I-Quant:Importance Matrix + 超低 bit
2024 年初,ikawrakow 在 K-Quant 基础上推出 I-Quant(Importance-matrix Quantization),目标是把有效 bpw 压到 2–4 bit 区间,同时保持可用质量。
I-Quant 和 K-Quant 是 并列的两套方案,不是简单的「K-Quant 升级版」:
1 | K-Quant:super-block + 跨 tensor 混合精度,≥4 bpw 的主力 |
1. Importance Matrix(imatrix)是什么
PR #4861 引入的核心思想:量化一行 weight 时,不同 column 对 layer output 的贡献不同,应该 按重要性加权 最小化重建误差。
对 tensor 某一行
对
1 | 高 ⟨a_i²⟩ → 对应 weight 更重要 → 量化时分配更多精度 |
生成 imatrix 的工具是 llama-imatrix:
1 | # 1. 准备与目标任务相关的 calibration 文本(wiki 通用,但领域文本更好) |
关键区分(社区常混淆):
- imatrix 是一种校准数据,K-Quant 和 I-Quant 都可以 用它提升质量
- I-Quant 格式(IQ2_XXS、IQ3_M 等)在 极低 bit 下 必须 依赖 imatrix,否则质量崩溃
- 对 Q4_K_M,加 imatrix 通常只有 ~0.5% 量级改善;对 IQ2_XXS,改善可达 50%+
2. I-Quant 格式族
I-Quant 命名规则:IQ{bit}_{size}
1 | bit 档位:IQ2、IQ3、IQ4、IQ5、IQ6 … |
常见格式及定位:
| 格式 | 有效 bpw | 典型体积(8B 模型) | 定位 |
|---|---|---|---|
| IQ2_XXS | ~2.06 | ~2.5 GiB | 极限压缩,必须 imatrix |
| IQ2_XS / IQ2_S | ~2.3–2.5 | ~2.8 GiB | 2 bit 可用档 |
| IQ3_XXS / XS / S / M | ~3.0–3.7 | ~3.5–4.7 GiB | 3 bit 主力 |
| IQ4_XS | ~4.25 | ~4.17 GiB | 比 Q4_K_M 更小,需 imatrix |
| IQ4_NL | ~4.0 | — | 非线性 4 bit,block=32/64 |
I-Quant 还引入了 Legacy/K-Quant 没有的机制(Discussion #5063):
- 非线性映射:
,用 3 阶多项式替代线性 scale,同样 bpw 下重建误差更小 - Row-wise scale:每行一个 scale,解决 tensor 列数非 256 整除的问题
- k-means 聚类量化(IQ4_NL 等):权重映射到聚类中心而非均匀 grid
代价是 kernel 更复杂,decode 速度有时不如 K-Quant;但在 VRAM 不够、必须多塞几层到 GPU 时,更小体积带来的 offload 收益可以抵消 kernel 开销。
3. IQ4_XS vs Q4_K_M:4 bit 档位的两种哲学
两者都是「4 bit 级别」,设计思路不同:
1 | Q4_K_M(K-Quant): |
Llama-3.1-8B 上(Kaitchup 对比):IQ4_XS ~4.17 GiB vs Q4_K_M ~4.58 GiB,生成速度 IQ4_XS 略快,prompt 处理 Q4_K_M 略快。质量差距取决于 imatrix 是否与任务匹配。
五、Legacy / K-Quant / I-Quant 怎么选
arXiv:2601.14277 在 Llama-3.1-8B-Instruct 上做了目前最系统的 GGUF 格式对比(13 种 K-Quant + Legacy,FP16 baseline)。核心结论:
1. 质量–体积 Pareto 前沿
1 | 质量优先 + 仍要压缩: Q5_0(Avg 甚至略高于 F16,体积 -65%) |
注意:5 bit 并不总是比 4 bit 好。Q5_0 在该评测中 aggregate 最高,但 Q5_K_S 反而不如 Q4_K_S——说明 格式设计比名义 bit-width 更重要。
2. 按场景选型
| 场景 | 推荐格式 | 理由 |
|---|---|---|
| 日常聊天 / 通用本地部署 | Q4_K_M | 质量稳定、无需 imatrix、生态兼容最好 |
| 磁盘/内存极紧,仍要 4 bit | IQ4_XS + 好 imatrix | 比 Q4_K_M 小 ~10%,需校准 |
| 数学 / 多步推理 | Q5_0 或 Q4_K_S | GSM8K 对 3 bit 最敏感 |
| 指令遵循敏感 | Q4_K_S / Q5_0 | IFEval 在 mid-bit K-Quant 上甚至略超 F16 |
| VRAM 只够 2–3 bit | IQ3_M / IQ2_XS + imatrix | 不用 imatrix 基本不可用 |
| 质量接近 FP16 | Q6_K / Q8_0 | PPL delta < 0.05 |
| 纯 CPU 吞吐优先 | Q3_K_S / Q4_K_M | 低 bit → 高 tg128 tokens/s |
3. 一张决策树
1 | 需要跑本地 LLM? |
六、实操:从 HF 模型到 GGUF
1. 转换 + 量化流程
1 | # 克隆 & 编译 |
2. 验证
1 | # Perplexity |
不要只看 PPL。统一评测 表明:PPL 接近的格式,在 GSM8K / IFEval 上可以差好几个点。最终格式应在你自己的任务上跑一轮。
3. imatrix 校准数据建议
1 | 通用对话 → WikiText / C4 子集即可 |
imatrix 是 task-aware 的:用代码语料校准的 imatrix 量化出的模型,在代码任务上通常优于通用 wiki 校准。
七、和「学术量化」的关系
把 llama.cpp 量化放进 大模型量化系列 的脉络里:
1 | LLM.int8() → 发现 activation outlier |
llama.cpp 没有 GPTQ 的 Hessian 重构,没有 AWQ 的等价缩放——它的哲学是:
- Block-wise 仿射量化 足够简单,CPU SIMD / GPU kernel 都好写
- Super-block + 混合精度 用格式工程弥补简单取整的不足
- Importance Matrix 在极低 bit 下引入 activation 信息(和 AWQ 思路有呼应,但实现完全不同)
- 社区迭代:新格式通过 PR + perplexity + 下游任务反馈快速演进,而非等论文
这不是「学术 vs 工程」谁更好的问题——部署路径不同,选型就不同。有 CUDA 服务器跑 vLLM,AWQ/GPTQ 往往更快;要在 MacBook 或 8G 核显笔记本上跑 70B,GGUF + llama.cpp 几乎是唯一解。