Archipelago

Lec 24加速器(二)(Accelerators II)

讲义完成更新于 2026-09-30
后续

当前课程暂无后续已收录内容。

Lec 24 加速器(二)(Accelerators II)

MIT 6.5900 Fall 2024 · Joel Emer 主题:稀疏张量(Sparse Tensors)、纤维树抽象(Fibertree)、张量表示与遍历、稀疏加速三特性(Format / Gating / Skipping)、稀疏卷积数据流、FuseMax

TL;DR

  • 稀疏加速三特性:利用张量稀疏性实现能效突破的核心手段为表示格式(Format 节省存储)、时钟门控(Gating 消除无效计算功耗)与周期跳过(Skipping 压缩计算周期)。
  • 纤维树(Fibertree)抽象:将多维稀疏张量统一建模为分层纤维树,通过坐标列表与段指针表示稀疏数据,将张量代数自然规约为坐标投影、纤维求交(&)与归约原语。
  • 数据流与算子融合演进:稀疏卷积利用空间切分(Split Equal)与双边跳零消除无效访存;注意力机制通过在线 Softmax 融合(FuseMax)将多次访存合并为单趟(1-pass)流式计算。

一、稀疏性与其价值

许多问题使用稀疏张量([ExTensor, Hegde et al., MICRO 2019])。利用稀疏性的收益:

  • 稀疏数据可压缩 → 节省空间与能量(避免操作零值):
a×0=0,a+0=aa \times 0 = 0, \qquad a + 0 = a
  • 可节省时间与能量:避免取无用操作数、避免无效计算(ineffectual computation)。

DNN 中的动机

利用 CNN 稀疏性提升能效。以 AlexNet 为例,各卷积层的激活(IA)与权重(W)密度都明显低于 1,乘法工作量随之下降([SCNN, Parashar et al., ISCA 2017])。

可利用的稀疏度

可接受的稀疏度取决于目标任务与误差容忍(MLPerf 误差容忍):

模型≤0%≤1%≤2%
ResNet-50~90%~90%~91%
AlexNet~93%
VGG-16~80%~88%~92%
MobileNet V1~72%~79%~82%
Inception V3~50%~62%~73%
MobileNet V2~25%

误差容忍越大,可剪掉的稀疏度越高([Hoefler et al., arXiv 2021])。


二、硬件稀疏加速三特性

特性含义
格式(Format)选择张量表示,节省与零访问相关的存储空间与能量
门控(Gating)显式消除无效的存储访问与计算——让硬件单元空闲一拍以省能量(省能不省时间)
跳过(Skipping)显式消除无效的存储访问与计算——跳过该拍,同时省能量与时间

三、张量表示与纤维树抽象

张量术语回顾

每个 rank(维度)的元素由坐标标识;每个元素由各 rank 坐标的元组(即一个点)标识,如 (1,2)→f(1,2) \to f;形状记 [0,3)[0,3)。

树形张量抽象(Tree-based)

把张量组织成一棵树:从 Root 出发,按 rank 逐层下降,每层节点带坐标,叶子是值。

纤维树抽象(Fibertree)

  • 每个坐标引用一个纤维(fiber);
  • 查找点 (2,1)(2,1):getPayload(2) 再 getPayload(1) 逐层下降;
  • 稀疏时:树中只保留非零元素对应的纤维与坐标,零值不占位。

四、张量遍历(Tensor Traversal)

2-D 遍历(抽象写法)

t = Tensor(H, W)
sum = 0
for (h, t_h) in t:
    for (w, t_val) in t_h:
        sum += t_val

每次迭代返回一个 (coordinate, payload) 元组。这种逐层 Pos→Coord→Payload 的遍历称为协调遍历(Concordant Traversal)。

纤维表示方式

每个纤维是一组 (coordinate, payload) 元组,数据按其位置/偏移访问。

表示特点
数组(Array)位置即坐标,存全部 payload(含零)
坐标/载荷列表(Coordinate/Payload List)只存非零,显式存坐标与 payload

