Skip to content

模型压缩与加速

本页介绍深度学习落地必备的模型压缩与加速技术:在不显著损失精度的前提下,让模型更小、更快、更省电。它是深度学习概览的工程延伸——训练出好模型只是第一步,把它塞进手机、车载芯片、IoT 设备才是真正的挑战。

模型压缩就像给一个臃肿的快递包裹做瘦身,三种最经典的手法:

  • 量化(Quantization)= 把高清照片压成标清:模型权重从 32 位浮点(FP32)压缩到 8 位整数(INT8)甚至 4 位(INT4)。一张 10MB 的图压到 2MB,乍看差不多,体积省了 80%——精度略损但推理快得多。
  • 剪枝(Pruning)= 砍掉枯枝:神经网络里很多连接权重接近 0(“枯枝”),对输出几乎没贡献。把这些冗余参数置零或删除,模型变小、变快,几乎不影响精度。剪到极致就是稀疏网络(Sparse Network,大部分权重为零的网络)。
  • 知识蒸馏(Knowledge Distillation)= 名师出高徒:让一个庞大的”教师模型”手把手教一个”学生模型”。学生不只学正确答案(硬标签),还学教师对每个类别的置信度分布(软标签 / 暗知识)——小模型因此获得了大模型的部分”直觉”,精度远超它自己从头学。

三者常常组合使用:先蒸馏得到一个小模型,再剪枝去掉冗余,最后量化到 INT8——一部手机就能实时跑的 MobileNet 就是这样炼成的。

量化的核心思想是将连续的浮点数映射到有限的离散值集合。对于从 FP32 到 INT8 的对称量化:

scale=r127,zero_point=0\text{scale} = \frac{r}{127}, \quad \text{zero\_point} = 0 q=clip ⁣(round ⁣(xscale),  −127,  127)q = \text{clip}\!\left(\text{round}\!\left(\frac{x}{\text{scale}}\right),\; -127,\; 127\right) xrecovered=q⋅scalex_{\text{recovered}} = q \cdot \text{scale}

对于非对称量化(适用于激活值,因为激活通常非负):

scale=xmax⁡−xmin⁡255,zero_point=round ⁣(−xmin⁡scale)\text{scale} = \frac{x_{\max} - x_{\min}}{255}, \quad \text{zero\_point} = \text{round}\!\left(\frac{-x_{\min}}{\text{scale}}\right) q=clip ⁣(round ⁣(xscale)+zero_point,  0,  255)q = \text{clip}\!\left(\text{round}\!\left(\frac{x}{\text{scale}}\right) + \text{zero\_point},\; 0,\; 255\right) xrecovered=(q−zero_point)⋅scalex_{\text{recovered}} = (q - \text{zero\_point}) \cdot \text{scale}

量化误差的来源:量化本质是有损压缩。round()\text{round}() 引入的误差最大为 scale/2\text{scale}/2。对于权重范围在 [-1, 1] 的网络层,INT8 量化的 scale≈0.0078\text{scale} \approx 0.0078,误差极小。但如果某些权重范围极大(如 [-100, 100]),scale≈0.78\text{scale} \approx 0.78,误差就不可忽略了——这正是需要量化感知训练(QAT)的原因。

训练后量化(PTQ)vs 量化感知训练(QAT)

Section titled “训练后量化(PTQ)vs 量化感知训练(QAT)”
  • 训练后量化(Post-Training Quantization, PTQ):模型训练完成后直接量化。只需少量校准数据(calibration data,约 100-500 张样本)来估计激活值的统计分布,无需重训练。简单快速,但极端量化(如 INT4)时精度损失大。
  • 量化感知训练(Quantization-Aware Training, QAT):在训练过程中模拟量化误差。具体做法是在前向传播时插入”假量化”操作(Fake Quantization):先按量化公式计算,再反量化回浮点,模拟真实的量化-反量化过程。这样模型在训练时就能感知量化带来的信息损失,学会调整权重来补偿。反向传播时用直通估计器(Straight-Through Estimator, STE)——对 round() 函数的梯度直接当作 1 处理(因为 round 不可导)。
