Categories
程式開發

腾讯微信团队开源推理加速工具TurboTransformers


近日,腾讯正式宣布开源Transformer推理加速工具TurboTransformers。该工具是面向自然语言处理领域中Transformers相关模型丰富的线上预测场景所提出的加速方案,已经在微信、腾讯云、QQ看点等产品的线上服务中广泛应用,这是腾讯通过GitHub对外开源的第100个项目。

TurboTransformers的诞生源于腾讯内部对开源协同的推动。2019年初,腾讯技术委员会成立,下设开源协同、自研上云两个项目组和对外开源管理办公室,以此来促进内部代码的开放共享和协同共建。TurboTransformers来自于深度学习自然语言处理基础平台TencentNLP Oteam,作为基础性技术版块,率先进行了开源协同实践,旨在搭建统一的深度学习 NLP (Natural Language Processing,自然语言处理)基础平台、提升研发效能。

TurboTransformers项目背景

TurboTransformers是一款小而美的Transformer加速工具,就像它的名字所寓意的,Turbo(涡轮)可以增加汽车发动机氧气含量,从而带来更大动力,使用TurboTransformers也可以让你的推理引擎更加强劲。

在自然语言处理领域,以BERT为代表的Transformers相关神经网络模型是近年来最重要的模型创新,可为阅读理解、文章摘要、语义分类、同义改写等NLP任务提供显著的效果提升。但提高模型精度的同时,Transformes相关模型也带来了更多的计算量。由于深度学习的训练和推理任务存在的差异,训练框架直接应用于线上推理并不能得到极致的性能。众多模型算法工程师都遇到了训练模型效果很好,但因为响应延迟不满足要求而无法上线的问题。

业界很多工具尝试弥合推理和训练之间实现差异的鸿沟,如onnxruntime、tensorRT、torchlib、XLA等,这些工作大多需要根据输入尺寸预先对计算图进行预处理和优化,以获得更好的推理时性能。与图像处理任务的输入常常没有变化不同,NLP推理任务输入尺寸多个维度会存在变化。实际推理时如果通过补零或者截断整理成固定的输入尺寸,则会引入了额外补零计算开销。因此,针对固定输入尺寸进行预处理优化的方案对NLP任务并不适用。

如下图比较了最典型的Transformer模型BERT和一些计算机视觉模型的计算量,可见使用Transformer的线上NLP服务部署更具挑战。鉴于BERT在各大互联网公司的广泛应用,非常必要实现一个能发挥充分CPU/GPU硬件计算能力的Transformer推理方法。

image

项目介绍

TurboTransformers可以让推理引擎更加强劲。具体来说,它具有高速、实用、简单三个特点:

  • 更优的CPU/GPU性能表现。面向Intel多核CPU和NVIDIA GPU硬件平台,通过核心融合和并行算法优化,TurboTransformers充发挥硬件的各层级并行计算的能力。在多种CPU和GPU硬件上获得了超过PyTorch/TensorFlow和目前主流优化引擎(如onnxruntime-mkldnn/onnxruntime-gpu, torch JIT, NVIDIA faster transformers)的性能表现。

  • 为NLP推理任务特点量身定制。TurboTransformers可以支持变长输入序列处理,无需序列补零、截断或者分桶带来的无用计算,也无需任何针对计算图在推理前进行预调优的过程。

  • 简单的使用方式。TurboTransformers支持python和C++接口进行调用。TurboTransformers支持TensorFlow和PyTorch预训练模型的载入。它可以作为huggingface/transformers的推理加速插件,通过加入几行python代码获得的BERT模型的端对端加速效果。

image

此前,TurboTransformers已应用在腾讯内部多个线上BERT服务服务场景。其中,微信常用问题回复服务获得1.88倍加速,QQ看点推荐服务获得13.6倍加速等。

项目地址:https://github.com/Tencent/TurboTransformers

技术差异

TurboTransformers的软件架构如下图所示,它让微信内部众多NLP线上应用能够充分榨取底层硬件的计算能力,让算法更好地服务用户。

image

具体来说,TurboTransformers可以在算子优化、框架优化和接口部署方式简化三个方面做了工作。

算子层优化

如下图所示,图(a)展示了论文Transformer结构示意图,这里称灰色方框内的结构为一个Transformer Cell,BERT encoder堆叠了Nx个这样的Transformer Cell。图(b)将一个Cell的细节加以展开,每一个矩形都是一个独立的计算核心。

image

Transformer Cell计算包含了8个GEMM(通用矩阵乘法,General Matrix Multiplication)运算,TurboTransformers通过调优Intel MKL和cuBLAS的GEMM接口调用方式来获得最佳GEMM性能。具体来说,它精心调整了预训练模型矩阵存储方式,并且在硬件允许条件下,在GPU上使用tensor core硬件进行GEMM运算。

类似NVIDIA FasterTransformers方案,TurboTransformers将所有GEMM运算之间的计算融合成一个调用核心。融合会带来两个好处:一是减少内存访问开销;二是减少多线程启动开销。对于这些核心,TurboTransformers在CPU上采用OpenMP进行并行实现,在GPU上使用CUDA进行并行实现。对于比较复杂的LayerNorm和Softmax算子,它们包含了不适合GPU上并行的规约操作,TurboTransformers为它们设计了创新并行算法,极大降低算子延迟。理论上,Transformers推理延迟应该近似于矩阵乘法延迟。

框架层优化

TurboTransformers采用了一个简单有效的内存管理方式。由于NLP的变长输入特性,每次运算中间结果的大小其实并不相同。为避免每次推理都分配释放内存,腾讯通过Caching方式管理显存。

为了能够无缝支持pytorch/tensorflow训练好的序列化模型,腾讯提供了一些脚本可以将二者的预训练模型转化为npz格式,供TurboTransformers读入。特别的,考虑到pytorch huggingface/transformers是目前最流行的transformers训练方法,该项目支持直接读入huggingface/transformers预训练模型。用户可以在huggingface/transformers的BERT实现基础上增加几行python代码,就可获得端到端的加速效果。

应用部署

该项目提供了C++和Python的调用接口。可以嵌入到C++多线程后台服务流程中,也封装成用Python方式书写的微服务。腾讯建议TurboTransformers通过docker部署,一方面保证编译的可移植性,另一方面也可以无缝应用于K8s等线上部署平台。

性能结果

下图是在Intel Xeon 6133 CPU的性能测试结果:

image

下图是在NVIDIA RTX 2060 GPU的性能测试结果:

image

下图是在NVIDIA P40 GPU的性能测试结果:

image

下图是在NVIDIA V100 GPU的性能测试结果:

image

未来展望

目前,TurboTransformers的功能相对有限,只支持FP32的计算,并重点支持了BERT模型。接下来,腾讯计划支持更低的浮点精度,并增加TurboTransformers对其他模型的支持。期待和社区一起完善该项目。

对项目感兴趣的开发者,欢迎访问如下项目地址:

https://github.com/Tencent/TurboTransformers