跳转至

量化与压缩

📉 模型量化如何减少推理显存?INT8/INT4 的效果

💡 模型量化通过降低权重和/或激活的数值精度(如从 FP16 到 INT8/INT4),直接减少每参数/每激活所占的字节数,从而成比例地压缩显存占用。推理时,最显著的是权重显存减少;配合 KV Cache 量化,总显存需求可降至原来的 1/4 甚至 1/8。

🔢 量化效果(以 7B 模型为例):

  • FP16(基准):每参数 2 字节,权重 14 GB,KV Cache(FP16,长 2048)约 1 GB,总显存约 15 GB+。

  • INT8 量化(权重 + 激活):权重占 7 GB,节省 50%。若 KV Cache 也量化为 INT8,KV Cache 降至 0.5 GB,总显存可减半。

  • INT4 量化(仅权重):权重仅占 3.5 GB,节省 75%。若配合 FP16 KV Cache,总显存可控制在 5–6 GB。若 KV Cache 也降至 4-bit,节省更惊人。

  • 实际部署:在 24GB 显卡上,INT4 量化的 70B 模型(权重约 35 GB)可以勉强运行;而 FP16 需要 140 GB,完全不可能。

🔬 原理:量化将浮点数映射到低比特整数,例如 INT8 将 FP32 值线性映射到 [-127, 127] 范围,并存储缩放因子(scale)和零点(zero-point)。推理时,反量化回 FP16/FP32 进行计算,或直接用整数运算(现代 GPU 支持 INT8 Tensor Cores)。显存节省等于每个参数的比特数比例。

✅ 因此,量化是最直接有效的推理显存优化手段,4-bit 量化往往能在不明显损失精度的情况下将大模型装入消费级显卡。


⚙️ GPTQ 量化的原理是什么?为什么能保持精度?

💡 GPTQ(Post-Training Quantization for GPT)是一种基于近似二阶信息(Hessian)的逐层权重量化算法。它通过考虑权重扰动对输出误差的影响,按顺序补偿量化误差,从而在 4-bit 甚至 3-bit 下保持极低精度损失。

🔬 原理详解:

  1. 优化目标:量化权重的目标是最小化层输出误差,即 min || WX - ŴX ||^2,其中 Ŵ 是量化后的权重。

  2. 逐层量化:GPTQ 逐层对权重矩阵进行量化,利用一小批校准数据计算该层输入的 Hessian 矩阵(或近似值)来度量各权重的敏感度。

  3. 按顺序量化与补偿:对权重矩阵的一列(或一组)进行量化后,立即计算产生的输出误差,并调整剩余未量化的权重以补偿这个误差。这种补偿机制类似于求解线性系统,能有效控制累积误差。

  4. 使用 Cholesky 分解:预先根据 Hessian 做 Cholesky 分解,避免反复计算,速度较快,能在几小时内完成百亿参数模型的量化。

🧠 为什么保持精度?

传统的直接舍入量化(round-to-nearest)会忽视权重的相互作用,导致输出偏差大。GPTQ 通过二阶误差补偿,将量化误差分散到其他权重,使最终输出尽可能逼近原始输出。尤其在 4-bit 时,配合 Group Size(如 128)和适当的校准数据,性能几乎与 FP16 持平。

✅ 因此,GPTQ 是目前最流行的 LLM 训练后量化方法之一,可一键将模型压缩至 4-bit,且精度损失极小。


🌊 AWQ 量化怎样根据激活值保护重要权重?

💡 AWQ(Activation-aware Weight Quantization)观察到,不同权重通道的重要性差异很大,且与对应激活值的幅度有关。它通过分析激活分布,找出重要的“显著权重”通道,并在量化前对其缩放(scaling)加以保护,从而减少量化误差。

🔍 机制:

  1. 显著权重识别:AWQ 通过校准数据统计每个通道的激活值幅度(如平均值),发现激活值大的通道对应的权重对输出影响更大——这些就是“显著权重”。

  2. 每通道缩放:对于显著权重通道,AWQ 将其输入和输出进行等效的缩放(权重乘以系数 s,对应的输入除以 s),使这些通道的权重值分布更易于量化,同时不改变模型输出。

  3. 保护机制:缩放后的显著通道,量化误差相对减小。缩放因子通过快速网格搜索确定,以最小化层输出误差。

  4. 量化执行:然后应用常规的逐通道或逐组 INT4 量化。

🔬 为什么有效:显著权重原本量化时可能产生较大误差,通过缩放将其“移入”量化器的有效范围,减少了裁剪错误。相较于 GPTQ,AWQ 不需要求逆矩阵,速度更快,且在一些任务上精度更优。

✅ 因此,AWQ 利用激活值作为权重重要性的“探针”,通过简单的等价变换大幅提升 4-bit 量化的精度,是一种轻量高效的量化方案。


🧈 SmoothQuant 如何通过平滑激活值来降低量化难度?

💡 SmoothQuant 解决了 LLM 中激活值存在极端离群值(outliers)导致量化困难的问题。它通过数学等效变换,将激活值的量化难度“平滑”迁移到权重上,使得两者都能较容易地 INT8 量化,同时保持精度。

