稀疏化(Sparsification)技术介绍

稀疏化(Sparsification)技术介绍

一、基本概念

稀疏化,简单来说,就是通过适当的方法减少神经网络中的冗余成分,以降低网络对计算量和存储空间的需求。

神经网络推理的过程,本质上是"激活值"和"权重"不断做乘加运算。研究发现,大量参数(权重)接近于零,对最终输出结果贡献极小。稀疏化干的事,就是把这些"没用"的参数直接置为零,让模型变得更小、更快。

剪枝(Pruning)是实现稀疏化的核心手段。剪枝是在保证网络准确率下降较小的前提下,通过去除神经网络中部分组件(如权重、特征图、卷积核),降低网络的参数量,从而降低网络部署时的存储和计算代价。

二、技术原理与作用

2.1 怎么做:剪枝的工作流程

剪枝通常分为三个步骤:

  1. 训练一个普通(稠密)神经网络:先得到一个性能良好的完整模型。
  2. 选择阈值,剪掉不重要的连接:将绝对值小于阈值的权重置为零,得到一个稀疏网络。
  3. 微调(Fine-tuning):剪枝后网络性能通常会下降,需要对稀疏网络进行再训练,将性能恢复上来。

剪枝可以基于"幅值大小"(Magnitude Pruning)------绝对值越小的权重越不重要;也可以基于"梯度信息"或其他重要性评估标准。

2.2 有什么用:稀疏化的三大收益

收益 说明
减少存储 模型参数变少,文件体积缩小,便于部署到嵌入式设备
减少计算 0 × 任何数 = 0,跳过与零相关的无效乘加运算,加速推理
降低功耗 少算一次乘法、少搬一次数据,芯片功耗显著下降

三、稀疏化的分类

稀疏化按照"零值在矩阵中的分布规律",可以分为两大类:非结构化稀疏结构化稀疏 。区分这两类的核心标准是:零值在矩阵中是否有规律可循。有规律的硬件友好,没规律的硬件难办。

3.1 非结构化稀疏(Unstructured Sparsity)

非结构化稀疏是最直接的剪枝方式:将权重张量中绝对值最小的个体权重随机置零,不考虑任何位置或结构约束。

举例说明

假设训练好的一个4×4权重矩阵如下:

css 复制代码
[ 0.5,  0.1, -0.3,  0.8]
[-0.2,  0.7, -0.1,  0.3]
[ 0.6, -0.4,  0.9, -0.2]
[ 0.4, -0.8,  0.2, -0.5]

设定阈值,把绝对值小于 0.3 的权重全部置零,剪枝后:

css 复制代码
[ 0.5,  0,    0,    0.8]
[ 0,    0.7,  0,    0.3]
[ 0.6, -0.4,  0.9,  0  ]
[ 0.4, -0.8,  0,   -0.5]

零值的位置完全随机,没有规律。稀疏率约 37.5%。

为什么对硬件不友好?
  • 无法预取:硬件不知道下一个非零值在哪,必须先读索引再读值
  • 负载不均衡:不同PE分配到的非零值数量不同,快的等慢的
  • 内存访问不规则:非零值离散分布,无法利用连续读取的带宽优势

3.2 结构化稀疏(Structured Sparsity)

结构化稀疏的核心思想是:按固定模式移除权重,让零值呈规律性分布,从而适配硬件并行架构。

根据剪枝粒度可分为三个层次:

① Channel剪枝(通道剪枝) ------ 删除整个输入通道

如一个卷积层有4个输入通道、8个输出通道,每个卷积核尺寸为 3×3×4。 若删除第2个输入通道,每个卷积核从 3×3×4=36 个权重变为 3×3×3=27 个权重,总权重减少 25%。 输入特征图通道数从4变为3,后续层需相应调整。

② Filter剪枝(滤波器剪枝) ------ 删除整个卷积核(即输出通道)

删除后,输出特征图通道数直接减少,网络宽度被压缩。

③ Layer剪枝(层剪枝) ------ 删除整个网络层

粒度最粗,通常用于极深网络(如ResNet-50以上),计算量大幅下降但精度损失显著。

三种结构化剪枝对比
剪枝类型 删除单位 粒度 硬件友好度 精度影响
Channel剪枝 单个输入通道 中等
Filter剪枝 整个卷积核 较大
Layer剪枝 整个网络层 极高 很大

3.3 2:4 稀疏(2:4 Sparsity)

2:4 稀疏是 NVIDIA 在 Ampere 架构(A100 GPU)中引入的细粒度结构化稀疏技术。

