Lec 24加速器(二)(Accelerators II)
当前课程暂无后续已收录内容。
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])。利用稀疏性的收益:
- 稀疏数据可压缩 → 节省空间与能量(避免操作零值):
- 可节省时间与能量:避免取无用操作数、避免无效计算(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 坐标的元组(即一个点)标识,如 ;形状记 。
树形张量抽象(Tree-based)
把张量组织成一棵树:从 Root 出发,按 rank 逐层下降,每层节点带坐标,叶子是值。
纤维树抽象(Fibertree)
- 每个坐标引用一个纤维(fiber);
- 查找点 :
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):大小为 ,充当行纤维的偏移指针表,记录每行在底层数组中的起始与结束边界; - 坐标数组(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
开销与效率权衡:
- 访存跳过与带宽压缩:遍历总次数从密集矩阵的 骤降至非零元素总数(),有效规避了海量无意义的零值读取;
- 间接访问代价:通过
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:
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)→ 填充输出点;
- 索引算术(如 )→ 投影(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()需为以下迭代空间增加循环嵌套并加入并行:2-D 输入激活与滤波器、多输入通道 、多输出通道 。
纤维在位置空间上的等分(Split Equal)
在密集计算中,循环平铺通常简单地在坐标空间均匀切片(如按固定步长划分索引)。但稀疏张量在坐标轴上的非零元分布具有高度不规则性;若按坐标切片,不同处理单元(PE)分得的非零计算量差异极大,极易造成木桶效应与硬件闲置。
为了实现硬件负载均衡,纤维树引入了位置空间等分(splitEqual):直接在底层物理存储序列上将非零元等额切分(例如每 2 个非零元素组成一个子纤维 ),确保每个并行处理通道分得绝对相等的有效工作量。
并行的权重固定(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内部的元素数目恒定,使得参与并行的乘法单元时钟完全对齐; - 二维空间映射:硬件上形成了 的处理单元阵列,权重在本地 PE 寄存器常驻,输入激活跨输出通道广播,兼顾了并行度与本地数据复用。
六、注意力机制的稀疏与级联
多头注意力(Einsum,回顾)
1-D Softmax 与"趟"(Pass)
趟(Pass):对某张量某 rank 某纤维的一次完整遍历;每当必须在遍历完其他元素后重新访问某元素时,就多一趟。
数值稳定的 Softmax(减最大值)
多种注意力变体:3-trip vs 1-trip 级联
- 3 趟级联(3-pass):依次算 → 求全局最大 → 算 → 算 ;
- 1 趟级联(FuseMax):用运行最大值 与运行分母 做在线 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 稀疏)或统一纤维树抽象,在「控制逻辑的确定性」与「数据跳跃的稀疏收益」之间找到最优雅的帕累托平衡点。