前阵子一个做工业检测的朋友给我看他的演示环境:模型在机房服务器上跑得挺顺,挪到产线旁的工控机上,帧率掉到没法用。他没急着换模型,先看了一遍内存占用——权重加载完,留给推理中间结果的空间已经不多了。
这类情况现在不算少见。算力的增长追不上参数的增长,硬件也不是每个现场都能换。于是“能不能小一点”从优化项变成了必选项,模型压缩也就被频繁提起。
压掉的通常是冗余,不是能力
训练出来的网络里,相当一部分权重对最终输出的影响很小,也有不少数值用不着那么高的精度。压缩做的事,就是把这些余地找出来。
常见做法大致几类:
- 量化:把权重和激活从高精度降到低位宽,显存占用和访存压力随之下降,工程改动相对局部。
- 剪枝:按某种重要性判断去掉一部分连接或通道,模型变稀疏,但真要省下时间,还得看算子和硬件是否配合。
- 蒸馏:让小模型去拟合大模型的输出分布,压的不只是数值,还有行为方式。
几类手段可以叠加使用,只是每叠一层,调参与验证的成本就往上走一步。
代价落在哪些地方
压缩不是免费的。位宽压得很低时,数值敏感的部分会先出问题——概率分布被压平,输出的置信度变得不太可信。剪枝过度则是另一种表现:常见样本上看不出差别,碰到长尾情况才露馅。这些毛病在实验室的小测试集上往往不明显,要等上线之后才慢慢浮现。
所以做模型压缩之前,比挑方法更要紧的是准备一套评估方式:不只看整体指标,还要盯住业务上真正在意的那一小部分样本。压缩带来的收益是显存表上的数字,代价却常常藏在指标的均值里。
先量瓶颈,再谈方法
还有一种情况值得单独说:有些团队一上来就压缩模型,最后发现瓶颈在数据预处理或者前后处理环节,模型本身并不慢。合理的顺序是先量——推理时显存、访存带宽、算力各占多少,再决定动不动手。带宽吃紧的场景,量化往往够用;算力吃紧的场景,结构调整更对症。
边缘设备还有个现实约束:并非所有硬件都对稀疏结构友好。纸面上省下计算量的稀疏模型,落到具体芯片上,可能因为算子支持不到位反而跑得更慢。
我倾向把模型压缩看成一次交易:用可接受的精度损失,去换显存、延迟或者部署成本。交易划不划算,取决于业务能容忍多少误差,不取决于压缩比看着多漂亮。所以在动手之前,那个问题最好先问清楚——你要救的究竟是显存、延迟,还是部署成本?