目录
Transformer模型中抛弃了传统的CNN和RNN,整个网络结构完全是由Attention机制组成。更准确地讲,Transformer由且仅由self-Attenion和Feed Forward Neural Network(多层向前神经网络)组成。一个基于Transformer的可训练的神经网络可以通过堆叠Transformer的形式进行搭建,同时Transformer的提出解决了之前的模型存在的两个问题,首先它使用了Attention机制,将序列中的任意两个位置之间的距离是缩小为一个常量;其次它不是类似RNN的顺序结构,因此具有更好的并行性,符合现有的GPU框架,这将大大降低Transformer模型在硬件的实现的难度。从个人理解上看Transformer的本质上是一个Encoder-Decoder的结构,我们通过对输入数据的各个特征部分进行加权区分,在Transformer的encoder中,数据首先会经过一个叫做self-Attention的模块得到一个加权之后的特征向量 Z,这个Z便是公式中的:
得到Z后,他会通过self-Attention它会被送到encoder的下一个模块,即Feed Forward Neural Network。这个全连接有两层,第一层的激活函数是ReLU,第二层是一个线性激活函数,可以表示为:
从上述描述可知Attention机制可以描述为
- 如上文,将输入数据转化成嵌入向量;
- 根据嵌入向量得到 q , k , v 三个向量;
- 为每个向量计算一个score: score=q⋅k ;
- 为了梯度的稳定,Transformer使用了score归一化,即除以
;
- 对score施以softmax激活函数;
- softmax点乘Value值 v ,得到加权的每个输入向量的评分 v ;
- 相加之后得到最终的输出结果 z : z=∑v
而一般Transformer模型中更多地是采取Multi-Head Attention,Multi-Head Attention相当于多个不同的self-attention的集成(ensemble)因此我们可以将多头注意力基质可以表现为如下公式:
Multi-head Attention(Q,K,V)=Concat (head1,⋯,headh)W0
其中
headi=Attention(Q,K,V)
也就是说每个Attention的每个头的计算计算是基于输入数据特征中Q,K,V的计算,而多头注意力基质是将每个头的输出拼接起来,再通过矩阵W0进行线性变换最终得到输出。公式中,Q , K , V分别表示query、key和value。key把query作为依据,经过计算,得到对于每个key的attention权重,这些权重加起来等于1,最终结果为利用attention权重,对value进行加权求和。Q , K , V三者再各应用中不一定相同,但是对于Transformer模型中的Self-Attention,三者取值都一样,就是取输入数据的embedding。需要注意的是我们的激活函数不一定是Softmax函数也可以是Sigmoid函数,我们如何区别使用呢?
首先我们需要明确Softmax函数从代表着多类型分类的问题,由于多个感知机的存在,Softmax函数的输出结果之间是互斥的,构建分类器,解决只有唯一正确答案的问题时,用Softmax函数处理各个原始输出值。Softmax函数的分母综合了原始输出值的所有因素,这意味着,Softmax函数得到的不同概率之间相互关联。接着我们上述的模型他的方程为,Softmax函数在模型中就可以表达为如下表达式:
他的整体的计算流程可以简单描述为下图
Softmax函数是二分类函数Sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来。如图2所示,Softmax直白来说就是将原来输出是3,1,-3通过Softmax函数一作用,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们就可以将它理解成概率,在最后选取输出结点的时候,我们就可以选取概率最大(也就是值对应最大的)结点,作为我们的预测目标。
由于Softmax函数先拉大了输入向量元素之间的差异(通过指数函数),然后才归一化为一个概率分布,在应用到分类问题时,它使得各个类别的概率差异比较显著,最大值产生的概率更接近1,这样输出分布的形式更接近真实分布。
相比而言Sigmoid函数解决的是多标签的分类问题,构建分类器解决有多个正确答案的问题时,用Sigmoid函数分别处理各个原始输出值。总而言之该函数是相对于一个感知机,也就是决定神经网络中的数据是或者不是,输出结果之间不是互斥的,其函数表达式为:,其图像如下
通过图像我们看出Sigmoid函数的输出在(0,1)之间,输出范围有限,优化稳定,可以用作输出层。连续函数,便于求导。但是他的也比较严重:最明显的就是饱和性,从上图也不难看出其两侧导数逐渐趋近于0,容易造成梯度消失。激活函数的偏移现象。Sigmoid函数的输出值均大于0,使得输出不是0的均值,这会导致后一层的神经元将得到上一层非0均值的信号作为输入,这会对梯度产生影响。因为Sigmoid函数是指数形式导致计算复杂度高。
总而言之两者对比,基于Transformer模型的Multi-head Attention基质来看Softmax函数会得出更符合预期的效果输出,因此在该模型中多选择Softmax函数。
Softmax函数的FPGA实现
首先我们回顾一下Softmax函数的公式,从设计的思路来看我们需要做的就是实现三个部分就是指数部分、加法部分、除法部分。但其实加法除法部分是数字电路设计中比较成熟的部分,因此我们主要的设计是体现在指数部分的实现:目前的主流方式是而 FPGA 实现指数运算,目前主要利用的方法有查表法、CORDIC 算法、泰勒级数展开和多项式拟合等。
泰勒级数展开的方法需要阶数过多,运算量较大,会消耗 FPGA 大量乘法器,另外,查表法是比较直接简单的方法,是将不同自变量对应的函数值事先存入 ROM中供查找。优点是适用于任何复杂函数,理论上可以做到无限逼近。另外,这种方法不消耗乘法器,能在一个时钟内出结果。缺点是一旦精度要求高,查找表的尺寸就会增大,消耗存储资源。多项式拟合非线性函数的时候同样存在需要阶数过高,消耗资源较大的问题,而且计算时间长。CORDIC 算法即坐标旋转数字计算方法,消耗资源较少,但耗时长,同时存在精度不高的问题。分段函数拟合逼近的方法实现 Sofmax 函数,即在一个范围内将 Softmax 函数划分为段,每一段用次数较低的多项式进行拟合的方法。这种方法有着占用资源少,速度较快,精度较高的特点,相对可行。总结对比这几种方法情况如下表:
查表法
查表法的最开始的思路是我们可以通过事先计算好对应的ex 的值,将计算好的对应的函数值存储在ROM中供查找,理论上来说这种操作。但是如果直接用为了ex 的值去运算需要高精度复时所需的存储单元太大,为了简化这种方法同时兼顾相对高的精度,目前主流是通过软硬结合的方式通过分段函数拟合的方式和查表法结合,使得在可以接受的精度范围内实现Softmax函数,Mario Vaccaro等人[1]通过使用线性插值法将ex 进行精度可调节的简化,如下图的操作:
通过插值拟合的方式将ex 这样一个在硬件描述上较为复杂的函数进行简化,通过简化逼近的方式从而实现误差范围可接受的Softmax函数,在函数处理阶段通过不同的h取值,选择h = 0.25和h= 0.125,在均方根下可以获得小于0.8%的最大相对误差为0.566%,小于0.2%,RMS = 0.14%。其硬件架构原理图如下:
实现了20个ns的时钟约束。实验结果表明,在设备中使用硬件资源的方法非常低,结果显示出了减少的耗散。这是一个非常重要的方面,特别是在所有这些应用中,电力不是直接由电力线提供的,但它是由电池或能量收集系统提供的。这就是IoT系统的例子。结果显示,两种分析案例的功率消耗为0.120w和0.107w。
在选取不同的区间进行了性能测试:
X-rage(-16,15)
X-rage(-2,1)
这种方式给了我们一个较为明确的思路就是我们可以先通过软件的方式将ex 通过拟合的方式形成可以减少查找表的位置数的方式,从而减少ROM的存储量,加快计算速度。
同时通过查表法也有可以将ex指数的部分分为几个部分通过并行查表的方式从而增大整体体系的吞吐率,Wen qiang Wang等人采取了这样的一个思路对Softmax函数进行了硬件实现,由于指数函数的基本性质我们能将一个基本的指数函数转变为如下的形式:
为了保持AXI总线的兼容性这个体系中将数据宽度设计为32 bits,将上一步的数据的浮点数字进行定点化之后选取小数位为16,同时采用移位寄存的方式将基底进行拆分。
然后通过将每部分数并行进行查表操作,将数值查到后通过一步乘法器运算从而实现ex 将得到的数值进行投入Softmax函数中,基本的流程图为下图:
在选取并行运算指数函数的同时,这个体系也选取双重流水线的模式来提升整个体系的吞吐率,通过ex 的指数运算和最终加和后的除法运(移位和相减结合实现)算形成两个流水线,如下图:
并且文章作者通过ASIC和FPGA两方面对该计算方式进行了应将实现从下图的数据可以看出,该方案在速度方面具有很大的优势。同时该方案实现的硬件系统功耗也较低。
同时其他团队也有运用[3]对数运算应用于函数的两边,从而将除法运算转换为减法运算。通过修改,证明了修改函数中剩余的所有指数项的值都满足性质ex≤1,从而简化了LUT的实现Softmax函数,其硬件结构和面积对比如下图所示:
同时Gian Carlo Cardarilli[5]通过一种伪Softmax函数的方式大大减少了内存的使用,并提高了芯片的运行速度,神经网络系统的硬件实现使用整数量化,通常是8位整数(INT8),因此将ex转化为以二为底的指数将更容易实现将Softmax函数在硬件当中实现,因此我们将公式转化为以下的形式:
其硬件结构图如下所示,
其中他们通过ASIC将函数实现其芯片面积如下图
一个softmax函数的伪softmax近似及其硬件结构。用MSE测量的近似误差小于最近提出的其他软最大值近似。此外,伪softmax函数遵循概率分布的性质,其输出值可被解释为概率。伪softmax架构在VHDL语言中实现,并在标准单元中合成。实现结果表明,虽然伪软最大单元的面积大于23单元,但其输入位宽的减小可以使驱动神经网络的面积减小。在这项工作的未来扩展中,伪softmax体系结构可以重新安排,以处理串行或混合并行串行输入。这将允许它的硬件实现在具有大量输出类的网络中。
这几个例子将查表法需要存储单元较大的劣势有所弥补,同时通过对ex 函数的改进大大减少了ROM内存的使用减少了芯片的功耗,提高了芯片的运行速度。
CORDIC算法的简介
CORDIC 的英文全称是 Coordinate Rotation Digital Computer。CORDIC 算法应用广泛,如离散傅里叶变换、离散余弦变换、离散Hartley变换、Chirp-Z变换、各种滤波以及矩阵的奇异值分解中都可应用 CORDIC 算法。从广义上讲,CORDIC 算法提供了一种数学计算的逼近方法。由于它最终可分解为一系列的加减和移位操作,故非常适合硬件实现。示意图如下:
该坐标旋转在一个半径为r的圆中进行旋转(注意是一个圆坐标系,因为还有在线性坐标和双曲线坐标系中,其他坐标系推导也类似,这里不进行阐述),
那么(x1,y1)坐标可以表示为
x1=rcosφ, y1=sinφ;
(x1,y1)旋转θ角度后为(x2,y2)坐标可以表示为
x2=rcos(φ+θ)=rcosφcosθ-rsinφsinθ=x1cosθ- y1sinθ;
y2=rsin(φ+θ)=rsinφcosθ+rcosφsinθ=y1cosθ+ x1sinθ;
因此,在圆坐标系中,(x1,y1)逆时钟旋转θ角度后,得到的(x2,y2)坐标为
x2=x1cosθ- y1sinθ;
y2=x1sinθ+y1cosθ;
这个就是圆坐标系的旋转公式。通过提出因数cosθ ,方程可写成下面的形式
x2 =cosθ(x1 – y1 tanθ)
y2= cosθ(y1 + x1 tanθ)
如果去除 cosθ项,我们得到 伪旋转 方程式
x2’ =(x1 – y1 tanθ)
y2’= (y1 + x1 tanθ)
即旋转的角度是正确的,但是 x 与 y 的值增加1/cosθ 倍 ( 由于1/cosθ大于1,所以模值变大),为什么要去除cosθ,是因为去除后可以简化坐标平面旋转的计算操作。
其中Z为角度累加器,di为旋转因子
随后由于我们进行的旋转的过程活忽略了旋转点模的改变因此我们引入伸缩因子K去修正这个参数。
该算法可以分为两种模式,即旋转模式与向量模式,其基本原理图如下图所示:
Aishwarya Kagalkar团队[4]构建了如下图的计算模式通过CORDIC算法实现了指数和除法的运算从而实现了Softmax函数。他们通过 16位定点数实现CORDIC算法。
基于CORDIC的算法在面积和时间方面都明显更好,而所有方法的精度几乎相同。 因此,当涉及到Softmax实现时,CORDIC算法是重要的方向之一,因为它在面积和时间方面同时提供了改进,同时不会降低计算结果的准确性。 当Softmax 比较了基于CORDIC的逆函数:虽然最初认为Softmax逆算法由于没有除法运算而更优,但在逆函数中时间和面积增加了 分别为20%和25%。
从基本的原理上我们可以这样剖析:
基本处理单元由三个加法器和一个 LUT (储存角度), 外加两个移位操作构成。 这正是 CORDIC 算法的优势。 由于每次迭代所用到的处理单元基本结构是一致的, 只是移位量和存储角度不同, 据此可得三种 CORDIC 算法硬件实现架构, 即串行结构、 并行结构和并行流水结构,串行结构占用的资源最少, 这缘于对 CORDIC 处理单元的分时复用, 也正因此使得控制单元设计略显复杂, 时序控制较为烦琐, 系统处理速度较低。 并行结构是对串行结构的扩展, 对每次迭代赋予了独立的 CORDIC 处理单元, 从而无须控制电路, 只需移位、 加减操作。 这是与串行结构中 CORDIC 处理单元最大的不同。 显然, 相比于串行结构, 并行结构消耗的资源显著增加。 为了提高系统处理速度, 对并行结构添加流水寄存器, 这即为并行流水结构。 它有效地缩短了关键路径, 使得关键路径的长度由并行结构的 N 个 CORDIC 处理单 元 变 为 1 个 CORDIC 处理单元。 因此, 并行流水结构具有最快的处理速度, 而这是以消耗更多的资源换取的。
其串行结构的原理图如下:
并行结构的原理图如下:
借鉴多个参考资料,总结下来CORDIC算法就4点:
(1)CORDIC算法就是通过伪旋转来简化计算,期间需要注意与圆坐标系旋转之间的关系。
(2)旋转模式就是从X轴上一点,伪旋转到某个角度的坐标点的过程,该模式下可计算cosz和sinz。
(3)向量模式就是从某个角度的坐标点伪旋转到X轴上一点的过程,该模式下可计算角度值。两个模式的旋转恰好相反
(4)FPGA的实现时注意数值与角度的量化标准
(5)目前只介绍了圆坐标系的CORDIC算法,延伸到线性坐标系或双曲线坐标系,都可以推导以及实现三角函数计算,除法运算以及指数运算。
但是其实我们综合来看,CORDIC算法虽然消耗的资源较少,但是由于伸缩因子和伪旋转的引入将大大减少函数的精度,并且我们需要进行的计算虽然简单但是需要进行重复的计算需要消耗大量的时间。
泰勒级数展开法
其实从根本意义来讲我们用泰勒级数展开的方式实现Softmax函数从根本上来来说是运用泰勒级数展开公式来实现ex的过程,其核心的公式如下:
通过基本的泰勒展开公式中我们能够发现如果在硬件的角度泰勒级数展开的实现ex的过程中天然存在着一个比较矛盾的问题,即硬件规模和阶数之间的矛盾很显然,在计算的时候阶数越高函数的精度也自然越高,但是从泰勒级数的展开式上看当阶数上升时在硬件结构的实现时候会消耗大量的乘法器,这对硬件资源是一种极大的消耗,那么如何均衡这两者之间的问题。
目前Fabrizio Lombardi [6]团队提出了一种基于基底查表和泰勒级数展开相结合的方式如下图所示,总结起来主要思想归结如下:
•利用近似的LUT提出了一种新的指数单元硬件结构。所提议的指数单元被划分为由ram实现的几个部分。它使用泰勒级数展开在最低有效位数据中执行近似计算。
•除法被转换为简单的移位和减法运算,通过简化余数运算得到近似结果。
其中ex的的硬件实现为如下图:
实现了一个常规的LUTs要求将其划分为若干段,每段代表该定义域对应的指数函数值。然后利用乘法器得到最终值。该方法所需资源少,在保持较高精度的前提下,实现了较高的性能。同时对比[8][9]的硬件设计来看具有较好的精度和运行速度,具体数据如下图所示:
多项式拟合法:
多项式曲线拟合是指根据给定的 k 个点,通过近似逼近这些点,拟合出相似曲线通过拟合的方式来调节对ex 的拟合精度但是从根本上来说多项式拟合法和泰勒级数展开的形式有很大的相似之处但是也面对相似的问题。黄静[10]等人设计通过在 Matlab 工具上调用Ployfit 函数,产生二阶多项式拟合系数。首先对Softmax函数进行如下变换:
经过上面的公式变换,使得原来以e为底变为以(1/e)为底。需实现的指数值域变为(0,1],范围大大缩小,指数的幂从 0 开始,这将有效限制指数拟合模块的输入范围。巧妙解决了原定义式中“e指数值域范围过大,硬件设计难度较大”的问题,另外,通过拟合的系数不等额划分法,提高了设计的精度,减小了系数查找表的占用的存储空间。
随后通过硬件加速通过 AXI4 读写通道对 DDR 进行读写操作,实现和 ARM 硬核的数据交互。下图为该设计的设计思路图:
控制测试模块重复发出启动信号,每次启动刷新将要输入的数据、控制寄存器值和用于验证的标准结果,检测到 done 信号后,记录验证的结果。另外 AXI 从机用于存储数据,供多个 AXI 主机设备读写。其他部分就是加速器、写入测试集与读取结果的 AXI 主机设备。通过顶层模块仿真波形图显示,AXI 读写通道 burst 触发正确。
根据 Synplify 的时序评估报告,系统最高数据传输速率达到 130Mbps,芯片资源消耗为 5906 个LUT、3037 个FF以及 16 个 DSP 硬核。实现了高速低功耗的性能预期设计目标。
参考文献
[1] Di Franco F, Rametta C, Russo M, et al. An hardware implementation of the softmax function on FPGA[C]//Proceedings of the International Conference for Young Researchers in Informatics, Mathematics, and Engineering 2020. CEUR-WS, 2020, 2768: 21-25.
[2] Sun Q, Di Z, Lv Z, et al. A high speed softmax VLSI architecture based on basic-split[C]//2018 14th IEEE International Conference on Solid-State and Integrated Circuit Technology (ICSICT). IEEE, 2018: 1-3.
[3] Kouretas, Ioannis, and Vassilis Paliouras. ”Simplified hardware implementation of the softmax activation function.” 2019 8th International Conference on Modern Circuits and Systems Technologies (MOCAST). IEEE, 2019
[4] Kagalkar A, Raghuram S. Cordic based implementation of the softmax activation function[C]//2020 24th International Symposium on VLSI Design and Test (VDAT). IEEE, 2020: 1-4.
[5] Cardarilli G C, Di Nunzio L, Fazzolari R, et al. A pseudo-softmax function for hardware-based high speed image classification[J]. Scientific reports, 2021, 11(1): 1-10.
[6] Gao Y, Liu W, Lombardi F. Design and implementation of an approximate softmax layer for deep neural networks[C]//2020 IEEE International Symposium on Circuits and Systems (ISCAS). IEEE, 2020: 1-5.
[7] Q. Sun, Z. Di, Z. Lv, F. Song, Q. Xiang, Q. Feng, Y. Fan, X. Yu, and W. Wang, “A high speed softmax VLSI architecture based on basicsplit,” in Proc. 14th IEEE International Conference on Solid-State and Integrated Circuit Technology, 2018, pp. 1–3
[8] Q. Sun, Z. Di, Z. Lv, F. Song, Q. Xiang, Q. Feng, Y. Fan, X. Yu, and W. Wang, “A high speed softmax VLSI architecture based on basicsplit,” in Proc. 14th IEEE International Conference on Solid-State and Integrated Circuit Technology, 2018, pp. 1–3
[9] X. Geng, J. Lin, B. Zhao, A. Kong, M. M. S. Aly, and V. Chandrasekhar,“Hardware-aware softmax approximation for deep neural networks,” in Proc. Asian Conference on Computer Vision. Springer, 2018, pp. 107–122
[10] 周维康, 王才才, 张皓清, 等. 采用软硬件协同设计的 SoftMax 函数的 FPGA 实现[J]. 信息通信, 2019 (10): 59-60.