xquantized=round ⁣(xscale)⋅scalex_{\text{quantized}} = \text{round}\!\left(\frac{x}{\text{scale}}\right) \cdot \text{scale}

最经典也最常用的剪枝方法:直接删除绝对值最小的权重。直觉是”小权重对输出的贡献也小,删了影响不大”。

# 幅度剪枝的核心步骤
1. 计算所有权重的绝对值 |w|
2. 设定稀疏度目标 sparsity(如 50%)
3. 找到第 sparsity 分位数的阈值 threshold
4. 将 |w| < threshold 的权重置零(结构化)或删除(非结构化)
5. (可选)对剪枝后的网络做几步微调,恢复精度
  • 非结构化剪枝(Unstructured Pruning):逐个权重置零,产生不规则的稀疏模式。理论上可以达到极高的稀疏度(如 90%+),但需要专门的稀疏矩阵运算库才能加速——标准 GPU/CPU 硬件对不规则稀疏的加速很有限。
  • 结构化剪枝(Structured Pruning):整行、整列、整个通道(channel)或整个注意力头为单位删除。稀疏模式规则,可以直接减少矩阵维度,标准硬件就能加速。代价是同等精度下稀疏度不如非结构化。
# 结构化剪枝示例:按通道剪枝
# 假设第 L 层有 256 个输出通道,剪掉贡献最小的 50%
channel_importance = sum(|W_L[:, c, :, :]| for each channel c) # 每个通道的 L1 范数
threshold = percentile(channel_importance, 50) # 第 50 百分位
keep_mask = channel_importance > threshold # 保留 128 个通道
# 删除不需要的通道后,第 L 层和第 L+1 层的维度都要相应缩减

彩票假设(Lottery Ticket Hypothesis)

Section titled “彩票假设(Lottery Ticket Hypothesis)”

2018 年 Frankle 和 Carbin 提出了一个著名发现:在一个训练好的稠密网络中,存在一个极小的子网络(“中奖彩票”),如果用原始初始化权重重新训练这个子网络,能达到和原始网络相当甚至更好的精度。这意味着大网络中大部分参数是”冗余的”,真正起作用的只是少数关键连接。

这个假设的实践意义:剪枝不是简单的”删小的”,而是要找到那个”中奖子网络”。后续工作(如 LTH 的迭代版本、边缘弹出算法)进一步优化了寻找中奖彩票的效率。

知识蒸馏的核心是让小模型学习大模型的输出分布,而非只学最终标签。

标准 softmax 将 logits 转换为概率分布:

pi=exp⁡(zi)∑jexp⁡(zj)p_i = \frac{\exp(z_i)}{\sum_j \exp(z_j)}

蒸馏时引入温度参数 T(Temperature)来软化分布:

piT=exp⁡(zi/T)∑jexp⁡(zj/T)p_i^T = \frac{\exp(z_i / T)}{\sum_j \exp(z_j / T)}

当 T=1 时就是标准 softmax;T 越大,分布越”平滑”(各类别概率越接近均匀)。例如对于一张猫的图片,标准 softmax 可能输出 [0.99, 0.005, 0.003, 0.002](猫 99%,狗 0.5%,汽车 0.3%),而 T=4 的软标签可能是 [0.7, 0.15, 0.1, 0.05]——这暴露了”猫和狗在视觉上更相似”这个关键信息(暗知识 / Dark Knowledge),而硬标签只告诉你”这是猫”。

Ltotal=α⋅Lsoft+(1−α)⋅LhardL_{\text{total}} = \alpha \cdot L_{\text{soft}} + (1 - \alpha) \cdot L_{\text{hard}} Lsoft=T2⋅KL ⁣(pteacherT  ∥  pstudentT)=T2∑ipteacher,iT⋅log⁡pteacher,iTpstudent,iTL_{\text{soft}} = T^2 \cdot \text{KL}\!\left(p_{\text{teacher}}^T \;\|\; p_{\text{student}}^T\right) = T^2 \sum_i p_{\text{teacher},i}^T \cdot \log \frac{p_{\text{teacher},i}^T}{p_{\text{student},i}^T} Lhard=CrossEntropy(student_logits,true_labels)L_{\text{hard}} = \text{CrossEntropy}(\text{student\_logits}, \text{true\_labels})

