AI芯片怎么降功耗?从ISSCC2017说起

AI芯片怎么降功耗?从ISSCC2017说起

鸿鹤鸿鹤

本文适用读者:对Deep Learning算法有一定了解的IC工程师,对IC设计和计算机架构有一定了解的算法工程师。


尝试从ISSCC2017的session 14 Deep Learning Processor的几篇文章出发,分析一下同行们都用了哪些方法来降低DL 加速器和处理器的功耗,提高能效。水平有限,欢迎指教。

先来一张slide镇镇场,tutorial上Verhelst总结了近几年VLSI和ISSCC会议上发表的一些结果。其中,灰色的图标应该都是ISSCC2017以前的结果。这张图体现了性能、错误率、能效三方面的trade off。性能上,大家似乎很难超越GPU,但是能效上,可以算是秒杀。大家都喜欢拿自己的数据和NVIDIA的GPU比较,然后可以给出很漂亮的对比结果,甩出NVIDIA几条街。
但是大家也不要兴奋,学术界成果给出的数据,总是不能闭着眼睛就接受的。大家都是过来人,都懂的。


目录
1。使用低功耗工艺。涉及14.1,14.5
2。降低数据计算功耗
2.1降低weight量化位数。涉及14.2
2.2优化乘法。涉及14.2
2.3降低计算精度。涉及14.5
2.4稀疏化。涉及NVIDIA,combricon,leuven
3。降低数据翻转功耗。涉及14.3
4。降低数据存储访问功耗。涉及14.6,14.7
5。存储器上的新花样


  1. 使用低功耗工艺

一般提到低功耗工艺,可能大家普遍想到的还是foundary的low power工艺,HVT/LVT library等。
在ISSCC 2017的session 14上,出现了SOI工艺的身影。有几家以可穿戴或IOT为应用目标的研究机构已经使用SOI工艺来做DL processor了。

下表列出了ISSCC2017上的几篇文章使用的工艺。session中有有两篇使用了FDSOI工艺,Forum中,ETH Zurich的PULP项目的芯片也使用了28nm FDSOI。

作为做IOT等低功耗产品所喜欢的工艺,FD-SOI工艺的优点是,
a。well和衬底 间的寄生电容很小,漏电小,减少了静态功耗。
b。可以通过控制Body Bias的电压,来控制晶体管的工作。如果加入正偏压,可以提高器件响应速度,增强性能;如果加入负偏压,相当于可以关掉晶体管,使晶体管只有很低的漏电流,大概是1pA/micron的水平。这种方式关闭、开启电路器件的方式,要比power gate控制速度快。
不过,工艺这件事,不是你想用哪家就可以用哪家的事情。ISSCC上发文章的都还是以高校研究院所为主。对他们来说,SOI工艺的成本还是太高。你看KAIST的文章,前两年是65nm,这两年的文章还是以65nm为主。

2. 降低数据计算功耗

14.1的文章用图形显示现在流行了几家Net里的操作以及参数的数量级。可以看到,为了解决更复杂的应用和提高准确度,操作数量和参数数量都很吓人。

从14.1的另外一张图中可以看到,对于AlexNet的不同layer,操作和参数的数量是不同的。尤其是,对于卷基层和全连接层,操作以及参数的数量都差别较大。
这里补充一张tutorial上Verhelst引用的统计图(在其他多篇介绍性文章内都看到过),可对目前常见的网络参数规模有所认识。

再看14.2的一张图,对于卷基层、全连接层和RNN,操作和参数的数量差别也很大。不用太纠结与14.1的区别,14。2这里没有提这些模型参数的具体来源。



因此,直观地,在不能大幅降低算法精度的前提下,为了降低功耗,可以拍脑袋想出好几方面
a.减少参与操作的数据或参数的数量。例如,稀疏化方案。
b.减少操作数的字长。例如,降低weight量化位数。
c.减少操作的复杂度。例如,优化乘法计算,降低乘法计算的精度。
下面就带着读者来看看ISSCC上各家高手们是怎么在这几方面各显神通的。



