第3章:稀疏化与结构化稀疏

章节大纲

本章深入探讨神经网络稀疏化技术在低功耗AI推理芯片中的应用。稀疏化通过将神经网络中的大量权重或激活值设置为零,显著减少计算量和存储需求,是实现高能效推理的关键技术之一。我们将从稀疏的数学基础出发,系统介绍各种稀疏模式、硬件支持机制,以及在实际芯片设计中的权衡考虑。通过NVIDIA Ampere架构的深入分析,读者将理解如何在硬件层面高效支持稀疏计算。

学习目标:

  • 掌握稀疏化的数学原理和能效优势
  • 理解结构化稀疏与非结构化稀疏的权衡
  • 学习稀疏数据的存储格式和索引机制
  • 分析硬件加速器对稀疏计算的支持策略
  • 探索动态稀疏和自适应计算的前沿技术

3.1 稀疏的数学基础

3.1.1 稀疏性定义与度量

稀疏性是指矩阵或张量中零元素所占的比例。对于一个矩阵 $\mathbf{W} \in \mathbb{R}^{m \times n}$,其稀疏度定义为:

$$s = \frac{\text{number of zero elements}}{m \times n} = 1 - \frac{|\mathbf{W}|_0}{m \times n}$$ 其中 $|\mathbf{W}|_0$ 表示矩阵中非零元素的个数(L0范数)。

3.1.2 稀疏矩阵向量乘法的计算复杂度

考虑稠密矩阵向量乘法 $\mathbf{y} = \mathbf{W}\mathbf{x}$,其中 $\mathbf{W} \in \mathbb{R}^{m \times n}$,$\mathbf{x} \in \mathbb{R}^n$。

  • 稠密计算:需要 $m \times n$ 次乘法和 $m \times (n-1)$ 次加法
  • 稀疏计算:设稀疏度为 $s$,则仅需要 $(1-s) \times m \times n$ 次乘法

功耗节省比例近似为: $$\text{Power Saving} \approx s \times P_{\text{MAC}}$$ 其中 $P_{\text{MAC}}$ 是单个乘累加操作的功耗。

3.1.3 稀疏化的信息论视角

从信息论角度,稀疏性可以通过熵来量化。对于权重分布 $p(w)$,其微分熵为: $$H(W) = -\int p(w) \log p(w) dw$$ 稀疏分布(如Laplace分布)比高斯分布具有更低的熵,意味着可以用更少的比特编码,从而降低存储和传输功耗。

3.1.4 稀疏正则化与诱导技术

在训练阶段引入稀疏正则化可以诱导网络权重稀疏化:

L1正则化(LASSO): $$\mathcal{L}_{\text{total}} = \mathcal{L}_{\text{task}} + \lambda \sum_{i,j} |w_{ij}|$$ L0正则化近似: 由于L0范数不可微,实践中常用可微近似,如: $$|\mathbf{W}|_0 \approx \sum_{i,j} \sigma\left(\frac{|w_{ij}| - \tau}{\epsilon}\right)$$ 其中 $\sigma$ 是sigmoid函数,$\tau$ 是阈值,$\epsilon$ 控制近似精度。

3.1.5 稀疏化的数值稳定性

稀疏化后的数值计算需要考虑:

  1. 条件数变化:稀疏化可能增加矩阵条件数 $$\kappa(\mathbf{W}_{\text{sparse}}) = \frac{\sigma_{\max}(\mathbf{W}_{\text{sparse}})}{\sigma_{\min}(\mathbf{W}_{\text{sparse}})}$$

  2. 梯度流动:过度稀疏可能导致梯度消失 $$\frac{\partial \mathcal{L}}{\partial w_{ij}} = 0, \quad \text{if } w_{ij} = 0$$

  3. 量化误差累积:稀疏化与量化结合时的误差分析 $$\mathbf{e}_{\text{total}} = \mathbf{e}_{\text{sparse}} + \mathbf{e}_{\text{quant}} + \mathbf{e}_{\text{sparse}} \otimes \mathbf{e}_{\text{quant}}$$

3.1.6 稀疏化的能效模型

