近日,腾讯正式宣布开源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 推理方法。
项目介绍
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模型的端对端加速效果。
此前,TurboTransformers 已应用在腾讯内部多个线上 BERT 服务服务场景。其中,微信常用问题回复服务获得 1.88 倍加速,QQ 看点推荐服务获得 13.6 倍加速等。
项目地址:https://github.com/Tencent/TurboTransformers
技术差异
TurboTransformers 的软件架构如下图所示,它让微信内部众多 NLP 线上应用能够充分榨取底层硬件的计算能力,让算法更好地服务用户。
具体来说,TurboTransformers 可以在算子优化、框架优化和接口部署方式简化三个方面做了工作。
算子层优化
如下图所示,图(a)展示了论文 Transformer 结构示意图,这里称灰色方框内的结构为一个 Transformer Cell,BERT encoder 堆叠了 Nx 个这样的 Transformer Cell。图(b)将一个 Cell 的细节加以展开,每一个矩形都是一个独立的计算核心。
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 的性能测试结果:
下图是在 NVIDIA RTX 2060 GPU 的性能测试结果:
下图是在 NVIDIA P40 GPU 的性能测试结果:
下图是在 NVIDIA V100 GPU 的性能测试结果:
未来展望
目前,TurboTransformers 的功能相对有限,只支持 FP32 的计算,并重点支持了 BERT 模型。接下来,腾讯计划支持更低的浮点精度,并增加 TurboTransformers 对其他模型的支持。期待和社区一起完善该项目。
对项目感兴趣的开发者,欢迎访问如下项目地址:
https://github.com/Tencent/TurboTransformers
评论