2.1 降低数据计算功耗之——降低weight量化位数

14.2提出了一种在线调整的动态定点方法。从给出的对比图中可以看出,这个方法可以只使用4bit来量化weight,达到其他方法8bit的精度。

这个方法的理论基础是,对于每一层,weight的最大值是不一样的,weight参数的分布也是不一样的。在我们知道weight分布大概是一个高斯分布的基础上,可能只需要关心3个σ以内的weight数值。那么,每一层有效的weight数值的取指范围就会不一样。如果,将每一层weight数值都乘以一个不同的系数,例如,左移或右移几bit,那么,就有可能将不同层的weight分布转换为相同或相近的分布形态。进一步的,就可以在保留精度的基础上,用相同的bit来进行量化。



理论基础很简单,所以必然是有牛人认识到这个问题的。14.2引用的一个方法是基于离线学习的动态定点方法,就是在训练学习的过程中确定每一层weight表示的小数点位置。这是依赖于训练数据的。
14.2的方法是在线调整的动态定点方法。在实际计算过程中,每层根据累加器的计算溢出情况,修改一次fraction point位置。

从其给出的结果看,全部使用4bit字长来表示weight,效果还不错。除了最初几帧,使用4bit字长所能得到的score,和使用32bit浮点的结果是差不多的。
从能效的对比结果看,还是很有效果的。但是,文章中的能效数据的提高,并不只是依赖于这个方法(还是用了基于LUT的乘法,稍后介绍)。


BNN
比4bit更激进的,可以是2bit。最极端的,weight可以是1bit。当weight变为1bit的时候,就成了一种特殊的网络——BNN(binary neutral network)。
近来研究BNN的也不少,只是ISSCC2017的正式论文里还没有专门针对BNN的。ISSCC2017最后一天的forum里(forum好贵),来自ETH Zurich的PULP项目做的处理器对BNN的计算进行了专门优化。需要赞的是,他们的加速器的名字比较牛——YodaNN。Yoda,对,就是Starwars 里面的绝地武士,Yoda大师,"small in size but wise and powerful"的Yoda大师。亲爱的做IC的兄弟们,“May the force be with you”。


2.2降低数据计算功耗之——优化乘法电路

可以接着上一节继续说了,还是14.2这篇文章,用查找表的方式来代替乘法运算。
作者将输入乘法器的16bit数据分割为4个4bit数。16bit乘法变成4个4bit乘法然后求和的运算。为了快速实现4bit乘法,作者使用了查表的方式。作者将weight的奇数倍结果预先存到LUT内(偶数倍不需要真的存下来),乘法就变成了查表。这个方法是要结合这篇文章的动态策略(见上一节)来使用的。
看到这里,如果你想问“这种形式的乘法器和16bit直接乘相比,究竟能省多少功耗?”,那么说明你可以在工程师这条路上走的更远、飞的更高。答案,我也不知道。除了图里显示的逻辑电路,你还得考虑,weight的宽度,weight的选择电路实现,等等。理论上,weight的宽度是不限制的。但是,weight的宽度会影响部分积PP0/1/2/3、部分和PS1/2的宽度。
14.2中,最后将w的宽度定为了4bit。
14.2还提出了一种基于量化表的乘法实现方式,以降低全连接层(FCL)的计算功耗。作者将训练得到的FCL的浮点weight值进行非均匀分布的量化。可以是4-7 bit的量化。以4bit量化为例,得到16个量化后的weight值,然后针对一个输入数据i,分别乘以16个weight值,计算得到16个乘法结果,存为table。14.2的设计中,如果是4bit量化,可以同时存8个这种table(如果对weight做7bit量化,只能存一个table)。在做FCL计算时,先取8个数点,得到8个table,然后把这8个输入点相关的所有MAC计算做完,可以得到输出点的部分和。然后,再选另外8个输入点,产生新的8个table,继续计算部分和。不断循环,得到输出层的所有结果。基于这种方法,除了建立table,所有乘法计算都被替换成了查表。

