基于张量敏感度的 GGUF 量化布局优化方法

0 阅读

背景:量化中的未知与变数

在 llama.cpp 的 GGUF 量化实践中,一直存在大量不确定性和效果波动。官方的 llama-quant.cpp 脚本虽然经过多次迭代,但其核心逻辑已显陈旧——这并非批评开发者,而是因为该模块极其关键又难以维护,直接影响每一个量化模型的质量。

几年前,随着 MoE(Mixture of Experts)模型兴起,人们发现原有算法难以有效处理超过 8 个专家的情况(原代码仅针对 Mixtral 的 8 专家做了特例)。同时,像 shexp 这类极小但高度敏感的张量也需要特殊对待。为此,社区陆续提出改进方案,作者也维护了自己的 llama-quant.cpp 分支以更好支持 MoE 模型。然而,随着新架构不断涌现,仅靠手工规则已难以为继。

U shape of sensitivity and relative damage charts

核心问题:通用规则的局限

KLD charts heuristic vs map

无论是官方还是社区修改版,现有方法本质上都是模型无关的。它们虽会根据张量形状或网络深度动态调整精度(例如对前 1/8、后 1/8 层及中间每隔三层使用更高精度),但这些启发式规则源于多年前的有限测试,无法适应新模型的复杂结构。比如,某些注意力层会被提升精度,而另一些则被压缩,只为凑出目标比特率。这种“一刀切”的策略显然不够精细。

数据驱动:张量敏感度测绘

为突破这一限制,作者设计了一套大规模实验框架,在 Framework 提供的 AMD AI Max+ 395 128GB 台式机上连续运行约 96 小时,对 Qwen3.5-0.8B 和 Qwen3.5-4B 模型生成并评估了超过 1000 种量化配置。

实验采用两种策略:

  • 降级单一张量:除一个张量设为 q2_k 外,其余均为 q8_0
  • 升级单一张量:除一个张量设为 q8_0 外,其余均为 q2_k

结果显示,“升级”测试噪声较大,而“降级”数据清晰揭示了各张量的敏感度差异。该方法与 Thireus 的 GGUF-Tool-Suite 思路类似,即通过单独压缩某个张量来评估其理论敏感度。此外,还在 Gemma 4、Granite 4.2、Ling 等多个模型家族上验证了趋势的一致性。

关键发现:哪些张量最怕被量化?

所有敏感度均通过 KL 散度(KLD)衡量——即量化模型与 bf16 原始模型在 wikitext-2-raw 数据集上的 token 概率分布差异,数值越低越好。

主要结论如下:

  1. 词嵌入层(token_embd)极度敏感:其对 KLD 的贡献是普通权重张量的 8–16 倍(随模型规模增大)。虽然 q4_k 已能恢复大部分性能,但在低比特模型中仍需显著提升精度。

  2. 网络深度呈 U 型敏感曲线:首尾层比中间层更敏感,这与现有 use_more_bits 规则一致,但新数据提供了更精确的量化依据。

  3. 特定注意力/FFN 投影高度敏感attn_vattn_outputffn_upssm_out 对量化误差极为敏感,而 ffn_gate 几乎无需额外比特。

  4. 小型张量统一保留为 F32:极小的张量(如 TINY_PARAMS)直接使用 F32,兼顾速度与精度。

这些发现被整理为 prior.json 文件,作为后续布局生成的先验知识。

解决方案:自动布局求解器

基于上述数据,作者与 Claude 协作开发了一个布局求解器(solver.py)。它接收模型结构、目标量化类型、ggml 块大小等参数,输出最优的 per-tensor 量化分配方案。

Damage per crushed tensor

有趣的是,对于 K 系列量化(如 Q4_K),降低某些张量的精度(“crush”)反而会损害整体性能,因为 K 量化层级间的精度差距过大。而 IQ 系列因粒度更细,偶尔可通过牺牲低敏感张量来换取高敏感张量的精度提升。

重建量化命名的意义

过去,Q3_K_S 等名称已名不副实——文件可能大部分并非 Q3_K 类型,甚至比特率远超预期。为此,新方案引入严格比例规则:

  • _S(Small):至少 90% 主体张量为命名类型
  • _M(Medium):至少 70%
  • _L(Large):允许低至 50%

这意味着 Q3_K_S 确实主要由 Q3_K 张量构成。同时,禁止 K 量化混用 IQ 类型(出于兼容性考虑),而 IQ 量化可自由组合。

结果上,部分量化文件体积发生变化。例如 Qwen3.5-4B 的 Q3_K_M 缩小 15%,但因比特分配更合理,同等文件大小下性能反而提升。测试显示,Q4_K_M 虽总 KLD 略高,但体积减小 5% 以上,单位比特效率更优。

泛化能力验证

关键问题是:在 Qwen 上学到的敏感度能否迁移到其他架构?作者在 8 个异构模型上测试,包括:

  • Qwen-3.6-35B-A3B(MoE)
  • Gemma 4 E4B
  • Granite-4.2-8B
  • Ling 3.0 tiny/flash
  • MiniCPM5-2B
  • Muse Glimmer-30B
  • DeepSeek-V2-Lite(MLA 架构)

image

初始版本在 Granite、MiniCPM(全注意力结构)和 DeepSeek 上失败,但通过两项改进解决:

  1. 为不同架构类别维护独立的主体先验表
  2. 嵌入层规则考虑其在文件中的占比

最终,新方法在所有测试模型上均优于或持平于原启发式规则,尤其在 3–5 比特区间提升显著。

“金丝雀测试”:持续质量保障

为防止未来新模型失效,作者设计了自动化“金丝雀测试”:

  1. 对每个新模型架构(由名称+张量维度序列定义),用新布局和旧启发式分别生成 Q4_K_MQ3_K_MIQ2_XS 量化
  2. 计算六者的 KLD 与比特率,绘制“KLD/比特”曲线
  3. 若新布局点显著高于曲线(超出噪声范围),则拒绝该布局,回退到旧方法

测试结果会公开在 Hugging Face 模型页面的“Per-tensor layouts”部分。例如 MiniCPM5-2B 初始未通过测试,系统自动回退,避免了劣质发布。

实际影响与变更

用户将注意到 _L 变体的含义已改变:

  • 旧版Q2_K_L/Q3_K_XL/Q5_K_L 仅表示“嵌入层和输出层用 q8_0”
  • 新版:仅保留 Q4_K_LQ6_K_L 作为高预算选项,移除其他 _L 变体

理由很简单:若需要更高精度嵌入层,直接选用更高一级的量化(如 Q4_K_MQ5_K_M)更合理。此举也解决了 Q3_K_XL 文件大于 Q5_K_M 的反常现象(如 Gemma-4-E4B 所示)。

后续计划与局限

下一步工作

  • 在 Qwen3.8-27B 上全面应用新布局
  • 支持含 n-gram 表的模型(如 Qwen3.8-Flash-Next、DeepSeek-V4.1-Flash)
  • 探索复杂 MLA 架构(如 Hy4-preview 的稀疏注意力)

当前局限

  • KLD 仅在 wikitext-2 上评估,需更多数据集验证
  • 先验数据主要来自两个小型 Qwen 模型
  • 高于 Q5 时精度提升接近噪声水平
  • 目前仅两个模型公开使用该方法,需社区广泛反馈

尽管如此,通过持续的金丝雀测试,作者对新量化模型的质量充满信心。