深入浅出腾讯BERT推理模型--TurboTransformers

Overview
TurboTransformers是腾讯最近开源的BERT推理模型,它的特点就是一个字,快。本人用BERT(huggingface/transformers)在V100上做了测试,测试结果和官宣的基本一致:TurboTransformers的推理速度要比Pytorch快上1~4倍。

它之所以快,是因为它是专用于BERT的轻量级推理模型。
分层
不管是计算机的硬件、软件,还是现在的深度学习,它们都遵循着一个很重要的设计思想--分层:
- 用简单的代码(或电路)来实现一个基本功能组件。
- 用几个基本组件组合成一个功能更强的复杂组件。
- 从简单到复杂,像搭积木一样,一层层地搭建出拥有很强功能的组件。
开发者只需要基于PyTorch的几个基本组件就能搭建出BERT模型,而且这些组件本身对他们来说都是透明的。正因如此,PyTorch才越来越受到研究者青睐。

分层设计的优点很多,例如,可以简化问题、降低创新门槛、加速开发等,但它的缺点也很明显:
- 流程固定化
- 存在中间层延迟
深度神经网络里有个经典套路:一个激活函数层后面紧跟着一个dropout层。PyTorch需要lanuch两个GPU kernel程序来完成这两步计算。
F.dropout(F.relu(x))
实际上,这两项计算都是element-wise的,是可以合并成一个kernel的。但目前来说,不管是PyTorch,还是其他的通用训练框架,它们都很少有提供这种融合计算的API。
至于中间层延迟,最经典的要属“hello world”程序。虽然只有几行代码,但实际上要经过的中间层数根本数不过来。
你可以阅读深入浅出PyTorch(算子篇)来了解下矩阵相乘这个最基本的计算在PyTorch里要经过多少个中间层。
分层展开
要想将程序的低延迟最大化,就需要把分层的代码完全展开,并重构代码。典型例子就是嵌入式系统,为了实现某种需求,它可以打破应用程序、程序库、操作系统甚至是硬件设备的界限,打造一个软硬件一体化产品。
这种分层展开的设计模式当然也有它的局限性:专用。由于高度定制化,它通常只能用于完成某个特定功能。低延迟和专用化是呈绝对的正相关的。
TurboTransformers就是采用这种设计:只实现BERT模型前向传播所需要的算子,并融合那些可以合并的算子。
turbo.Tensor
首先,它用CUDA开发了一个轻量级的tensor计算库,所谓的轻量级,指的是不用考虑反向传播、稀疏矩阵等操作,只实现BERT前向传播所必需的operator。
虽然tensor库是用C++写的,但考虑到python在AI开发中的地位,它用pybind11将C++ API暴露给前端的python Tensor类。
# turbo_transformers/python/pybind.cpp
72 py::class_<core::Tensor>(m, "Tensor")
73 .def_static("from_dlpack",
74 [](py::capsule capsule) -> std::unique_ptr<core::Tensor> {
75 auto tensor = (DLManagedTensor *)(capsule);
76 PyCapsule_SetName(capsule.ptr(), "used_tensor");
77 return absl::make_unique<core::Tensor>(tensor);
78 })
79 .def("to_dlpack",
80 [](core::Tensor &tensor) -> py::capsule {
81 auto *dlpack = tensor.ToDLPack();
82 return py::capsule(dlpack, "dltensor", DLPack_Capsule_Destructor);
83 })
84 .def("n_dim", &core::Tensor::n_dim)
85 .def("shape", &core::Tensor::shape)
从预训练模型(PyTorch)那迁移参数时,turbo.Tensor不能直接对接torch.Tensor,需要先将PyTorch的参数转成dlpack格式, 再通过from_dlpack()将这些数据导入生成TurboTransformers tensor。除了dlpack之外,还支持*.npz文件格式。

turbo.xxxlayer
TurboTransformers用CUDA重构了Embedding、self-attention、intermediate、output、LayerNorm和pooler等layer。turbo.layer不仅代码结构简洁,overhead少,还合并了一部分算子。

这里以intermediate layer为例,来分析这些算子的特点。

intermediate layer的实现比较简单:一个Linear layer后面紧跟着一个gelu activation layer。
PyTorch的intermediate layer的会lanuch 3个kernel来完成这部分计算:
- #1: y = input.matmul(weight)
- #2: y = y + bias
- #3: y = gelu(y)
由于#2和#3都是element-wise kernel,turbo把它们进行了融合--AddBiasAct(),相同的计算操作,只需要lanuch 2个kernel,计算速度当然更快。