根据文章描述,减少了99%的乘法计算量,降低了75%的片外存储器的带宽。这对降低功耗都是有积极贡献的。从对比结果看,能效优势明显。哦,对了,需要提一下,用来对比的是han song的EIE那篇文章,电压一栏的数据明显不对(不要赞我有一双发现美的眼睛)。


2.3降低数据计算功耗之——降低计算精度

其实,前面说的降低weight的量化位数,也可以算是一种降低计算精度。只要能满足应用需求就行。
但是,这一节说的降低计算精度,是另外的事情。

14.5文章里,提到了DVAFS。作为一个IC工程师,DVFS自然知道的。那么DVAFS是什么鬼?看英文,Dynamic-Voltage-Accuracy-Frequency-Scaling。好吧,字面意思知道了,具体呢?

其实,Dynamic Accuracy并不是ISSCC2017的文章里首次提出来的概念。14.5的文章作者Moons引用了自己JSSC2016上的文章,见图。有的时候,两个4bit数相乘时,结果的LSB可能并不重要,只需要MSB结果就可以了。于是,直接算一下两个4bit数的高2bits相乘的结果就可以了。这就是dynamic accuray的概念了。至于,什么时候需要4bit乘的结果,什么时候只需要高2bit乘的结果,谁知道呢。动态的意思就是说,自己看着办吧。对结果准确度要求高的时候,用4bit乘吧;对功耗要求高的时候,用2bit乘吧。你开心就好。

既然提到了DVAFS,就简单说说吧。上面提到的DVAS中,如果只做2bit乘,会有其他3/4的乘逻辑没有工作。此时,可以利用其中的一部分,同时做另外一个2bit乘法。这样,同时就做了两个2bit乘法。从效率角度看,相当于频率提高了一倍。
14.5中,根据算法或应用需要,可以动态配置乘法器,为一个16bit乘法,或者是2个8bit乘法,或是4个4bit乘法。这就是DVAFS和DVAS的区别了。
有心的人可能早就发现了,14.2中基于LUT的可配置乘法器也是可以当做4个4bit乘、2个8bit乘或是1个16bit乘的。哎呦,不错哦。

2.4降低数据计算功耗之——稀疏化

(ISSCC2017对稀疏化没有特别值得谈的亮点,本节纯属赠送)
稀疏化是Deep learning算法的一个趋势,对硬件加速器或处理器的设计实现有较大的影响。但是,稀疏化并不是为了降低功耗而出现的。先有算法的稀疏化,然后设计加速器和处理器的吾等苦*们就要考虑如何应对这种奇葩的情况。
先简单扫盲一下,稀疏化可以分为feature稀疏化和weight稀疏化。
feature稀疏化:feature经过卷积计算后,再经过ReLU,就会变得稀疏。找张图看吧,不多说了。
weight稀疏化:用来做卷积的kernel中的weight参数,可以有一部分为0。
如果不管稀疏化,还用原来的加速器或处理器来执行稀疏化后的算法,那么就会有很多浪费的存储和计算。所以,稀疏化给IC工程师带来了一些列问题。
-ReLU计算之后的0值,要不要存储到片外memory或片内sram内?
-稀疏化的weight参数,怎么存储?0元素要不要存?
-大量的0元素,如果存在memory里,很浪费空间。如果不存,电路读feature或weight的时候,怎么知道哪些数据是0,哪些不是?
-有0元素参与的乘运算,怎么处理?调用MAC直接计算一下a*0?还是直接bypass MAC?
ok,好多问题。有没有一脸的懵圈?
真想看看同行们是怎么做的,遗憾的是,ISSCC2017上的几篇文章,都没有太多针对稀疏化的新的亮点。那就用上搬山、 卸岭之能,开动发丘、摸金之术,随便看看吧。