纤维表示的选择

  • 隐式坐标:未压缩(无元数据);压缩(如游程编码 RLE);
  • 显式坐标:如坐标/载荷列表;
  • 压缩 vs 未压缩:
    • 压缩/未压缩是表示的属性,稀疏/密度是数据的属性;
    • 未压缩:大小正比于最大坐标值;
    • 压缩格式有元数据开销——对密集数据可能比直接用未压缩更贵;
    • 表示的空间效率取决于稀疏度。

CSR:压缩稀疏行(Compressed Sparse Row)

CSR 是纤维树抽象在二维矩阵上的经典具体实现。它将外层行维度保持为未压缩的密集结构,而将内层列维度压缩为仅存放非零项的连续序列。数据由三部分紧凑数组组成:

  • 段数组(Segment Array, t_segs):大小为 H+1H + 1,充当行纤维的偏移指针表,记录每行在底层数组中的起始与结束边界;
  • 坐标数组(Coordinate Array, t_coords):记录所有非零元素的列坐标(Column Index);
  • 值数组(Value Array, t_vals):记录与列坐标严格一一对应的非零有效载荷(Payload)。

CSR 遍历实现与执行原语:

在硬件遍历中,外层行循环以连续的行号直接索引段数组,内层循环仅在当前行非零区间内连续扫描,彻底跳过了所有零值:

for t_h_pos in [0, H):
    h = t_h_pos                                   # 未压缩 rank:坐标=位置
    t_w_start = t_segs[t_h_pos]
    t_w_len   = t_segs[t_h_pos + 1] - t_w_start   # 相邻指针相减得出本行非零元素个数
    for t_w_pos in [t_w_start, t_w_start + t_w_len):
        w     = t_coords[t_w_pos]                 # 仅读取非零元素的列坐标
        t_val = t_vals[t_w_pos]                   # 提取对应数值
        sum  += t_val

开销与效率权衡:

  • 访存跳过与带宽压缩:遍历总次数从密集矩阵的 H×WH \times W 骤降至非零元素总数(NNZNNZ),有效规避了海量无意义的零值读取;
  • 间接访问代价:通过 t_segs 进行二级指针解引用会引入间接寻址开销,若矩阵密度较高,额外的元数据开销(Segment 与 Coordinate)在容量与能耗上甚至可能超过未压缩的原生数组。

五、稀疏卷积的数据流

1-D 输出固定卷积

int i[W];   // 输入激活
int f[S];   // 滤波器权重
int o[Q];   // 输出激活,  Q = W - ceil(S/2)
for q in [0..Q):
    for s in [0..S):
        o[q] += i[q+s] * f[s];

若部分滤波器权重为零:可避免读操作数、做乘法、更新输出。

门控(条件执行):

if (!f[s]) o[q] += i[q+s] * f[s];   // f[s]==0 时不执行

用条件执行省了能量,但没省时间(仍占该拍)。

Eyeriss 的时钟门控

当图像数据为零时,门控乘法器与存储器读取;可降低 PE 功耗约 45%([Eyeriss, Chen et al., ISSCC 2016])。这是 Gating 的典型实现。

权重固定 — 稀疏权重(Weight Stationary, Sparse Weights)

Einsum:Oq=Iq+s×FsO_q = I_{q+s} \times F_s

i = Array(W)    # 输入激活
f = Tensor(S)   # 滤波器权重(稀疏)
o = Array(Q)    # 输出激活
for (s, f_val) in f:        # 只遍历非零权重 -> Skipping
    for q in [0, Q):
        w = q + s
        o[q] += i[w] * f_val

协调遍历:只遍历非零权重,从而跳过无效计算。 实例:Cambricon-X 用权重元数据驱动对输入激活的访问([Zhang et al., MICRO 2016])。

输出固定 — 稀疏权重 + 稀疏输入