稀疏计算的能效提升来源于三个方面:

  1. 计算能耗降低: $$E_{\text{compute}} = (1-s) \times N_{\text{ops}} \times E_{\text{MAC}}$$ 其中 $N_{\text{ops}}$ 是总操作数,$E_{\text{MAC}}$ 是单个MAC操作能耗(典型值:45nm工艺下约0.9pJ)

  2. 数据移动能耗降低: $$E_{\text{memory}} = (1-s) \times N_{\text{weights}} \times E_{\text{access}}$$ 不同存储层次的访问能耗:

  • 寄存器文件:~0.1 pJ
  • L1 Cache:~0.5 pJ
  • L2 Cache:~5 pJ
  • DRAM:~100 pJ
  1. 索引开销: $$E_{\text{overhead}} = N_{\text{nz}} \times (E_{\text{idx_store}} + E_{\text{idx_compute}})$$ 其中 $N_{\text{nz}}$ 是非零元素数量。

净能效增益: $$\text{Energy Efficiency Gain} = \frac{E_{\text{dense}}}{E_{\text{sparse}}} = \frac{E_{\text{dense}}}{(1-s) \times E_{\text{dense}} + E_{\text{overhead}}}$$ 当稀疏度 $s > 0.5$ 且采用高效索引格式时,通常可获得1.5-3倍的能效提升。


3.2 2:4结构化稀疏及硬件支持

3.2.1 2:4稀疏模式定义

2:4结构化稀疏是NVIDIA在Ampere架构中引入的一种细粒度结构化稀疏模式。其核心约束是:在每连续的4个元素中,恰好有2个为零

数学表示: $$\forall i \in \{0, 4, 8, ...\}: \sum_{j=i}^{i+3} \mathbb{1}[w_j \neq 0] = 2$$ 这种模式提供50%的稀疏度,同时保持规则的访问模式,便于硬件实现。

3.2.2 2:4稀疏的硬件实现优势

稠密权重布局:
[w0, w1, w2, w3, w4, w5, w6, w7, ...]

2:4稀疏权重布局(示例):
[w0, 0, w2, 0, 0, w5, w6, 0, ...]

压缩存储:
值: [w0, w2, w5, w6, ...]
索引: [0b1010, 0b0110, ...] (每4位表示一个2:4模式)

硬件优势

  1. 固定压缩率:恰好2:1压缩,简化内存管理
  2. 规则索引:每组4个元素仅需3位索引(C(4,2)=6种模式)
  3. 向量化友好:适合SIMD执行单元
  4. 流水线效率:固定的稀疏模式便于流水线调度

3.2.3 2:4稀疏训练算法

训练2:4稀疏网络的关键是在保持精度的同时强制执行结构化约束:

SR-STE (Straight-Through Estimator with Sparse Refinement)

算法流程:

1. 前向传播:应用2:4掩码
   W_sparse = W ⊙ M_2:4

2. 计算梯度:
   ∇W = ∂L/∂W_sparse

3. 权重更新:
   W = W - η∇W

4. 重新稀疏化:
   对每组4个权重,保留绝对值最大的2个
   M_2:4 = top2_per_4(|W|)

渐进式稀疏化策略: $$s(t) = s_{\text{final}} \left(1 - \left(1 - \frac{t}{T}\right)^3\right)$$ 其中 $t$ 是当前训练步骤,$T$ 是总训练步骤,立方调度避免训练初期过度稀疏。

3.2.4 硬件加速器设计

2:4稀疏张量核心的微架构设计:

     激活输入 (Dense)
          ↓
    ┌─────────────┐
    │  索引解码器  │ ← 3-bit索引
    └─────────────┘
          ↓
    ┌─────────────┐
    │ 选择器网络  │ ← 压缩权重
    └─────────────┘
          ↓
    ┌─────────────┐
    │  MAC阵列    │ (仅计算非零)
    └─────────────┘
          ↓
    ┌─────────────┐
    │  累加树     │
    └─────────────┘
          ↓
       部分和输出

关键设计参数

  • 选择器延迟:1个时钟周期
  • 有效吞吐量:2× 稠密张量核心
  • 面积开销:约15%(主要是选择器和索引逻辑)
  • 功耗节省:约30-45%(取决于数据局部性)

3.2.5 精度影响与补偿技术