T2T^2 乘子的含义:因为 softmax 中除以了 T,梯度会被缩小 T2T^2 倍,所以反向传播时要乘回 T2T^2 来保持梯度量级不变。α\alpha 通常取 0.5-0.9(软标签权重高于硬标签,因为软标签信息更丰富)。

特征蒸馏(Feature-based Distillation)

Section titled “特征蒸馏(Feature-based Distillation)”

除了在输出层做蒸馏,还可以在中间特征层做对齐(让学生网络的中间层特征逼近教师网络的中间层特征)。代表方法 FitNets、AT(Attention Transfer):

Lfeature=∑l∥projection(Fstudentl)−Fteacherl∥2L_{\text{feature}} = \sum_l \left\| \text{projection}(F_{\text{student}}^l) - F_{\text{teacher}}^l \right\|^2

特征蒸馏通常比纯输出蒸馏效果更好——中间层特征包含了更丰富的结构化信息。

PyTorch 动态量化(最简量化示例)

Section titled “PyTorch 动态量化(最简量化示例)”
import torch
import torch.nn as nn
from torchvision.models import mobilenet_v3_small
model = mobilenet_v3_small(pretrained=True).eval() # 加载预训练 MobileNet
# 动态量化 Linear 层:FP32 → INT8(一行搞定)
quantized = torch.quantization.quantize_dynamic(
model, {nn.Linear}, dtype=torch.qint8
)
print(f"原模型: {sum(p.numel() for p in model.parameters())} 参数")
# 量化后体积更小、CPU 推理更快
dummy = torch.randn(1, 3, 224, 224)
print(quantized(dummy).argmax()) # 推理正常输出
import torch
import torch.nn as nn
from torchvision.models import mobilenet_v3_small
model = mobilenet_v3_small(pretrained=True).eval()
# 静态量化需要对 Conv2D 和 Linear 都量化
# 第 1 步:准备量化配置
model.qconfig = torch.quantization.get_default_qconfig('fbgemm') # x86 CPU
model_fused = torch.quantization.fuse_modules(model, [['features.0.0', 'features.0.1']])
# 第 2 步:插入观察者(Observer)
model_prepared = torch.quantization.prepare_qat(model_fused)
# 第 3 步:用校准数据做前向传播(收集激活值统计信息)
for _ in range(200):
dummy = torch.randn(1, 3, 224, 224)
model_prepared(dummy)
# 第 4 步:转换为量化模型
model_quantized = torch.quantization.convert(model_prepared)
print(f"量化后模型大小: {torch.save(model_quantized.state_dict(), 'tmp.pth')}")
import torch.nn as nn
import torch.nn.functional as F
def distill_loss(student_logits, teacher_logits, labels, T=4.0, alpha=0.5):
"""学生模仿教师的输出分布 + 真实标签"""
soft = F.kl_div(
F.log_softmax(student_logits / T, dim=1), # 学生软概率
F.softmax(teacher_logits / T, dim=1), # 教师软概率
reduction="batchmean") * (T * T) # 温度缩放
hard = F.cross_entropy(student_logits, labels) # 硬标签损失
return alpha * soft + (1 - alpha) * hard # 加权组合
import torch
import torch.nn as nn
import torch.nn.functional as F
def train_with_distillation(student, teacher, train_loader, epochs=50,
T=4.0, alpha=0.7, lr=0.001):
"""
完整的知识蒸馏训练循环。
student: 小模型(学生)
teacher: 大模型(教师,冻结参数)
"""
teacher.eval() # 教师模型不更新
for p in teacher.parameters():
p.requires_grad = False
optimizer = torch.optim.AdamW(student.parameters(), lr=lr, weight_decay=1e-4)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=epochs)
for epoch in range(epochs):
student.train()
for images, labels in train_loader:
# 教师前向(不计算梯度)
with torch.no_grad():
teacher_logits = teacher(images)
# 学生前向
student_logits = student(images)
# 蒸馏损失
loss = distill_loss(student_logits, teacher_logits, labels,
T=T, alpha=alpha)
optimizer.zero_grad()
loss.backward()
optimizer.step()
scheduler.step()
print(f"Epoch {epoch+1}/{epochs}, Loss: {loss.item():.4f}")
import torch
import torch.nn.utils.prune as prune
def magnitude_prune(model, amount=0.5):
"""对模型所有 Conv2d 做非结构化幅度剪枝"""
for name, module in model.named_modules():
if isinstance(module, torch.nn.Conv2d):
prune.l1_unstructured(module, name='weight', amount=amount)
prune.remove(module, 'weight') # 永久化剪枝(删除零权重)
print(f"剪枝 {name}: 稀疏度 {amount*100:.0f}%")
# 使用:将 MobileNet 50% 的卷积权重剪掉
model = mobilenet_v3_small(pretrained=True)
magnitude_prune(model, amount=0.5)
# 剪枝后建议做几个 epoch 的微调恢复精度
  • 优先尝试 PTQ:训练后量化是最快的压缩手段。对于 INT8,大多数 CNN 在 PTQ 后精度损失 < 1%。先 PTQ,不行再上 QAT。
  • 校准数据要代表性:PTQ 的校准数据必须来自真实推理分布(同域、同分辨率),否则激活值统计不准,量化误差大。
  • 量化敏感层跳过:某些层(如最后的分类头、超低 bit 输出)对量化极敏感,可以保持 FP32(混合精度量化)。
  • INT4 是极限挑战:INT4 量化通常精度损失显著,需要 QAT + 特殊技巧(如分组量化、Learnable Quantization Scale)。
  • 渐进式剪枝:不要一步到位剪到 90%。从 20% 开始,逐步增加到目标稀疏度,每次剪枝后微调几个 epoch,效果远好于一次性剪枝。
  • 剪枝后微调至关重要:剪枝破坏了网络的功能,必须用原学习率(或更低)微调恢复。通常微调 10-30% 的原始训练 epoch 数即可恢复。
  • 结构化剪枝更适合落地:非结构化剪枝虽然稀疏度高,但需要专门的稀疏计算硬件支持(如 NVIDIA Ampere 的 2:4 结构化稀疏)。结构化剪枝(通道剪枝)直接减少矩阵维度,标准硬件即受益。
  • 教师选择:教师越大、越强,学生受益越多。用 10 倍参数量的教师蒸馏出的学生,通常比自己训练的学生高 2-5% 精度。
  • 温度选择:T=2-10 是常用范围。类别数越多(如 1000 类),T 可以大一些(如 4-6),让软标签更平滑。
  • 数据增强一致性:教师和学生必须看到相同的输入(含相同数据增强),否则软标签对不上。
  • 特征蒸馏增强效果:在中间层加特征对齐损失,通常比纯输出蒸馏多 1-3% 精度。
  • 经典流水线:蒸馏 → 剪枝 → 量化。蒸馏先得到一个好学生,剪枝去冗余,量化减精度。每步都要评估精度,及时止损。
  • 量化蒸馏:在蒸馏的同时做量化感知训练,让学生模型在量化约束下学习教师的暗知识——这是 INT4 量化模型能保持高精度的关键技巧。