LEUVEN的ENVISION
来自leuven的14.5的这篇文章里,提到使用了sparse network。但是,这不是他们今年的新亮点,这是他们VLSI2016上的工作。见图,sparsity的信息存储在GUARD SRAM中,用来控制乘法器模块是否进行计算。如果乘数为0,FRD SRAM中的index会是0,就会关闭相应位置的乘法,节省计算功耗。

直接上VLSI2016上的文章的截图。在GRD SRAM的帮助下,功耗可以优化1.9x。借用moons这篇文章的一张表,可以看到稀疏化带来的好处。




Eyeriss
由于在ISSCC2017会场见到了vivienne,就把她们ISSCC2016的牛文eyeriss拿出来说说吧(这奇怪的逻辑也是没谁了)。
Eyeriss在处理稀疏化的feature上的做法是:压缩。设计了一种压缩方式,将稀疏化的feature压缩后存储到外部DRAM内。效果呢,如下图,可以降低存储空间。考虑到DRAM访问的功耗不小,也算是降低了功耗。
在处理有关0值参与的乘法运算时,eyeriss使用了skip的方法:遇到0,跳过乘法计算(从图上看,实际是计算的0*0),跳过weight参数的读取,可以节省PE的功耗45%。

总结一下,针对稀疏化,eyeriss做了三点:不从ram中读0值,不做乘0的乘法,压缩片外数据存储。都可以降低功耗。



此外,还有两个报告提及了稀疏化。

NVIDIA
NVIDIA在ISSCC2017最后一天的forum上做了报告。
NVIDIA报告基本上都在讲Han Song的那篇EIE的peper,有兴趣的去翻翻吧。

寒武纪
同样在forum上,寒武纪的报告把diannao家族深情地回忆了一遍,没有提及cambricon指令集(ISA属于计算机架构了,ISCA上讲才合适嘛),也没有提及用于sparse neural network的Cambricon-X加速器(处女座要哭,作为DL加速器,竟然不是diannao家族成员。起名cambricon-X,竟然不是cambricon 指令集的扩展。这听起来不make sense啊)。
对cambricon-X感兴趣的,自行google学术吧。哦,对不起,上不去,百度学术吧。继续吐槽,百度挺不错的,能在最硬的国际会议的forum上做一个又虚又软的报告,也是能力的一种体现。

3. 降低数据翻转功耗

14.3文章中做了些有意思的工作,分析了一下weight的分布,发现weight是均值为0的高斯分布。如果用传统的二进制补码(TC)的方式表示,负数表示中为1的bit会很多。而如果用符号位+幅值(SM)的方式表示,可以降低为1的bit数,进而就可以减少计算的翻转率,从而降低计算功耗。
废话少说,直接上图。实验结果显示,SM的功耗略低于TC。下图,只看最左边三个数据既可以了。


4.降低数据存储访问功耗

借ISSCC2016的那篇Eyeriss的一张slide。可看到,数据访问所带来的功耗要远大于计算的功耗。因此,可以从两方面着手,降低系统执行Deep Learning算法时的memory访问功耗。
一,减少存储功耗。例如,前面说的稀疏化,减少了feature和weight,通过压缩或者特殊设计的存储方式,就可以降低存储空间。不再累述。
二,减少访问功耗。这方面今年有几篇文章都有亮点。