2:4稀疏化通常导致0.5-2%的精度损失,可通过以下技术补偿:

  1. 通道级缩放因子: $$\mathbf{W}_{\text{compensated}} = \mathbf{W}_{\text{sparse}} \odot \boldsymbol{\alpha}$$ 其中 $\boldsymbol{\alpha}$ 是可学习的per-channel缩放因子

  2. 知识蒸馏: $$\mathcal{L} = \mathcal{L}_{\text{task}} + \lambda \text{KL}(p_{\text{student}} || p_{\text{teacher}})$$

  3. 混合精度补偿: 关键层保持稠密,非关键层应用2:4稀疏


3.3 块稀疏与向量稀疏

3.3.1 块稀疏模式

块稀疏将权重矩阵划分为固定大小的块,以块为单位进行稀疏化: $$\mathbf{W} = \sum_{i,j} \mathbf{B}_{ij} \otimes \mathbf{M}_{ij}$$ 其中 $\mathbf{B}_{ij}$ 是大小为 $b \times b$ 的权重块,$\mathbf{M}_{ij} \in \{0,1\}$ 是块级掩码。

常见块大小选择

  • 4×4:平衡精度和硬件效率
  • 8×8:适合Tensor Core等矩阵单元
  • 16×16:最大化数据重用

3.3.2 块稀疏的硬件映射

块稀疏特别适合脉动阵列和矩阵处理单元:

块稀疏矩阵乘法数据流:

   稠密激活矩阵 A              块稀疏权重 W
   ┌───┬───┬───┐            ┌───┬───┬───┐
   │B00│B01│B02│            │B00│ 0 │B02│
   ├───┼───┼───┤            ├───┼───┼───┤
   │B10│B11│B12│     ×      │ 0 │B11│ 0 │
   ├───┼───┼───┤            ├───┼───┼───┤
   │B20│B21│B22│            │B20│ 0 │B22│
   └───┴───┴───┘            └───┴───┴───┘

硬件执行:仅计算非零块的矩阵乘法

功耗模型: $$E_{\text{block-sparse}} = N_{\text{nz-blocks}} \times (E_{\text{block-mult}} + E_{\text{block-load}})$$ 其中:

  • $N_{\text{nz-blocks}}$:非零块数量
  • $E_{\text{block-mult}}$:单个块乘法能耗
  • $E_{\text{block-load}}$:块数据加载能耗

3.3.3 向量稀疏(Column/Row Pruning)

向量稀疏通过删除整行或整列来实现结构化稀疏:

列稀疏(输出通道剪枝): $$\mathbf{W}_{\text{col-sparse}} = \mathbf{W} \cdot \text{diag}(\mathbf{m})$$ 其中 $\mathbf{m} \in \{0,1\}^n$ 是列选择掩码

行稀疏(输入通道剪枝): $$\mathbf{W}_{\text{row-sparse}} = \text{diag}(\mathbf{m}) \cdot \mathbf{W}$$ 硬件优势

  1. 连续内存访问:无需复杂的间接寻址
  2. SIMD友好:可直接跳过整个向量操作
  3. 缓存效率高:改善空间局部性

3.3.4 混合稀疏模式

实际系统常结合多种稀疏模式以平衡效率和精度:

层级稀疏结构:
Level 1: 向量稀疏(粗粒度)
         删除不重要的通道
         ↓
Level 2: 块稀疏(中粒度)
         在保留通道内进行块剪枝
         ↓
Level 3: 2:4稀疏(细粒度)
         在非零块内应用2:4模式

联合优化目标: $$\min_{\mathbf{W}, \mathbf{M}} \mathcal{L}(\mathbf{W} \odot \mathbf{M}) + \lambda_1 |\mathbf{M}_{\text{vec}}|_0 + \lambda_2 |\mathbf{M}_{\text{block}}|_0 + \lambda_3 |\mathbf{M}_{2:4}|_0$$

3.3.5 自适应块大小选择

根据层特性动态选择块大小:

选择准则

  1. 计算密度: $$\text{Block Size} \propto \sqrt{\frac{\text{Output Channels}}{\text{Input Channels}}}$$

  2. 激活稀疏度: 高激活稀疏度 → 小块尺寸 低激活稀疏度 → 大块尺寸

  3. 硬件约束: 块大小应匹配硬件处理单元的粒度(如Tensor Core的16×16)