大模型的爆发催生了大量 LLM 专用量化方法:

  • GPTQ:基于二阶信息(近似 Hessian)的训练后量化方法。能将 LLaMA 等大模型量化到 3-4 bit,精度损失极小。核心思想是逐层用 Hessian 信息指导量化,补偿每个权重量化对输出的影响。
  • AWQ(Activation-aware Weight Quantization):基于”不是所有权重同等重要”的洞察——激活值大的通道对应的权重对输出影响也大。AWQ 通过保持这些”显著”通道的高精度来减少整体量化误差。
  • SmoothQuant:将量化的难度从激活值转移到权重上。通过数学等价变换 Y = (X / s) * (s * W),将激活值中的”离群点”(outlier,个别极大的激活值导致量化困难)缩小 s 倍,同时将权重放大 s 倍。因为权重分布更均匀,放大后量化误差更可控。
  • GGUF / llama.cpp 格式:社区驱动的量化格式,支持 2-8 bit 的混合精度量化。llama.cpp 让普通用户在笔记本甚至手机上运行量化后的 LLM。常见量化等级如 Q4_K_M(4 bit 均值,关键层保留更高精度)在消费级硬件上广受欢迎。
  • EXL2 / EXL3:ExLlamaV2 的量化方案,支持任意 bit 精度(如 2.5 bit、4.5 bit),通过逐层最优 bit 分配实现极致压缩。