核心规则

每连续 4 个元素为一组,强制保留 2 个非零值、剪掉 2 个

举例:[0.5, 0.1, -0.3, 0.8] 经过2:4稀疏后,必须变成下列之一:

css 复制代码
[0.5, 0,   0,   0.8]  或  [0,   0.1, -0.3, 0]
[0.5, 0.1, 0,   0  ]  或  [0,   0,   -0.3, 0.8]

每4个中恰好2个非零、2个零,非零值在组内位置任意。

为什么硬件喜欢2:4稀疏?
  • 每4个权重里一定有2个非零值 → 每个PE分到的有效计算量确定且均匀
  • 索引信息仅需 2位 编码零值位置,开销极小
  • 提供 确定性加速(NVIDIA Sparse Tensor Core可达2倍稠密吞吐量)
精度表现

通过一次幅值剪枝(保留绝对值最大的2个权重)后再训练,精度损失通常在 1%以内

3.4 块稀疏(Block Sparsity)

块稀疏将权重矩阵划分为固定大小的块,每个块要么全部保留,要么全部置零

举例说明

采用 2×2 块大小,一个4×4矩阵被分成4个2×2的块:

scss 复制代码
块A (行0-1, 列0-1)    块B (行0-1, 列2-3)
[1, 2]                [0, 0]
[3, 4]                [0, 0]

块C (行2-3, 列0-1)    块D (行2-3, 列2-3)
[0, 0]                [5, 6]
[0, 0]                [7, 8]

块B和块C全零,被整体跳过;块A和块D有非零值,全部保留。

块大小选择:小块(2×2)精度损失小但索引开销大;大块(16×16)硬件收益大但精度损失大。2×2 或 4×4 是常见折中。

为什么硬件喜欢块稀疏?
  • 控制逻辑极简:只需检查块头标志位(0跳过 / 1计算)
  • 内存访问连续:块内数据连续存储,可突发读取
  • 完美适配脉动阵列:可跳过整个零块,不产生流水线气泡
2:4稀疏 vs 块稀疏
对比维度 2:4稀疏 块稀疏
零值分布 每组4个中恰好2个零 整块全零或全非零
硬件复杂度 中等 极低
稀疏率 固定50% 可调
脉动阵列适配 良好 极佳
工业界代表 NVIDIA A100 学术界块稀疏研究

四、稀疏数据的硬件表示

稀疏化后的矩阵大部分是零,如果仍然按稠密方式存储,就浪费了存储空间和带宽。因此需要专门的数据格式来高效表示稀疏矩阵。

4.1 常见稀疏矩阵存储格式

