4.1 量化剪枝蒸馏三板斧 本节摘要:把云端大模型搬到端侧,核心障碍是体积和算力需求。模型压缩有三个主流手段:量化(quantization)降低数值精度,把 32 位浮点权重压成 8 位甚至 4 位整数,体积直接砍到四分之一到八分之一;剪枝(pruning)去掉不重要的权重或通道,让模型变稀疏;蒸馏(distillation)用大模型当老师训练一个小模型学生,让小模型学到接近大模型的能力。三者原理不同、代价不同,实践中常组合使用——先蒸馏得到小模型,再量化降精度,最后剪枝去冗余。本节拆解每种技术的机理、适用场景和工程取舍。
本节摘要:把云端大模型搬到端侧,核心障碍是体积和算力需求。模型压缩有三个主流手段:量化(quantization)降低数值精度,把 32 位浮点权重压成 8 位甚至 4 位整数,体积直接砍到四分之一到八分之一;剪枝(pruning)去掉不重要的权重或通道,让模型变稀疏;蒸馏(distillation)用大模型当老师训练一个小模型学生,让小模型学到接近大模型的能力。三者原理不同、代价不同,实践中常组合使用——先蒸馏得到小模型,再量化降精度,最后剪枝去冗余。本节拆解每种技术的机理、适用场景和工程取舍。
阅读完本节,你应当能够:
假设你要把一个图像分类模型部署到手机上。原始模型是 FP32(每个权重 32 位浮点),体积 100MB,推理要 500ms,手机跑起来既慢又发烫。怎么办?
最直接的想法是换个更小的模型架构,但小模型精度往往差一截。能不能在不换架构的前提下让它变小变快?这就是压缩技术要解决的。三个思路:让每个权重占的空间小一点(量化)、把没用的权重删掉(剪枝)、或者干脆训练一个天生小但能力接近的模型(蒸馏)。
这三招不是互斥的,它们解决的是不同维度的"大"。量化解决的是"每个权重占多少字节",剪枝解决的是"有多少权重是冗余的",蒸馏解决的是"小架构能不能学到大能力"。组合起来效果最好——这也是工业界的主流做法。
神经网络里的权重和激活值通常是 FP32(32 位浮点)。量化把它们表示成低精度整数——最常见的是 INT8(8 位整数),更激进的有 INT4。
直觉上你会担心:把 32 位浮点压成 8 位整数,精度损失不会很大吗?实践表明,对于大多数神经网络,INT8 量化后精度损失通常在 1% 以内,几乎无感。原因是神经网络对小幅度的数值扰动有鲁棒性,且训练时学到的权重分布往往集中在某个范围,量化到 256 个离散值(INT8)足够覆盖。
量化分两种:
训练后量化(Post-Training Quantization, PTQ):模型训练完之后,用一小批校准数据统计激活值的分布,然后把权重和激活量化到 INT8。优点是简单快,几行代码搞定;缺点是对某些模型(尤其是激活值分布范围大的)精度损失明显。
量化感知训练(Quantization-Aware Training, QAT):在训练过程中就模拟量化的效果(插入假量化节点),让模型适应量化带来的精度损失。优点是精度更好;缺点是要重新训练,成本高。
| 量化方式 | 精度损失 | 工程成本 | 适用场景 |
|---|---|---|---|
| PTQ INT8 | 通常 <1% | 低(几分钟) | 多数模型的默认选择 |
| QAT INT8 | 极小 | 高(要重训练) | 对精度敏感的模型 |
| INT4 | 明显(要测试) | 中高 | 极致压缩、大模型 |
| 混合精度 | 可控 | 中 | 关键层保留高精度 |
💡 关键直觉:量化别一刀切。模型的某些层(比如第一层和最后一层)对精度更敏感,全量 INT8 可能让它们精度掉得明显。混合精度策略——敏感层保留 FP16 或 INT16、其他层 INT8——往往能在体积和精度间拿到更好的平衡。
训练好的神经网络里,很多权重其实接近零,对输出几乎没贡献。剪枝(pruning)就是把这些"不重要"的权重去掉,让模型变稀疏。
剪枝分两类:
非结构化剪枝:逐个权重判断重要性,把不重要的置零。能剪掉很高比例(比如 90%)的权重,模型理论计算量大减。但问题是:稀疏矩阵的计算在大多数硬件上没有加速——GPU 和 NPU 是为密集矩阵优化的,稀疏矩阵反而更慢,因为要跳过零值。所以非结构化剪枝的"理论加速"很难兑现。
结构化剪枝:整个通道或整层地剪,剪完还是密集矩阵,硬件能直接加速。能剪的比例比非结构化低(比如 30–50%),但加速能真实兑现。
| 剪枝方式 | 剪枝率 | 实际加速 | 硬件友好度 |
|---|---|---|---|
| 非结构化 | 高(70–90%) | 难(需稀疏支持) | 低 |
| 结构化 通道级 | 中(30–50%) | 能 | 高 |
| 结构化 层级 | 低 | 能 | 高 |
⚠️ 常见坑:别被"剪掉 90% 权重"的论文数字忽悠。那多半是非结构化剪枝,理论计算量小但实际推理未必快,除非你的硬件和推理引擎专门优化稀疏计算。端侧部署优先考虑结构化剪枝,虽然剪枝率低但加速真实。
知识蒸馏(Knowledge Distillation)的思路是:训练一个小的"学生"模型,让它模仿大的"老师"模型的输出。关键在于学生学的不是"标准答案",而是老师的"软标签"——老师对每个类别的概率分布。这个分布比硬标签包含更多信息(比如老师觉得某个样本"60%像猫、30%像狗、10%像鸟",这个软分布比单纯"是猫"教给学生更多)。
蒸馏损失函数通常结合两部分:学生预测和老师软标签的差异(KL 散度),加上学生预测和真实硬标签的差异(常规交叉熵)。前者让学生学到老师的"暗知识",后者保证学生不跑偏。
蒸馏在端侧部署里特别有用,因为它能让你用一个小架构达到接近大架构的精度。比如用一个 ResNet-18 的学生模型模仿 ResNet-152 的老师,体积小十几倍但精度可能只差 2–3%。
实际工程中三者常组合使用,顺序一般是:先蒸馏(得到一个小而精的模型架构),再量化(把精度压下来),最后剪枝(去残余冗余)。每一步都要验证精度别掉太多。
每一步的典型压缩倍数:蒸馏可能让模型小 5–10 倍(换架构),量化让体积小 4 倍(FP32→INT8),剪枝让计算量小 30–50%。组合起来,一个云端几百 MB 的模型,能压到几 MB 在手机上跑,精度损失控制在可接受范围。
PTQ 量化要用一小批校准数据统计激活值分布。这批数据的选择很关键——它要能代表真实推理时的输入分布,否则量化参数会偏。
常见错误是用随机数据或训练集的某个固定 batch 校准。正确做法是用真实业务数据的代表性样本(几百到一两千条),覆盖各种输入情况。比如图像分类要用各种光照、角度、背景的真实图片,不能用干净的训练集图片。
量化后必须测精度,而且要测全。不要只看整体准确率,要分类型看——量化可能让某些少数类别精度掉很多但整体数字看不出。还要看边缘情况(极端输入、对抗输入)的表现,这些往往是量化最先崩的地方。
# 概念性量化精度校验 class QuantizationValidator: def __init__(self, fp32_model, int8_model): self.fp32 = fp32_model self.int8 = int8_model def compare(self, test_data): results = {"match": 0, "mismatch": 0, "big_gap": []} for sample in test_data: fp_out = self.fp32(sample) int_out = self.int8(sample) if self._argmax(fp_out) == self._argmax(int_out): results["match"] += 1 else: results["mismatch"] += 1 # 记录预测差异大的样本 重点分析 gap = self._output_distance(fp_out, int_out) if gap > self.threshold: results["big_gap"].append(sample) return results
前面讲的主要是 CNN 类小模型。大语言模型(LLM)的量化有特殊性——它太大,INT8 都嫌大,所以 INT4 量化是热门方向。但 LLM 量化有个坑:不同层的敏感度差异比 CNN 大得多,有些层(比如attention的某些投影)量化后质量骤降。所以 LLM 量化常用分组量化(group-wise)或混合精度,对敏感层保留高精度。
端侧跑 LLM(比如手机上跑一个 1.8B 或 3B 的小模型)是近年的新方向。Phi-3、Gemma 2B、Qwen 1.8B 这些就是为端侧设计的。它们本身参数小,配合 INT4 量化,能在高端手机上跑出可用的速度。
💡 关键直觉:端侧 LLM 不要追求"和云端一样的能力",那不现实。要找准它的定位——离线场景的基础问答、隐私敏感的本地处理、低延迟的简单任务。在这些场景里,一个 INT4 量化的小 LLM 比云端大模型体验更好(即时响应、无网络依赖、数据不出端)。
下一节讲压缩后的模型怎么在端侧设备上跑起来——选哪个推理框架、怎么用硬件加速、怎么针对不同设备调优。
三板斧各自的历史轨迹决定了今天的使用姿势。量化是最老的:定点推断在信号处理时代就有,深度学习量化在 2015 年前后随 MobileNet 论文系统化,GPTQ、AWQ 这类面向 LLM 的权重量化方法是 2023 年之后才补齐的拼图。剪枝的起点更早——1989 年 LeCun 的最优脑损伤论文就提出了权重显著性分析,但三十年过去它仍是三者中最难用好的一把:非结构化剪枝能删掉 80% 权重,稀疏模式却无法映射到硬件加速,实际推断速度几乎不变;结构化剪枝(整通道、整注意力头地删)能真加速但幅度有限。这个"理论收益与硬件现实的落差"是剪枝近年热度下降的主因。蒸馏则从 2015 年 Hinton 确立"软标签"框架后一路走高,它的地位变化最有意思:从"压缩手段"演化成了"能力转移协议"——今天的端侧小模型(1B-3B LLM)基本都经过大规模合成数据蒸馏训练,学生学的不再只是老师的输出分布,而是老师生成的百万级指令数据。
组合策略也在演化。经典流水线"蒸馏定架构、量化定精度、剪枝去冗余"依然成立,但 LLM 时代多了两个新共识。一是量化前移:与其压缩一个现成大模型,不如在训练后期就加入量化感知(QAT 收尾几个 epoch),INT4 的精度损失可以压到几乎不可测;二是"压缩即训练目标":直接训练一个原生小型架构(配合大模型数据蒸馏),效果普遍好于把大模型层层削薄——同样的参数预算,原生小模型在吞吐和精度上都占优,这也是各家端侧模型清一色从小架构从头训的原因。
工程验收上补一个实操清单:每一步压缩后要测的不只是整体精度,还有分组指标的退化(长尾类别、少数口音、低置信样本),压缩损失往往集中在分布尾部;要测的也不只是精度,还有真实设备的延迟和内存峰值——很多"理论提速 2 倍"的方案在手机上因为内存拷贝模式变化反而更慢。建立"精度分组报表 + 真机性能曲线"的双验收,是压缩项目不翻车的底线。