和PyTorch一样,turbo的MatMul算子也是调用cuBLAS来进行矩阵运算,而且turbo还启用了Tensor Core来加速计算(CUBLAS_TENSOR_OP_MATH)。
总结
到此,本文基本上讲清了TurboTransformers的速度优势来源,由于篇幅所限,不能分析所有的算子。BERT的核心模块是self-attention,如果想了解更多,可以阅读深入浅出Transformer。
更多精彩文章,欢迎扫码关注下方的公众号 ~~ 欢迎关注和点赞,你的鼓励将是我创作的动力
欢迎转发至朋友圈,公众号转载请后台留言申请授权~

深入浅出腾讯BERT推理模型--TurboTransformers的更多相关文章
- Redis云端架构深入浅出
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB 发表于云+社区专栏 作者介绍:邹鹏,腾讯云数据库Redis产品负责人,多年数据库.网络安全研发经验. ...
- [转帖]单集群10万节点 走进腾讯云分布式调度系统VStation
单集群10万节点 走进腾讯云分布式调度系统VStation https://www.sohu.com/a/227223696_355140 2018-04-04 08:18 云计算并非无中生有的概念, ...
- 微信小游戏爆款秘笈 数据库MongoDB攻略篇
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB 发表于云+社区专栏 随着微信小游戏的爆发,越来越多开发者关注到MongoDB与小游戏业务的契合度. ...
- Paddle Release Note
Paddle Release Note 重要更新 飞桨paddle框架2.0.0版本有如下重要更新: 编程范式:默认开启动态图模式进行模型开发和训练,通过动转静的方式进行模型部署和训练加速.如果需要使 ...
- [NLP自然语言处理]谷歌BERT模型深度解析
我的机器学习教程「美团」算法工程师带你入门机器学习 已经开始更新了,欢迎大家订阅~ 任何关于算法.编程.AI行业知识或博客内容的问题,可以随时扫码关注公众号「图灵的猫」,加入”学习小组“,沙雕博主 ...
- Scala 深入浅出实战经典 第81讲:Scala中List的构造是的类型约束逆变、协变、下界详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-97讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala 深入浅出实战经典 第79讲:单例深入讲解及单例背后的链式表达式
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala 深入浅出实战经典 第78讲:Type与Class实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
- Scala 深入浅出实战经典 第77讲:模式匹配下的提取器动手构造实战
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
随机推荐
- leetcode56之合并区间
题目描述: 给出一个区间的集合,请合并所有重叠的区间. 示例: 输入: [[1,3],[2,6],[8,10],[15,18]]输出: [[1,6],[8,10],[15,18]]解释: 区间 [1, ...
- 【Hadoop】hdfs的秘密,namenode,datanode,yarn,安全模式,fsimage,edits...
1.bin/hdfs namenode -format ** 注意事项 1.在配置好了配置文件之后,首次启动之前,做初始化操作 2.在后续启动的时候,不需要再初始化 3.初始化的一些影响 一.初始化操 ...
- ecilpse 纠错插件
在market里面搜索 Spot Bugs Unnecessary Code Detector
- Java实现 LeetCode 665 非递减数列(暴力)
665. 非递减数列 给你一个长度为 n 的整数数组,请你判断在 最多 改变 1 个元素的情况下,该数组能否变成一个非递减数列. 我们是这样定义一个非递减数列的: 对于数组中所有的 i (1 < ...
- Java实现 LeetCode 2 两数相加
两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...
- 用斗地主的实例学会使用java Collections工具类
目录 一.背景 二.概念 1.定义 2.方法 2.1.排序方法 2.2.查找/替换方法 三.斗地主实例 3.1.代码结构 3.2.常量定义 3.3.单只牌类 3.4.玩家类 3.5.主程序 四.深入理 ...
- 除了FastJson,你也应该了解一下Jackson(一)
在上月末的时候收到一条关于fastjson安全漏洞的消息,突然想到先前好像已经有好多次这样的事件了(在fastjson上面).关于安全方面,虽然中枪的机率微小,但是在这个信息越来越复杂的时代,安全性也 ...
- 经典文本特征表示方法: TF-IDF
引言 在信息检索, 文本挖掘和自然语言处理领域, IF-IDF 这个名字, 从它在 20 世纪 70 年代初被发明, 已名震江湖近半个世纪而不曾衰歇. 它表示的简单性, 应用的有效性, 使得它成为不同 ...
- workbench中如何导入.sql文件
在做电商管理系统的时候,需要使用 mysql 中的数据,在执行 app.js 文件时出现错误 于是将 mydb.sql 导入到workbench中,步骤如下: 1. 打开 workbench 软件,选 ...
- 第一个SpringMVC程序 (配置版)
通过配置版本的MVC程序,可以了解到MVC的底层原理,实际开发我们用的是注解版的! 1.新建一个普通Maven的项目,然后添加web的支持 2.导入相关的SpringMVC的依赖 3.配置web.xm ...