基于TensorRT的BERT实时自然语言理解(下)
基于TensorRT的BERT实时自然语言理解(下)
BERT Inference with TensorRT
请参阅Python脚本bert_inference.py还有详细的Jupyter notebook BERT_TRT.ipynb
在sample文件夹中进行推理过程的逐步描述和演练。在本节中,让我们回顾几个关键参数和概念,以便使用TensorRT进行推理。
BERT(更具体地说是编码器层)使用以下参数来控制其操作:
- Batch size
- Sequence Length
- Number of attention heads
这些参数的值取决于所选的BERT模型,用于设置TensorRT计划文件(执行引擎)的配置参数。
对于每个编码器,还要指定隐藏层的数量和注意头的大小。您也可以从Tensorflow检查点文件中读取上述所有参数。
由于我们所使用的BERT模型已经针对SQuAD数据集上的问答下游任务进行了微调,网络的输出(即输出完全连接层)将是一段文本,答案出现在文章中(在示例中称为h_output)。一旦我们生成了TensorRT引擎,我们就可以对其进行序列化,然后在TensorRT运行时中使用它。
在推理过程中,我们异步地执行从CPU到GPU的内存复制,反之亦然,从而分别将张量导入和移出GPU内存。异步内存复制操作通过与设备和主机之间的内存复制操作重叠计算来隐藏内存传输的延迟。异步内存复制和内核执行如图3所示。
Figure 3: TensorRT Runtime process
The inputs to the BERT model, which are shown in Figure 3, include:
- input_ids: tensor with token ids of paragraph concatenated along with question that is used as input for inference
- segment_ids: distinguishes between passage and question
- input_mask: indicates which elements in the sequence are tokens, and which ones are padding elements
输出(start_logits)和end_logits结束逻辑表示答案的范围,网络根据问题在文章中预测答案的范围。
在Jupyter笔记本中,我们使用了作为TensorRT插件实现的层的加速和高效实现。请参阅TensorRT文档以了解有关TensorRT插件以及如何在TensorRT中导入自定义层的更多信息。
Optimizing BERT for Inference
让我们浏览一下在TensorRT优化的BERT中实现的关键优化。
BERT架构基于Transformer,由12个用于BERT基的Transformer单元和24个用于BERT大型单元的Transformer单元组成。在被Transformer处理之前,输入标记通过一个嵌入层传递,该层查找它们的向量表示并对它们在句子中的位置进行编码。每个Transformer单元由两个连续的剩余块组成,每个剩余块随后进行层标准化。第一残差块代替第一完全连通层并通过多头自注意机制激活,第二剩余块使用高斯误差线性单元(GELU6)激活。
图4说明了Transformer单元的结构。
为了用TensorRT优化BERT,我们重点研究了Transformer单元的优化。由于在BERT中堆叠了几个Transformer单元,因此我们能够通过这组优化实现显著的性能提升。
为了在TensorRT中使用这些优化,我们使用定制插件来加速BERT模型中Transformer编码器元素中的关键操作。插件将多个操作融合到单个CUDA内核中的子图中。每个子图由几个基本计算组成,每个计算都需要对GPU的全局内存(即最慢的设备内存)进行读写。通过将基本操作融合到单个CUDA内核中,我们允许计算在更大的子图上进行,同时访问全局内存的次数最少。让我们更详细地看看这些插件。
Figure 4: Optimizations through TensorRT for BERT encoder cell of Transformer
The Gelu Activation performs the following elementwise computation where a, b and c are some scalar constants:
gelu(x) = a * x * (1 + tanh( b * (x + c * x^3) ))
A naive implementation using elementary layers in TensorRT would require the following operations:
Result = x^3
Result = c * Result
Result = x + Result
Result = b * Result
Result = tanh(Result)
Result = x * Result
Result = a * Result
对于k层,朴素的实现将需要。k-1不必要的全局内存往返,我们将其合并到单个CUDA内核中的元素计算中。参考geluPlugin.cu目录中获取更多详细信息。
跳过层和层规范化(LN)层在每个转换器层出现两次,并在单个内核中融合。有关此融合操作的实现,请参见中的skipLayerNormPlugin.cu在plugins目录中。
Transformer中的自我注意机制(图5)基于使用完全连接(FC)层的输入嵌入计算查询(Q)、键(K)和值(V)的表示。所有这些FC层的输入和输出维都是B x S x(N*H),其中B是批大小,S是序列长度,N是注意头数,H是隐藏层大小。然后将每个FC层的输出转置以形成大小为B x N x S x H的结果矩阵。将3个FC层合并到单个较大的层中可得到B x S x(3*N*H)的输出维度。
在融合的FC层之后,有三个转置操作可以被融合到单个更大的转置中,从而产生3xb×N×S×H的输出维。通过融合FC层,然后在较大张量上执行单个转置,Q、K和V表示被连续地放置在存储器中,以便进行以下操作他们。这将导致更快的内存访问,提高模型的吞吐量。
我们还融合了元素级缩放和softmax层(图5a和5b的右侧)。
参考qkvToContextPlugin.cu在自我注意实现的plugins目录中。
Figure 5a: Self-Attention Layer before Optimization
Figure 5b: Self-attention Layer after Optimization
Benchmarking BERT Inference Performance
BERT可以应用于在线和离线用例。在线NLU应用程序,如会话式人工智能,在推理过程中会有较紧的延迟预算。为了响应单个用户的查询,需要按顺序执行多个模型。当作为服务使用时,客户体验的总时间包括计算时间以及输入和输出网络延迟。时间越长,性能就越差,客户体验也就越差。
虽然单个模型可用的确切延迟可能因应用程序而异,但多个实时应用程序需要语言模型在10毫秒内执行。使用Tesla T4 GPU,使用TensorRT优化的BERT可以在2.2毫秒内对批处理大小=1、序列长度=128的QA任务执行推断。使用TensorRT优化的示例,对于BERT base,您可以执行高达8的批处理大小,对于在10毫秒延迟预算内具有较少Transformer层的模型,可以执行更高的批处理大小。对于批处理大小=1,在仅CPU平台上用高度优化的代码执行相同的任务需要40毫秒,而更高的批处理大小不会运行到完成并出现错误退出。
Figure 6: Compute latency in milliseconds for executing BERT-base on an NVIDIA T4 GPU versus a CPU-only server
该基准测试测量在将张量作为输入传递和将逻辑集作为输出之间执行QA任务时仅计算的延迟时间。您可以在中找到用于对示例进行基准测试的代码sampleBERT.cpp.
Conclusion
NVIDIA是开放源码的几个优化,使它能够在2.2ms内使用TensorRT在T4 gpu上执行BERT推断。优化的代码可以在TensorRT开源repo中作为开源示例提供。要在GCP上运行这个示例,可以从google cloud ai Hub访问它。repo展示了如何优化Transformer层,它是BERT和其他几种语言模型的核心构建块。我们希望您能够轻松地定制这些构建块,以适合您的定制模型和应用程序。本文概述了如何使用TensorRT示例、关键优化和性能结果。我们进一步描述了如何使用BERT示例作为简单应用程序和Jupyter笔记本的一部分的工作流程,在这里您可以传递一个段落并询问与之相关的问题。
新的优化和可实现的性能使得首次将BERT用于延迟预算较紧的应用程序(如会话式AI)成为现实。在接下来的几个月里,我们希望分享更多的例子,展示如何将BERT用作其他工作流的一部分。
我们一直在寻找新的想法来分享新的例子和应用程序。您使用BERT进行哪些NLP应用程序?您将来希望从我们这里看到哪些示例?
If you have questions regarding the TensorRT sample repo, check the NVIDIA TensorRT Developer Forum to see if other members of the TensorRT community have a resolution first. NVIDIA Registered Developer Program can also file bugs at https://developer.nvidia.com/nvidia-developer-program.
- CPU-only specifications: Gold 6240@2.60GHz 3.9GHz Turbo (Cascade Lake) HT Off, Single node, Single Socket, Number of CPU Threads = 18, Data=Real, Batch Size=1; Sequence Length=128; nireq=1; Precision=FP32; Data=Real; OpenVINO 2019 R2
GPU-server specification: Gold 6140@2GHz 3.7GHz Turbo (Skylake) HT On, Single node, Dual Socket, Number of CPU Threads = 72, Tesla T4 16GB, Driver Version 418.67 (r418_00), BERT-base, Batch Size=1; Number of heads = 12, Size per head = 64; 12 layers; Sequence Length=128; Precision=FP16; XLA=Yes; Data=Real; TensorRT 5.1
References:
- [Devlin et al 2018] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. Jacob Devlin, Ming-Wei Chang, Kenton Lee, Kristina Toutanova
- [Y Liu 2019] RoBERTa: A Robustly Optimized BERT Pretraining Approach
- SQuAD leaderboard
- [Vaswani et al 2017] Attention Is All You Need Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser, Illia Polosukhin
- [Jinhyuk Lee et al 2019] BioBERT: a pre-trained biomedical language representation model for biomedical text mining Jinhyuk Lee, Wonjin Yoon, Sungdong Kim2, Donghyeon Kim1, Sunkyu Kim1, Chan Ho So3 and Jaewoo Kang
- [Dan et al 2016] Gaussian Error Linear Units (GELUs) Dan Hendrycks, Kevin Gimpel
基于TensorRT的BERT实时自然语言理解(下)的更多相关文章
- 基于TensorRT的BERT实时自然语言理解(上)
基于TensorRT的BERT实时自然语言理解(上) 大规模语言模型(LSLMs)如BERT.GPT-2和XL-Net为许多自然语言理解(NLU)任务带来了最先进的精准飞跃.自2018年10月发布以来 ...
- 基于TensorRT车辆实时推理优化
基于TensorRT车辆实时推理优化 Optimizing NVIDIA TensorRT Conversion for Real-time Inference on Autonomous Vehic ...
- java自然语言理解demo,源码分享(基于欧拉蜜)
汇率换算自然语言理解功能JAVA DEMO >>>>>>>>>>>>>>>>>>>&g ...
- 【中文版 | 论文原文】BERT:语言理解的深度双向变换器预训练
BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding 谷歌AI语言组论文<BERT:语言 ...
- 基于TensorRT 3的自动驾驶快速INT8推理
基于TensorRT 3的自动驾驶快速INT8推理 Fast INT8 Inference for Autonomous Vehicles with TensorRT 3 自主驾驶需要安全性,需要一种 ...
- 如何使用OLAMI自然语言理解开放平台API制作自己的智能对话助手小程序
我们经常在电影中看到机器和人对答如流,随着越来越多自然语言开放平台的出现,IT爱好者制作一个自己的APP或者小玩具等逐渐可以变为现实. 自然语言对话即你的APP或者你制作的工具.机器人等能够对用户输入 ...
- 基于socket.io的实时在线选座系统
基于socket.io的实时在线选座系统(demo) 前言 前段时间公司做一个关于剧院的项目,遇到了这样一种情况. 在高并发多用户同时选座的情况下,假设A用户进入选座页面,正在选择座位,此时还没有提交 ...
- 苏宁基于Spark Streaming的实时日志分析系统实践 Spark Streaming 在数据平台日志解析功能的应用
https://mp.weixin.qq.com/s/KPTM02-ICt72_7ZdRZIHBA 苏宁基于Spark Streaming的实时日志分析系统实践 原创: AI+落地实践 AI前线 20 ...
- 微软自然语言理解平台LUIS:从零开始,帮你开发智能音箱
今年微软开发者大会Build 2017上展示了一款Invoke智能音箱,受到了媒体和大众的广泛关注.近两年,不少大公司纷纷涉足该领域,使得智能音箱逐渐成为一款热门的人工智能家用电器.智能音箱的兴起也改 ...
随机推荐
- CString,string,char数组的转换
来源:http://ticktick.blog.51cto.com/823160/317550 //----------------ANSI字符串转换为UNICODE字符串-------------- ...
- CVE-2013-2551:Internet Explore VML COALineDashStyleArray 整数溢出漏洞简单调试分析
0x01 2013 Pwn2Own 黑客大赛 在 Pwn2Own 的黑客大赛上,来自法国的 VUPEN 安全团队再一次利用 0day 漏洞攻破 Windows8 环境下的 IE10 浏览器,这一次问题 ...
- Windows核心编程 第23章 结束处理程序
第2 3章 结束处理程序 SEH(结构化异常处理) 使用 S E H的好处就是当你编写程序时,只需要关注程序要完成的任务. 如果在运行时发生什么错误,系统会发现并将发生的问题通知你.利用S E H,你 ...
- Windows核心编程 第十四章 虚拟内存
第1 4章 虚 拟 内 存 <这一章没啥,是说的几个内存相关的函数 > 14.1 系统信息 许多操作系统的值是根据主机而定的,比如页面的大小,分配粒度的大小等.这些值决不应该用硬编码的形式 ...
- 影子卫士汉化语言包 res.ini
[translate];authorinfo=Simplified Chinese Translation 简体翻译 by: Clarence [common]0=Shadow Defender 10 ...
- Android拆分与加载Dex的多种方案对比
http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=207151651&idx=1&sn=9eab282711f4eb2b ...
- Day008 三种初始化及内存分析
三种初始化和内存分析 Java内存分析: 堆: 存放new的对象和数组. 可以被所有的线程共享,不会存放别的对象引用. 栈: 存放基本变量类型(会包含这个基本类型的具体数值). 引用对象的变量(会存放 ...
- Mybatis-Plus03 代码自动生成器
先看完Mybatis-Plus01和Mybatis-Plus02再看Mybatis-Plus03 AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerato ...
- 【vue-06】webpack npm
什么是Webpack Webpack是一款模块加载器兼打包工具,他能把各种资源,比如js,css,less转化成一个静态文件,减少页面的请求,提高效率. 安装Webpack 在安装webpack之前, ...
- VS“无法查找或打开PDB文件”解决方法
``#运行时报错提示 "温度柱状图.exe"(Win32): 已加载"C:\Windows\SysWOW64\rpcrt4.dll".无法查找或打开 PDB 文 ...