14.6
先看14.6的文章,又是KAIST的。不得不吐槽,看人家的IEEE Fellow,学生发ISSCC跟bbs上灌水似得(不知道bbs是啥的,没关系,说明你很年轻)。去年在ISSCC2016的session14上灌了4篇文章,今年在session14上灌了两篇。
书回正传,14.6首先将feature乘以矩阵kernel近似成了两步乘以向量的运算。然后,引入一种定制的7T bit-cell的SRAM,可以支持行方向和列方向两种读取模式,即其所谓的conventional r/w和transposed r/w。
分析一下,将矩阵分解成独立的两个向量,可以减少weight参数数量,减少weight读取次数;引入transposed r/w,可以一个周期读取列方向多个数据,可以减少访问sram列方向的次数。综合下来,给出的实验结果表明,可以降4.2倍activity factor。
但是,这不是功耗数据。从其分解的操作来看,对kernel为n*n的卷积运算来说,至少多做了n次乘法。并且,T-SRAM的面积是传统6T SRAM的1.4倍。所以,实际上T-SRAM的效果可能没有那么有吸引力。
在会议的Demo现场中,撞到KAIST的大佬HJ YOO,自然要讨论一下这个T-SRAM。HJ YOO很自豪地地表示这个T-SRAM是他们自己设计的,而不是三星给做的。并且,YOO Fellow说,如果google过他,应该知道他一开始就是做memory出身的。好吧,服了u。来来来,“May I take a photo with you?”咔嚓咔嚓。

14.7
这是Michigan大学的一篇文章。它将PE可以访问的memory分为四级,每级的大小不同。对于经常访问的数据,放在L1;很少访问的数据,放到L4。
这种做法的出发点很容易理解。sram size(图中的bank size)越大,每次访问所需的能量越多,也就是读取一个数据所浪费的能量越多。所以,将数据分级存储到不同size的sram中。存在bank小的sram的数据,虽然访问频繁,但是每次访问的能量少。存在bank size大的sram里的数据,虽然每次访问的能量大,但是访问次数少。
如果你以为这就结束了,那就太小看ISSCC文章的水平了。在不访问sram的时候,sram也是有静态功耗的。IC界处理这种情况的常用方法是,使用有retention功能的sram。在低功耗模式下,关闭sram 的工作电源,但是保留一个可以保持sram存储内容的电压。
这篇文章在使用有retention功能的sram的方式上,使用了动态控制的方法。除了动态控制正常的sram控制信号,还动态的控制sram的PG_EN信号。不只是动态控制不同level的sram,还包括每级sram里的不同bank。
从结果看,的确还不错。作为一个ICer,需要提的问题是:Dynamic Drowsy Mode下,SRAM的访问时间与alway on 比,有多少延迟?直接点,SRAM上电时间是多少?这个答案俺知道,不到100ns。如果系统跑在100M,要等10个周期。你要问这数据靠谱吗?只能告诉你,哥们用微信问的,信不信由你。


5.存储器上的新花样

Forum上,PULP用了SCM。第一次听说SCM,哥们有点慌,被业界甩了好几条街的样子。赶紧看看是什么鬼,原来就是用standard cell做的memory哈。摒弃标准6T的SRAM,用这个SCM,必然是有好处的。好处就是和standard cell一样,在VDD降到很低时,依然可以工作。对比之下,6T SRAM的工作电压只能降到0.7伏左右。


但是,没有绝对的事情。本人跑去听了ISSCC2017的另外一个session,这个session的主题就是“SRAM”。
先来一个ISSCC2016发布的总结性的趋势图。即使到14nm,SRAM的电压似乎也只能到0.75V。SRAM的VDD的降低程度,在40nm以后一直赶不上logic的VDD降幅。

session12.3的文章中,TSMC做了一个10nm的针对移动应用的sram。可以看到,这个sram的工作电压范围很宽。
最后,再来一个有意思的。这是会上的一个poster。作者在6T SRAM上,做了一个独特的电路,可以在SRAM内就做完乘法。例如,把4bit的weight存在sram内,然后根据输入的feature数据,编码得到4bit的控制时序,送入SRAM接口,然后既可以得到4bit乘法结果。听着是不是很高大上?跑个题,第一作者名字看着很像华人,一问才知,是个韩国人。只好英文交流,累死个人了。

结束语

“吾生也有涯,而知也无涯”,我掉Deep Learning的坑里了,拉你一把,一起掉下来吧。
「真诚赞赏,手留余香」
还没有人赞赏,快来当第一个赞赏的人吧!
文章被以下专栏收录
15 条评论
推荐阅读