3.4 稀疏索引与存储格式

3.4.1 经典稀疏存储格式

COO (Coordinate)格式

值数组:    [9, 8, 4, 2, 5, 3]
行索引:    [0, 0, 1, 2, 2, 3]
列索引:    [0, 3, 1, 0, 2, 3]

存储开销:3N(N为非零元素数)

CSR (Compressed Sparse Row)格式

值数组:    [9, 8, 4, 2, 5, 3]
列索引:    [0, 3, 1, 0, 2, 3]
行指针:    [0, 2, 3, 5, 6]

存储开销:2N + M + 1(M为行数)

BCSR (Block CSR)格式: 将矩阵分块后使用CSR存储非零块,适合块稀疏:

块值数组:  [[B00], [B02], [B11], [B20], [B22]]
块列索引:  [0, 2, 1, 0, 2]
块行指针:  [0, 2, 3, 5]

3.4.2 硬件友好的索引格式

位图(Bitmap)索引

原始矩阵:     位图表示:
[9 0 0 8]     [1 0 0 1]
[0 4 0 0]     [0 1 0 0]
[2 0 5 0]     [1 0 1 0]
[0 0 0 3]     [0 0 0 1]

压缩值: [9, 8, 4, 2, 5, 3]
位图:   0x9214 (16-bit)

优势

  • 固定大小索引,便于硬件流水线
  • 支持快速位运算(popcount计算非零数)
  • 缓存行对齐友好

RLC (Run-Length Coding)索引

稀疏向量: [0, 0, 5, 0, 0, 0, 3, 0, 2]
RLC编码: [(2, 5), (3, 3), (1, 2)]
格式: (零的个数, 非零值)

适合高稀疏度(>90%)的场景。

3.4.3 分层索引结构

针对大规模稀疏矩阵的多级索引:

Level 0: 超块索引(32×32)
         ┌───┬───┬───┬───┐
         │ 1 │ 0 │ 1 │ 0 │
         ├───┼───┼───┼───┤
         │ 0 │ 1 │ 0 │ 1 │
         └───┴───┴───┴───┘

Level 1: 块索引(8×8)
         对每个非零超块,记录内部块分布

Level 2: 元素索引(标量)
         对每个非零块,使用位图或2:4索引

访问延迟模型: $$T_{\text{access}} = T_{\text{L0}} + p_{\text{L1}} \times T_{\text{L1}} + p_{\text{L2}} \times T_{\text{L2}}$$ 其中 $p_{\text{Li}}$ 是访问第i级索引的概率。

3.4.4 动态索引压缩

根据稀疏模式动态选择最优索引格式:

索引选择算法
if 稀疏度 < 50%:
    使用位图索引
elif 稀疏度 < 75%:
    使用CSR格式
elif 稀疏度 < 90%:
    使用COO格式
else:
    使用RLC编码

自适应索引的能耗模型: $$E_{\text{index}} = E_{\text{decode}} + E_{\text{fetch}} \times \text{Index Size}$$

3.4.5 索引缓存优化

专用索引缓存设计:

    ┌──────────────┐
    │ 索引TLB      │ (快速索引转换)
    └──────────────┘
           ↓
    ┌──────────────┐
    │ 索引Cache    │ (缓存热点索引)
    │  - 位图行    │
    │  - CSR指针   │
    └──────────────┘
           ↓
    ┌──────────────┐
    │ 索引预取器   │ (预测性加载)
    └──────────────┘

缓存命中率优化

  • 空间局部性:按行/列连续存储索引
  • 时间局部性:LRU替换策略
  • 预取策略:基于访问模式的stride预取

3.5 工业界案例:NVIDIA Ampere稀疏张量核心

3.5.1 Ampere架构稀疏计算概览

NVIDIA A100 GPU引入了第三代Tensor Core,首次支持细粒度结构化稀疏:

关键规格

  • 稀疏模式:2:4结构化稀疏
  • 理论加速:2×稠密Tensor Core性能
  • 支持精度:FP16, BF16, TF32, INT8, INT4
  • 峰值性能:312 TFLOPS (FP16稀疏)

3.5.2 稀疏Tensor Core微架构

稀疏Tensor Core数据路径:

输入准备阶段:
┌─────────────────────────────────┐
│  稀疏权重解压缩单元              │
│  - 2:4索引解码                  │
│  - 数据重排序                   │
└─────────────────────────────────┘
              ↓
计算阶段:
┌─────────────────────────────────┐
│  4×4×4 MMA单元阵列              │
│  ┌───┬───┬───┬───┐             │
│  │FMA│FMA│ 0 │ 0 │ (稀疏)     │
│  ├───┼───┼───┼───┤             │
│  │ 0 │FMA│FMA│ 0 │             │
│  └───┴───┴───┴───┘             │
└─────────────────────────────────┘
              ↓
累加阶段:
┌─────────────────────────────────┐
│  累加器 (FP32)                   │
│  - 部分和累加                   │
│  - 舍入与饱和                   │
└─────────────────────────────────┘

3.5.3 稀疏性检测与压缩硬件

硬件压缩流水线

  1. 稀疏模式检测器:识别2:4模式
  2. 压缩器:生成压缩数据和索引
  3. 验证单元:确保符合2:4约束
原始数据 → [检测] → [选择top-2] → [压缩] → 稀疏数据
   ↓                                           ↓
延迟: 2 cycles                          索引: 2-bit

3.5.4 软件栈支持

cuSPARSELt库API

// 创建2:4稀疏矩阵描述符
cusparseLtMatDescriptor_t mat_A;
cusparseLtStructuredDescriptorInit(&mat_A, 
    rows, cols, lda, alignment,
    CUSPARSE_ORDER_ROW,
    CUSPARSELT_SPARSITY_50_PERCENT);

// 剪枝与压缩
cusparseLtSpMMAPrune(&handle, &matmul,
    d_A, d_A_pruned, 
    CUSPARSELT_PRUNE_SPMMA_STRIP);

// 稀疏矩阵乘法
cusparseLtMatmul(&handle, &plan, 
    &alpha, d_A_compressed, d_B,
    &beta, d_C, d_D);

3.5.5 性能与功耗分析

实测性能数据(A100 40GB)

| 工作负载 | 稠密TFLOPS | 稀疏TFLOPS | 加速比 | 功耗节省 |

工作负载 稠密TFLOPS 稀疏TFLOPS 加速比 功耗节省
BERT-Large 156 289 1.85× 35%
ResNet-50 143 251 1.75× 32%
GPT-2 162 298 1.84× 38%

功耗分解

稠密Tensor Core (250W TDP):

- 计算核心: 150W (60%)
- 内存访问: 70W (28%)
- 其他: 30W (12%)

稀疏Tensor Core:

- 计算核心: 85W (-43%)
- 内存访问: 45W (-36%)
- 索引处理: 15W (新增)
- 其他: 30W
总计: 175W (-30%)

3.5.6 优化策略与最佳实践

  1. 层选择策略: - 优先稀疏化计算密集层(GEMM占比>80%) - 保持首尾层稠密以维持精度

  2. 批处理优化

最优batch size = L2_cache_size / (2 × 矩阵大小)
  1. 混合精度策略: - 权重:INT8 + 2:4稀疏 - 激活:FP16稠密 - 累加:FP32

  2. 内存布局优化: - 使用NCHW_32格式对齐Tensor Core - 权重预压缩并缓存


3.6 高级话题:动态稀疏与自适应计算图

3.6.1 动态稀疏的概念与动机

动态稀疏是指稀疏模式随输入数据变化的计算范式,与静态稀疏(固定权重稀疏)形成对比:

静态稀疏 vs 动态稀疏

静态稀疏(权重):
W_sparse = W ⊙ M_static  (M在部署时固定)

动态稀疏(激活):
A_sparse = A ⊙ M_dynamic(A)  (M依赖于输入A)

联合稀疏:
Y = (W ⊙ M_w) × (A ⊙ M_a)

动态稀疏的优势

  • 自适应计算量:简单样本使用更少计算
  • 更高的实际稀疏度:激活稀疏度通常达70-90%
  • 能效优化潜力:可节省50-80%的动态功耗

3.6.2 激活稀疏性的特征

ReLU诱导的自然稀疏: $$\text{Sparsity}(\text{ReLU}(x)) = P(x < 0) \approx 50\%$$ 层深度与稀疏度关系