2024 年最激进的研究方向是极低比特量化:

  • BitNet(1-bit LLM):微软提出的 1-bit Transformer 架构,权重只有 -1 / 0 / +1 三种值。推理时完全不需要矩阵乘法(只需加减法),内存占用降到原来的 1/32。BitNet b1.58(2024)将权重三值化为 {-1, 0, 1},在 3B 参数量级上匹配了 FP16 LLaMA 的精度。
  • 训练时量化(Quantization in Training):传统方法先训练 FP32 再量化(PTQ/QAT),新方法直接在低精度下训练——权重在训练过程中就是 INT4 或 1-bit,省去量化步骤。

结构化剪枝在 Transformer 中的应用

Section titled “结构化剪枝在 Transformer 中的应用”
  • LLM-Pruner / Wanda:针对大语言模型的结构化剪枝方法。Wanda(Pruning by Weights and Activations)不需要重训练,只需一次前向传播就能确定哪些权重可以安全剪除。
  • Sheared LLaMA:将 LLaMA-7B 通过结构化剪枝压缩到 2.7B/1.3B,精度接近同尺寸的从头训练模型。

不是压缩模型本身,而是通过”小模型猜测 + 大模型验证”的方式加速 LLM 推理:一个小模型(draft model)先生成候选 token,大模型(target model)并行验证。验证通过的部分无需大模型逐 token 自回归生成,推理速度提升 2-3 倍且输出完全一致。

  • MLC-LLM:基于 TVM 编译器的端侧 LLM 推理框架,支持将量化后的 LLM 部署到 iPhone、Android、浏览器。
  • ExecuTorch:PyTorch 官方端侧推理框架(2024 正式发布),支持 LLM 和 CNN 的端侧量化部署。
  • Apple MLX:Apple 的机器学习推理框架,针对 Apple Silicon 优化了量化 LLM 推理,统一内存架构让手机端运行 7B 模型成为可能。
  • 手机端 AI(MobileNet 系列):Google 的 MobileNet 通过深度可分离卷积 + 量化,让手机实时跑图像分类、人脸解锁、AR 特效——Pixel、iPhone 的相机 AI 功能都依赖这类轻量模型。详见MobileNet 与移动端推理。
  • 自动驾驶芯片(Tesla FSD / 地平线):车载芯片算力受限、功耗敏感,量产方案均用量化(INT8)+ 剪枝把检测网络压到芯片可实时运行的尺寸,延迟要求 < 30ms。
  • 边缘设备部署(智能摄像头 / IoT):工厂产线缺陷检测、智能门禁人脸识别,依赖 ONNX Runtime / OpenVINO 做量化推理,在无 GPU 的边缘盒子上跑深度学习。
  • 降低云端推理成本:大厂 API 服务通过量化(FP16→INT8)将单卡吞吐翻倍,直接砍掉一半 GPU 服务器——百亿级 token 服务中,这是数百万美元级的成本节省。
  • 大模型本地部署:通过 GGUF 4-bit 量化,LLaMA-3-8B 可以在 6GB 显存的消费级显卡上运行,Phi-3-mini 量化后可在手机上运行——这让个人隐私数据无需上云的本地 AI 成为现实。
