2、稀疏化基础:稀疏化定义、类型(结构化/非结构化)、稀疏度指标与模型压缩收益
TinyML 模型部署的最大瓶颈,从来不是“精度不够”,而是“资源装不下”。一个 300KB 的模型在 PC 上运行毫无压力,但放到仅有 256KB Flash 和 64KB RAM 的 MCU 上,连加载都成问题。稀疏化(Sparsity)正是解决这一矛盾的核心手段之一:通过将模型中大量接近零的权重直接置零并跳过计算,从而同时压缩存储体积和减少推理计算量。本章将系统梳理稀疏化的数学定义、两种主流类型(结构化与非结构化)、衡量稀疏程度的指标体系,以及稀疏化带来的真实压缩收益与代价。
2.1 稀疏化的数学定义与本质
稀疏化本质上是对神经网络权重张量(Weight Tensor)或激活张量(Activation Tensor)中冗余信息的一种“剪除”操作。从线性代数角度看,一个权重矩阵 W 的稀疏度定义为:
Sparsity = (||W||₀) / (m × n)
其中 ||W||₀ 表示矩阵中非零元素的个数(L0 范数),m × n 为矩阵总元素数。稀疏度越高,意味着越多的权重被置为零。例如一个 4×4 的卷积核矩阵,若其中 12 个元素为 0,则稀疏度为 75%。
但稀疏化并非简单的“随机丢权重”。其核心依据是:神经网络在训练收敛后,大量权重值趋近于零,这些权重对最终输出的贡献微乎其微。通过将这些权重置零,我们可以在几乎不影响模型精度的前提下,获得存储和计算上的双重收益。在 TinyML 场景中,这种收益直接转化为:Flash 占用减少、RAM 峰值降低、推理延迟缩短、电池续航延长。
2.2 稀疏化类型:非结构化 vs 结构化
根据置零权重的分布模式,稀疏化分为两大类,它们在硬件友好性、压缩效率和实现难度上差异巨大。
| 对比维度 | 非结构化稀疏(Fine-grained) | 结构化稀疏(Coarse-grained) |
|---|---|---|
| 置零粒度 | 单个权重元素 | 整行、整列、整个通道或滤波器 |
| 稀疏度上限 | 可达 90%~95% | 通常 50%~75% |
| 硬件加速 | 需要专用稀疏计算单元(如 EIE、Sparse CNN 加速器) | 通用 CPU/DSP 可直接受益,无需特殊硬件 |
| 存储压缩 | 需索引编码(如 CSR/CSC),额外开销 | 可直接删除整块数据,压缩简单 |
| 精度损失 | 同等稀疏度下精度损失更小 | 同等稀疏度下精度损失更大 |
| 典型应用 | 云端大模型压缩 | TinyML 边缘设备部署 |
非结构化稀疏的典型代表是权重剪枝(Weight Pruning)。训练完成后,将绝对值小于阈值的权重直接置零。这种方式的优点是稀疏度高、精度损失小,但缺点是权重在内存中的分布变得“支离破碎”,CPU 无法连续读取有效数据,必须依赖索引表(如 CSR 格式)来定位非零元素,这反而增加了额外的存储和计算开销。在 Cortex-M 级别的 MCU 上,非结构化稀疏往往得不偿失。
结构化稀疏则完全不同。它按规则模式置零,例如将某个 3×3 卷积核的整行置零,或者将整个输出通道剪掉。这样处理后,权重矩阵仍然保持规则的矩形结构,CPU 可以连续读取数据,无需索引表。虽然稀疏度上限较低,但在实际 TinyML 部署中,结构化稀疏带来的“有效加速比”往往更高。
2.3 稀疏度指标体系:如何量化与评估
稀疏化训练过程中,我们需要一套完整的指标来监控稀疏化效果和模型健康度。仅看“全局稀疏度”远远不够,必须分层、分维度地观察。
2.3.1 核心指标定义
- 全局稀疏度(Global Sparsity):整个模型中零值权重占总权重数的比例。公式:
S_global = (总零值数) / (总权重数)。用于宏观评估压缩潜力。 - 层间稀疏度(Layer-wise Sparsity):每一层独立的稀疏度。不同层对稀疏化的敏感度差异极大,全连接层通常比卷积层更“耐剪”。
- 权重稀疏度 vs 激活稀疏度:权重稀疏度指静态参数中的零值比例;激活稀疏度指推理过程中特征图(Feature Map)中零值的动态比例。激活稀疏度往往更高(ReLU 后可达 50%+),但利用难度更大。
- 粒度(Granularity):描述稀疏模式的最小单元。细粒度(1×1 元素)、中等粒度(1×4 块)、粗粒度(整个通道)。粒度越粗,硬件加速越容易,但精度损失越大。
2.3.2 判断稀疏化质量的综合指标
仅看稀疏度数字是不够的,必须结合以下指标综合判断:
- 精度保留率:稀疏化后模型在验证集上的 Top-1/Top-5 精度与原始模型的比值。通常要求 ≥98%。
- 有效计算减少率:实际跳过的 MACs(乘加运算)比例。对于结构化稀疏,这个值约等于稀疏度;对于非结构化稀疏,需要根据硬件支持情况计算。
- 模型体积压缩比:稀疏化后模型文件大小与原始大小的比值。注意,非结构化稀疏需要额外存储索引,压缩比会打折扣。
- 推理延迟变化:在目标 MCU 上实测的推理时间变化。这是最终衡量标准。
2.4 模型压缩收益:从理论到实际部署
稀疏化的收益不能只看“参数少了多少”,必须从存储、计算、能耗三个维度综合评估。
2.4.1 存储收益(Flash 占用)
对于结构化稀疏,假设原始模型为 300KB,稀疏度为 60%,则理论上 Flash 占用可降至 120KB。但实际中,还需要考虑存储格式的开销。对于非结构化稀疏,使用 CSR 格式存储时,每个非零元素需要额外存储列索引(通常 2 字节),当稀疏度低于 70% 时,压缩收益会被索引开销大幅抵消。
// 示例:CSR 格式存储稀疏矩阵
// 原始 4×4 矩阵,稀疏度 75%(12 个零,4 个非零)
// 存储内容:
// values: [1.2, 3.4, 5.6, 7.8] // 4 个非零值
// col_idx: [0, 2, 1, 3] // 每个非零值的列号
// row_ptr: [0, 1, 2, 4] // 每行起始位置
// 总存储:4×4B + 4×2B + 4×2B = 32B
// 原始稠密存储:16×4B = 64B
// 压缩比:2:1(但稀疏度需 ≥75% 才有此效果)
2.4.2 计算收益(MACs 减少)
在 MCU 上,乘加运算(MAC)是最耗时的操作。稀疏化后,跳过的 MACs 数量直接决定推理加速比。对于结构化稀疏(如通道剪枝),加速比 ≈ 1/(1-稀疏度)。例如稀疏度 50% 时,理论加速 2 倍;稀疏度 75% 时,理论加速 4 倍。但实际中,由于内存访问瓶颈,加速比通常达不到理论值。
2.4.3 能耗收益
对于电池供电的 TinyML 设备,能耗是关键指标。跳过计算意味着减少 CPU 活动时间,从而降低动态功耗。根据实验数据,在 ARM Cortex-M4 上,稀疏度 50% 的结构化稀疏模型,推理能耗可降低约 40%。
2.5 案例拆解:8KB 模型在 Cortex-M0+ 上的稀疏化实战
下面通过一个完整的案例,展示稀疏化从设计到部署的全过程。
背景与约束:某智能传感器项目需要部署一个关键词唤醒(KWS)模型,目标硬件为 STM32L0 系列(Cortex-M0+,32MHz,Flash 64KB,RAM 8KB)。原始模型为 2 层卷积 + 2 层全连接,参数量 45,000,模型大小 180KB,远超 Flash 限制。
初始目标:将模型压缩至 32KB 以内,同时保证唤醒准确率 ≥95%(原始准确率 97.2%)。
关键参数与指标:
| 层名称 | 参数量 | 原始稀疏度 | 目标稀疏度 | 敏感度 |
|---|---|---|---|---|
| Conv1 (3×3×16) | 448 | 5% | 30% | 高 |
| Conv2 (3×3×32) | 9,248 | 8% | 50% | 中 |
| FC1 (512×128) | 65,664 | 12% | 80% | 低 |
| FC2 (128×10) | 1,290 | 10% | 60% | 中 |
分析判断过程:首先,通过逐层剪枝敏感性分析(每层单独剪枝 10%,观察精度变化),发现 FC1 层对剪枝最不敏感,而 Conv1 层最敏感。因此,决定采用“差异化稀疏度策略”:FC 层使用高稀疏度(70%~80%),Conv 层使用低稀疏度(30%~50%)。同时,考虑到 Cortex-M0+ 不支持稀疏计算指令,决定采用结构化通道剪枝而非细粒度剪枝。
实际操作步骤:
- 使用 TensorFlow 训练原始模型,达到 97.2% 准确率。
- 对 FC1 层执行通道剪枝(每个神经元对应一个输出通道),逐步将 512 个神经元剪至 128 个。
- 对 Conv2 层执行滤波器剪枝,将 32 个滤波器剪至 16 个。
- 剪枝后微调(Fine-tune)5 个 epoch,学习率设为原训练时的 1/10。
- 量化至 int8 后,模型大小降至 28KB。
结果对比:
| 指标 | 原始模型 | 稀疏化+量化后 | 变化 |
|---|---|---|---|
| 模型大小 | 180KB | 28KB | ↓84% |
| 准确率 | 97.2% | 95.8% | ↓1.4% |
| 推理时间 | 无法运行 | 38ms | 满足实时性 |
| RAM 占用 | 无法运行 | 6.2KB | 满足 8KB 限制 |
风险与代价:结构化剪枝导致 Conv1 层信息丢失较多,准确率下降超出预期。通过将 Conv1 的剪枝率从 30% 降至 20%,并增加一个 epoch 的微调,最终准确率回升至 96.1%。代价是模型大小增加 2KB。
复盘经验:在 TinyML 场景中,结构化稀疏 + 量化的组合远比单一非结构化稀疏有效。稀疏化训练必须与目标硬件协同设计,不能脱离硬件谈稀疏度。此外,逐层敏感度分析是稀疏化训练 schedule 设计的第一步,它决定了各层稀疏度的分配策略。
2.6 常见误区与总结
稀疏化基础阶段,以下误区需要特别警惕:
- 误区一:稀疏度越高越好。实际上,超过一定阈值后,精度会急剧下降,且硬件加速收益趋于饱和。建议在 TinyML 中,非结构化稀疏度不超过 85%,结构化稀疏度不超过 70%。
- 误区二:忽略索引开销。非结构化稀疏在存储时,索引表可能占据 30%~50% 的额外空间。计算“有效压缩比”时,必须将索引计入。
- 误区三:只看权重稀疏度,不看激活稀疏度。在 TinyML 中,激活稀疏度对计算加速同样重要,尤其是在使用 ReLU 的模型中。
- 误区四:所有层使用相同的稀疏度。不同层对稀疏化的敏感度差异巨大,必须差异化设计。
总结而言,稀疏化是 TinyML 模型压缩的基石。理解其定义、类型、指标和收益,是后续设计稀疏化训练 schedule 的前提。下一阶段,我们将深入探讨如何在训练过程中动态控制稀疏度,以及如何设计合理的 schedule 策略。