剪枝
剪枝移除不重要的权重、通道或结构,以减少计算或存储。依据裁剪粒度可分为非结构化剪枝与结构化剪枝,二者对硬件加速的支持程度差异很大,直接决定剪枝能否带来真实收益。按幅值剪枝的经典做法可追溯到 Han 等人提出的 Learning both Weights and Connections for Efficient Neural Networks,其思路是先训练后剪枝再微调;后续 彩票假设 (Lottery Ticket Hypothesis) 进一步指出,稠密网络中可能存在可独立训练的子网络,这为「为什么剪掉大部分参数后模型仍能恢复精度」提供了一种解释。
快速开始¶
剪枝前先确认目标硬件和推理框架是否支持对应的稀疏模式,否则裁剪后的模型可能无法被运行时利用。然后固定基线和评测集,在相同任务上记录精度、延迟和显存占用。
从较小比例(如 10% 到 30%)开始裁剪并重新评测,观察精度下降幅度。每次只改一个变量,先小步验证再逐步提高比例,避免一次性剪太多导致无法定位退化来源。最简单的起点是全局幅值剪枝:按权重绝对值排序,把最小的一批置零,再对剩余权重做一次微调恢复精度。验证成功的标准是模型文件或激活计算量下降,同时延迟或显存占用在目标框架下确实同步下降,而不仅是精度指标的表面持平。
取舍¶
非结构化剪枝按单个权重的幅值置零,理论上压缩率高、对精度影响较小,但产生的稀疏模式不规则,通用矩阵乘法很难直接加速,多数硬件下反而没有吞吐收益。形式上,给定权重矩阵 \(W\) 和阈值 \(\theta\),非结构化剪枝可写成逐元素操作:
其中 \(\theta\) 通常按目标稀疏率取 \(|W|\) 的分位数。这种方式只改变单个权重,不会改变张量形状,因此计算图不变,运行时也无法省去对应乘法。
结构化剪枝按通道、注意力头或整层移除,改变模型的计算图,更容易被推理框架和硬件利用,能带来真实的延迟和显存下降,但代价是精度损失通常更大。它直接删掉整行或整列权重,例如剪掉一个注意力头就同时移除该头对应的 \(W_Q,W_K,W_V,W_O\) 投影,矩阵乘法维度随之缩小,硬件可以真实减少计算。
因此剪枝的选择取决于目标:若只为减小存储体积,非结构化稀疏加上压缩存储即可;若要缩短推理延迟,应优先选择运行时能落地的结构化剪枝。此外,NVIDIA Ampere 及之后的 GPU 提供 2:4 结构化稀疏支持,即在每 4 个连续权重中至少保留 2 个非零值,参见 官方文档,这类半结构化稀疏兼顾了压缩率和硬件加速,但同样要求框架显式支持。
案例¶
某实验按注意力头的输出范数排序,剪去若干不重要的 head 后重新评测。模型文件确实变小,但端到端延迟几乎不变,说明推理框架并未利用这种稀疏,计算量没有实际减少。
此时应改为框架支持的结构(如整层或整块裁剪),或直接停止这条优化路径,把资源投入量化等能真实加速的手段。判断标准始终是延迟与显存,而不是文件体积。一个可操作的排查顺序是:先确认框架是否识别了稀疏权重,再确认 kernel 是否走稀疏路径,最后对比剪枝前后的端到端 TPOT 与 TTFT;若三者都无法证明收益,剪枝在该部署栈上就不划算。