类库语言说明
TensorRTC++/PythonNVIDIA 官方推理加速库,支持 INT8/FP16 量化与算子融合
ONNX RuntimeC++/Python跨平台推理引擎,支持动态量化,CPU/GPU/移动端通吃
OpenVINOC++/PythonIntel 推理工具包,针对 Intel CPU/核显优化,支持 PTQ
torch.quantizationPythonPyTorch 内置量化工具,支持动态量化、静态量化、QAT
NNCFPythonOpenVINO 的神经网压缩框架,集成量化+剪枝+蒸馏
TFLiteC++/PythonTensorFlow Lite,移动端推理标配,支持全整数量化
llama.cppC++社区驱动的 LLM 推理框架,支持 GGUF 格式 2-8bit 量化
AutoGPTQPythonLLM 训练后量化工具,基于 GPTQ 算法
AutoAWQPythonLLM 量化工具,基于 AWQ 算法
MLC-LLMPython/C++端侧 LLM 部署框架,支持量化模型在手机/浏览器运行
术语英文解释
量化Quantization将权重/激活从高精度浮点压缩到低位整数(INT8/INT4)
训练后量化Post-Training Quantization (PTQ)模型训练完成后直接量化,无需重训练,简单快速
量化感知训练Quantization-Aware Training (QAT)训练时模拟量化误差,精度比 PTQ 更高
直通估计器Straight-Through Estimator (STE)QAT 中处理 round() 不可导的技巧,反向传播时当作恒等映射
对称量化Symmetric Quantization零点固定为 0 的量化方式,适用于权重
非对称量化Asymmetric Quantization零点不为 0 的量化方式,适用于非负的激活值
剪枝Pruning删除权重接近零的冗余连接,使网络稀疏化
非结构化剪枝Unstructured Pruning逐个权重置零,稀疏度高但需要专用硬件加速
结构化剪枝Structured Pruning以通道/层为单位删除,标准硬件即可加速
彩票假设Lottery Ticket Hypothesis稠密网络中存在稀疏子网络,用原始初始化重训可达到同等精度
知识蒸馏Knowledge Distillation用大模型(教师)的输出指导小模型(学生)训练
教师/学生模型Teacher / Student Model蒸馏中的大模型(教师)与被训练的小模型(学生)
稀疏性Sparsity网络中零值参数的比例,越高模型越”瘦”
ONNXOpen Neural Network Exchange开放神经网络交换格式,跨框架部署的中间表示
暗知识Dark Knowledge教师模型软标签中蕴含的类别间相似度信息
温度参数Temperature (T)蒸馏中软化 softmax 分布的参数,T 越大分布越平滑
推测解码Speculative Decoding小模型先生成候选、大模型验证的 LLM 推理加速方法
  • 知识蒸馏开山作:Hinton et al., “Distilling the Knowledge in a Neural Network”, NeurIPS Workshop 2015. 提出”暗知识”与温度 softmax,奠定了知识蒸馏范式。
  • 深度压缩:Han et al., “Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding”, ICLR 2016. 将剪枝、量化、编码三者串联,AlexNet 压缩 35× 几乎不损精度。
  • 模型剪枝:Han et al., “Learning both Weights and Connections for Efficient Neural Networks”, NeurIPS 2015. 基于”小权重不重要”的幅度剪枝法,是工业界最常用的剪枝思路。
  • 彩票假设:Frankle & Carbin, “The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks”, ICLR 2019. 揭示稠密网络中存在可独立训练的稀疏子网络。
  • MobileNet 系列:Howard et al., “MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications”, 2017. 深度可分离卷积的奠基工作,移动端 CNN 的标杆。
  • GPTQ:Frantar et al., “GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers”, ICLR 2023. LLM 训练后量化的里程碑工作。
  • AWQ:Lin et al., “AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration”, MLSys 2024. 基于激活感知的大模型量化方法。
  • BitNet:Wang et al., “BitNet: Scaling 1-bit Transformers for Large Language Models”, 2023. 1-bit LLM 架构的奠基工作;后续 BitNet b1.58 (2024) 将权重三值化。
  • SmoothQuant:Xiao et al., “SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models”, ICML 2023. 将量化难度从激活转移到权重的方法。