🔬 原理:

  • 在 Transformer 中,某些通道的激活值常出现非常大的离群值(比其他通道大 100 倍以上),如果直接对激活值做 INT8 量化,会导致大量截断误差。而权重分布相对平坦,容易量化。

  • SmoothQuant 引入一个平滑因子 s(每通道一个标量),对线性层做如下变换:

Y = XW = (X · diag(s)^{-1}) · (diag(s) · W)
  • 即把输入 X 除以 s,权重乘以 s。数学上等价,但改变了量化难度。

  • 通过选择合适的 s(例如利用激活值的最大值),将离群值“转移”到权重上。因为权重量化更宽容,可以吸收这些不平滑,使变换后的 X 更容易量化。

  • 最终,激活和权重都能平滑地量化为 INT8,且几乎没有精度损失。

📊 效果:SmoothQuant 实现了权重 INT8 + 激活 INT8 的全 INT8 推理,相比仅权重量化,进一步节省了激活显存和带宽,提升速度。在 OPT、LLaMA 等模型上效果显著。

✅ 因此,SmoothQuant 是一种无损的“难度转移”技术,为全整数推理铺平了道路,是 INT8 推理的标配之一。


🧠 KV Cache 量化(KV8, KV4)是如何工作的?能省多少显存?

💡 KV Cache 量化将存储于显存中的键(Key)和值(Value)张量由 FP16 转换为低精度格式,如 INT8(KV8)或 INT4(KV4),直接减少缓存容量,节省显存可达 2-4 倍,但可能轻微影响生成质量。

🔧 工作方式:

  • 逐 token 量化:解码时,每生成一个新 token 的 K、V,在写入 Cache 前立即量化;读取时,反量化回 FP16 用于注意力计算。

  • 校准:通常在校准数据集上统计 K、V 的分布,确定每通道或每张量的缩放因子和零点。也可使用动态量化。

  • 实现:主流推理框架(如 vLLM、TensorRT-LLM、llama.cpp)均支持 KV Cache 量化。vLLM 中设置 --kv-cache-dtype fp8 即可使用 FP8 KV Cache。

📊 节省效果:

  • FP16 → INT8:Cache 大小减半。例如 13B 模型、seq=4096、batch=1 时,KV Cache 从 ~6 GB 降至 ~3 GB。

  • FP16 → INT4:减至原来的 1/4。但此时精度损失较明显,通常需要配合精细量化方法。

  • 长文本场景:对于 128K 长序列,KV Cache 可能占数十 GB,FP8 量化可将容量需求砍半,使单卡推理成为可能。

⚠️ 质量影响:低精度 KV Cache 可能导致注意力分数偏差,从而影响生成质量。KV8 通常几乎无损;KV4 需谨慎校准,适用性因模型而异。

✅ 因此,KV Cache 量化是长文本推理必开的优化,几乎无代价地将显存容量翻倍。


🆚 量化训练(QAT)和训练后量化(PTQ)在显存上的区别?

💡 QAT 在训练过程中模拟量化操作,需要存储梯度、优化器状态,显存占用远高于 PTQ;PTQ 则是在预训练模型上直接转换,无需反向传播,因此显存需求极低,可以单卡甚至 CPU 完成。

🔍 显存差异:

  • QAT(量化感知训练)
  • 需要完整训练循环:前向时插入伪量化节点(fake-quant),反向传播计算梯度,更新原始浮点权重。
  • 显存至少包括:全精度权重副本、梯度、优化器状态(Adam 等)、激活值。量化本身增加少量缩放因子梯度,但主体与全量微调类似。
  • 对于 7B 模型,QAT 显存需求接近全量微调(80 GB+),因此很少单独用于大模型。

  • PTQ(训练后量化)

  • 不需要反向传播,只需少量校准数据(几百到几千条)进行统计或层输出重建。
  • 显存仅需加载模型权重(可能 FP16)+ 校准时所需的激活和中间缓冲,通常比推理稍高但远低于训练。
  • 例如 GPTQ 或 AWQ 处理 7B 模型,在 24GB 显卡即可完成,显存占用约 10-15 GB。

📊 对比表:

查看内嵌表格

✅ 因此,对于 LLM,PTQ 是唯一实际可行的量化方式,QAT 受显存限制基本不在大模型上使用。


🚫 为什么训练时不常用 INT8 权重?(更新精度问题)

💡 训练中,权重更新量(梯度 × 学习率)通常远小于 INT8 的量化分辨率,若权重以 INT8 存储,微小更新会因舍入误差而丢失,导致模型无法有效学习。因此训练需要高精度(FP16/FP32)表示,INT8 仅用于推理。

