知识蒸馏与模型压缩
总览
模型压缩是将大型神经网络模型压缩到更小尺寸的技术集合,目标是在尽可能保持精度的前提下减少显存占用、加快推理速度、降低部署成本。
模型压缩四大方向
├── 量化(Quantization)—— 降低参数位宽
├── 剪枝(Pruning)—— 移除冗余参数/结构
├── 知识蒸馏(Knowledge Distillation)—— 大模型指导小模型
└── 低秩分解(Low-rank Decomposition)—— 矩阵近似实际工程中常组合使用:先蒸馏得到小模型 → 剪枝去除冗余 → 量化降低位宽,可在精度损失 <5% 的前提下实现模型体积缩减 80%+。
知识蒸馏(Knowledge Distillation)
核心原理
知识蒸馏通过将大型复杂模型(教师模型)的知识迁移到小型简单模型(学生模型),使学生模型能够继承教师模型的性能。
教师模型(Teacher)
│
│ 软标签(Soft Labels)+ 温度 T
▼
学生模型(Student)
│
│ 同时学习:硬标签(真实标签)+ 软标签(教师输出)
▼
轻量级高性能模型数学公式(面试高频)
软标签生成(温度缩放):
p_i = exp(z_i / T) / Σ_j exp(z_j / T)- T > 1 时分布更平滑,保留更多类间关系信息("暗知识")
- T = 1 退化为标准 softmax
总损失函数:
L_total = α · L_KL(p_teacher^T, p_student^T) + (1-α) · L_CE(y, p_student)- α 控制软标签与硬标签的权重比
- KL 散度衡量学生与教师输出的分布差异
蒸馏流程
- 教师模型训练:训练大型高性能教师模型
- 学生模型设计:选择更小的架构(层数/宽度缩减)
- 蒸馏训练:用教师模型的 logits 作为额外监督信号
- 微调:在目标任务上进一步对齐
蒸馏类型
| 类型 | 知识来源 | 典型方法 |
|---|---|---|
| Logit 蒸馏 | 输出层概率分布 | 经典 Hinton 蒸馏 |
| Feature 蒸馏 | 中间层特征表示 | FitNet / PKT |
| Attention 蒸馏 | 注意力权重分布 | TinyBERT |
| 关系蒸馏 | 样本间关系 | RKD |
工业界案例
DeepSeek 蒸馏实践:
- 将 671B MoE 模型蒸馏为 32B/70B 版本
- 训练成本压缩至 OpenAI 同类模型的 1/20
- 推理速度提升 3× 以上,延迟从 850ms 降至 150ms
- 显存占用从 320GB 减少至 8GB
DistilBERT:
- 从 BERT-base(110M)蒸馏为 DistilBERT(66M)
- 保留 97% 性能,速度提升 60%
剪枝(Pruning)
剪枝分类
剪枝策略
├── 非结构化剪枝(Unstructured)
│ ├── 权重级别:直接将小权重置零
│ └── 优点:压缩率高;缺点:需要稀疏硬件支持
├── 结构化剪枝(Structured)
│ ├── Channel 级:移除整个通道/注意力头
│ ├── Layer 级:移除整层 Transformer 块
│ └── 优点:不依赖特殊硬件;缺点:压缩率相对较低
└── 半结构化剪枝(Semi-structured)
└── N:M 稀疏(如 2:4):NVIDIA A100+ 硬件原生支持重要性评估准则
| 准则 | 方法 | 说明 |
|---|---|---|
| 幅度准则 | L1/L2 范数 | 权重绝对值小 → 不重要 |
| 梯度准则 | Taylor 展开 | 移除对 loss 影响最小的参数 |
| 信息准则 | Fisher 信息 | 基于参数的信息量 |
| 激活准则 | 注意力分数 | 注意力权重低 → 可剪枝 |
KV Cache 剪枝(2025-2026 前沿)
针对推理阶段 KV Cache 显存占用过大的问题:
- 学习通道重要性:通过 L2 蒸馏损失 + L1 稀疏正则化学习连续重要性分数
- 生成二进制掩码:转化为硬件对齐的剪枝掩码
- 效果:K 缓存内存削减约 70%,V 缓存削减 16-18%,精度几乎无损
注意力层剪枝
- FastV:发现图像 Token 在 LLM 深层获取的注意力极低,可在浅层后大幅修剪
- StreamingLLM:仅保留 Attention Sink + 滑窗 token 的 KV
量化(Quantization)
数据类型对比
| 类型 | 位宽 | 指数位 | 尾数位 | 特点 |
|---|---|---|---|---|
| FP32 | 32 | 8 | 23 | 完全精度 |
| FP16 | 16 | 5 | 10 | 精度高,范围小 |
| BF16 | 16 | 8 | 7 | 范围大,精度低(深度学习首选) |
| FP8 (E4M3) | 8 | 4 | 3 | 训练推理兼用 |
| INT8 | 8 | — | — | 推理加速 |
| INT4 | 4 | — | — | 极致压缩 |
为什么 BF16 是深度学习首选? 深度学习更关心数值范围而非精度,过参数化本身可以弥补精度损失。BF16 的 8 位指数提供了与 FP32 相同的表示范围。
主流量化方法
| 方法 | 类型 | 精度保持 | 速度 | 适用场景 |
|---|---|---|---|---|
| GPTQ | PTQ(训练后量化) | 好 | 快 | 离线量化部署 |
| AWQ | PTQ | 更好 | 快 | 精度敏感场景 |
| GGUF | PTQ | 好 | 中 | llama.cpp / 端侧 |
| SmoothQuant | PTQ | 好 | 很快 | INT8 推理 |
| QLoRA | QAT(量化感知训练) | 最好 | 慢(训练) | 微调场景 |
| FP8 训练 | QAT | 极好 | 快 | 大规模预训练 |
显存估算公式(面试必考)
推理显存:
模型参数显存 = 参数量(B) × 每参数字节数
FP32: 1B → 4GB
FP16/BF16: 1B → 2GB
INT8: 1B → 1GB
INT4: 1B → 0.5GB
实际显存 ≈ 模型参数显存 × 1.2(前向传播开销约 20%)KV Cache 显存:
KV Cache = 2 × n_layers × n_heads × head_dim × seq_len × batch_size × 字节数
7B 模型 (32层, seq_len=4096, batch=1, FP16):
= 2 × 32 × 32 × 128 × 4096 × 1 × 2B ≈ 2GB混合精度训练要点
- 前向/反向:FP16/BF16(节省显存和计算)
- 参数主副本:FP32(保证梯度累积精度)
- Layer Norm:建议 FP32(需要精确的均值/方差计算)
- 优势:大 batch 下速度更快(小 batch 瓶颈在 IO,差异不大)
低秩分解
将大权重矩阵 W(m×n) 分解为两个小矩阵的乘积 W ≈ A(m×r) × B(r×n),其中 r << min(m,n)。
- SVD 分解:经典方法,直接对权重矩阵做奇异值分解
- LoRA 本质:微调时冻结原矩阵,只学习低秩增量 ΔW = AB
- 适用于推理加速(减少矩阵乘法计算量)和微调(减少可训练参数)
组合压缩策略(工程最佳实践)
完整压缩流水线:
教师模型(72B)
→ 知识蒸馏 → 学生模型(7B) # 参数量缩减 10×
→ 结构化剪枝 → 剪枝模型(5B) # 移除冗余头/层
→ INT4 量化 → 最终模型(2.5GB) # 极致压缩
→ 投机解码部署 # 运行时加速 3-4×高频面试追问
知识蒸馏中温度 T 的作用?T 太大或太小有什么问题?
- T 越大分布越平滑,暗知识越多但信号越弱;T=1 退化为硬标签;通常 T=2~10
量化为什么能加速而不只是省显存?
- 降低了数据传输量(memory-bound 瓶颈),INT8/INT4 运算有专用硬件加速(Tensor Core)
GPTQ 和 AWQ 的核心区别?
- GPTQ 用二阶信息(Hessian)逐列量化;AWQ 根据激活值分布找重要通道,保护这些通道的精度
QLoRA 为什么能在量化的同时进行微调?
- 线性层量化为 INT4(冻结,只做前向),LoRA 部分用 FP16 训练;两者优势互补
结构化剪枝和非结构化剪枝的实际部署差异?
- 非结构化剪枝产生稀疏矩阵,需要稀疏硬件(如 A100 的 2:4 稀疏);结构化剪枝直接减少维度,任何硬件都能加速
显存不够部署 70B 模型,有哪些方案?
- INT4 量化(→~35GB)、多卡 TP 并行、CPU offloading、用蒸馏得到更小模型、MoE 稀疏激活