Layer 1:  ~30% 稀疏
Layer 5:  ~50% 稀疏
Layer 10: ~70% 稀疏
Layer 20: ~85% 稀疏

空间相关性: 激活稀疏具有强空间聚类特性,可用于预测和优化。

3.6.3 动态稀疏的硬件挑战

  1. 不规则内存访问: - 无法预知的访问模式 - 缓存命中率下降 - 内存带宽利用率低

  2. 负载不均衡

PE0: 处理20个非零元素
PE1: 处理80个非零元素
PE2: 处理35个非零元素
PE3: 处理10个非零元素
  1. 控制开销: - 动态调度逻辑复杂 - 同步开销增加

3.6.4 自适应计算图优化

早期退出(Early Exit)机制

                  输入
                    ↓
            ┌───────────────┐
            │   Layer 1     │
            └───────┬───────┘
                    ↓
            ┌───────────────┐
            │  置信度检查   │→ 高置信度 → 输出
            └───────┬───────┘
                    ↓ 低置信度
            ┌───────────────┐
            │   Layer 2     │
            └───────┬───────┘
                    ↓
                  继续...

条件计算(Conditional Computation): $$y = \sum_{i=1}^{N} g_i(x) \cdot f_i(x)$$ 其中 $g_i(x) \in \{0,1\}$ 是门控函数,决定是否执行 $f_i(x)$。

3.6.5 稀疏预测与投机执行

稀疏模式预测器

预测算法

1. 历史模式缓存存储最近K个输入的稀疏模式
2. 相似度匹配计算当前输入与历史的相似度
3. 模式预测基于最相似的历史预测稀疏位置
4. 投机执行预取预测的非零元素

预测准确率与能效权衡: $$E_{\text{total}} = E_{\text{compute}} + E_{\text{mispred}} \times \text{Misprediction Rate}$$

3.6.6 动态稀疏加速器架构

自适应处理单元设计

    ┌─────────────────────────┐
    │   稀疏检测单元          │
    │   - 阈值比较器          │
    │   - 稀疏度估计器        │
    └────────┬────────────────┘
             ↓
    ┌─────────────────────────┐
    │   工作分配器            │
    │   - 动态负载均衡        │
    │   - 工作窃取队列        │
    └────────┬────────────────┘
             ↓
    ┌─────────────────────────┐
    │   可重构计算阵列        │
    │   ┌──┬──┬──┬──┐        │
    │   │PE│PE│PE│PE│        │
    │   ├──┼──┼──┼──┤        │
    │   │PE│PE│──│──│(关闭)  │
    │   └──┴──┴──┴──┘        │
    └─────────────────────────┘

动态功耗管理策略

  1. 细粒度时钟门控:基于稀疏度动态关闭PE
  2. 电压频率调节:根据工作负载调整DVFS
  3. 功耗预算分配:在计算和内存间动态分配功耗

3.6.7 未来研究方向

  1. 神经架构搜索(NAS)for 稀疏性: 自动设计稀疏友好的网络结构

  2. 混合精度动态稀疏: 结合量化和稀疏的自适应策略

  3. 跨层稀疏优化: 利用层间稀疏模式相关性

  4. 稀疏Transformer优化: 针对注意力机制的动态稀疏模式


本章小结

本章系统介绍了稀疏化技术在低功耗AI推理芯片中的应用。我们从稀疏的数学基础出发,深入探讨了各种结构化稀疏模式,特别是2:4细粒度稀疏的硬件实现。通过NVIDIA Ampere架构的案例分析,展示了工业界如何在保持高性能的同时实现显著的功耗降低。

关键要点

  1. 稀疏度与能效的关系:50%以上的稀疏度通常可带来1.5-3倍的能效提升
  2. 结构化vs非结构化权衡:结构化稀疏牺牲一定灵活性换取硬件友好性
  3. 索引开销的重要性:高效的索引格式是稀疏计算成功的关键
  4. 动静结合策略:权重静态稀疏+激活动态稀疏的协同优化
  5. 软硬件协同设计:稀疏化需要算法、编译器和硬件的紧密配合

