模型压缩技术全景:剪枝、量化、知识蒸馏、低秩分解、轻量化架构设计
各位同学,今天我们来聊聊模型压缩。说实话,这个话题在AI运动控制里特别重要。你想想看,一个几百兆的深度学习模型,放到嵌入式芯片上跑,那基本就是灾难。我当年第一次把训练好的模型部署到STM32上,直接卡死,连个电机都转不起来。从那以后,我就开始认真研究模型压缩了。
模型压缩说白了就是给模型「减肥」。让它变小、变快,但尽量保持精度。今天我把五种主流方法都捋一遍:剪枝、量化、知识蒸馏、低秩分解,还有轻量化架构设计。嗯,咱们一个一个来。
1. 剪枝:把没用的连接砍掉
剪枝这个概念,最早是从神经网络生物学启发来的。人脑里也不是所有神经元都活跃,对吧?模型也一样,很多权重其实接近于零,留着它们纯粹浪费算力。
剪枝分两种:非结构化剪枝和结构化剪枝。
- 非结构化剪枝:把单个权重置零。优点是压缩率高,但硬件不友好。你想想,稀疏矩阵在普通CPU上跑,反而更慢。
- 结构化剪枝:直接砍掉整个通道或卷积核。硬件友好,但精度损失大一些。
我个人习惯的做法:先做一次全局剪枝,把低于阈值的权重干掉。然后微调几个epoch,再剪一次。反复两三轮,效果最好。
我曾经在一个人体姿态估计项目里,把MobileNetV2剪掉了40%的参数,推理速度提升了1.8倍,精度只掉了0.7%。嗯,这个结果我是满意的。
2. 量化:用更少的位数表示参数
量化是工业界用得最多的方法。为什么?因为它直接改数据类型,不需要改模型结构。
默认情况下,模型参数是FP32,也就是32位浮点数。量化之后可以变成INT8,甚至INT4。你想想,32位变8位,内存直接降到四分之一。推理速度也能翻倍,因为整数运算比浮点快太多了。
| 量化类型 | 位宽 | 模型大小缩减 | 典型精度损失 |
|---|---|---|---|
| FP32(基准) | 32 | 1x | 0% |
| INT8 | 8 | 4x | 0.5%~2% |
| INT4 | 4 | 8x | 1%~5% |
避坑指南:我曾经在量化一个强化学习策略网络时,直接用了后训练量化,结果动作输出全乱了。后来改用量化感知训练(QAT),在训练过程中模拟量化误差,效果就好多了。所以我的建议是:能上QAT就上QAT,别偷懒。
3. 知识蒸馏:让学生模仿老师
知识蒸馏的思路很有意思。你训练一个大模型(老师),然后用它的输出去训练一个小模型(学生)。学生学到的不仅是正确答案,还有老师对模糊样本的判断。
举个例子,手写数字识别里,老师模型看到数字「7」,输出可能是:7的概率0.9,1的概率0.08,其他0.02。这种「软标签」比硬标签(直接说这是7)包含更多信息。学生模型学这个,效果比直接训练好得多。
# 知识蒸馏的损失函数示意
loss = alpha * KL_div(student_output, teacher_output) +
(1 - alpha) * CE_loss(student_output, hard_label)
alpha一般取0.7到0.9之间。温度参数T也很关键,T越大,软标签越平滑。我一般设T=4,效果比较稳。
4. 低秩分解:用矩阵分解降维
低秩分解,说白了就是把一个大矩阵拆成两个小矩阵的乘积。比如一个1000x1000的权重矩阵,可以拆成1000x50和50x1000两个矩阵。参数量从100万降到10万,直接省了90%。
常用的方法有SVD分解和CP分解。SVD适合全连接层,CP分解适合卷积层。
注意:低秩分解对模型精度影响比较大,尤其是分解比例过高的时候。我建议分解比例控制在50%以内,然后配合微调恢复精度。我曾经试过把卷积层分解70%,结果模型直接废了,怎么微调都救不回来。
5. 轻量化架构设计:从源头开始瘦
前面四种方法都是对已有模型做压缩。但如果你是从零开始设计模型,为什么不直接设计一个轻量化的架构呢?
这里重点讲两个:MobileNet和ShuffleNet。
MobileNet的核心是深度可分离卷积。普通卷积同时处理空间和通道信息,而深度可分离卷积把它们拆开。先对每个通道做空间卷积,再用1x1卷积融合通道。计算量直接降到原来的十分之一左右。
ShuffleNet更进一步,它用了分组卷积和通道混洗。分组卷积减少计算量,通道混洗保证组之间信息流通。嗯,这个设计很巧妙。
我在一个四足机器人步态控制项目里,用ShuffleNetV2替换了原来的ResNet18,模型大小从44MB降到了3.5MB,推理速度提升了5倍,而且步态稳定性几乎没有下降。说实话,这个结果让我挺惊喜的。
知识体系总览
下面这张图,我把五种方法的关系和适用场景画出来了。你可以保存下来,以后选方案时对照着看。
最后说一句,这五种方法不是互斥的。我实际项目中经常组合使用。比如先做知识蒸馏得到一个较小的学生模型,然后做量化到INT8,最后再剪掉一些冗余通道。三层压缩下来,模型能缩小到原来的5%左右,精度损失控制在2%以内。嗯,这个效果在运动控制场景里完全够用。
好了,模型压缩的全景图就讲到这里。每种方法后面还会单独展开讲,到时候我会带你们手撸代码,把每个方法都跑一遍。