综述
Convolution Pipeline是NVDLA核心逻辑里面流水线中的一个。它用于加速卷积算法,支持各种卷积大小的综合可编程参数。一些功能,如Winograd和multi-batch也在卷积管道中执行,以改善性能和提高MAC效率。
卷积流水线有五级,分别是:Convolution DMA、Convolution Buffer、Convolution Sequence Controller、Convolution MAC和 Convolution Accumulator,它们也被分别称为CDMA、CBUF、CSC、CMAC和CACC。每一级都有自己的CSB slave端口,用于接收来自控制CPU的配置数据。所有阶段都使用单一的同步机制,这五个模块对应的顶层module和例化所在的文件分别是:
CDMA: NV_NVDLA_cdma (NV_NVDLA_partition_c.v)
CBUF: NV_NVDLA_cbuf (NV_NVDLA_partition_c.v)
CSC: NV_NVDLA_csc (NV_NVDLA_partition_c.v)
CMAC: NV_NVDLA_cmac (NV_NVDLA_partition_m.v)
CACC: NV_NVDLA_cacc (NV_NVDLA_partition_a.v)
Convolution Pipeline支持三种类型的操作,它们分别是:
- 特征数据的直接卷积,或DC模式
- 图像输入或图像输入模式的卷积
- Winograd卷积或Winograd模式
Convolution Pipeline包含1024个用于int16或fp16的MAC,以及一个用于部分和存储的32元素累加器阵列。MAC资源也可以配置为int8提供2048台MAC。此外,卷积缓冲器中有512KB的SRAM,提供输入权重和激活存储,下面是卷积流水线的示意图。
下面介绍具体操作。
Direct Convolution
Convolution Pipeline总是有两部分输入数据,一个是输入激活数据,另一个是权重数据。假设NVDLA引擎有这样的输入参数:
- 特征数据立方体的尺寸:WxHxC
- 一个权重内核的尺寸:RxSxC
- 内核总数:K,通常决定了第三维的层数
- 零填充尺寸:LP在左边界,RP在右边界,TP在顶层边界,BP在底层边界。
- 卷积步长:X维的SX,Y维的SY
- Dilation(空洞卷积内部步长):X维的DX,Y维的DY
- 输出数据立方体的大小:W'xH'xC'
步长和补零的概念如下图
这些参数的公式是(即下一层feature map的长、宽和高)
输出数据立方体中的每个元素y、输入特征数据立方体中的元素x和权重核中的元素wt的关系是
上述方程中的坐标w、h、c、k都是从零开始的,这是卷积神经网络的一些基本概念,具体可参考感受视野 的介绍。为了完成上述等式中的卷积运算,卷积流水线使用一种称为direct convolution的方法。direct convolution的关键思想是将来自每个卷积核的乘法运算分成组,使得每组包含64个乘法运算。基本规则是:
- 将所有MACs硬件分配到16个子单元中。一个子单元称为MAC Cell,是一个具有用于64个int16/fp16 MACs或128个int8 MACs的硬件。
- MAC单元的集合称为MAC Cell阵列。
- 针对int16、fp16和int8,将所有输入数据立方体分成1x1x64元素的小立方体。
- 将所有权重数据立方体分为int16、fp16和int8的1x1x64元素小立方体。
- 将一个小的输入数据立方体乘以一个小的权重数据立方体,并将乘积相加(这里我们完成了三维feature map中一个像素点,针对一个卷积核的一个点的操作)。这些乘法和加法是在一个MAC Cell内执行的。
- 将这些计算操作组合成4个级别的操作,即原子(atomic)操作、条带(stripe)操作、块(block)操作和通道(channel)操作。
下面以int6 percision模式为例介绍这四种操作。
原子操作(Atomic Operation)
原子操作是direct convolution的基本步骤。在一个原子操作中,每个MAC Cell缓存一个来自某个特定权重内核的1x1x64权重立方体。因此,16个MAC Cell缓存来自16个int16/fp16内核或32个int8内核的权重。所有MAC Cell共享一个1x1x64原子立方体的特征数据(由于卷积是多层的,所以每一个特征数据都需要多次相乘)。MAC Cell执行上述规则5中提到的计算。每个MAC Cell的输出称为部分和(partial sum)。该操作需要1个周期来完成,这样每个周期有16个部分和。部分和被发送到卷积累加器模块进行进一步计算。部分和的等式是:
等式中,PS指部分和,变量c总是能被64整除,原子操作的流程图如下。
Stripe操作(Stripe Operation)
stripe操作结合了来自几个卷积的一组原子操作。在一个stripe操作期间,MAC Cell阵列中的权重数据保持不变,输入数据沿着输入数据立方体滑动(即同一个位置卷积核中的一个点位,不同位置的特征数据点位,两者不断地相乘)。请注意,一个stripe操作中的部分和不能相加,因为它们对应于输出立方体中的不同点(同一个卷积核中的点位,不同的数据特征点位,而一次完整卷积是按照一个卷积核的filter范围来相加的)。stripe操作的长度有限制。下限16是由于下一个stripe操作提取权重的内部带宽。由于累加器中的缓冲区大小,上限为32。在某些极端情况下,长度可能小于下限。
下图显示了包含16(4X4)个原子操作的stripe操作示例,对应的是权重核(0,0)位置的权重。在这种情况下,padding尺寸为0。注意这不是对输入数据立方体的渐进式扫描,尽管一般来说,stripe确实首先沿着w维度扫描。下图显示了一个没有padding的示例,因此最后两列不是第一个stripe的一部分(使用3x3内核,没有padding,输入w=6,输出的w为4),得到的是一组(0,0)位置权重对应的部分和,K15_00表示第15个卷积核的00索引位置的卷积点位。
简而言之,原子操作是特征数据点位x卷积核点位,而stripe操作是特征数据面x卷积核点位。
块操作(Block Operation)
块操作是由多个stripe操作组成的更高级操作。在块操作期间,内核组中的每个内核使用RxSx64权重元素(同一个内核,且第3维度范围也一样),以及一个小立方体的输入特征数据,其大小适当,以确保结果可以跨stripe操作相加,并累积到16-32元素累加器中。
一个块操作中的所有stripe操作具有相同的原子操作号(权重内核和第三维度范围都要一致)。在卷积累加器中,来自同一块操作的部分和基于每个stripe操作相加在一起(比较拗口,其实就是一个卷积核的乘积都加到一起),这些结果称为累加和(这里完成了指定第三维度范围内的一个卷积核的一次卷积操作)。
累计和的等式为:
等式中,AS指累加和,变量c总是能被64整除,好了至此,一定要搞清楚前两个概念:部分和和累加和。部分和是一个特征(像素点)在指定第三维通道指定范围内的乘积求和,而累加和则是在第三通道指定范围内对应一个卷积核的求和。
通道操作(Channel Operation)
通道操作是更高层次的操作,它包括(C+63)/64个块操作,除了通道方向的坐标不同,一个通道操作中的块操作是相似的,如下图所示
一个通道操作的所有部分和可以通过stripe操作相加在一起。在一个通道操作之后,卷积累加器中的结果就是卷积结果。 通道操作结果的等式:
这个等式等同于16-32个输出点的stripe的原始卷积等式,这里就比较好理解了,就是将对应第三通道结果对位累加就得到了最终的卷积结果。一个通道操作完成后,累加器被卸载并发送到后处理器,为下一个通道操作腾出空间。
分组操作
分组操作是比通道操作更高级的操作,其中包含了大约int((data out _ height * data out _ width)/stripe _ size)个通道操作。在分组操作之后,输出数据组成一个W x H x K' 输出surface。
这里K’指的是内核组中的内核尺寸,一个内核组是一次处理的内核数量,每个MAC Cell一个。
输出序列
每个操作中提到的顺序主要是针对输入特征数据和权重数据,而不是输出顺序。输出数据序列非常简单。它遵循C'(K')->W->H->C(K)的顺序。这里C '或K '指的是内核组大小,对于int16/fp16是16,对于int8是32,直接卷积的输出顺序与feature memory mapping顺序一致,这个就很直观很容易理解了,如下图:
Int8和fp16的操作
上面提到的操作反映了int16精度。Fp16的处理方式相同。然而,int8的处理方式略有不同。 在卷积流水线中,int16/fp16的每个乘累加原语被分成int8的两个MAC。因此,int8的元件吞吐量是int16元件吞吐量的两倍,下表记录了一个原子操作的参数。
Winograd Convolution
Winograd卷积是优化direct convolutin的可选算法,卷积管道仅支持3x3xC大小内核的Winograd。 Winograd卷积的动机是减少所需的乘法次数,从而大幅提高给定数量的MAC硬件元素的性能。 Winograd需要一些附加的加法器来对输入和输出激活数据执行Winograd变换,卷积流水线中使用的Winograd卷积的公式为:
这里,符号⊙表示逐元素乘法,符号g是3×3内核,d是输入数据立方体特征图,前两个维度是4x4。符号S是g和d的卷积结果,不补零的情况下,是一个2x2矩阵。
A、G和C都是变换权重和输入特征的矩阵
假定 U=GgG’ 以及V=C‘dC, 那么等式可以被表示为
根据等式,与A、G和C的乘法可以用加法器来实现,因此计算3×3内核的4个结果只需要16次乘法,而在直接卷积模式下需要36次乘法。因此,Winograd的性能是直接卷积的2.25倍。
安装U=GgG',将3x3内核转换为4x4内核,用于对输入激活多维数据集的4x4补丁进行逐点乘法。软件应在NVDLA引擎运行之前转换权重内核。卷积管道处理输入特征数据的转换和乘法结果。
与direct convolution不同,Winograd卷积管道将内核和输入特征数据划分为4x4x4元素的小型数据立方体。在MAC Cell之前,使用额外的加法器来用矩阵CT转换这些立方体
这一步叫做PRA。
在一个Winograd原子操作中,一个MAC Cell中的64个乘积不像direct convolution那样简单地相加在一起,而是有额外的三个阶段:
- 阶段1,将channel方向的4个乘机相加,阶段1的输出是16个部分和,代表一个4x4矩阵。
- 阶段2,每个4x4部分和矩阵乘以矩阵A',阶段2的输出是8个部分和,或4×2矩阵。
- 阶段3,来自阶段2的每个4x2部分和矩阵与矩阵A相乘,输出是4个部分和。
然后,4个部分和存储在累加器中,用于进一步计算。阶段2和阶段3都称为POA。
Winograd模式也有五种操作。下表列出了参数的比较:
Winograd卷积的输出序列类似于direct convolution,Winograd的一些不同之处:
- 对于Winograd操作,输出宽度和高度应能被4整除,这是强制性要求,这是为了特殊的扫描顺序。
- Winograd卷积中stripe操作的扫描顺序与直接卷积不同,请参见下图。
- 块操作总是只有一个stripe操作。
- Winograd层总是并行输出4行。SDP将保证输出数据立方体内存映射的正确性。
反卷积
反卷积是一种特殊的卷积。它是正常卷积的某种逆运算。与正常的卷积情况不同,反卷积层总是在计算之后放大数据立方体。
在NVDLA架构中,反卷积是一项软件功能。从硬件角度来看,软件反卷积层由一个串行卷积层和一个由RUBIK单元支持的收缩层组成。
下图是一维反卷积层的例子。输入数据立方体的维数为W x 1 x 1,内核维数为3 x 1 x 1。虽然计算流程与卷积不同,但结果公式是:
该公式与卷积公式非常相似,只是权重R/S顺序相反。更一般地,具有K个SxRxC内核的WxHxC输入数据立方体的公式为:
根据等式,3D反卷积等于具有(S-1)和(R-1)零填充和反向R/S权重顺序的卷积
如果反卷积X stride或Y stride不为1,计算流程就有点不同。权重核被分成更小的核集。每组核集作为卷积层运行,其中X和Y跨度等于1。因此,使用几个卷积层来生成反卷积层结果。
在一个串行卷积层之后,所有的反卷积结果值都准备好了,但是映射顺序不是预期的结果。如果我们在C方向依次追加卷积输出立方体,那么总输出数据立方体就是Winograd channel扩展数据立方体。扩展参数是deconv_x_stride和deconv_y_stride。
因此,NVDLA使用一个特殊的层收缩层(由Rubik执行)来重新排序这些输出值,以获得所需的反卷积输出立方体。
总之,NVDLA通过以下策略支持反卷积层:
- NVDLA使用两个步骤来执行跨度大于1的反卷积层
- 第一步是使用逆序核的串行卷积层。
- 第一步的输出形成Winograd通道扩展的输出数据立方体。扩展参数是反卷积x步距和反卷积y步距。
- 第二步是在RUBIK单元上运行。
- Rubik单元对Winograd通道扩展的数据立方体进行反向操作。
- 在第二硬件层之后,输出数据立方体按照预期的结果被格式化。
图像输入卷积
NVDLA支持以特殊模式与图像数据卷积,以提高MAC利用率。这里,图像数据可以是部分或整个图像surface。但是NVDLA只能支持direct convolutin。DC,Winograd和反卷积层不能使用像素格式。图像输入也不支持多批次选项。
与DC相比,图像输入情况有一些不同:
- 通道预延伸,权重核应该进行通道预扩展,它不同于DC模式或Winograd模式。
- 卷积缓冲器中的数据映射,卷积缓冲器中的图像数据映射不同于DC和Winograd模式,左、右填充和输入像素行的所有元素都紧凑地驻留在CBUFentries中。见下图。如果通道大小为4,则元素映射顺序为R(Y)->G(U)->B(V)->A(X)。如果通道大小为3,则顺序为R(Y)->G(U)->B(V)。
- stripe操作的分布,stripe操作长度固定为64,并且stripe操作不得越线,以便每个stripe操作从CBUF entries的第一个字节开始。
- 使用通道后扩展加速。即使有通道预扩展,通常内核通道大小也小于32。因此,通道后扩展对于图像输入卷积层非常有用。
通道后扩展(Channel Post-Extension)
通道后扩展是一个选项,用于提高与图像输入卷积的MAC利用率。
在卷积流水线中,一个原子操作需要通道维度中的64个元素(不包括Winograd模式),如果输入数据立方体的通道大小小于64,则MAC在每个周期中不会被100%利用。因此,在DC模式和图像输入模式下,MAC效率取决于通道的大小。
通道后扩展的基本思想是在运行时进行垂直扩展以扩大通道大小。
例如,图像输入层的内核大小为4x4x4。如果不启用后扩展,则扩展前的通道大小为16,MAC的效率会下降到25%。然而,如果后扩展参数被设置为4,则每个原子循环卷积流水线将提取4条相邻线,并将它们组合为C=64条线,那么MAC效率回升到100%。
通道后扩展会有一些限制:
- 通道后扩展仅用于图像输入卷积。
- 通道后扩展仅支持2行扩展和4行扩展。
- 通道后扩展受到预扩展通道大小和卷积×步幅的限制。
有必要提一下,通道后扩展数(N)不需要小于内核高度(R)。硬件可以自动裁剪冗余行,以避免它们参与计算。然而,这也意味着在这种情况下,用户不应该期望MAC效率提高N倍。
多批次模式(Multi-Batch Mode)
NVDLA引擎还支持多批处理,以增强性能并降低带宽,尤其是对于全连接(FC)层,一个FC层的输出是1x1xC数据立方体,这意味着一个FC层中的所有权重仅使用一次。FC层中的一个stripe操作只有一个原子操作,但是卷积流水线需要16个周期来为下一个原子操作加载权重,这在管道中引入了大量泡沫,MAC效率降至6.25%。为了节省效率,NVDLA引擎可以应用多批处理模式。
多批处理是DC模式的一个特殊选项,一次处理多个输入特征数据立方体。卷积管道为一组加权核提取多个输入数据立方体。这也改变了原子操作。来自不同输入数据立方体的小立方体被交错加载,用于一个接一个的原子操作。stripe操作包含多个批处理的原子操作。由于权重被跨条带重复使用,权重加载的cycles被隐藏,这样提升了效率。
不同批量大小的stripe操作的长度为:
Dilation
Dilation是用零值在R和S维度上扩大内核的选项,也就是我们平时说的空洞卷积。该功能可由软件根据需要启用。 下图显示了膨胀参数= 3的情况。
NVDLA支持R和S维度的dilation。
Dilation限制:
- Dilation仅适用于DC模式。
- Dilation不适用于Winograd或图像输入模式。
功耗
卷积流水线支持每个主要流水线阶段的时钟门控,如果流水线阶段空闲并且没有有效的硬件层可用,则流水线阶段的数据路径将被时钟门控。
先说到这,下节开始介绍一次介绍流水线中的五个模块。