异构脉动阵列设计:高效支持深度可分离卷积的硬件加速方案
1. 项目概述:当脉动阵列遇上深度可分离卷积
在移动端和边缘设备上部署神经网络,就像是在一辆微型跑车里塞进一台V8引擎,既要动力澎湃,又要省油高效。这几年,以MobileNet、EfficientNet为代表的紧凑型卷积神经网络(Compact CNN)大行其道,它们通过深度可分离卷积(Depthwise Separable Convolution, DWConv)等精巧设计,在保证精度的前提下,将模型的参数量和计算量砍掉了一大截。这无疑是算法层面的巨大成功。
然而,当我们兴冲冲地想把这类高效模型部署到专用的硬件加速器上时,却常常遭遇“水土不服”。特别是对于那些基于经典脉动阵列(Systolic Array)架构的加速器,比如谷歌的TPU,问题尤为突出。你可能会发现,一个在标准卷积(SConv)上跑得飞快的加速器,一遇到DWConv层,性能就断崖式下跌。论文里的数据很直观:在某些紧凑型CNN中,DWConv层的计算量(FLOPs)只占全网的10%左右,但它消耗的推理时间却超过了60%。这就像一个高效的流水线,突然遇到了只能单件处理的特殊工序,整个生产线都被拖慢了。
问题的根源在于架构与算法的不匹配。传统的脉动阵列是为处理大规模的矩阵乘法(GEMM)而生的,其规则的数据流和同构的处理单元(PE)设计,在SConv这种“粗活”上如鱼得水。但DWConv的本质是矩阵-向量乘法(MV),计算粒度细,数据复用模式完全不同。当MV的小任务块被映射到庞大的PE阵列上时,会产生大量的空闲PE,资源利用率骤降,性能自然上不去。
我这次要拆解的,就是一篇直击这个痛点的论文:《异构脉动阵列架构:提升紧凑型CNN硬件加速器效率》。它没有选择去改动已经训练好的模型,也没有推翻重来设计一个全新的复杂加速器,而是提出了一个相当巧妙的思路:在保持脉动阵列简洁、高效内核的前提下,通过引入“异构”的PE设计,让同一个硬件阵列能够动态切换数据流,从而同时高效处理SConv和DWConv。这个名为HeSA(Heterogeneous Systolic Array)的设计,像给流水线装上了一套可快速切换的柔性夹具,既能高效处理标准件,也能从容应对特殊件。
2. 核心问题拆解:为什么标准脉动阵列“水土不服”?
要理解HeSA的妙处,我们得先搞清楚标准脉动阵列在DWConv上栽跟头的根本原因。这不仅仅是“大炮打蚊子”那么简单,背后是数据流、计算模式与硬件架构的深层矛盾。
2.1 脉动阵列的工作原理与数据流
脉动阵列可以想象成一个计算细胞的网格。每个细胞就是一个简单的处理单元(PE),通常只做乘累加(MAC)操作。数据像血液一样,按照固定的节奏(时钟周期)在细胞间脉动传递。它的核心优势在于数据复用和规整的数据流,避免了频繁访问高延迟的外部存储器(如DRAM)。
最常见的数据流是输出静止(Output-Stationary, OS)数据流。在这种模式下,输出部分和(psum)会暂时驻留在每个PE中累积,而输入特征图(ifmap)数据和权重(weight)数据则分别从左侧和上方流入阵列,在网格中水平或垂直移动。对于一次大规模的GEMM运算,我们可以将其切分成多个与阵列尺寸匹配的块(Tile),依次送入阵列计算。由于每个数据在流过阵列时会被多个PE使用,数据复用率很高,PE利用率可以轻松达到90%以上。
2.2 深度可分离卷积的计算特性
DWConv是紧凑型CNN的基石。它与标准卷积的关键区别在于“分离”:
- 深度卷积(Depthwise Convolution):每个输入通道单独与一个对应的二维卷积核进行卷积,产生一个输出通道。通道之间没有计算交互。这一步计算量小,但数据复用模式特殊。
- 逐点卷积(Pointwise Convolution):使用1x1的卷积核,对深度卷积输出的所有通道进行线性组合。这本质上是一个小规模的SConv。
问题就出在深度卷积这一步。经过im2col展开后,SConv会变成一个大的[M, C*K*K] x [C*K*K, R*R]的GEMM(M是输出通道数)。而DWConv的深度卷积部分,由于每个通道独立计算,展开后变成了C个独立的[1, K*K] x [K*K, R*R]的矩阵-向量乘法(MV)。这里的“1”就是关键,它意味着在输出通道维度(M维度)上,完全没有并行和数据复用的机会。
2.3 效率瓶颈的量化分析
当把一个MV任务块映射到二维脉动阵列时,会发生什么?假设我们有一个16x16的阵列。
- 在OS数据流下,阵列的一次计算会固定输出一个
[S, S]大小的输出块(S是阵列宽度)。对于SConv,这个输出块包含了S个通道的S个空间位置,数据复用充足。 - 对于DWConv,由于每个输出通道是独立计算的,一次只能计算同一个通道的S个空间位置。这意味着,在任何一个计算周期内,阵列中只有一列(或一行,取决于映射方式)的PE在活跃地计算不同空间位置,而其他列的PE因为等待不同通道的数据而处于空闲状态。
论文中的图2非常直观地展示了这种差异。处理GEMM时,阵列中的PE(红色)利用率很高;而处理MV时,大量PE(白色)处于闲置状态。更糟糕的是,阵列规模越大,这种闲置现象越严重。因为任务粒度(MV)是固定的,而计算资源(PE数量)增加了,但可用的并行度并没有增加,导致“空转”的PE比例更高。这就是为什么在大型阵列上运行MobileNet等模型时,DWConv层的PE利用率可以低至个位数百分比。
注意:这里存在一个常见的误解,认为增加阵列规模总能提升性能。对于计算密集型的SConv(GEMM)确实如此,但对于内存访问密集、并行度有限的DWConv(MV),盲目扩大阵列规模只会加剧资源浪费,无法转化为实际性能提升,甚至可能因为数据供给瓶颈而变得更差。
3. HeSA架构设计:用“异构”实现“一招两用”
既然问题出在单一数据流无法适配两种计算模式,最直接的思路就是让硬件支持多种数据流。但之前的研究要么引入了复杂的路由器和控制逻辑,牺牲了脉动阵列的简洁性;要么增加了大量存储单元,拉高了面积和功耗成本。HeSA的聪明之处在于,它几乎是在“零成本”的基础上,实现了数据流的动态切换。
3.1 核心思想:为DWConv设计新的数据流
论文提出了针对DWConv优化的OS-S(Output-Stationary Single-channel)数据流。它与传统OS-M(Multi-channel)数据流的区别在于映射目标:
- OS-M:同时计算多个输出通道(M维度)上的多个空间位置。
- OS-S:集中计算单个输出通道上的所有可能空间位置。
OS-S数据流如何提升PE利用率?它改变了数据在阵列中的流动方式。在OS-M中,ifmap数据主要沿水平方向流动复用。在OS-S中,为了计算单个通道内不同空间位置,ifmap数据需要在PE间同时进行水平和垂直两个方向的传递和复用。这样,一个ifmap数据可以被同一列中上下多个PE使用,从而将原本闲置的PE调动起来参与计算。
3.2 异构处理单元(PE)的巧妙改造
支持OS-S数据流,意味着PE需要能接收来自上方(而不仅仅是左侧)的ifmap数据。如果为每个PE都增加一个垂直向上的输入端口和配套寄存器,硬件开销会很大。HeSA的解决方案堪称“神来之笔”:复用已有的、在计算阶段闲置的数据通路。
在一个标准PE中,通常有:
- 一个寄存器(REG1)存放权重。
- 一个或多个寄存器(REG2)存放输入的ifmap数据,并向右传递给相邻PE。
- 一个累加器(Psum Reg)存放部分和。
- 一条向下的数据通路,用于将最终输出传递出去。
关键洞察在于:在计算进行中时,这条向下的输出通路是空闲的。HeSA的做法是,通过一个多路选择器(MUX),将这条向下的通路在需要时“借用”过来,作为向上的ifmap输入通路。同时,原本用于暂存最终输出的寄存器,也被临时用作缓存来自上方PE的ifmap数据的额外寄存器(REG3)。
具体切换机制如下:
- 当执行SConv(OS-M数据流)时:MUX断开新增的路径,PE工作模式与标准脉动阵列完全一致,数据从左流入,从上流入,输出向下传递。硬件行为和性能无任何损失。
- 当执行DWConv(OS-S数据流)时:控制单元配置MUX,连通新增的垂直路径。此时,ifmap数据可以从上方PE的“输出寄存器”流入当前PE,作为其输入。阵列顶部的PE需要额外的数据预加载机制,论文中巧妙地利用阵列顶部一行PE本身的寄存器来充当这个缓存角色,虽然轻微牺牲了顶部一行PE的计算能力,但省去了添加独立存储单元的昂贵开销。
这种设计使得硬件开销微乎其微——主要就是每个PE增加了一个MUX和一些控制逻辑。论文的评估显示,HeSA的面积相比标准脉动阵列仅增加了约3%,几乎可以忽略不计。
3.3 操作流程与数据映射示例
为了更具体地理解,我们来看一个2x2的HeSA计算一个简单DWConv的例子(假设ifmap 3x3, kernel 2x2, ofmap 2x2)。
- 数据映射:首先,输出特征图(ofmap)的数据会被旋转180度后映射到阵列的PE上。这一步是为了让ifmap数据能更自然地自上而下流动。
- 预加载阶段:权重数据从阵列顶部预加载到每个PE的权重寄存器中。ifmap数据从左侧缓冲区 skewed(斜进)输入。
- 计算阶段:
- 周期1:第一行PE开始计算。它们从左侧获取ifmap数据,从本地寄存器获取权重,进行MAC操作。同时,它们将接收到的ifmap数据存入REG3(即原来的输出寄存器)。
- 周期2:第一行PE继续计算新的ifmap数据(从左侧获取)。此时,第二行PE开始计算。但它们所需的ifmap数据不是从左侧来,而是从第一行PE的REG3寄存器中获取(通过新开启的垂直路径)。这就实现了ifmap数据在垂直方向的复用。
- 流水线化:上述过程以流水线方式持续进行,直到整个通道计算完毕。
通过这种方式,一个2x2的阵列在计算这个DWConv时,所有4个PE都能持续工作,利用率达到100%。而在标准OS-M数据流下,可能只有2个PE能有效工作。
4. 可扩展性挑战与灵活缓冲结构
解决了单一阵列内的效率问题后,另一个现实挑战随之而来:如何设计可扩展的阵列来应对不同规模的网络?对于大型CNN,我们自然希望用更大的阵列(更多PE)来获得更高吞吐量。但如前所述,对于DWConv,简单地把小阵列“放大”(Scaling-Up)会导致利用率暴跌。
4.1 两种传统扩展方式的利弊
论文分析了两种主流扩展思路:
- 纵向扩展(Scaling-Up):直接增加阵列的行列数,做成一个更大的单体阵列。
- 优点:结构简单,数据复用效率高,所需的外部存储带宽增长较慢(与阵列边长的平方根成正比)。
- 缺点:对小型或并行度低的任务(如DWConv)极其不友好,PE利用率随规模增大而急剧下降。
- 横向扩展(Scaling-Out):使用多个独立的小阵列并行工作。
- 优点:灵活性高,可以将不同任务或任务的不同部分映射到不同阵列,保持每个小阵列的高利用率。
- 缺点:硬件开销大(每个阵列都需要独立的缓冲区和控制器),数据通信开销高(可能需要在阵列间复制数据),所需总带宽与阵列数量成线性增长。
4.2 HeSA的解决方案:灵活缓冲结构
HeSA没有二选一,而是提出了一个融合两者优点的灵活缓冲结构。其核心是一个可配置的交叉开关(Crossbar),它位于共享的片上缓冲区和多个PE子阵列之间。
这个交叉开关支持三种连接模式:
- 单播(Unicast):一个缓冲区端口连接一个子阵列。这类似于Scaling-Out,每个子阵列独立工作。
- 多播(Multicast):一个缓冲区端口连接多个子阵列。可以将同一份数据(如共享的权重)同时广播给多个子阵列,减少数据重复加载。
- 广播(Broadcast):一个缓冲区端口连接所有子阵列。在需要所有阵列执行相同操作时最大化数据复用。
通过配置交叉开关,我们可以动态地将多个小规模PE阵列“组合”成不同形态的计算单元。例如,一个由4个8x8子阵列构成的系统,可以配置为:
- 模式A:4个独立的8x8阵列(纯Scaling-Out)。
- 模式B:2个独立的8x16阵列。
- 模式C:1个独立的16x16阵列(等效于Scaling-Up)。
- 模式D:1个8x32阵列加1个独立的8x8阵列。
4.3 配置算法与带宽优化
这种灵活性带来了一个关键优势:可配置的带宽分配。Scaling-Up模式带宽需求低但利用率可能低,Scaling-Out模式带宽需求高但利用率高。FBS允许我们为不同的网络层、甚至同一层的不同阶段,选择最合适的阵列组合和带宽配置。
论文给出了一个简单的配置算法:对于给定的网络层,遍历所有可能的阵列组合配置(C),估算每种配置下的PE利用率(PE_Util_C)和所需带宽(BW_C)。最终选择在满足带宽约束(BW_MAX_C)的前提下,PE利用率最高的配置。这个估算过程可以通过周期精确模拟器或分析模型快速完成。
实际意义:对于网络中的大型SConv层,我们可以将子阵列合并成一个大阵列,享受高数据复用和低带宽的好处。对于其中的DWConv层,我们可以将大阵列拆分成几个小阵列独立工作,保持高PE利用率。这种动态适配能力,使得HeSA在整体性能和能效上超越了固定的Scaling-Up或Scaling-Out设计。实验数据显示,与纯Scaling-Out相比,FBS在保持相同性能的同时,减少了高达40%的数据通信量。
5. 实现评估与性能分析
理论再优美,也需要实验验证。论文对HeSA进行了全面的评估,对比基线标准脉动阵列,以及Eyeriss等经典加速器架构。
5.1 实验设置与评估指标
- 测试平台:使用可配置的、基于脉动阵列的周期精确模拟器SCALE-Sim进行性能仿真。
- 设计实现:采用45nm工艺进行RTL综合,使用Synopsys Design Compiler评估面积,使用Aladdin模拟器评估功耗。
- 对比基线:
- 标准SA(Gemmini):仅支持OS-M数据流的传统脉动阵列。
- SA-OS-S:论文中假设的一种仅支持OS-S数据流的变体阵列(作为理论对照)。
- Eyeriss:著名的CNN加速器,采用不同的空间架构。
- 工作负载:三种主流的紧凑型CNN:MobileNetV3, MixNet, EfficientNet-Lite0。均使用8位量化,批大小为1,以模拟边缘推理场景。
- 关键指标:
- PE利用率:直接反映硬件效率。
- 性能(GOP/s)与加速比:实际吞吐量。
- 数据通信量:影响带宽需求和能耗。
- 面积与能耗:硬件成本。
5.2 性能提升结果
实验结果有力地支撑了HeSA的设计价值:
PE利用率大幅提升:
- 对于DWConv层,在8x8阵列上,标准SA的平均PE利用率仅为~11%,而HeSA通过切换到OS-S数据流,将其提升至~60%,提升了约4.5-11.2倍。
- 对于整个网络,HeSA将总PE利用率从基线的较低水平提升到了接近SConv层的高效率水平。
- 在扩展到16x16和32x32阵列时,优势更明显。标准SA的DWConv利用率跌至6%和3%以下,而HeSA配合FBS仍能保持在50%和30%以上,避免了大规模阵列的资源浪费。
端到端性能加速:
- 在8x8阵列上,HeSA对三个紧凑型CNN模型实现了1.6倍至3.1倍的整体加速。
- 在更大阵列上,由于标准SA利用率衰减严重,HeSA带来的性能优势倍数更大。
- 在32x32阵列上,标准SA由于利用率极低,实际性能(170.9 GOP/s)仅达到其峰值算力(1024 GOP/s @ 500MHz)的16.7%。而HeSA的实际性能达到了525.3 GOP/s,是标准SA的3倍以上,更充分地利用了硬件算力。
数据通信优化:
- 与纯Scaling-Out方法相比,HeSA的灵活缓冲结构(FBS)在保持高利用率和性能的同时,将数据通信量降低了40%。这对于能耗敏感的移动设备至关重要。
5.3 面积与能效分析
这是HeSA设计最令人印象深刻的地方之一——高性能提升并未带来显著的硬件代价。
- 面积开销:HeSA(16x16,含FBS)的整体面积为1.84 mm²。与同等规模的标准SA(Gemmini)相比,面积增加仅为3%。这主要归功于其极简的异构PE改造,仅增加了MUX和少量控制逻辑,没有引入额外的存储或复杂路由。相比之下,Eyeriss的面积要大得多,因为它每个PE内部都集成了较大的局部缓存。
- 能耗降低:由于PE利用率的提升减少了空转功耗,并且更好的数据复用降低了缓冲区的读写次数,HeSA在运行紧凑型CNN时的总能耗比标准SA降低了20%以上。能耗节省主要来自PE阵列(~30%)和片上缓冲区(~40%)。DRAM的能耗变化不大,因为其访问主要由模型总数据量决定。
5.4 与同类工作的对比
HeSA的设计在“效率”和“简洁性”之间取得了很好的平衡:
- 相比于Eyeriss v2等通过复杂全局网络和大量片上存储来支持灵活数据流的架构,HeSA保持了脉动阵列的规整性和简洁性,面积和功耗更有优势。
- 相比于一些通过修改网络结构(如DRACO)来适应硬件的方法,HeSA无需重新训练模型,部署门槛更低。
- 它精准地解决了DWConv在脉动阵列上的特定瓶颈,而不是做一个大而全的通用优化,使得其改进效果非常显著且硬件代价可控。
6. 设计启示与实战考量
读完这篇论文并深入理解HeSA后,我认为它给硬件加速器设计,特别是面向边缘AI的ASIC设计,带来了几点重要的启示:
6.1 架构设计应面向真实工作负载
很多早期AI加速器设计主要针对ImageNet上的大型CNN(如VGG, ResNet),其计算以大型GEMM为主。但当工作负载转向移动端的紧凑型模型时,原有的架构优势可能变成劣势。HeSA的成功在于它敏锐地发现了这一转变,并针对DWConv这一新兴主导算子进行了特化优化。在设计之初,就必须用目标场景下的真实模型(而不仅是学术基准)来驱动架构决策。
6.2 “最小改动”原则的价值
在工程上,优雅的解决方案往往不是推倒重来,而是在现有成熟框架下做最小的、最关键的改动以获得最大收益。HeSA没有改变脉动阵列最核心的脉动数据传递机制和二维网格结构,只是让PE变得“聪明”了一点,能切换一下数据路径,就解决了大问题。这种设计哲学极大地降低了集成风险、验证成本和兼容性负担。在旧架构上做“外科手术式”的精准优化,有时比发明新架构更具实用价值。
6.3 可配置性是应对多样性的关键
未来的AI模型只会越来越多样,算子类型也会更丰富。HeSA通过支持两种数据流和可配置的灵活缓冲结构,赋予硬件一定的“弹性”。虽然它没有做到完全通用的可重构,但这种有限范围、低成本的可配置性是一个非常实用的折衷。在实际芯片设计中,可以借鉴这种思路,通过引入类似的可配置交叉开关、可切换的数据通路、可编程的序列发生器等,让硬件能更好地适应算法的发展。
6.4 对系统级设计的考虑
HeSA的FBS结构启示我们,计算阵列的拓扑和存储层次之间的连接是可以动态调整的。这不仅仅适用于多个子阵列,也可以引申到更广泛的系统级设计,比如:
- 计算单元与不同层级缓存(L1/L2)之间的可配置连接。
- 多核加速器之间通过可配置网络进行动态任务分配与数据共享。
- 在存算一体架构中,配置存储单元与计算单元之间的数据流模式。
这种“柔性互联”的思想,对于构建能效比更高、更适应动态负载的异构计算系统具有重要意义。
6.5 实际部署的潜在挑战
当然,将HeSA或类似思想投入实际应用,也需要考虑一些工程问题:
- 控制复杂度:虽然硬件改动小,但需要增加一个轻量级控制单元来协调数据流切换和FBS配置。这需要精细的编译器或运行时支持,以分析网络图,自动为每一层选择最优数据流和阵列配置。
- 数据供给瓶颈:当使用OS-S数据流时,ifmap数据需要同时从左侧和顶部供给,对缓冲区的带宽和寻址逻辑提出了更高要求。需要确保内存子系统不会成为新的瓶颈。
- 工艺与频率:增加的MUX和路径选择逻辑可能会对关键路径产生轻微影响,需要在物理设计阶段仔细评估,确保不影响目标时钟频率。
从我个人的经验来看,这类架构创新的价值,不仅在于论文中的性能数字,更在于它开辟了一条清晰的路径。它告诉我们,面对紧凑模型在传统硬件上的效率困境,我们并非无计可施。通过深入理解算法特征与硬件行为,完全可以在不颠覆现有设计范式的前提下,找到四两拨千斤的优化点。对于从事AI芯片设计,特别是边缘侧AI加速器开发的工程师来说,HeSA的设计思路是一个非常值得研究和借鉴的案例。它提醒我们,在追求算力峰值的同时,更要关注硬件在真实、多样且不断演进的AI工作负载下的实际效率。
