趋近智
为了使模型部署高效,模型剪枝提供了一种直接的方法,通过移除对模型性能贡献最小的参数 (parameter)来降低复杂度。像量化 (quantization)这样的技术降低了参数的精度,而剪枝则将它们完全移除,从而带来更小的模型尺寸和更快的推理 (inference)速度。
其核心思路源于这样一个发现:许多大型神经网络 (neural network)存在明显的过参数化问题。它们包含冗余的权重 (weight),甚至可以移除整个结构元素(如神经元或通道),且对精度影响很小,尤其是在微调 (fine-tuning)阶段之后。这与像“彩票假说”这样的观点相符,该假说认为,密集网络包含更小的子网络,这些子网络在独立训练时能够达到相似的性能。剪枝旨在找出并分离这些高效的子网络。
剪枝技术通常分为两大类:
无结构剪枝: 指根据特定标准(通常是权重 (weight)的大小)从网络中移除单个权重。值接近零的权重被认为影响力较小,并被精确地设置为零。这会创建稀疏权重矩阵。
torch.sparse)。模型尺寸的减小程度显著,这对于存储和内存带宽有利。结构化剪枝: 这种方法不是移除单个权重,而是移除整个结构组件,例如卷积层中的滤波器或通道,或者全连接层中的神经元。
无结构剪枝和结构化剪枝的选择,取决于主要的优化目标(最大压缩率还是标准硬件上的直接加速)以及可用的推理基础设施。
应用剪枝的常见工作流程包含以下步骤:
我们如何判断哪些权重 (weight)或结构“不那么重要”?存在以下几种标准:
torch.nn.utils.prune实现剪枝PyTorch提供了一个便捷的工具模块torch.nn.utils.prune,用于实现各种剪枝技术。它的工作原理是为指定的模块参数 (parameter)(weight或bias)添加一个weight_mask缓冲区。在前向传播过程中,原始权重 (weight)张量与此掩码进行逐元素相乘,从而有效地将剪枝后的权重归零,而最初不修改原始的weight张量本身。这有助于逐步剪枝和微调 (fine-tuning)。
我们来看一个使用基于大小剪枝的基本示例:
import torch
import torch.nn as nn
import torch.nn.utils.prune as prune
# 示例层
layer = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3)
# --- 无结构剪枝 ---
# 剪枝该层中L1范数最小的30%权重(全局)
prune.l1_unstructured(layer, name="weight", amount=0.3)
# 掩码现已附着。你可以查看它:
print(hasattr(layer, 'weight_mask'))
# 输出: True
print(layer.weight_mask)
# 输出: (一个由0和1组成的张量,约有30%的元素是0)
# 原始权重仍然存在,但在前向传播时被掩蔽
print(layer.weight) # 显示原始权重
# 查看计算中使用的剪枝后权重:
print(layer.weight * layer.weight_mask) # 显示被掩蔽的权重
# --- 结构化剪枝(示例:剪枝通道) ---
# 为结构化示例创建一个新层
structured_layer = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3)
# 剪枝25%的通道(dim=0对应输出通道)
# 使用每个通道滤波器中权重的L2范数
prune.ln_structured(structured_layer, name="weight", amount=0.25, n=2, dim=0)
print(hasattr(structured_layer, 'weight_mask'))
# 输出: True
# 注意掩码结构:整个通道(dim=0)都被归零了
print(structured_layer.weight_mask[0:5, 0, 0, 0]) # 检查前5个滤波器的掩码
# --- 使剪枝永久化 ---
# 微调后,你可能希望移除掩码并永久性地将参数归零
# 这可以减少开销,并使模型准备好部署。
# 对于无结构示例:
prune.remove(layer, 'weight')
print(hasattr(layer, 'weight_mask'))
# 输出: False
# 现在layer.weight直接包含零值
print(torch.sum(layer.weight == 0)) # 计算归零的权重数量
在典型的训练循环中,你会在开始微调阶段之前应用剪枝函数(例如prune.l1_unstructured)。在微调期间,梯度将只流经未被掩蔽的权重,使它们能够调整。掩码本身不参与训练。微调完成后,调用prune.remove会将掩码直接应用于权重张量并移除掩码缓冲区及其关联的前向预钩子,从而使稀疏性永久化。
剪枝在模型压缩/速度与精度之间引入了一种权衡。
通过剪枝实现的模型稀疏度与微调 (fine-tuning)后的验证精度之间的典型关系。精度通常在初始阶段保持稳定,但在更高的稀疏度水平下下降得更快。
考量方面包括:
模型剪枝是一种有效技术,用于减小深度学习 (deep learning)模型的计算开销。通过仔细移除不那么重要的参数,无论是单个移除还是结构性移除,并对生成的网络进行微调,你可以创建更小、可能更快的模型,适用于资源受限环境下的部署。torch.nn.utils.prune模块提供了灵活的工具,用于在你的PyTorch工作流程中实现各种剪枝策略。
这部分内容有帮助吗?
torch.nn.utils.prune documentation, PyTorch Developers, 2024 (PyTorch) - PyTorch官方文档,介绍用于对神经网络层应用各种剪枝技术的模块。© 2026 ApX Machine LearningAI伦理与透明度•