把 Einsum 的索引语义映射到数据流原语:

  • 共享索引(shared indices)→ 交集(intersection);
  • 被约索引(contracted indices)→ 归约(reduction);
  • 未约索引(uncontracted indices)→ 填充输出点;
  • 索引算术(如 q+sq+s)→ 投影(projection)([ExTensor, MICRO 2019])。
i = Tensor(W)   # 输入激活(稀疏)
f = Tensor(S)   # 滤波器权重(稀疏)
o = Array(Q)    # 输出激活
for q in [0, Q):
    for (s, (f_val, i_val)) in f.project(+q) & i:   # 投影 + 交集
        o[q] += i_val * f_val                        # 归约 + 填充输出

纤维坐标投影(Fiber Coordinate Projection):.project(+2) 把坐标整体平移,使两个纤维的坐标空间对齐,便于求交。 纤维交集(Fiber Intersection):a & b 只保留两纤维坐标都非零的位置,从而同时跳过两侧的零。

扩展到 DNN 的其他维度

要扩展到完整 DNN(Op,q,m=Ic,p+r,q+s×Fm,c,r,sO_{p,q,m} = I_{c,p+r,q+s} \times F_{m,c,r,s})需为以下迭代空间增加循环嵌套并加入并行:2-D 输入激活与滤波器、多输入通道 CC、多输出通道 MM。

纤维在位置空间上的等分(Split Equal)

在密集计算中,循环平铺通常简单地在坐标空间均匀切片(如按固定步长划分索引)。但稀疏张量在坐标轴上的非零元分布具有高度不规则性;若按坐标切片,不同处理单元(PE)分得的非零计算量差异极大,极易造成木桶效应与硬件闲置。

为了实现硬件负载均衡,纤维树引入了位置空间等分(splitEqual):直接在底层物理存储序列上将非零元等额切分(例如每 2 个非零元素组成一个子纤维 W0,W1,…W_0, W_1, \ldots),确保每个并行处理通道分得绝对相等的有效工作量。

并行的权重固定(WS)稀疏卷积映射:

在此映射中,外层按位置等分抽取非零权重,内层结合输出维度的空间展开构建并行计算网格:

for (s1, f_split) in f.splitEqual(2):       # 每次取两个非零权重分块
    for q1 in [0, Q/4):
        parallel-for (s0, f_val) in f_split:    # 2 个权重通道并行发射
            parallel-for q0 in [0, 4):          # 4 个输出空间点并行累加
                q = q1*4 + q0
                w = q + s
                o[q] += i[w] * f_val            # 广播激活并累加至各个输出点

并行度与硬件复用:

  • 负载均衡保障:f_split 内部的元素数目恒定,使得参与并行的乘法单元时钟完全对齐;
  • 二维空间映射:硬件上形成了 2×42 \times 4 的处理单元阵列,权重在本地 PE 寄存器常驻,输入激活跨输出通道广播,兼顾了并行度与本地数据复用。

六、注意力机制的稀疏与级联

多头注意力(Einsum,回顾)

Kb,h,m,e=Ib,m,d×WKd,h,e,Qb,h,m,e=Ib,m,d×WQd,h,eQKb,h,m,p=Qb,h,p,e×Kb,h,m,e,SNb,h,m,p=exp⁡(QKb,h,m,p)SDb,h,p=∑mSNb,h,m,p,Ab,h,m,p=SNb,h,m,p/SDb,h,pVb,h,m,f=Ib,m,d×WVd,h,f,AVb,h,p,f=Ab,h,m,p×Vb,h,m,fZb,p,d=Cb,p,f×WZg,d\begin{aligned} K_{b,h,m,e} &= I_{b,m,d} \times WK_{d,h,e}, \quad Q_{b,h,m,e} = I_{b,m,d} \times WQ_{d,h,e} \\ QK_{b,h,m,p} &= Q_{b,h,p,e} \times K_{b,h,m,e}, \quad SN_{b,h,m,p} = \exp(QK_{b,h,m,p}) \\ SD_{b,h,p} &= \textstyle\sum_m SN_{b,h,m,p}, \quad A_{b,h,m,p} = SN_{b,h,m,p}/SD_{b,h,p} \\ V_{b,h,m,f} &= I_{b,m,d} \times WV_{d,h,f}, \quad AV_{b,h,p,f} = A_{b,h,m,p} \times V_{b,h,m,f} \\ Z_{b,p,d} &= C_{b,p,f} \times WZ_{g,d} \end{aligned}

