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的更多相关文章

  1. Redis云端架构深入浅出

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB 发表于云+社区专栏 作者介绍:邹鹏,腾讯云数据库Redis产品负责人,多年数据库.网络安全研发经验. ...

  2. [转帖]单集群10万节点 走进腾讯云分布式调度系统VStation

    单集群10万节点 走进腾讯云分布式调度系统VStation https://www.sohu.com/a/227223696_355140 2018-04-04 08:18 云计算并非无中生有的概念, ...

  3. 微信小游戏爆款秘笈 数据库MongoDB攻略篇

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB 发表于云+社区专栏 随着微信小游戏的爆发,越来越多开发者关注到MongoDB与小游戏业务的契合度. ...

  4. Paddle Release Note

    Paddle Release Note 重要更新 飞桨paddle框架2.0.0版本有如下重要更新: 编程范式:默认开启动态图模式进行模型开发和训练,通过动转静的方式进行模型部署和训练加速.如果需要使 ...

  5. [NLP自然语言处理]谷歌BERT模型深度解析

    我的机器学习教程「美团」算法工程师带你入门机器学习   已经开始更新了,欢迎大家订阅~ 任何关于算法.编程.AI行业知识或博客内容的问题,可以随时扫码关注公众号「图灵的猫」,加入”学习小组“,沙雕博主 ...

  6. Scala 深入浅出实战经典 第81讲:Scala中List的构造是的类型约束逆变、协变、下界详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-97讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  7. Scala 深入浅出实战经典 第79讲:单例深入讲解及单例背后的链式表达式

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  8. Scala 深入浅出实战经典 第78讲:Type与Class实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  9. Scala 深入浅出实战经典 第77讲:模式匹配下的提取器动手构造实战

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

随机推荐

  1. Java Word中的文本、图片替换功能

    Word中的替换功能以查找指定文本然后替换为新的文本,可单个替换或全部替换.以下将要介绍的内容,除常见的以文本替换文本外,还将介绍使用不同对象进行替换的方法,具体可包括: 1. 指定字符串内容替换文本 ...

  2. Java实现 蓝桥杯 算法提高 日期计算

    算法提高 日期计算 时间限制:1.0s 内存限制:256.0MB 问题描述 已知2011年11月11日是星期五,问YYYY年MM月DD日是星期几?注意考虑闰年的情况.尤其是逢百年不闰,逢400年闰的情 ...

  3. Java实现高效便捷还容易懂的排序算法

    PS:我现在越来越认为排序大法是,很深的算法了,就是简单的几个步骤,网上的大佬们能给你玩出花来(ง •_•)ง public class zimuzhenlie2 { public static vo ...

  4. Java实现 蓝桥杯VIP 算法提高 数的划分

    算法提高 数的划分 时间限制:1.0s 内存限制:256.0MB 问题描述 一个正整数可以划分为多个正整数的和,比如n=3时: 3:1+2:1+1+1: 共有三种划分方法. 给出一个正整数,问有多少种 ...

  5. java实现罗马数字转十进制

    古罗马帝国开创了辉煌的人类文明,但他们的数字表示法的确有些繁琐,尤其在表示大数的时候,现在看起来简直不能忍受,所以在现代很少使用了.之所以这样,不是因为发明表示法的人的智力的问题,而是因为一个宗教的原 ...

  6. java实现手机尾号评分

    30年的改革开放,给中国带来了翻天覆地的变化.2011全年中国手机产量约为11.72亿部.手机已经成为百姓的基本日用品! 给手机选个好听又好记的号码可能是许多人的心愿.但号源有限,只能辅以有偿选号的方 ...

  7. java实现第五届蓝桥杯写日志

    写日志 写日志是程序的常见任务.现在要求在 t1.log, t2.log, t3.log 三个文件间轮流 写入日志.也就是说第一次写入t1.log,第二次写入t2.log,... 第四次仍然 写入t1 ...

  8. 在树莓派3b or 3a or 4a or 4b上搭建OpenWebRX

    OpenWebRx OpenWebRX 项目提供了搭建WebSDR的解决方案,该项目基于 Python 编写,除了完全开源外,官方还提供了完备的技术文档.您只需要一台电脑或是树莓派,一个SDR设备和网 ...

  9. shell命令:命令置换、进程管理

    1:命令置换 command1  `command2` 将command2的结果作为command1的参数 注意:command2的引号为esc键下的单引号 2:进程管理 1)命令 (1)ps  -a ...

  10. MongoDB知识点总结

    一:MongoDB 概述    一.NoSQL 简介 1. 概念:NoSQL(Not Only SQL的缩写),指的是非关系型数据库,是对不同于传统的关系型数据库的数据库管理系统的统称.用于超大规模数 ...