FasterTransformer 2.0优化——公开课听课笔记

    2020.04.09英伟达就FasterTransformer 2.0做了一个线上的公开课分享,由于老板的要求,我也报名听课了。做了一份听课笔记,分享一下。这里的优化主要是由底层的CUDA和cuBLAS编程支撑的,这个代码我是没有去看的,也是看不懂的。听课笔记主要就宏观的原理上进行一个总结。

 

目录

一、FasterTransformer 1.0版关于encoder的优化

二、FasterTransformer 2.0版相关优化

2.1 FasterTransformer 2.0 新增加功能介绍

2.2如何针对decoder和decoding进行优化

2.3如何使用decoder和decoding

2.4 Decoder和decoding能够带来什么样的加速效果

总结:


一、FasterTransformer 1.0版关于encoder的优化

 

英伟达开源的 FasterTransformer 1.0版本中,针对BERT中的 Transformer Encoder进行了优化和加速,经过高度优化之后,降低了用户使用transformer编码的时延。主要做的工作是:

  1. 为了减少kernel调用次数,将除了矩阵乘法的kernel都尽可能合并
  2. 针对大batch单独进行了kernel优化
  3. 支持选择最优的矩阵乘法
  4. 在使用FP16时使用half2类型,达到half两倍的访存带宽和计算吞吐
  5. 优化gelu、softmax、layernorm的实现以及选用rsqrt等

这里的kernel定义主要是指在tensorflow里的概念是operation的计算实现,在cuda里是执行一个线程的函数,也是一次计算,只不过tensorflow的更加宏观些。每次tensorflow执行一个operation,都要调用对应的OpKernel,试想一个通过TF实现的transformer,有将近60个operation,计算一次要执行60次上述过程,进行频繁的GPU调度和显存读写。

 

优化原理:

Faster Transformer只用了14个kernel就完成了原来将近60个kernel的计算逻辑。这其中8个kernel是通过调用cuBLAS接口计算矩阵乘法(绿色框),其余6个是自定义kernel (蓝色框),把kernel合并减少了。。

Faster Transformer还优化了前向计算中耗时较高的GELU激活函数,Layer Normalization以及SoftMax等操作。比如利用warp shuffle实现高效的矩阵按行求和操作, 将1/sqrtf计算替换为rsqrtf函数,以及power (x, 3.0) 替换为x * x * x等。

计算流程图:

二、FasterTransformer 2.0版相关优化

 

2.1 FasterTransformer 2.0 新增加功能介绍

Transformer的计算量很大,推理的时延是不太适合工业界的需求的。Bert中使用了很多层的Transformer结构。Transformer结构由encoderdecoder。单纯的encoder架构优化后性能很好了。下图中encoderdecoder的一些对比,在encoder-decoder的架构中,decoder使用了大概90%的时间。

另外Decoder解码的过程一次只能解码一个字,因此做解码的过程中就需要多次使用到decoder,这过程就对GPU就不是很友善。

经过测试后,发现仅仅优化decoder,效果是不太好的。因此提出了一个更大的模块就是decoding,对decoding也做优化,可以进一步提高效率。

 

decoding的流程中,会在while循环中多次调用decoder。首先就需要对decoder进行优化,然后对其他的例如beamsearch等进行优化。

2.2如何针对decoderdecoding进行优化

Kernels太小了,又需要很多次kernel操作,导致GPU有很多时间限制的。

CPU启动Kernels、GPU计算Kernels。

图中的蓝色方块就是GPU计算的耗时,白色方块就是闲置时间。

TensorFlow中的LayerNorm就需要很多个kernel来完成,如下图:

怎么来优化呢?优化思路如下:

  1. 矩阵计算单独拿出来,因为矩阵运算使用了cuBLAS——高度优化的库,很高效。
  2. 把非矩阵计算的部分kernels尽可能的合并在一起。

24个kernel减少到14个kernel;单层的Transformer就优化了。

上图结果显示,kernel是变大了,但是GPU还是有一些闲置,但是已经得到了很好的优化了,闲置明显减少了。

Decoder的优化同样的是和上述思想类似

需要70个kernels——优化后减少到16个

其他的一些优化:

Decoding中需要使用beam search,针对这个优化——topk——GPU并行计算,Fuse the “add bias” and “SoftMax” in beam search。

Half2 使得每次读写2个FP16这样就是的速度加快

特定的kernels,比如softMax FP32和FP16是不一样的要单独拿出。

2.3如何使用decoderdecoding

源码中有具体的例子和指导,详情略。

2.4 Decoderdecoding能够带来什么样的加速效果

仅仅使用encoder的优化。。提速1.5倍。当然还有一个规律也就是batch_size越小,提升效果越好。

Decoder翻译任务

首先batch_size =1,效果如上:单独使用decoder和decoding,提速分别为3.5倍和8.3倍

FP32数据类型比FP16加速更好!F16可能会丢失一点精度。

总结:

优化原理——Kernels融合

也就是batch_size小的时候,kernel变小了,kernel的数量变多了。主要的耗时就是CPU启动——CPU调用一个函数——而等待的时间导致效率很慢,启动以后,GPU然后再计算;另外GPU的计算不是很长。当kernels很多的时候,CPU启动的时间就很多了,导致整体的时间变长;所以融合后就减少CPU启动kernels的时间,从而提升了效率。

Kernels的大小一般都是和batch_size的大小正相关的,batch_size越小kernel就越小,反之就越大。

目前fastTransformer都是基于TensorFlow来进行优化的,未来是支持pytorch OP的 ,也就是说pytorch中以后也可以使用这个优化的。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值