1-D Softmax 与"趟"(Pass)

Nm=eIm,D=∑mNm,Am=Nm/DN_m = e^{I_m}, \qquad D = \textstyle\sum_m N_m, \qquad A_m = N_m / D

趟(Pass):对某张量某 rank 某纤维的一次完整遍历;每当必须在遍历完其他元素后重新访问某元素时,就多一趟。

数值稳定的 Softmax(减最大值)

GMp=max⁡m(QKm,p),SNm,p=e QKm,p−GMp,SDp=∑mSNm,p,Am,p=SNm,p/SDpGM_p = \max_m\bigl(QK_{m,p}\bigr), \quad SN_{m,p} = e^{\,QK_{m,p} - GM_p}, \quad SD_p = \textstyle\sum_m SN_{m,p}, \quad A_{m,p} = SN_{m,p}/SD_p

多种注意力变体:3-trip vs 1-trip 级联

  • 3 趟级联(3-pass):依次算 QKQK → 求全局最大 GMGM → 算 SN,SD,ASN, SD, A → 算 AVAV;
  • 1 趟级联(FuseMax):用运行最大值 RMRM 与运行分母 RDRD 做在线 softmax 融合,在一趟内边遍历边更新,类似 FlashAttention 的在线归一化思想,减少对中间张量的重复访问。

空间架构与 FuseMax 架构在端到端推理上获得性能收益。


七、后续课程

Hardware Architecture for Deep Learning(6.593[01],Spring 2025)大纲:

  • Part I 理解 DNN:引论、DNN 概览;
  • Part II DNN 处理硬件设计:关键指标与目标、核计算、加速器设计、专用硬件上的操作映射;
  • Part III 硬件与算法协同设计:降精度、利用稀疏性、设计高效 DNN 模型、先进技术。

稀疏张量加速架构与纤维树抽象总结

  • 稀疏性可同时省空间、能量、时间,但收益受任务误差容忍约束;
  • 三大硬件特性:Format(表示选择)、Gating(空闲省能)、Skipping(跳过省能省时);
  • 纤维树抽象统一了张量表示(含 CSR 等),其遍历可映射为投影、交集、归约、填充输出等原语;
  • 稀疏卷积/注意力的关键是用坐标投影 + 纤维交集只处理双方都非零的点,并用 split/parallel 引入并行;
  • 在线 softmax 融合(FuseMax)用更少的"趟"完成注意力,降低数据移动。

稀疏加速的终极权衡:元数据开销与控制复杂度的博弈

在密集计算架构中,数据地址由连续嵌套循环规则推导,硬件流控极为简单规整。然而一旦引入稀疏性,虽然表面上消除了大量乘零无效运算,硬件却必须引入坐标元数据(如 CSR 的指针与索引数组)并部署动态求交与分发网络(Intersection & Distribution Logic)。当张量稀疏度不够高(例如低于 50%)时,解压缩元数据的存储与搬运功耗、以及非规则访问导致的内存 Bank 冲突与负载不均(Load Imbalance),往往会完全抵消跳过乘法所节省的能耗。因此,真正的现代稀疏硬件设计从不孤立追求无结构稀疏(Unstructured Sparsity),而是通过算法-硬件协同定义半结构化稀疏(如 NVIDIA 2:4 稀疏)或统一纤维树抽象,在「控制逻辑的确定性」与「数据跳跃的稀疏收益」之间找到最优雅的帕累托平衡点。