十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ik_llama.cpp 量化权重之谜:`weight[j] = qw[j] * sqrtf(sigma2 + xb[j]*xb[j])` 的由来与原理

ik_llama.cpp 量化权重之谜:`weight[j] = qw[j] * sqrtf(sigma2 + xb[j]*xb[j])` 的由来与原理 ik_llama.cpp 量化权重之谜weight[j] qw[j] * sqrtf(sigma2 xb[j]*xb[j])的由来与原理【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp导读本文围绕 ik_llama.cpp 量化器源码中反复出现的一行加权公式展开——weight[j] qw[j] * sqrtf(sigma2 xb[j]*xb[j])。它出现在 Q4_0、Q4_1、Q5_0、Q5_1、Q6_0 等经典量化类型以及本仓库特有的 i-quants / IQx_KS 系列量化实现中是基于重要性矩阵imatrix的加权 RMSE 量化的核心修正项。读完本文你将理解 imatrix 量化为什么不能直接使用weight[j] qw[j]、sqrt(sigma² x²)这一经验修正的取舍逻辑以及当模型为 DeepSeek、Arctic 这类高专家数 MoE 时如何用--override-kv expert_used_count改进 imatrix 数据质量。一、问题缘起量化器里的weight[j]是什么该问题最初来自仓库讨论区的一则提问见 github-data/discussions/140 - Questions about weight_j_.md提问者在阅读quantize_row_q4_0_impl等函数时发现每个被量化元素 j 的权重被写成了weight[j] qw[j] * sqrtf(sigma2 xb[j]*xb[j]);而不是更直白的weight[j] qw[j];这里的符号含义可以从源码中逐一确认qw[j]从 imatrix重要性矩阵数据中读取的、与该元素一一对应的量化权重。即 examples/imatrix/imatrix.cpp 计算出的对角 Hessian 近似值xb[j]当前量化块内第 j 个原始浮点权重值sigma2整行权重的平均平方和即sum_x2 / n_per_row其中sum_x2 Σ x[j]²。以 ggml/src/ggml-quants.c 中的quantize_row_q4_0_impl为例完整流程是float sum_x2 0; for (int j 0; j n_per_row; j) sum_x2 x[j]*x[j]; float sigma2 sum_x2/n_per_row; for (int ib 0; ib nb; ib) { const float * xb x QK4_0 * ib; for (int j 0; j QK4_0; j) weight[j] qw[j] * sqrtf(sigma2 xb[j]*xb[j]); float d make_qx_quants(QK4_0, 8, xb, L, 1, weight); ... }同样的公式还出现在quantize_row_q4_1_impl、quantize_row_q5_0_impl、quantize_row_q5_1_impl、quantize_row_q6_0_implggml/src/ggml-quants.c、ggml/src/ggml-quants.c、ggml/src/ggml-quants.c、ggml/src/ggml-quants.c以及本仓库特色的 ggml/src/iqk/iqk_quantize.cppIQ2_K、IQ3_K、IQ4_K、IQ5_K、IQ6_K 等中说明这是整套加权量化路径上的通用约定。weight[j]最终会被送入make_qx_quantsggml/src/ggml-quants.c。该函数在求解最优量化 scale 时把加权项融入加权最小二乘目标累加sumlx w*x[i]*l、suml2 w*l*l最优 scale 取sumlx/suml2并通过贪婪翻转迭代g scale * w * (x[j] - scale*l)逐步优化。可见w直接决定了每个元素在误差最小化中的话语权——这正是理解weight[j]为何需要修正的关键。二、核心回答这是一次经验修正而非科学推导针对为什么不用weight[j] qw[j]作者 ikawrakow 在讨论中的回答非常坦诚这只是经验性修正背后没有严格的科学依据this is simply an empirical correction, there is no science behind it。其来龙去脉是imatrix 出现之前量化器用不带外部信息的权重做加权 RMSE 最小化实践反复证明给幅度更大的权重更高的重要性量化结果更好。于是人们实验过各种幅度依赖形式——x²、|x|、σ² x²、σ |x|等——都是被尝试过的变体imatrix 出现之后作者的期望自然是终于可以扔掉这些非科学的东西直接使用 Hessian 对角元素。但实践证明事情没那么简单单纯使用 Hessian 对角线效果并不理想把sqrt(σ² x²)保留在qw[j]旁边确实能提升量化精度以 perplexity 或 KL 散度衡量。换言之sqrtf(sigma2 xb[j]*xb[j])是在有了 Hessian 之后依然保留的幅度依赖修正项用来弥补纯 imatrix 方案的不足。三、为什么偏偏是sqrt(sigma² x²)而不是别的形式作者给出了三条理由逐条对应设计约束约束含义对公式形式的推导影响Hessian 已提供大量重要性信息经验修正不能再像无 imatrix 时代那样强烈依赖幅度幅度依赖的指数不能太高sqrt恰好弱化了x²的增长小幅度权重的相对重要性不能趋近于零纯x²会让小权重的重要性趋近 0从而几乎不参与误差最小化必须有一个地板项σ²兜底无 imatrix 时代的经验积累幂次过强/过弱都试过sqrt(σ² x²)是作者尝试过的所有形式中效果最好的从数学形态看sqrt(σ² x²)的渐近行为非常合理当|x| σ时它近似于|x|线性幅度依赖当|x| σ时它趋近于常数σ小权重获得平坦的非零重要性。它既保留了大幅度元素更受重视的经验规律又不会让小权重被完全忽略还不会像x²那样过度放大离群值的影响——这与修正不能太强地依赖幅度的第一条约束是自洽的。四、为什么需要修正 Hessian 本身即使接受了要对 imatrix 做幅度修正还需要回答为什么 Hessian 信息本身需要修正作者的解释分两层只用对角线本身就是近似。我们使用的是完整 Hessian 的仅对角近似每个权重只保留二阶导数∂²L/∂w²忽略交叉项。在作者的工程经验里给近似加上一个修正项往往比直接信任近似效果更好RMSE 未必是正确的相似度度量。加权 RMSE 只是量化前后权重向量差异的便利度量表达式简单、可解析求解但真实的目标可能是让量化模型的输出分布perplexity、KL 散度最接近原模型。换一种相似度度量就会对应一个不同的理论 Hessian、不同的重要性矩阵。既然我们并不确切知道该最小化什么那么当前使用的 importances 本质上仍然是经验实验的结果。这解释了为什么代码中还会出现fudge因子——例如 ggml/src/ggml-quants.c 的const float fudge ggml_get_quantize_fudge_factor(GGML_TYPE_Q4_0)其取值表定义在 ggml/src/ggml.c。这些都是工程修正哲学的一部分理论是起点实践调优才是终点。五、正则化视角为什么经典正则化在量化中行不通讨论中另一个有价值的分支是能否用正则化理论解释/替代这个经验修正。作者的观点非常鲜明Tikhonov 正则化恰恰是量化最不想要的。Tikhonov 项的目标是把解压向零Gaussian prior centered at zero而量化时我们绝不想把量化值做得尽可能小有人提出对权重的 log 做正则化等价于 log-normal prior、以 1 为中心的 Gaussian把权重正则向 1即全部等权。参与者 jukofyork 实测确认这类更有理论根基的方案在当时的模型上表现比作者的经验公式略差作者进一步指出i-quants 在某种意义上已经自带正则化它强制一组量化值落在有限网格点上例如IQ2_XXS在 E8 格上只用 6561 个候选点中的 256 个这种离散化天然抑制过拟合可以视为一种正则化形式。结论是LLM 量化并不是经典意义上需要往目标函数里加惩罚项的问题经验修正之所以胜出是因为它的形式恰好与量化误差的实际分布匹配。六、MoE 场景imatrix 数据质量与专家激活问题讨论的后半段把话题延伸到 MoE 模型DeepSeek、Arctic 等的 imatrix 计算并揭示了一个与weight[j]密切相关但常被忽视的问题如果某个专家在训练数据上从未被激活那么它的 Hessian 对角元素即qw[j]就没有数据积累。6.1 常见的三个数据质量问题参与者 jukofyork 归纳了社区常见的三个误区(A) 用同一份 ~250KB 的calibration_datav3.txt同时跑密集模型和 DeepSeek-V3。对 256 专家的 MoE有效样本量最多只有密集模型的 1/32约 3%若路由惩罚router penalty训练不佳实际更低。应增大样本量或在大模型无法增大样本时调整正则化因子(B) 用wiki.train.raw算 imatrix、再用wiki.test.raw测 perplexity。两者文本风格高度相似同一来源的 wiki 文章会得到看起来很美但实际上有偏的 imatrix 改进估计(C) 只对每个超长上下文的前 512 个 token 跑 imatrix。会偏向短序列的激活模式且 transformer 块与 MLP 块的张量被采样的机会不均等。6.2 专家未被激活时的真实报错社区在 Arctic128 专家上实测发现blk.0.ffn_gate_exps.weight的 imatrix 数据只有 99.22% 覆盖率导致保存时被跳过save_imatrix: entry blk.0.ffn_gate_exps.weight has partial data (99.22%) - skipping进而在极低比特量化时直接失败llama_model_quantize: failed to quantize: Missing importance matrix for tensor blk.0.ffn_gate_exps.weight in a very low-bit quantization从源码看imatrix 收集器对 MoE 张量确实会按专家维度分别统计在 examples/imatrix/imatrix.cpp 中collect_imatrix针对GGML_OP_MUL_MAT_ID/GGML_OP_MOE_FUSED_UP_GATE读取ids张量top-k 选中的专家 id循环遍历n_as个候选专家只对当前 batch 中实际被路由到的专家累加其输入激活的平方和。因此某专家长期不被路由其对应列就没有统计量——这与整个 experts 张量因一个专家缺失而无法量化的社区报告完全吻合。6.3 用--override-kv提高激活专家数作者给出的实用建议是用--override-kv让模型激活比元数据规定更多的专家从而提高 imatrix 对每个专家的覆盖率./bin/llama-imatrix -m some_model -f some_training --override-kv deepseek2.expert_used_countint:N--override-kv的解析位于 common/common.cpp格式为KEYTYPE:VALUE支持int、float、bool、str四种类型见 docs/parameters.md。注意expert_used_count的 key 名称随架构而变例如qwen3moe.expert_used_count参见 github-data/discussions/385、llama4.expert_used_count参见 github-data/pull_requests/321 - LlaMA-4 supporttext only.md等。作者的实测经验以 DeepSeek-Lite 为例元数据为 6 个激活专家激活 7 个专家PPL 略降约 0.2%激活 8、9 个与默认基本持平激活 10 个PPL 升高约 0.3%。结论是在低 bpw 量化如IQ1_S、IQ1_M下略微调高激活专家数如 DeepSeek-Lite 从 6 提到 8、Mixtral 8x7 从 2 提到 3能明显改善效果但随着 bpw 升高收益消失甚至适得其反Mixtral 在 4 bpw 下调专家数已无意义。社区对 R1 的测试也印证了这一点下述表格为社区用户实测数据仅作现象展示不代表本仓库结论激活专家数PPL同一 imatrix 下多组上下文位置83.4155, 4.2311, 3.0817, 2.8601, 2.6933, 2.5792, 2.5123, 2.523963.4227, 4.2400, 3.1610, 2.9933, 2.8307, 2.7110, 2.6253, 2.648843.5790, 4.5984, 3.5135, 3.4490, 3.2952, 3.2563, 3.1883, 3.297826.2387, 7.7455同时要注意DeepSeek-V3 系列用 sigmoid 而非 softmax 做门控激活更多专家时输出隐状态之和会持续增大极端情况下如 10/12 专家可能出现 NaN而 16 专家反而正常——参与者推测与各专家输出的相关性、误差相互抵消有关。这提醒我们expert_used_count是用于改善 imatrix 质量的校准手段不代表推理时也应使用同样的专家数。七、总结一行公式背后的三层设计思想回到最初的问题——为什么不是weight[j] qw[j]可以从三个层次总结经验层无 imatrix 时代的量化实践已经证明幅度更大的权重应当获得更高重要性sqrt(σ² x²)是这一规律的最优经验形态互补层imatrix 提供的是 Hessian 对角近似它信息量大但未必完备加上幅度修正项后两者互补实测 perplexity/KL 更优务实层作者明确表示这是带 fudge factor 的工程实践——理论是起点实验调优才是终点。同一哲学也体现在 MoE imatrix 场景与其纠结正则化理论不如用--override-kv expert_used_count提高专家激活率、用更贴合的校准数据把qw[j]本身的质量做扎实。理解这行代码等于同时理解了 ik_llama.cpp 量化体系的两大支柱重要性矩阵的采集examples/imatrix/imatrix.cpp、examples/imatrix/README.md与加权 RMSE 的求解ggml/src/ggml-quants.c、ggml/src/iqk/iqk_quantize.cpp。对于希望自行改进量化精度的开发者这篇文章给出的关键启示是公式形态只是表象校准数据质量、专家覆盖率与幅度修正三者共同决定最终量化质量。【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表