大模型量化:FP16→INT4 丢了多少信息?又省了多少资源?
副标题不是降质换速度——FP16 的 11 位尾数对 LLM 权重大部分是冗余。量化的问题是怎么知道哪些权重要多留一位哪些可以砍到底GPTQ、AWQ、GGUF 给了三种不同的答案。一、你其实一直在用量化从 #1 开始这个系列用的一直是 GGUF 格式的量化模型。Qwen3-8B Q4_K_M、Llama 2 7B Q4_K_M——所有实验都是4-bit 模型跑的。但 Q4_K_M 不等于原始模型直接砍掉 4 倍大小。你下载的 4.7GB 文件Qwen3-8B Q4_K_M如果按原始 FP16 存是 16GB但这不是简单的每个 float 砍到 4 bit——有些权重保留了 6 bit有些砍到了 3 bit通过一种叫重要性感知混合精度的机制。这正是量化最反直觉的地方量化不是uniform 降精度——它是给每一层的每一位精打细算。有些权重对精度极度敏感少一位输出就变有些权重哪怕砍到 2-bit 也看不出区别。如何区分它们是所有量化方法的核心问题。这篇博客不讲公式讲物理——FP16 的 11 位精度对于权重参数到底意味着什么为什么我们用 INT4 跑了 19 篇博客的实验从来没出过问题二、先理解数字FP16、INT8、INT4 到底差多少2.1 精度不是0.0001 和 0.1 的区别是格子的大小FP16 (16 位): 1 bit 符号 5 bit 指数 10 bit 尾数 ≈ 3.3 位有效十进制数字 能表示的范围: ±65504 INT8 (8 位): 1 bit 符号 7 bit 数值 能表示的范围: -128 ~ 127 格子大小: f_max / 127 INT4 (4 位): 1 bit 符号 3 bit 数值 能表示的范围: -8 ~ 7 格子大小: f_max / 7以权重范围 [-1, 1] 为例FP16: 2 / 65504 ≈ 0.00003 的精度 ← 溢出了 INT8: 2 / 127 ≈ 0.0157 的精度 ← 足够细 INT4: 2 / 7 ≈ 0.2857 的精度 ← 很粗了 但注意权重的范围通常不在 [-1, 1] 之间 在一些层中重要的权重集中在 f_max 附近的小范围内 而在另一些层中权重分散在整个范围决定量化质量的不是bit 数而是你给重要的数值留了多少格子。这就是为什么有些 INT4 模型质量几乎无损而有些 INT8 模型反而差——问题不在 bit 数本身在量化方案。2.2 从 FP16 到 INT44 倍压缩后的存储成本Qwen3-8B FP16: 8.2B × 2 bytes 16.4 GB Qwen3-8B INT4: 8.2B × 0.5 bytes 4.1 GB (理论) 实际 GGUF Q4_K_M ≈ 4.7 GB含 overhead 节省: 约 70% 的显存/带宽4 倍压缩不是简单的每个数字砍 4 倍精度——因为存储从 16 bit 降到 4 bit但 GPU 在计算时会把 INT4 的值先解压回 FP16 再算。所以推理时的实际流程以 INT4 量化模型为例: 1. 从 HBM 读取 INT4 权重 ← 带宽需求降到 INT4 级别 2. GPU 的 Tensor Core 支持 INT8/INT4 矩阵乘法 → 不需要解压就能算 ← T4/A100/H100 原生支持 INT4 matmul 3. 算出来的是 INT4 精度的结果 → 写回 HBM 前转成 FP16 ← 精度从 INT4 回升到 FP16 级别量化省的不是计算量是搬权重的带宽。这和 #18 的核心逻辑搬 KV Cache 是瓶颈完全一致——推理的大部分成本是搬权重不是算权重。把权重从 16 bit 压到 4 bit搬运量直接降到 1/4这才是加速的来源。三、量化的三个设计维度3.1 粒度逐层 vs 逐通道 vs 逐组粒度做法精度存储开销per-tensor整层用一个 scale factor粗极小每层 1 个 scaleper-channel每列/行一个 scale factor中稍微增加per-group每 G 个权重一组共享 scale细需要额外存 scaleper-element每个权重单独一个 scale—等于没压缩GGUF 的 Q4_K_M 中的 “M” 代表混合粒度——它在不同层用不同粒度一个 4096 × 4096 的权重矩阵~16M 参数: per-tensor: 1 个 scale × 2 bytes 2 bytes ← 太粗质量差 per-channel: 4096 个 scale × 2 bytes 8 KB ← 常见方案 per-group-32: 16M/32 个 scale 512K × 2 1 MB ← 最细质量最好per-group 的额外存储1 MB 对于 16M 参数来说只增加了约 6%但精度提升巨大。这 1 MB 花得非常值。3.2 对称性对称 vs 非对称对称量化: w_quant clamp(round(w / scale), -127, 127) 假设正负范围对称scale 2 × max(|w|) / 255 适用场景: 权重大致对称分布大部分层 非对称量化: w_quant clamp(round((w - zero_point) / scale), 0, 255) 引入 zero_point 偏移 适用场景: 权重分布偏斜某些激活层对称量化简单高效reLU 后的激活分布不对称时用非对称。3.3 精度恢复round-to-nearest那个时刻——量化唯一真正丢失精度的节点——就是 round。当你把 float 值映射到离它最近的 INT 格子时0.5 的差被舍去了0.5 的差被保留了但这个差值0.5 就已经是误差。Quantization Error |w_real - w_quant × scale| 对这个误差的处理方式决定了不同量化方法的优劣。 GPTQ 说: 我用一次校准数据最小化误差。 AWQ 说: 我保护重要通道把误差集中到不重要通道。 GGUF 说: 我直接用更细的粒度per-group来降低误差。四、三种主流方案的分歧精度应该怎么分配4.1 GPTQ让误差在整个层里对冲GPTQ2023Frantar et al.是最流行的训练后量化方法。它的核心想法来自最优脑外科Optimal Brain Surgery量化某个权重会产生误差。但如果你同时调整同行的其他权重可以部分抵消这个误差。GPTQ 的流程: 1. 从校准集取一小批输入 2. 逐列量化权重矩阵 3. 量化第 j 列时用一个二阶信息Hessian 矩阵来决定 - 第 j 列该用多少 bit - 如何调整其他列来补偿第 j 列的损失 4. 同类比逐列完成 本质: 利用权重间的冗余来分摊量化误差优点确实能做出质量最好的 INT3/INT4 模型缺点校准数据的选择非常敏感不同校准集质量差异大量化过程需要 GPU不能纯 CPU 跑时间长GPTQ 在 HuggingFace 生态中最常见AutoGPTQ库许多4-bit 模型用的是 GPTQ。4.2 AWQ保护重要通道AWQ2024Lin et al.观察到一个权重矩阵中大约 1% 的通道决定了输出的质量。这些重要通道的特征值是 outsier数量级远大于其他通道。观察: 逐通道的 scale 差异巨大 Channel 0: scale 0.5 ← 不重要 Channel 1: scale 45.2 ← 重要 Channel 2: scale 0.8 Channel 3: scale 32.7 ← 重要 ... AWQ 的想法: 给重要通道多留一位精度 方法不是手动保护而是: 将重要通道的权重乘以 1 的因子 → 量化 scale 自动变大 → 重要通道在 INT4 中有更多格子 推理时乘以倒数因子恢复原值优雅之处在不需要特殊算子支持——同一个 INT4 matmul kernel只是权重值变了。AWQ 量化后的模型可以直接用标准 INT4 kernel 推理。和 GPTQ 的关系GPTQ 用校准数据逐列优化计算量大质量上限高AWQ 仅靠分析权重分布就能找到重要通道速度快、不依赖校准数据两者可以叠加——先 AWQ 保护重要通道再 GPTQ 微调其他通道实际中AWQ 是当前推荐度最高的方案之一vLLM 默认就用 AWQ。4.3 GGUF 量化不玩技巧靠粒度GGUFllama.cpp 的格式是这三者中最朴实的不用校准数据、不分析重要性、不做误差对冲。它就是用更细的粒度来保证精度。GGUF 的 Q4_K_M 具体做了什么: 1. 把权重分成 32 个一组 (per-group-32) 2. 每组独立算 scale 和 min 3. 对 32 个权重做 quan(权重) (w - min) × scale → INT4 但 Q4_K_M 不是所有层统一 Q4——M 代表混合 (mixed): Attention 层: Q6保留更多精度因为它们更敏感 FFN 层: Q4ffn 对精度更宽容 Embedding: Q8第一层和最后一层对精度最敏感 RoPE 参数: FP16不改这个K的含义是核心——先评估每个 layer 对精度的敏感度用一小批校准数据跑一次然后分配 bitGGUF 变体含义平均 bitQ2_K极端压缩大部分 Q2~2.6 bitQ3_K_S/M小/M 型混合~3.3-3.5 bitQ4_K_M混合主力推荐~4.5 bitQ5_K_M高精度混合~5.3 bitQ6_K基本无损~6.5 bitQ8_0近乎无损~8 bitQ4_K_M 之所以是这个系列的默认选项不是因为它是 4-bit而是它把珍贵的 bit 分配给了最需要它们的地方——Attention 层的投影矩阵。这就是为什么跑了大半个系列的实验量化模型从未在质量上拖过后腿。三种方案对比GPTQAWQGGUF核心理念误差对冲保护重要通道混合粒度需要校准数据是质量敏感可选提升效果否只测 loss量化速度慢逐列优化快快推理引擎HuggingFace/vLLMvLLM默认llama.cpp/Ollama主要场景云端部署云端 本地本地 消费级质量同 bit⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐便携性需专用 kernel标准 INT4 kernel独占格式 GGUF五、量化不是降质为什么 Q4 模型在大部分任务上几乎无损这是整个系列 19 篇博客中从未被质疑过的假设——一直在用 Q4_K_M但从来没有一卷数据说Q4 比 FP16 差了多少。5.1 为什么能几乎无损原因一LLM 权重的有效信息密度远低于 FP16 的承载能力。FP16 有 10 位尾数 ≈ 3.3 位有效十进制数字。但 LLM 权重在训练过程中受到优化器噪声、随机初始化、批次顺序等影响其信噪比远低于 3 位有效数字。类比: 你有一个可以把距离测量到 0.001mm 的千分尺 但你用它去量一把被磨损的钢尺的刻度 钢尺本身的制造误差是 ±0.1mm 所以尽管千分尺的精度是 0.001mm你实际知道的只有 0.1mm → FP16 就是那个千分尺LLM 权重就是那把钢尺原因二量化误差和推理噪声分布类似。LLM 在推理时本身就有采样噪声temperature、top-k、top-p。量化引入的误差和采样噪声在统计特性上类似——它们都是小幅度随机扰动。如果 temperature 0.7 的采样变化都被认为是合理多样性那量化误差同样不会产生错误。原因三大多数任务是语言流畅度测试不是数值精度测试。写一段代码、翻译一句话、回答一个问题——这些任务对权重的第 8 位尾数完全免疫。量化误差只有在需要精确记忆的任务上才会暴露如检索一段引文的原文、计算精确的数学表达式。5.2 什么情况下量化确实会翻车场景原因能恢复吗极度少样本推理量化破坏了 few-shot 示例的精确模式增加 shot 数代码生成中精确变量名某些特殊 token 被量化压到边界值一般不影响长上下文 recall量化误差累积到长距离时变大需要更多 bit连续选择题MMLU多选项概率接近51% vs 49%量化后翻盘换 Q5/Q6结构化输出JSON量化可能让小概率的 ] 变 0 概率加约束解码Q4_K_M 在 99% 的任务上表现和 Q8/FP16 无显著差异。这是实测结论不是理论。六、MoE 量化冷热 expert 的精度难题接上 #20 的第六节MoE 量化这里展开为什么 MoE 的量化问题比 Dense 更棘手。6.1 同一个 expert同一个精度——但 expert 之间差异巨大Expert激活频率对精度的敏感度Expert 3高频15%低大量数据训练过Expert 42低频2%可能高仅见过少样本Expert 88极少0.5%极高过拟合于特定模式冷 expert 是 MoE 量化的暗坑。热 expert 被大量 token 训练过量化误差被均匀分布了。冷 expert 只处理极少数 token对这些 token 来说是最后一公里问题——量化误差可能直接改变对应关系。6.2 GGUF 处理 MoE 的方式llama.cpp 对 MoE 模型的量化仍然是用统一的 Q4_K_M——所有 expert 同样的 bit 分配。这意味着热 expert 分到了不必要的精度浪费冷 expert 分到了必要的但不够的精度风险改进方向按热度分级量化——热 expert Q4/Q5冷 expert Q6/Q8。但这需要先跑 routing profiling 才能知道每个 expert 的热度流程复杂度远超 Dense。七、如果在本地自己做量化你需要的是一把尺不是一把刀这个系列一直用的是别人量化好的模型提前下载 GGUF。如果要在本地量化自己的模型或者用特殊的量化方案7.1 三种产品级实现工具支持的方案适用场景llama-quantize(llama.cpp)GGUF 全系列本地量化CPU/GPU 均可AutoGPTQGPTQHuggingFace 生态AutoAWQAWQvLLM/SGLang 部署7.2 量化一个模型的实际流程以 llama-quantize 为例Step 1: 下载 FP16 完整模型 Step 2: 运行量化: ./llama-quantize \ --model qwen3-8b-fp16.gguf \ --output qwen3-8b-q4_k_m.gguf \ --type q4_k_m Step 3: 验证: ./llama-cli -m qwen3-8b-q4_k_m.gguf -p hello --temp 0 Step 4: 对比原始模型输出 — 看有没有量化翻车核心验证方法同 seed、同 prompt、temperature0比较量化前后输出的 token 序列。如果前 N 个 token 完全一致说明量化方案对这个模型是无损的。7.3 量化的终局不是用更少的 bit是用最合适的 bit统一量化的未来: 1. 混合精度模型: 不同层不同 bit → 已经实现Q4_K_M 就是 2. 动态精度推理: 运行时根据输入调整 bit → 是研究方向smoothquant 3. 自适应量化: 根据你的任务分布自动分配 bit → 非对称量化 重要性感知 新的 frontier八、总结量化不是在降低质量换速度——是在把精度放在最重要的地方让不重要的地方回归它所需要的精度。权重矩阵中 90% 的值不需要 FP16 的精度把这 90% 砍到 INT4推理速度翻 2-3×质量几乎不变。三个层面的理解表层现象从 FP16 到 INT4模型文件小了 4 倍推理快了 2-3× 中间层机制per-group 粒度 per-channel importance 几乎无损的压缩 深层物理LLM 权重的有效信息密度远低于 FP16 的承载能力 量化的三个关键决策: 1. 分组粒度: 每 N 个权重共享 scale (N32 是 popular choice) 2. 保护策略: 哪些通道/层需要更多 bitK 和 M 的含义 3. 量化方案: 是用校准数据做误差对冲GPTQ还是保护重要通道AWQ还是靠粒度取胜GGUF把这篇文章和 #17-#20 放在一起看技术省掉的东西省了多少PagedAttention预留的碎片空间30-60%依赖场景Speculative Decoding每 token 的 KV Cache 搬运次数2-3×FlashAttentionS/P 中间矩阵O(N²) → O(N)量化每参数 16 bit → 4 bit4×量化是条理最清晰的一个你放弃了些微的数值精度换来了权重搬运量直接减半——而绝大多数任务完全感受不到那点精度损失。附录进一步阅读Frantar et al. (ICML 2023):GPTQ: Accurate Post-Training Quantization for Generative Pre-trained TransformersLin et al. (2024):AWQ: Activation-aware Weight Quantization for LLM Compression and Accelerationllama.cpp GGUF 量化文档: github.com/ggml-org/llama.cppTim Dettmers 的博客:Which GPU(s) to Get for Deep Learning— 量化与显存分析SmoothQuant (2023):SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models这个专栏专注于 LLM 推理与部署的底层技术——从算子开发、显存管理、调度策略到生成优化用可运行的代码和可复现的实验把论文里的黑科技变成可以理解、可以动手验证的知识。如果你对GPU 到底在干什么和推理框架做了什么优化这类问题感兴趣欢迎来主页翻翻其他文章。