模型压缩总览:剪枝、量化与蒸馏怎么选

大模型参数量动辄数十亿到上千亿,直接部署往往「跑不动、跑不起、跑不快」。模型压缩就是把臃肿的模型变小的技术族,核心目标是在尽量不损失精度的前提下,降低显存占用、提升推理速度、削减算力成本。本文系统梳理三条主流路线——量化、剪枝、知识蒸馏,并给出按场景选型的决策表。

一、为什么要压缩

压缩的驱动力主要来自三类现实约束:

  • 端侧部署:手机、车机、嵌入式芯片算力与内存有限,一个 7B 模型以 FP16 存储就需要约 14 GB 显存,根本塞不进端侧设备。
  • 低延迟要求:实时对话、搜索排序、推荐等场景对首字延迟(TTFT)与吞吐敏感,模型越大,单次推理越慢。
  • 降本诉求:云端推理按显存和算力计费,把模型压缩数倍,往往意味着同等预算下吞吐翻几倍,单位成本显著下降。

可以这样理解压缩的「不可能三角」:精度、速度、显存三者很难同时最优。多数压缩方法都是在精度可接受的范围内,用精度换速度或显存。因此选型的第一步,永远是明确你的瓶颈到底在显存、延迟还是成本。

二、量化:用更少的位宽表示权重

量化的思路很直接:模型权重和激活原本用 FP16(16 位浮点)或 FP32(32 位浮点)存储,如果改用 INT8(8 位整数)甚至 INT4(4 位整数),体积直接按比例缩小,计算也能借助整数指令加速。

2.1 常见位宽

  • FP16 / BF16:基准位宽,几乎无损,但节省有限。
  • INT8:体积约为 FP16 的一半,精度损失通常较小,是工业界最成熟的方案。
  • INT4 / 3-bit / 2-bit:体积进一步缩小到四分之一甚至更低,但精度风险明显上升,需要更精细的算法。

注:INT8 相比 FP16 的具体精度保留比例与模型、任务强相关,本文不给出统一数字,实例请以你的评测集为准(待核实)。

2.2 主流量化算法

  • GPTQ(arXiv:2210.17323,已核验):一种基于近似二阶信息(Hessian)的一次性权重量化方法,属于训练后量化(Post-Training Quantization,PTQ),不需要完整重训。论文报告可将 175B 级别模型量化到每权重 3 或 4 位,在约 4 个 GPU 小时内完成,相对未压缩基线精度下降可忽略;相较此前的一次性量化方法,压缩收益翻倍以上,首次让 175B 模型可在单张 GPU 上做生成式推理。端到端推理相对 FP16 在 A100 上约快 3.25 倍,在 A6000 上约快 4.5 倍(已核验)。
  • AWQ(arXiv:2306.00978,已核验):激活感知权重量化,核心观察是「并非所有权重同等重要,仅保护约 1% 的显著权重就能大幅降低量化误差」,且显著通道应由激活分布而非权重本身判定。它通过对显著通道做等效缩放来保护重要权重,不依赖反向传播或重建,泛化性好。配套推理框架 TinyChat 在桌面与移动 GPU 上相对 Hugging Face FP16 实现有 3 倍以上加速(已核验)。
  • GGUF:llama.cpp 生态的通用模型文件格式,常配合 Q4_K_M 等量化等级使用,优势是跨平台、纯 CPU 也能跑,非常适合端侧与消费级硬件。

2.3 一段 Python 量化加载示例

下面给出三种常见加载方式,均基于公开生态库,实际使用时请注意各库版本与模型路径。

使用 bitsandbytes 做 4-bit 加载(NF4):

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype="bfloat16",
)

model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    quantization_config=bnb_config,
    device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")

加载已量化好的 GPTQ 模型:

from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained(
    "TheBloke/Llama-2-7B-GPTQ",
    device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained("TheBloke/Llama-2-7B-GPTQ")

用 llama-cpp-python 加载 GGUF(适合 CPU / 端侧):

from llama_cpp import Llama

llm = Llama(
    model_path="llama-2-7b.Q4_K_M.gguf",
    n_ctx=4096,
    n_gpu_layers=32,
)

output = llm("请简要介绍一下模型量化。", max_tokens=128)
print(output["choices"][0]["text"])

2.4 精度、速度、显存如何权衡

量化通常是「性价比最高」的第一步:它大多属于训练后量化,不需要你重训模型,改一行加载配置就能见效。代价是低位宽(尤其 INT4 以下)可能带来可感知的精度下降,且部分硬件对整数算子支持不一,需要实测吞吐。

三、剪枝:剪去「不重要」的权重

剪枝的直觉是:神经网络存在大量冗余连接,把其中不重要的权重置零或整块移除,模型仍能保持大部分能力。

3.1 结构化剪枝 vs 非结构化剪枝

  • 非结构化剪枝(稀疏剪枝):任意位置把单个权重置零,能达到很高的稀疏度(如 80% 权重为零),但剪后的矩阵是「稀疏」的,需要专门的稀疏计算内核才能真正加速,否则只是存储变小、速度不变。
  • 结构化剪枝:按「通道、注意力头、整层」等规则化单位移除,剪完的模型形状规整,普通硬件即可直接加速,但可压缩空间通常小于非结构化剪枝。

一句话区分:非结构化剪枝「省存储难加速」,结构化剪枝「易加速但更伤精度」(具体加速比与精度损失因模型而异,待核实)。

3.2 重要性评分怎么定

  • 幅度剪枝(Magnitude Pruning):最简单,认为绝对值小的权重不重要,直接按权重绝对值排序剪除。实现成本低,但可能误剪对任务关键的少数大激活通道。
  • 基于梯度的评分:结合损失对权重的梯度,衡量权重对输出的影响。
  • 基于二阶信息(Hessian)的评分:类似 GPTQ 的思路,用曲率信息估计移除某权重带来的误差,更准但计算更贵。

3.3 训练后剪枝流程

典型的训练后剪枝(无需从头训练)流程如下:

1. 准备校准/训练数据,确定目标稀疏度(如 50%)。
2. 按所选重要性准则(幅度 / 梯度 / Hessian)为权重打分。
3. 依阈值剪掉低分权重(置零,或结构化移除整块)。
4. (可选)短时微调(pruning + fine-tuning)恢复精度。
5. 导出模型:非结构化需稀疏推理内核;结构化可直接部署。

剪枝适合「你愿意花一点训练预算换取规则化加速」的场景,尤其结构化剪枝在固定硬件上收益稳定。

四、蒸馏:用大模型教小模型

知识蒸馏(Knowledge Distillation)让一个大模型(Teacher)去指导一个小模型(Student)训练:不仅让 Student 拟合真实标签(硬标签),更让它去学习 Teacher 输出的「软标签」——即各类别的概率分布,其中蕴含了类别之间的相似性信息(例如「猫」和「狗」比「猫」和「汽车」更相近)。

4.1 软标签与温度

蒸馏常用「温度」调节软标签的平滑程度。设 Teacher 输出 logits 为 z,温度 T 下的软概率:

softmax(z_i / T) = exp(z_i / T) / sum_j exp(z_j / T)

温度 T 越大,分布越平滑,暗知识越明显;推理时 Student 仍用正常温度(T=1)输出。损失通常结合软标签的 KL 散度与硬标签的交叉熵。

4.2 DistilBERT 案例

DistilBERT(arXiv:1910.01108,已核验)是在预训练阶段就用知识蒸馏压缩 BERT 的代表作,作者为 Victor Sanh 等人,发表于 NeurIPS 2019 高效机器学习研讨会。其核心结论:

  • 模型体积相比 BERT-base 减小约 40%(已核验);
  • 保留 约 97% 的语言理解能力(已核验);
  • 推理速度 提升约 60%(已核验)。

这三条数字是 DistilBERT 论文明确报告的结论,适合作为「蒸馏能达成什么效果」的参考基准。不过 40% / 97% / 60% 是特定于 BERT 蒸馏的结果,换到其他架构或任务时不能直接套用(待核实)。

蒸馏的代价是你需要训练资源:要有 Teacher 模型、训练数据和训练流程。一旦训好,Student 是一个独立的小模型,部署最简单,不依赖任何特殊推理库。

五、三者组合与选型

实际工程中,三条路线经常组合使用。例如:先用蒸馏得到小模型,再对小分子做结构化剪枝,最后量化到 INT4 部署到手机;或者对一个无法重训的大模型直接做 GPTQ/AWQ 量化,并在显存仍吃紧时叠加剪枝。

5.1 按场景的决策表

下面给出以三个维度为轴的选型参考:能否重训部署设备延迟预算

场景能否重训部署设备延迟预算推荐路线
已有大模型,无训练资源单 GPU / 云中等量化(GPTQ / AWQ,INT4)
手机 / 嵌入式端侧手机 NPU / CPU量化 GGUF + 蒸馏小模型
有训练资源,长期迭代任意宽松蒸馏小模型 + 结构化剪枝
单卡显存极度受限单卡 8 至 16 GBINT4 量化,必要时叠加剪枝
延迟极紧、硬件固定专用芯片极紧结构化剪枝 + 量化

5.2 速查建议

  • 只想快速见效、不动训练:优先量化,从 INT8 起步,显存仍不够再试 INT4(GPTQ/AWQ/GGUF)。
  • 有训练预算、要最好部署体验:优先蒸馏,得到一个干净的小模型。
  • 硬件固定、要确定性加速:结构化剪枝配合量化。
  • 端侧极致压缩:蒸馏 + 量化 +(可选)结构化剪枝三者叠加。

小结

模型压缩有三条主线:量化用更低位宽换显存与速度,几乎不需重训,是性价比最高的第一步;剪枝移除冗余连接,结构化剪枝能直接加速但需一点训练预算;蒸馏用大模型教小模型,部署最干净但要训练资源。三者并非互斥,常组合落地。选型时先问自己三件事:能不能重训、部署到什么设备、延迟预算多紧,再对照决策表选择。关键论文结论(DistilBERT 减小约 40%、保留约 97% 能力、快约 60%;GPTQ 端到端加速约 3.25 至 4.5 倍;AWQ 保护约 1% 显著权重)已逐一核验,可作为方案评估的基准参考。

参考与延伸阅读

  • DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter. Victor Sanh 等,NeurIPS 2019 Workshop. arXiv:1910.01108(已核验:减小约 40%、保留约 97% 能力、快约 60%)。
  • GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. Elias Frantar 等,ICLR 2023. arXiv:2210.17323(已核验:一次性量化到 3 至 4 位,175B 约 4 GPU 小时,端到端加速约 3.25 至 4.5 倍)。
  • AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration. Ji Lin 等,MLSys 2024 Best Paper. arXiv:2306.00978(已核验:保护约 1% 显著权重,TinyChat 加速 3 倍以上)。
  • GGUF 格式与 llama.cpp 推理生态(待核实:具体量化等级命名与兼容性随版本变化,请以当前仓库文档为准)。
  • INT8 量化相对 FP16 的通用精度保留比例(待核实:与模型、任务、校准集强相关,本文未给统一数字)。
  • 非结构化 / 结构化剪枝在具体模型上的加速比与精度损失对照(待核实:建议以你的目标模型实测为准)。
  • DistilBERT 的 40% / 97% / 60% 数字在其他架构上的可迁移性(待核实:仅针对 BERT 蒸馏结论)。
本文累计阅读