所有产品

阿里将 TVM 融入 TensorFlow在 GPU 上实现全面提速

  雷锋网 AI 研习社按,日前,阿里机器翻译团队和 PAI 团队发表博文,阐述将 TVM 引入 TensorFlow,可以带来至少 13 倍的 batch 矩阵相乘(matmul)加速。雷锋网 AI 研习社将原文编译整理如下:

  神经机器翻译(NMT)是一种端到端的自动翻译方法,可能克服传统的基于短语的翻译系统的缺点。最近,阿里巴巴集团正致力于在全球电子商务中部署 NMT 服务。

  目前,我们将 Transformer() 作为 NMT 系统的核心组成。相较于传统基于 RNN/LSTM 的方法,它更适合于高效的离线训练,有着相同或更高的精度。

  Transformer 在时间步长中打破了相关性,对离线训练更友好,但在在线推理上,它并没有那么高效。我们在生产环境中发现初版 Transformer 的推理速度大约比 LSTM 版本慢 1.5 倍到 2 倍。为了提高推理性能,我们已经进行了一些优化,包括图级别的 op 融合、循环不变节点外提(loop invariant node motion)。我们观察到一个特殊问题:batch 矩阵相乘是 Transformer 中的一个关键问题,目前它在 cuBLAS 中的实现并未得到很好的优化。

  下图表明,通过 TVM 生成的内核可以带来至少 13 倍的 batch 矩阵相乘加速,伴随算子融合,速度将更快。

  我们在推理阶段对 Transformer 模型进行了全面分析,结果表明,batch 矩阵相乘计算的开销达到 GPU 内核执行时间的 30%。当使用 nvprof 对 cuBLAS batch 矩阵相乘内核做一些第一原理(first-principle)分析,很明显,这种方法的表现并不好,同时我们还发现几个有趣的现象。

  通常,batch 矩阵相乘计算会在一批矩阵上执行矩阵-矩阵乘法。batch 被认为是「统一的」,即所有实例都具有相同的维度(M,N,K)、leading 维度 (lda,ldb,ldc) 和它们各自的 A、B、C 矩阵的转置。

  在语言翻译任务中,batch 矩阵相乘的形状比在其他工作负载下的常规矩阵相乘计算要小得多。Transformer 的形状与输入语句的长度和解码器步长有关。一般来说小于 30。

  首先,我们在理论上对 batch 矩阵相乘内核进行了 FLOP 分析。结果非常有趣:所有 batch 矩阵相乘的计算强度都是受限的(TFLOP 数少于 1)。

  即使形状不同(在 M、N、K 间变化),所有 maxwell_sgemmBatched_128x128_raggedMn_tn 调用执行的都是相同的 FLOP 数,这比理论值大得多。从中可以推断,所有这些不同的形状最终都会被填充成确定的形状。在所有的形状中,即使在最好的情况下,理论 FLOP 只占实际执行 FLOP 的 2.74%,因此大多数计算都是多余的。黄金城娱乐,类似地,调用另一个 cuBLAS 内核 maxwell_sgemmBatched_64x64_raggedMn_tn 也出现相同情况。

  显而易见,cuBLAS batch 矩阵相乘的执行效率很低。基于这个原因,我们在 NMT 中使用 TVM 生成高效的 batch 矩阵相乘内核。

  现有的「黑盒」cuBLAS 库调用一般会作为常用的「op 融合」优化策略的边界。然而,利用生成的高效 batch 矩阵相乘内核,融合边界极易被打破,将不仅仅是各个元素之间的融合,因此可以获得更好的性能改进。

  从计算图中可以看出,batch 矩阵相乘之后总是伴随着广播加法运算或转置运算。

  通过将「加法」或「转置」运算与 batch 矩阵相乘融合,可以减少内核启动开销和冗余内存访问时间。

  在我们的工作负载中,batch 矩阵相乘的输入形状是有限的,易于提前枚举。有了这些预定义的形状,我们可以提前生成高度优化的 CUDA 内核(固定形状的计算可以带来最佳优化潜能)。同时,还将生成一个适合大多数形状的通用 batch 矩阵相乘内核,为没有提前生成内核的形状提供回退机制。

  我们将生成的针对特定形状的高效内核和回退机制集成到 Tensorflow 中。我们开发了一些融合操作,例如 BatchMatMulTranspose 或 BatchMatMulAdd——使用 TVM runtime API 为确定输入形状启动特定生成的内核或调用回退内核。

  通过执行图优化 pass,可以利用融合操作自动替换原始batch matmul + add/transpose。同时,通过结合更激进的图优化 pass,我们尝试利用 TVM 为长尾操作模式生成更高效的融合内核,以进一步提升端到端性能。

  在阿里巴巴,我们发现 TVM 是非常有效的开发高性能 GPU 内核的工具,可以满足我们的内部需求。

  在本博客中,我们以 Transformer 模型为例,说明了我们利用 TVM 的优化策略。

  首先,我们通过第一原理分析确定了 Transformer 模型的关键问题。然后,我们使用 TVM 生成高度优化的 CUDA 内核来取代 cuBLAS 版本(此时达到 13 倍的加速)。

  接下来,利用 TVM 的内核融合机制来融合 batch 矩阵相乘的前/后操作,以带来进一步的性能改进(性能提升 1.7 倍)。端到端的性能改善达到 1.4 倍。基于这些生成的内核,我们开发了一个图优化 pass,自动用 TVM 融合内核替换掉原有的计算模式,确保优化对终端用户透明。

  最后,所有这些优化都以松散耦合的方式集成到 TensorFlow 中,这展示了将 TVM 与不同深度学习框架集成的潜在方式。

  目前我们还有一项正在进行的工作——将 TVM 整合为 TensorFlow 的 codegen 后端。我们希望将来与社群分享更多成果。