众所周知,深度学习的成功依赖大量神经网络的深度模型,这些模型的存储量可以达到几十兆Bytes到几百兆Bytes,在训练期间更是会达到十几亿次的运算。例如,我们熟悉的ResNet50,其权重和激活的存储量在int8格式下分别为25.5MB和10.1MB,计算量有77亿次。这样的算法复杂性给AI的广泛部署带来了巨大挑战,特别是在资源受限的边缘测环境中,在内存、功耗和模型精度方面都面临严重挑战。因此,对算法模型进行优化,是非常必要且势在必行的。
目前的AI芯片算法优化主要有三个方向:降低位宽、模型压缩、增加稀疏性。这些方法有些已有成熟的产品实现,有些则还停留在实验室样片阶段,通常都需要专门的硬件来支撑。
模型参数的数值精度(或称位宽)会影响到网络训练和推理的性能及效率。深度学习的一个特征是,它不需要很高的计算精度。降低CNN权重的位宽,可以显著降低存储要求和计算复杂性,因此受到越来越多的关注。但不当的量化会带来输出精度的损失。为了避免降低数值位宽之后引入的AI系统在训练阶段的精度损失,近年来很多研究人员对此做了大量研究,并提出了各种改进方案。例如,"多种精度混合"的自适应方法,会根据不同的需求进行位宽的灵活变换,从而在满足降低存储和计算量的同时,最大限度地保持训练精度。再比如,Google发明的16 bit脑浮点(Brain Floating Point, bf16 或bfloat16),与fp16相比增加了动态范围,与fp32相同,但能以fp32一半地位宽完成任务,从而使吞吐量翻倍,内存需求减半。bf16格式一直是第二代和第三代TPU的主力浮点格式,且也逐渐得到因特尔、ARM和一些初创公司的采用。
目前,通常采用的方案是,使用较高的数值精度用关于训练,较低的数值精度用于推理。有些芯片可以支持16/8/4甚至1bit的推理精度。一些商用芯片如Nvidia的Pascal、Google的TPUv1、TPUv2和TPUv3,Intel的NNP-L都采用了量化技术,训练采用16位浮点,推理使用8位整数。
但在实际使用中,需要根据场景来调整位宽与精度的选择,对于普通的图像处理、语音识别等应用,少量误差并不影响整体系统的质量,但对于像智能驾驶等对精度要求极高的场景,往往仍采用32位整数加法和16位整数乘法。
不过,随着技术的发展,低位宽会是未来的一个趋势。
在深度神经网络中,有许多值是0、接近0或者重复的值,这些值进行MAC(乘加运算)运算没有必要,因此可通过修剪和压缩的方式对其进行优化。
修剪的目的是使用稀疏矩阵技术有效地存储矩阵,甚至可以去掉不重要地单个权重,并能将其传递到硬件加速器。修剪的类型包括:修剪层数、修剪连接数、修剪神经元数量、修剪权重数量。
在数据量化之后,往往还会采用霍夫曼编码,以进一步降低网络的存储量。实验数据表明,对非均匀分布值进行霍夫曼编码可以节省20%的网络存储量。
剪枝和压缩可以大大减少存储器带宽,可把一个1GB规模的网络缩减到20~30MB,从而可只用片上SRAM进行数据存储,达到AI网络向移动终端部署的目的。
二值神经网络(Binary Neural Network, BNN)是通过将DNN前向传播中使用的权重二值化来消除乘法运算的技术。二值化网络仅约束两个值(0和1,或-1和1),使得乘法运算可以通过简单的加法(或减法)运算来执行,从而加快训练和推理速度。
有两种方法可以将实数值转换为相应的二值:确定方法和随机方法。
确定方法是直接把阈值技术应用与权重:
而随机方法是使用硬S形函数的概率将矩阵转换为二值网络。
BNN可以显著减少存储量和访问量,并通过逐位计算取代大多数算术运算,从而大大提高能效;二值处理单元用于CNN时,可节省60%的硬件复杂性。有人将二值网络在ImageNet数据集上进行了测试,与全精度AlexNet相比,分类精度仅降低了2.9%,而且由于其功耗小,计算时间短,使得通过专门硬件加速DNN的训练过程成为可能。
还有人提出了三值网络,即使用二位权重表示三个值。这种方法几乎不会降低精度,可以通过定制电路加速。
对于同一个神经网络来说,不同的应用,或者同一个应用的不同运算阶段,所需的数值精度可能会有差异。例如,有的应用可在中间层使用较少的位宽,达到DNN的最佳性能和输出精度之间的权衡;又比如,一个DNN的每一层都可以有不同的量化;甚至,网络同一层里面的数值精度也可以不同,可以是8 bit x 8 bit,也可以是2 bit x 4 bit,等等。因此,把芯片做成“可变精度”将会是一个较好的解决方案。
芯片硬件虽然是固化了的结构,但是仍然有办法使其做到“可变”。下图展示了实现硬件可变精度的几种方法:
近年来,位串行架构受到研究人员的重视,并已在一些先进AI芯片中得到应用。这是因为,位串行计算中,整数乘法可以表示为二值矩阵乘法的加权和,因此,位串行方案为研究人员提供了一个使用二值矩阵乘法加速器来计算任何精度矩阵乘法的可能性。
那么,什么又是迁移精度?
针对系统以同样精度运行造成资源浪费的问题,迁移精度可以根据不同的需求进行精度自适应,从而降低功耗、提高性能。
迁移精度可用于近似计算中。在使用迁移精度的计算框架中,可通过细粒度的硬件对精度进行分布式控制,使用可扩展、基于反馈的运行方式,并以一种可在线跟踪误差的编程模型来调整操作参数。下图表示了迁移精度和传统计算之间的比较。
按照自适应迁移精度的思路,有研究人员提出精度混合方法,即根据需要,混合使用二值、三值、8位整数和16位浮点数运算。
但不管是以上提到的可变精度、迁移精度还是混合精度,都需要增加不少额外电路来支撑硬件实现,需要设计者在受益和成本之间做出权衡。
对卷积层使用较小的卷积核替代较大卷积核,可以减少网络结构的内部操作和参数量。例如,一个5x5卷积核可以使用两个3x3卷积核替代;一个7x7卷积核可以使用3个3x3卷积核替代。这是因为,对于每个矩阵元素,7x7卷积核的运算量是49,而3个3x3卷积核的运算量仅为27。
这种方式与在第2节提到的剪枝方法类似。稀疏性包括权重的稀疏性和激活值的稀疏性。对于权重的稀疏性,可以省略整行、整列、卷积核、通道或内核来实现,如下图所示。
对于激活函数的稀疏性,则可以使用ReLU激活函数或最大池化。
进行稀疏性处理后,权重和激活矩阵中非零值的数量分别可降至20%~80%和50%~70%。但稀疏性处理会损失一定的输出精度,且需要额外的逻辑电路,视线中需要做好权衡。
参考材料: 《AI芯片:前沿技术与创新未来》