格式 全称 原理 特点
COO Coordinate 存储所有非零元素的(行, 列, 值)三元组 直观,但索引开销大
CSR Compressed Sparse Row 按行压缩存储,用三个数组表示:非零值、列索引、行偏移(每行第一个非零值在 values 中的起始位置 行访问高效,最常用
BCSR Block CSR CSR 的块版本,以块为单位存储 对块稀疏友好
位图(Bitmap) --- 用一个位图标记非零值的位置,压缩存储非零值本身 索引大小固定,适合硬件流水线,支持快速位运算

下面用一个具体的 4×4 稀疏矩阵,分别展示三种最常用的存储格式。

示例矩阵

css 复制代码
[ 1,  0,  0,  2 ]
[ 0,  3,  0,  0 ]
[ 0,  0,  4,  0 ]
[ 5,  0,  0,  6 ]

该矩阵共有 6 个非零值,稀疏率为 62.5%(16个元素中10个为零)。

4.1.1 COO(Coordinate,坐标格式)

原理 :存储所有非零元素的 (row, col, value) 三元组。

示例矩阵的 COO 表示

0 0 1
0 3 2
1 1 3
2 2 4
3 0 5
3 3 6

特点:最直观,但索引开销最大(每个非零值需要存储行和列两个索引)。

4.1.2 CSR(Compressed Sparse Row,压缩稀疏行)

原理 :用三个数组表示 ------ 非零值(values)、列索引(col_index)、行偏移(row_ptr)。行偏移记录每行第一个非零值在 values 中的起始位置

示例矩阵的 CSR 表示

ini 复制代码
values    = [1, 2, 3, 4, 5, 6]
col_index = [0, 3, 1, 2, 0, 3]
row_ptr   = [0, 2, 3, 4, 6]

解读

  • 第 0 行有 2 个非零值(1, 2),从 values[0] 开始
  • 第 1 行有 1 个非零值(3),从 values[2] 开始
  • 第 2 行有 1 个非零值(4),从 values[3] 开始
  • 第 3 行有 2 个非零值(5, 6),从 values[4] 开始

特点:压缩了行索引,按行访问效率高,是 CPU/GPU 上最常用的格式。

4.1.3 Bitmap(位图索引)

原理:用一个位图标记非零值的位置,然后压缩存储非零值本身。

示例矩阵的 Bitmap 表示

将矩阵按行展开成 16 个元素,非零标记为 1,零标记为 0:

ini 复制代码
原始序列: [1, 0, 0, 2,  0, 3, 0, 0,  0, 0, 4, 0,  5, 0, 0, 6]
位图:     [1, 0, 0, 1,  0, 1, 0, 0,  0, 0, 1, 0,  1, 0, 0, 1]
values:   [1, 2, 3, 4, 5, 6]

每 4 位一组转为十六进制:

  • 10010x9
  • 01000x4
  • 00100x2
  • 10010x9

特点 :索引大小固定(16 位),支持快速位运算(如 popcount 统计非零数量),最适合硬件加速

4.2 对硬件设计的启示

在硬件中处理稀疏数据,核心挑战是如何高效地找到非零值并跳过零值。位图索引因其固定大小和快速位运算能力,在硬件设计中尤其受关注。

五、稀疏化与脉动阵列的关系

5.1 核心矛盾

脉动阵列依赖规则、同步、密集 的数据流,而稀疏化产生的数据是不规则的。直接让稀疏矩阵在脉动阵列上运行,会引发两个问题:

5.2 流水线气泡

什么是气泡?

脉动阵列是同步流水线------每个 PE 在每个时钟周期都在工作。当某个 PE 遇到零值时,它只是跳过本次乘法 (省功耗),但仍然要消耗一个时钟周期来传递数据,以保证下游 PE 的同步。

如果跳零导致下游 PE 收到零值"空洞",这种空闲状态会像气泡一样沿流水线传播,降低整体吞吐率。

结论:跳零能省功耗,但压缩不了总时长------该占的周期一个没少,只是少干了活。

5.3 负载不均衡

什么是不均衡?

不同 PE 分到的有效数据量不同------有的 PE 全是非零值,忙不过来;有的 PE 全是零值,反复跳零。但最忙的那个 PE 决定了整列的完成时间,其他 PE 的空闲无法转化为总吞吐的提升。

结论:快 PE 等慢 PE,整个阵列被最忙的 PE 拖住。

六、总结

稀疏化是继量化之后,深度神经网络压缩与加速的第二把利刃。它与量化相辅相成:

  • 量化:把 32 位浮点数压缩成 4 位、8 位整数 → 减少数据位宽
  • 稀疏化:把不重要的权重直接置零 → 减少数据数量

两者结合,可以将模型体积和计算量压缩一个数量级以上。

参考阅读

  • 《从英伟达A100 GPU说起,浅谈细粒度结构化稀疏》
  • NVIDIA 2:4 Sparsity 技术解析
  • SMASH:软硬件协同的稀疏矩阵索引与存储机制
  • DenSparSA:兼顾稠密与稀疏的脉动阵列架构
相关推荐
-拟墨画扇-3 小时前
神经网络 | ⑬ 超参数验证:找到最佳学习超参数
深度学习·神经网络·学习
金斗潼关18 小时前
使用MLP神经网络模型预测质数
人工智能·深度学习·神经网络
Summer-Bright1 天前
AI 芯片简报 07.21-07.24:NVIDIA Vera 亮剑、AMD 2nm GPU、Google 叛逃 CoWoS
大数据·人工智能·ai·自然语言处理·芯片·agi
过期的秋刀鱼!1 天前
项目实战-神经网络预测
人工智能·神经网络·机器学习
满怀冰雪1 天前
09-使用 paddle.nn 构建第一个多层感知机
python·深度学习·神经网络·paddle
LaughingZhu1 天前
Product Hunt 每日热榜 | 2026-07-26
人工智能·深度学习·神经网络·搜索引擎·百度
JSMSEMI112 天前
JSM4480 N 沟道增强型 MOSFET
芯片
Summer-Bright2 天前
深度 | HBM4 标准急转弯:JEDEC 为什么在关键时刻「松绑」?
人工智能·语言模型·chatgpt·芯片·hbm
道影子2 天前
《黄帝内经》021章|津凝精晶 沉降为患
人工智能·深度学习·神经网络·算法·机器学习