第4章:模型剪枝理论基础

剪枝这玩意儿,说白了就是给神经网络「瘦身」。我刚开始接触剪枝时,总觉得这跟直接砍掉模型参数没啥区别。后来踩了不少坑才明白——剪枝不是简单粗暴地删东西,而是有策略地做取舍。

这一章,咱们把剪枝的理论基础掰开揉碎。你理解透了,后面实操才不会走弯路。

4.1 剪枝的分类:结构化 vs 非结构化

先问个问题:剪枝到底剪什么?

答案很简单——剪掉那些「不重要」的参数。但怎么定义「不重要」,就分出了两大流派。

4.1.1 非结构化剪枝

非结构化剪枝,也叫细粒度剪枝。它直接干掉单个权重或神经元连接。

举个例子:一个卷积核是 3×3 的矩阵,里面有些权重值特别小。非结构化剪枝就把这些值直接置零。

优点很明显——剪枝率高,模型压缩比大。我曾在某个分类任务上,把 80% 的权重都剪掉了,精度只掉了 0.5%。

但缺点也很致命——权重矩阵变得稀疏了。稀疏矩阵在普通硬件上跑,速度反而更慢。你得用专门的稀疏计算库,比如 NVIDIA 的 cuSPARSE。说白了,就是「剪得爽,跑得慢」。

核心要点: 非结构化剪枝适合学术研究,工业落地慎用。

4.1.2 结构化剪枝

结构化剪枝就聪明多了。它不剪单个权重,而是剪整个「结构单元」——比如一个通道、一个卷积核、甚至一整层。

这样做的好处是:剪完之后,模型结构还是规整的。你不需要特殊硬件,直接跑在普通 GPU 上就能加速。

我在项目中遇到过一件事:用非结构化剪枝剪了个 YOLOv5,精度还行,但推理速度没变。换成结构化剪枝后,模型小了 40%,速度提升了 1.5 倍。嗯,从那以后,工业项目我首选结构化剪枝。

类型 剪枝粒度 硬件友好度 压缩比 典型场景
非结构化 单个权重 学术研究
结构化 通道/卷积核/层 工业部署

4.2 剪枝粒度:从权重到层

剪枝粒度,就是「你一次剪多大一块」。我习惯把它分成三个级别。

4.2.1 权重级剪枝

这是最细的粒度。每个权重独立判断是否保留。

判断标准很简单:看权重的绝对值大小。绝对值越小,说明它对输出的贡献越小,剪掉它影响不大。

你想想看,一个权重值只有 0.001,跟一个权重值 0.5 的比,谁更重要?显然是后者。

我的习惯: 权重级剪枝配合重训练效果更好。剪完一轮,再训练一下,让剩下的权重「补位」。

4.2.2 通道级剪枝

这是工业界最常用的粒度。剪掉整个通道,相当于删掉了一整个特征图。

怎么判断一个通道重不重要?看它的 L1 范数。把所有权重的绝对值加起来,和越小,说明这个通道越「懒」。

我曾经剪过一个 YOLOv5s 模型,把 30% 的通道都砍了。结果呢?模型大小从 14MB 降到 8MB,mAP 只掉了 1.2%。这个性价比,我觉得很值。

4.2.3 层级剪枝

层级剪枝最暴力——直接删掉一整层。比如 ResNet 里的某个残差块,或者 YOLO 里的某个 C3 模块。

什么时候用?模型特别深,或者某些层确实「没用」的时候。我见过一个极端案例:某个检测模型有 100 多层,剪掉最后 10 层后,精度几乎没变。说白了,那些层就是在「摸鱼」。

注意: 层级剪枝风险最大。删掉一层,整个网络结构都变了。建议先做通道级剪枝,不够再考虑层级剪枝。

4.3 剪枝评价指标

剪得好不好,不能光看模型大小。你得有「尺子」去量。我常用的指标有这几个。

4.3.1 精度损失

这是最直接的指标。剪枝前后的精度对比。

公式很简单:

精度损失 = 原始精度 - 剪枝后精度

一般来说,精度损失控制在 1% 以内,算优秀。1%-3%,可以接受。超过 3%,你得重新调剪枝策略了。

4.3.2 压缩比

压缩比 = 原始模型大小 / 剪枝后模型大小

比如原始模型 100MB,剪完后 50MB,压缩比就是 2x。

但要注意:压缩比高不代表推理速度快。非结构化剪枝压缩比能做到 10x,但推理速度可能只提升 1.2x。结构化剪枝压缩比 2x,推理速度可能提升 2x。

4.3.3 加速比

这才是工业界最关心的指标。

加速比 = 原始推理时间 / 剪枝后推理时间

我曾经做过一个对比:同样剪掉 50% 的参数,非结构化剪枝加速比只有 1.1x,结构化剪枝加速比达到了 1.8x。为什么?因为结构化剪枝减少了计算量,而不仅仅是参数量。

指标 含义 理想值 注意点
精度损失 剪枝前后精度差 < 1% 分类任务看 Top-1,检测任务看 mAP
压缩比 模型大小缩减倍数 2x - 5x 非结构化压缩比高但加速有限
加速比 推理速度提升倍数 1.5x - 3x 结构化剪枝加速效果更好
FLOPs 减少率 计算量减少比例 30% - 60% 与加速比正相关

4.3.4 FLOPs 减少率

FLOPs 是浮点运算次数。减少 FLOPs,就是减少计算量。

这个指标跟加速比强相关。一般来说,FLOPs 减少 50%,加速比能到 1.8x 左右。

但要注意:FLOPs 减少率 ≠ 加速比。因为还有内存访问、数据搬运等开销。我见过一个模型,FLOPs 减少了 60%,但加速比只有 1.5x。原因就是内存带宽成了瓶颈。

总结一下: 剪枝评价不能只看一个指标。精度、压缩比、加速比,三个都要看。我个人的经验是:先保证精度损失在可接受范围内,再追求压缩比和加速比。

4.4 避坑指南

最后分享几个我踩过的坑。

坑一:剪枝后不重训练。 我曾经以为剪完直接部署就行,结果精度掉了 5%。后来老老实实做重训练,精度才回来。记住:剪枝只是第一步,重训练才是关键。

坑二:只看压缩比不看加速比。 有个项目,我剪到了 5x 压缩比,但推理速度只快了 10%。后来换成结构化剪枝,压缩比 2x,加速比到了 2x。嗯,从此我学会了「以加速比为导向」。

坑三:一次性剪太多。 我刚开始做剪枝时,总想一步到位。结果剪完模型直接崩了。后来改成「迭代剪枝」——每次剪 10%,重训练,再剪 10%。这样稳多了。

我的建议: 从通道级剪枝入手,每次剪 10%-20%,配合重训练。先跑通流程,再优化策略。

好了,这一章的内容就到这里。剪枝的理论基础,说白了就是「怎么剪」和「怎么评价」。下一章,咱们会讲具体的剪枝算法,比如 L1 范数剪枝、BN 层剪枝。到时候,我会带着代码一步步演示。

记住:理论是基础,实践出真知。别光看,动手试试。