核心公式汇总

  • 稀疏度定义:$s = 1 - \frac{|\mathbf{W}|_0}{m \times n}$
  • 能效增益:$\text{Gain} = \frac{E_{\text{dense}}}{(1-s) \times E_{\text{dense}} + E_{\text{overhead}}}$
  • 2:4约束:$\forall i: \sum_{j=i}^{i+3} \mathbb{1}[w_j \neq 0] = 2$
  • 动态稀疏:$Y = (W \odot M_w) \times (A \odot M_a)$

练习题

基础题

练习3.1:计算稀疏矩阵的存储效率 给定一个100×100的矩阵,稀疏度为80%,分别计算使用COO、CSR和位图格式的存储开销(假设每个非零元素占4字节,索引占2字节)。

Hint: 考虑每种格式需要存储的元素数量和索引数量

答案
  • 非零元素数:100×100×(1-0.8) = 2000
  • COO格式:值(2000×4) + 行索引(2000×2) + 列索引(2000×2) = 16000字节
  • CSR格式:值(2000×4) + 列索引(2000×2) + 行指针(101×2) = 12202字节
  • 位图格式:值(2000×4) + 位图(100×100/8) = 9250字节
  • 位图格式在高稀疏度下最优

练习3.2:2:4稀疏模式计数 在一个长度为8的向量中,有多少种不同的2:4稀疏模式?

Hint: 将向量分成两组,每组4个元素

答案
  • 每组4个元素选2个非零:C(4,2) = 6种
  • 两组独立:6 × 6 = 36种
  • 总共36种不同的2:4稀疏模式

练习3.3:稀疏矩阵乘法复杂度 两个n×n矩阵相乘,A的稀疏度为70%,B的稀疏度为60%,估算稀疏矩阵乘法相对于稠密矩阵乘法的计算量比例。

Hint: 考虑实际需要计算的乘法数量

答案
  • 稠密计算:n³次乘法
  • A的非零元素:0.3n²
  • 对A的每个非零元素,与B的对应行相乘
  • B每行非零元素:0.4n
  • 稀疏计算:0.3n² × 0.4n = 0.12n³
  • 计算量比例:12%

练习3.4:块稀疏的最优块大小 给定一个512×512的权重矩阵,目标稀疏度50%,硬件支持4×4和8×8的矩阵乘法单元。分析选择哪种块大小更优。

Hint: 考虑精度损失、硬件利用率和索引开销

答案
  • 4×4块:总块数(512/4)² = 16384,非零块8192
  • 索引开销:16384位 = 2KB
  • 精度损失较小,灵活性高
  • 8×8块:总块数(512/8)² = 4096,非零块2048
  • 索引开销:4096位 = 512B
  • 硬件利用率更高,但精度损失较大
  • 推荐4×4:平衡精度和效率

挑战题

练习3.5:混合稀疏策略设计 设计一个针对ResNet-50的层级稀疏策略,包括:(a)哪些层使用2:4稀疏;(b)哪些层使用块稀疏;(c)哪些层保持稠密。说明你的设计理由。

Hint: 考虑不同层的计算密度、参数量和对精度的影响

答案

策略设计:

  1. 第一层卷积:保持稠密(特征提取关键)
  2. 残差块主路径:2:4稀疏(计算密集,规则性强)
  3. 1×1卷积(瓶颈层):块稀疏4×4(通道压缩)
  4. 跳跃连接:保持稠密(梯度流动重要)
  5. 全连接层:向量稀疏(参数量大)

理由:

  • 早期层影响大,稀疏度应较低
  • 中间层计算密集,适合规则稀疏
  • 后期层参数多,可承受高稀疏度

练习3.6:动态稀疏的能效建模 建立一个考虑预测准确率的动态稀疏能效模型。假设:正确预测节省80%能耗,错误预测增加20%能耗,预测器本身消耗5%能耗。求预测准确率需要达到多少才能实现净收益?

Hint: 建立能耗期望值公式

答案

设预测准确率为p,基准能耗为E:

  • 正确预测能耗:0.2E
  • 错误预测能耗:1.2E
  • 预测器开销:0.05E

总能耗期望: E_total = p×0.2E + (1-p)×1.2E + 0.05E = 0.2pE + 1.2E - 1.2pE + 0.05E = 1.25E - pE

净收益条件:E_total < E 1.25E - pE < E p > 0.25

