作者:Sehoon Kim, Amir Gholami, Zhewei Yao, Michael W. Mahoney, Kurt Keutzer
发表单位:University of California, Berkeley 加州大学伯克利分校
会议:ICML2021
发表时间:2021.6.8
比较Transformer架构中应用于自我注意层的不同量化方案:
基本思想:利用多项式来近似非线性函数
挑战:找到一个好的低阶多项式,可以接近Transformer中使用的非线性函数。
原始GELU函数:
尝试过的方法:
a. 使用ReLU近似:GELU和ReLU在特别大正数/负数部分很相似,但是在0附近的值差异很大;
如下图片参考:https://blog.csdn.net/weixin_43791477/article/details/124871734
b. 直接求解 erf 积分项不靠谱,计算量很大
c. 根据前人的理论,使用sigmoid函数来近似erf(但是sigmoid需要浮点数计算,因此不可行!),需要再用h-sigmoid来进一步近似sigmoid,最后可以得到h-GELU,但近似误差还是太大。
本文方法:多项式近似
结果: 上图可以观察到,I-GELU(蓝色曲线)和原GELU函数(红色曲线)非常接近,特别是在0点附近的时候;h-GELU(黄色曲线)近似误差还是比较大;RELU(绿色曲线)就不用说了,本身在零点附近和GELU就不太一样。
分析结果: i-GELU的平均误差为8.2 × 10−3,最大误差为1.8 × 10−2。这比h-GELU的平均误差和最大误差分别为3.1 × 10−2和6.8 × 10−2的精度提高了3倍。此外,i-GELU甚至略优于基于Sigmoid的erf近似,但没有使用任何浮点算术。
这里的误差导致了后面i-GELU比h-GELU精度更好!
Softmax将输入向量归一化,并将其映射到概率分布:
以前的transformer都是用浮点运算处理这一层,但是不利于那些只支持整型运算的加速器的部署;
难点: 指数函数输入是无界的,一直在动态变化
尝试过的方法:
a. 查找表:占用内存大,不够优雅,因此要避免查找表;
b. 简单的多项式近似:需要使用高阶来近似exp,并且值越大,近似误差越大,需要高阶。
本文方法:限制范围的多项式近似
指数位先减去最大值,使得都是负数,类似pytorch当中防softmax溢出一样的操作;
然后将这个负数解码成如下形式,其中z是非负整数,p是(-ln2, 0)之间的一个浮点数
针对这个范围有限的exp§采用二项式来近似就很容易,且误差不会很大,最后得到的整型推理exp的形式如下:
上图绘制了i-exp的结果,它几乎与指数函数相同。发现这两个函数之间的最大差距只有1.9 × 10−3。考虑到单位区间的8位量化所引入的量化误差为1/256 = 3.9 × 10−3,因此,i-exp的近似误差相对可以忽略不计,可以纳入量化误差中。
LayerNorm在transformer中经常使用,它涉及到一些非线性操作,比如除法、平方根。此操作用于跨通道维度规范化输入激活。规范化过程描述为:
其中,μ和σ是输入在通道维度上的均值和标准差。这里的一个微妙的挑战是,输入统计数据(例如,µ和σ)在NLP任务中变化很快,这些值需要在运行时动态计算。计算µ很简单,计算σ需要平方根函数 。
简单地说量化LayerNorm函数难点就是动态计算方差。
本文方法:牛顿迭代法
牛顿迭代法,这块讲的比较简单,其实是取得泰勒展开式的前两项求方程根。
基于RoBERTa模型实现I-BERT,将原始RoBERTa模型中的所有浮点运算替换为本文的纯整型运算。其中,使用INT8精度来执行MatMul和Embedding,所有的MatMul操作都以INT8精度执行,并累计到INT32精度。此外,嵌入层保持在INT8精度。
数据集:GELU
baseline:FP32模型
实验结果:I-BERT 始终达到可比或略高于基线的准确性
实验结果:与FP32模型相比,在支持高效整数计算的专用硬件上部署I-BERT可以实现显著的加速。
另外,通过Nvidia的插件融合和加速Transformer架构中的关键操作,可能实现进一步的加速,可以期待比TensorRT提供的api快2倍。
使用GELU、h-GELU和 i-GELU进行GELU计算模型精度
实验结果
为什么i-GELU比GELU更好?还没有合理解释
I-BERT推荐读者读(姚明et al ., 2020)以了解更详细的quantization-aware微调integer-only量化的方法。