🔬 深入解释:

  • 训练时,每一步的权重更新量级大约为 lr * grad,学习率通常在 1e-5 到 1e-4,而梯度可能经过归一化,结果每步权重变化往往在 1e-6 到 1e-4 量级。

  • INT8 的动态范围有限,量化间隔(step size)约为 (max - min) / 255。假如权重大小在 0.1 附近,量化间隔约为 0.001。小于这个间隔的更新将被舍入到零,无法改变权重。这就是“更新精度不足”导致学习停滞。

  • 即使采用 INT8 存储权重,训练时仍需高精度副本(如 FP32)来计算梯度和应用更新,显存不会真正节省。这也是为什么混合精度训练使用 FP16 计算但保留 FP32 主权重。

🧮 量化训练(QAT)的做法:QAT 在训练期间保持 FP32 主权重,仅在模拟的前向中加入量化噪声(fake-quant),反向传播更新 FP32 权重。本质上仍然不是低精度存储。

✅ 因此,训练时权重必须保持高精度,INT8/INT4 量化专属于推理阶段。


✂️ 结构化剪枝与量化结合,显存能进一步优化吗?

💡 可以。结构化剪枝(如移除整个注意力头或层)直接减少模型的参数数量和维度,与量化结合能获得叠加效果:剪枝降低参数量,量化降低每个参数的比特数,最终显存节省 = 剪枝后参数量 × 量化比特率。

🔍 结合形式:

  • 先剪枝后量化:先对稠密模型进行结构化剪枝,去掉冗余的头或 FFN 通道,使模型变窄/变浅。然后对剪枝后的小模型应用 PTQ(如 GPTQ/AWQ)进一步压缩权重。由于剪枝保留了模型结构规整性,GPU 友好,不引入稀疏性开销。

  • 联合优化:也有研究在剪枝时考虑量化误差,或使用可微的结构搜索同时优化压缩率和精度。

  • 显存节省:假如原模型 7B,剪枝掉 30% 参数(剩 4.9B),再应用 4-bit 量化,权重显存从 14 GB (FP16) → 4.9B × 0.5 字节 ≈ 2.45 GB。相比原 FP16 节省超过 80%。

⚠️ 注意:非结构化剪枝(单个权重置零)虽然也能减少参数,但稀疏矩阵在 GPU 上的加速有限,显存节省不明显(需用稀疏格式存储)。结构化剪枝改变形状,能直接减小矩阵维度,因此更有效。

✅ 因此,结构化剪枝+量化是“减个数”和“减位宽”的组合拳,可极大压缩模型显存,但剪枝会损失一定模型能力,需谨慎平衡。


🧑‍🏫 知识蒸馏如何间接降低推理显存?

💡 知识蒸馏通过用大模型(教师)指导训练小模型(学生),获得一个参数量更少但性能接近的小模型。模型参数量下降直接减少权重显存,同时更小的 hidden dim 和更少的层数也减少了 KV Cache 和激活显存,从而全面降低推理资源需求。

🔍 间接路径:

  • 生成更小的学生模型:例如从 70B 教师蒸馏出一个 7B 学生,参数量变为原来的 1/10,权重显存同比例下降。

  • 架构优化:蒸馏时可以刻意设计高效架构(如更窄的 hidden、更少层、MQA),进一步减少 KV Cache 和计算量。

  • 不改变压缩方法:蒸馏本身不是压缩技术,但它产出的模型更小,可以再应用量化、剪枝等进一步压缩。

📊 例子:蒸馏后的 TinyLLaMA 1.1B 模型,推理时仅需约 2.2 GB (FP16) 或 0.6 GB (INT4),相比原始 7B 显存下降 6 倍以上。

✅ 因此,知识蒸馏是一种从源头减少模型尺寸的方法,间接大幅降低推理显存,常与量化协同使用。


📏 量化后模型的显存占用如何估算?需要校准集吗?

💡 量化后模型显存 = 量化权重字节数 + 量化常数(scale/zero-point)+ KV Cache(若适用)+ 激活。校准集在大多数 PTQ 方法中是必需的,用于确定量化参数和/或重建输出。

📐 估算公式:

  • 权重大小 = 参数量 × 每参数位数 / 8。
  • INT4:参数量 × 0.5 字节
  • INT8:参数量 × 1 字节
  • 分组量化(如 group_size=128)会额外增加 scale/zero-point 的开销。例如 INT4 分组量化,每 128 个权重共享一个 FP16 scale,开销 = 参数量 / 128 × 2 字节,占比约 3%,通常可忽略。

  • KV Cache = 2 × 层数 × KV 头数 × 头维度 × 精度字节 × 序列长度。

  • 总显存 ≈ 权重 + KV Cache + 少量激活(推理时约 0.5-2 GB)。

🔧 是否需要校准集?

  • 对于 PTQ(如 GPTQ、AWQ、SmoothQuant),需要。校准集用于收集激活统计、计算 Hessian 或优化量化参数,通常几百到几千条样例足够。校准数据应与任务分布匹配,以保持精度。

  • 动态量化(如 Dynamic Quantization) 不需要,但精度较低。

  • 权重量化(如简单的 RTN round-to-nearest) 不需要校准集,可直接转换,但精度损失大,大模型基本不用。

✅ 因此,估算显存可直接计算,而高效量化离不开校准集来保证质量。