预测准确率需要超过25%才有净收益

练习3.7:稀疏索引压缩算法 设计一个自适应索引压缩算法,根据稀疏模式的局部特征动态选择COO、CSR或RLC编码。给出选择策略和切换开销分析。

Hint: 考虑稀疏模式的聚类特性和编码效率

答案

自适应算法:

对每个32×32子矩阵:

1. 计算稀疏度s和聚类度c
2. if s < 0.5: 使用位图
3. elif c > 0.8: 使用RLC(高聚类)
4. elif 行稀疏方差小: 使用CSR
5. else: 使用COO

切换开销:

- 元数据:每个子矩阵2位编码类型
- 边界处理:4个边界元素额外索引
- 解码器:4种解码路径,增加15%面积

效率分析:

  • 平均压缩率提升25%
  • 解码延迟增加1-2周期
  • 适合大规模稀疏矩阵

练习3.8:稀疏Transformer优化 针对BERT模型的注意力矩阵(通常稀疏度>95%),设计一个专用的稀疏计算单元。要求支持动态稀疏模式,并给出功耗估算。

Hint: 利用注意力矩阵的特殊结构(局部性、因果性)

答案

设计方案:

  1. 分块注意力:将N×N分成√N个块
  2. Top-K稀疏:每行保留K个最大值
  3. 局部窗口:对角线附近w个元素稠密

硬件单元:

输入缓冲 → Top-K选择器 → 局部计算单元
         ↓                ↓
    稀疏索引生成器    块稀疏MAC阵列
         ↓                ↓
      索引缓存        部分和累加器

功耗估算(相对于稠密):

  • Top-K选择:5%
  • 稀疏计算:95%×5% = 4.75%
  • 索引处理:3%
  • 控制逻辑:2%
  • 总计:~15%(85%功耗节省)

常见陷阱与错误

陷阱1:过度追求稀疏度

问题:盲目提高稀疏度导致精度急剧下降 解决

  • 使用渐进式稀疏化
  • 保护关键层(首尾层)
  • 结合知识蒸馏恢复精度

陷阱2:忽视索引开销

问题:复杂的索引格式抵消了稀疏带来的收益 解决

  • 选择硬件友好的索引格式
  • 使用结构化稀疏减少索引
  • 批量处理摊薄索引开销

陷阱3:负载不均衡

问题:稀疏分布不均导致处理单元利用率低 解决

  • 使用工作窃取调度
  • 结构化稀疏保证均匀分布
  • 动态负载均衡机制

陷阱4:缓存性能下降

问题:不规则访问模式导致缓存命中率低 解决

  • 数据重排提高局部性
  • 专用稀疏数据缓存
  • 预取优化

陷阱5:训练-推理不匹配

问题:训练时的稀疏模式与推理硬件不匹配 解决

  • 硬件感知训练
  • 推理时fine-tuning
  • 可重构稀疏模式

最佳实践检查清单

算法层面

  • [ ] 选择合适的稀疏模式(结构化vs非结构化)
  • [ ] 确定每层的目标稀疏度
  • [ ] 实施渐进式稀疏化策略
  • [ ] 应用知识蒸馏或其他精度恢复技术
  • [ ] 验证稀疏模型的精度满足要求

硬件设计

  • [ ] 评估不同索引格式的开销
  • [ ] 设计高效的稀疏检测单元
  • [ ] 实现负载均衡机制
  • [ ] 优化数据通路减少零值传输
  • [ ] 添加稀疏度自适应的功耗管理

系统集成

  • [ ] 编译器支持稀疏模式识别
  • [ ] 运行时稀疏度监控
  • [ ] 动态稀疏模式切换
  • [ ] 性能分析工具集成
  • [ ] 功耗profiling支持

验证测试

  • [ ] 不同稀疏度下的精度测试
  • [ ] 极端稀疏模式的鲁棒性测试
  • [ ] 动态稀疏的响应时间测试
  • [ ] 功耗测量与模型对比
  • [ ] 与稠密基准的性能对比

部署优化

  • [ ] 模型压缩与稀疏化联合优化
  • [ ] 批处理策略优化
  • [ ] 内存带宽利用率监控
  • [ ] 热点分析与优化
  • [ ] 持续性能监控机制