Press "Enter" to skip to content

GTC 2022:GPU推理加速在OPPO NLP场景的优化落地

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

导读 :本文主要分享OPPO机器学习团队在Nvidia GTC 2022会议上的投稿经验,以及我们在GPU推理加速在NLP场景应用上所做的工作和落地后的实际效果。

 

 

在上周结束的Nvidia GTC 2022会议上,OPPO数智工程事业部机器学习团队分享了主题为《Evolution Path of GPU Inference Accelerating on Breeno Bot/NLP Scenario》的报告,主要讲述在GPU推理加速在小布助手NLP场景的演进路线,包含以下4个模块内容:

 

 

1. 此次技术优化的业务背景,及面临的挑战

 

2. 解决方案,及推理加速的演进过程

 

3. 此次GPU推理加速实践的具体工作

 

4. 后续的技术演进方向与规划

 

一、业务背景及挑战

 

 

小布助手简称小布,也叫Breeno,是OPPO智能手机和IoT设备上内置的多模态AI助手,包含语音、建议、指令、识屏和扫一扫5大能力模块。小布助手以“机智”、“有趣”、“温暖”为理念,致力于提供多场景、智慧有度的用户体验。

 

自然语言处理(Natural Language Processing, NLP)是提升AI助手能力的关键技术。大规模预训练语言模型是NLP领域近几年来取得的最显着的技术突破,在很多NLP下游任务上都显示出了压倒性的威力。然而,由于大规模预训练模型本身结构复杂,计算量巨大,在落地应用方面存在推理成本高、推理预测性能难以满足在线业务需求等问题。

 

小布助手也包含信息查询分类、生成式闲聊、指代消解、文本向量表征等应用场景,需要使用NLP大规模模型来提升任务的效果。

 

在小布助手预训练模型落地的场景中,我们探索了一系列GPU推理加速技术,使模型推理性能不断提升,同时也构建了一套高性能推理服务框架。

 

 

基于小布助手的应用场景特性,我们的通用推理服务框架需要满足以下需求:

 

(1) 灵活性:能够支持不同的场景,包括NLP/CV,也包含搜索/个人化推荐/广告等;在推理服务维度,也需要支持不同的推理引擎以及异构的AI硬件设备。

 

(2) 功能性:依据性能需求支持动态batch合并,提升吞吐能力;支持多模型连续推理。

 

(3) 高性能:能够支持大规模的模型,并且服务响应时延Latency和成本将会成为我们性能优化首要考虑因素。

 

二、解决思路及演进过程

 

 

基于这些需求,我们的解决思路是这样的:

 

1、选取合适的推理引擎,在运行时,它需要满足低时延高吞吐的性能要求,同时也能支持CPU、GPU设备的推理,支持多种模型场景

 

2、利用Cache缓存的方式,来提升推理服务的吞吐能力

 

3、应用MPS技术,帮助多进程共享context,减少context切换的开销

 

4、应用Multi-stream多流优化技术,通过不同streams之间共享GPU上下文提升GPU核心并发利用率,同时也可以提升内核job的并发度,减少内存显存拷贝的时延。

 

5、使用最新驱动版本的GPU,因为新版本包含了Nvidia最丰富的优化经验沉淀,往往拥有最优的性能;在升级过程中,我们需要考虑在线服务滚动升级问题

 

6、利用图优化,子图融合、高性能算子等方式帮助我们规避低效的子图,获取更好的模型计算性能

 

7、在调度框架方面,使用可灵活调整的batch size策略,推理服务与业务逻辑解耦,专注模型推理性能

 

 

基于上述解决思路,OPPO在线推理服务的实践经历了五个阶段(如上图所示):TensorFlow推理引擎、TVM编译优化、Model Structure优化、Nvidia生态优化、Subgraph优化。在这个演进过程中,每个阶段我们做了如下工作:

 

1. 在TensorFlow引擎推理阶段,我们使用了GPU推理对NLP大模型进行加速,相比于CPU推理性能提升了9倍,推理时延6.6ms,开启了NLP大模型上线部署之路

 

2. 在TVM编译优化阶段,我们运行了CUDA、CuBLAS计算库、TVM Ansor等优化方式,相比于TensorFlow GPU推理降低了45%的推理时延,提升了80%的吞吐量,解决了流量高峰期产生的超时问题,使得NLP大模型推理变得更稳定;同时MPS技术落地也在对应场景带来了12%的时延降低

 

3. 在模型结构优化阶段,我们使用了ONNXRuntime引擎,结合Transformer优化,获得更好性能的同时,支持了模型的Dynamic Shape功能,顺利支撑了变长序列的业务场景上线

 

4. 在Nvidia生态优化阶段,我们进一步使用FP16混合精度的方式提升计算性能,同时Multi-Stream多流技术、CUDA Driver升级也都为模型推理带来了不小的性能提升

 

5.在Subgraph优化阶段,我们深入模型结构,在计算图、算子维度进行深度优化,在部分子图融合场景可以带来10倍的性能提升

 

下面我们将详细解读上述推理加速技术的演进过程。

 

三、GPU推理加速实践的具体工作

 

 

第一阶段:TensorFlow引擎推理

 

在应用BERT等预训练模型之前,我们使用简单模型在CPU上进行推理,推理框架使用TensorFlow/Pytorch。然而BERT模型计算量特别大,在CPU上的单次推断耗时往往需要十几甚至上百毫秒,远远超过业务场景可接受的范围。鉴于BERT模型或者Transformer网络拥有大量的矩阵张量乘法操作,这一特性是非常适合使用Nvidia GPU进行加速的。

 

在小布助手的场景中,对话的语句以短Query为主,通常长度小于32个字词。因此我们设置了Benchmark场景:

 

模型:基于BERT-BASE

 

参数量:1.1亿

 

Batch size: 1

 

Sequence length: 32

 

Hardware:

 

CPU: Intel(R) Xeon(R) Gold 5118 CPU @ 2.30GHz

 

GPU: Nvidia Tesla T4

 

单次Query推理TensorFlow-CPU需要55ms,此时单颗CPU设备的利用率是100%,在Tesla T4上,单Query推理只需要6.66ms。这意味着使用T4 GPU加速后,我们可以得到9倍的性能提升。升级GPU加速后使得我们语义理解等场景达到了基本的上线需求。

 

 

第二阶段:TVM编译优化

 

在使用TensorFlow-GPU加速BERT模型之后,单并发请求的推理时延降低至了6.66ms,然而由于线上服务存在较大的并发请求,在高峰期部分请求存在超时(场景限制响应时间需要小于20ms)的情况,因此需要进一步优化推理的耗时。

 

此时我们应用了深度学习编译器TVM(Tensor Virtual Machine)。TVM借鉴了传统编译器LLVM的思路,它是一个端到端的深度学习编译器框架,可以加速模型在Nvidia GPU、CPU、NPU、手机芯片等Target设备的执行,特别在计算密集型场景有这不俗的优化效果。作为一个开源项目,TVM社区技术也不断演进,TVM Ansor等技术的出现进一步提升了模型在各设备端的性能。

 

通过应用与优化NLP生产模型在TVM编译中的性能表现,单Query的请求耗时优化至3.68ms,相比于TensorFlow-gpu的方式减少了45%的推理时延,同时单卡的吞吐量也提升了80%。TVM的编译优化优雅地解决了流量高峰期产生的超时问题,使得NLP大模型推理变得更稳定。

 

 

第三阶段:模型结构优化

 

随着越来越多的服务使用大模型推理,GPU推理成本也逐渐升高,需要我们进一步探索更低成本的方式,Transformer网络结构优化以及低精度计算是我们关注的方向。

 

ONNX(Open Neural Network Exchange),是由Microsoft、Facebook等公司为解决模型转换与部署的开源项目。随着ONNX生态的发展,ONNXRuntime迭代迅速(接近3个月一次大版本Release),其易用性、生态发展、性能表现也越来越出色。

 

在小布助手的场景中,Query的长度通常小于32,相比于TVM,ONNXRuntime擅长计算图和访存密集型算子优化,它的推理耗时略优于TVM(TVM在Sequence_length大于64时,有更好的性能表现)。

 

另外,ONNXRuntime社区针对Transformer网络有定制优化工具,专项优化了Layer Normalization、Attention、Gelu等结构与算子,可以带来一定的性能提升。

 

在精度优化方面,Transformer优化过程中,可以将部分算子使用FP16精度计算,利用Tesla T4卡的TensorCore计算单元加速,同时以黑名单的形式将精度敏感的算子,保持使用FP32进行计算。混合精度的计算方式可以在保持推理结果不变的前提下,更大限度的提升推理性能。

 

 

在推理性能和准确率评测上,ONNXRuntime 表现出了更好的效果,在如上图的Query理解分类场景,FP16混合精度的应用在分类结果的偏差可以控制在FP32精度的0.2%偏差之下,符合其业务上线要求。ONNXRuntime单Query的耗时可以控制在1.85ms,相比TVM Ansor方式进一步降低了50%,达到2倍的性能提升。

 

在推理结果精度、推理性能方面ONNXRuntime Transformer优化结合FP16混合精度的方式拥有最佳的性能表现,更低的成本,因此广泛地应用在了小布助手等NLP模型推理场景。

 

 

第四阶段:Nvidia生态优化

 

我们先来看下Multi-Stream多流的优化。

 

Nvidia GPU的调度在默认stream机制下,CUDA tasks将按顺序一个接一个执行。然而,CUDA也提供了多个CUDA tasks放置到多个streams执行的能力,我们可以用不同的stream来并行执行计算任务。

 

Multi-Stream可以节省创建CUDA上下文的时间,同时也能提升GPU核心并发的利用率和计算并行度。

 

Multi-Stream在GPU利用率较低的任务场景可以获得不错的收益,然而我们的场景中GPU util利用率较高,在上面的GPU Profiles分析图中,Streams 会花费更多的时间在等待资源分配,并且相互阻塞,因此没有获得正向的收益。

 

 

多进程服务(MPS,Multi Process Service)使用时,tasks之间有更好的隔离性,他们可以共享GPU核心。不同的Process之间具有显存隔离的能力,也可以指定每个进程的GPU 核心使用率。

 

Nvidia的MPS使用起来的比较简单的,它主要包含三个组件:

 

(1) Control Daemon Process:负载开启和关闭MPS Servers、连接clients和servers

 

(2) Client Runtime:构建于CUDA中,并且可以无感的被CUDA调用。

 

(3) Server Process:负责与Clients连接,并且提供GPU的并发能力。

 

MPS技术在OPPO的个性化推荐场景中,TP99时延降低了12%。

 

 

第五阶段:Subgraph优化

 

为了获取更好的性能表现,我们也尝试了Subgraph图优化策略。

 

策略1:将低效的算子和计算方式转变成高性能的算子组合。

 

Split+Concat”算子将会创建1024个split操作,带来大量重复冗余的计算。替换为”Reshape+Expand”之后,它在计算逻辑上可以保持与原来一致的计算结果,但是它的计算性能可以提升10倍。

 

 

策略2:自定义算子与算子融合。

 

例如,上面的例子中我们将左边这6个算子组成的pattern,自定义为BiasGelu融合算子,这个融合减少了算子调度引起的global memory拷贝,带来了2倍的性能提升。

 

此外,对于推理引擎中已有的算子,有的实现效率会比较低,也可以修改其代码使之更高效。但这种需case by case去抠细节,效益没那幺明显。

 

 

第六阶段:在线推理服务优化

 

上文中有介绍到我们选取推理引擎的标准:

 

(1)支持GPU与CPU推理

 

(2)支持Dynamic shape

 

(3)支持算子融合

 

(4)支持Multi-Stream多流等等

 

在调研和对比了各种推理引擎之后,我们选取了ONNXRuntime作为最核心的推理引擎,同时也将支持不同的推理后端,增强推理服务的灵活性。

 

 

接下来的优化工作为高频Query的缓存Cache方案。

 

如上图所示,这里统计了一段时间内小布助手收到的用户Query请求频次,例如“小布小布”被请求了1331次,是最高频的请求。

 

考虑到高频语句请求场景,经过统计分析,如果我们缓存TOP500的高频Hot Query,它可以帮助我们减少30%的模型推理请求;如果缓存最近20万条请求的话,可以减少60%的模型推理开销。据此,我们设计了Cache缓存方案,以一部分Cache开销,获得了更好的整体响应性能。

 

 

通常,保持使用最新的Nvidia CUDA Driver是推荐的方式,因为在驱动升级的过程中,CUDA Toolkit、cuDNN等配套加速库均获得了升级,另外新版本的驱动也可以支持更高版本的推理引擎,由此也能更好的获得ONNXRuntime等推理引擎迭代带来的收益。

 

然而,在英伟达生态下,某个组件的更新,往往要设计其他一系列组件相应的更新。对于线上服务,这种更新相当于“在高速路上一边开车一边换轮子”,这个过程需非常谨慎细心。我们投入了大量精力,利用“滚动停服升级”的方式,实现了各组件的平滑升级。

 

从上图表格中我们可以看到从Driver 440升级到470后,在各类业务的推理场景均取得了不错的性能提升,P99时延有最高达41%的降低。

 

 

基于上面提到的各种优化方案,我们的推理框架设计也逐步形成。我们将模型推理服务分为离线模型预处理和在线模型服务两个阶段(如上图流程所示):

 

 

离线模型预处理阶段:我们将训练好的模型进行剪枝、常量折叠、算子融合、混合精度、编译优化等模型加速优化,在完成准确性和性能验证后,模型可进入线上推理服务流程。

 

在线推理服务阶段:我们开发了Hot Query缓存模块“Cache Manager”;“DynamicBatch Manager”模块负责对Query请求进行打包以提升服务的吞吐能力;“DagScheduler and Model Manager”模块用来调度模型选用ONNXRuntime等引擎在CPU、GPU的执行。

 

 

 

在以上推理框架层优化之后,我们在小布的推理服务场景提升了两个核心指标:

 

(1)   新推理框架P99分位的时延降低了7ms,下降了35%

 

(2)   新推理框架也有更低的时延波动,P99的波动降低为2ms。

 

四、未来工作规划

 

 

首先,我们的预训练规模已经向10亿、100亿级别演进,这些模型也将逐步落地到各个场景中,进一步提升算法效果,因此后续推理的模型参数也将进一步提升,单卡推理会遇到显存墙的问题,我们需要探索模型并行、流水并行等分布式推理方案。

 

在AI芯片层面,我们也将使用Ampere以及Hopper架构的GPU卡来提升推理性能。降低成本。经过实际性能评测,A30/A100单卡推理时延小于T4卡时延的1/3,可以帮助我们承载更大规模模型。A30 在MIG切分下,BERT类测试1/4 A30 MIG卡的时延仍低于T4整卡,MIG技术可进一步降低推理成本。同时我们也将尝试Graphcore、昆仑芯、寒武纪芯片等异构AI芯片在推理场景带来的成本收益。

 

在推理架构层面,我们将引入”Triton + Python backend + 用户自定义代码” 的方式更大限度的拓展推理服务的灵活性。

 

在模型性能层面,我们将持续积累计算图优化patterns、高性能算子、编译优化等技术方向,继续模型加速的技术演进。

 

 

以上是我们在小布助手NLP场景推理加速技术的演进历程,感谢读者们的阅读,如有疑问或者需要进一步交流,请与我们联系。

 

附件:

 

GTC 2022议题及分享视频链接

 

https://www.nvidia.com/gtc/session-catalog/?tab.scheduledorondemand=1583520458947001NJiE&search=42152#/session/1639570246493001REaf

 

作者简介

 

Lawrence  高级后端工程师

 

毕业于哈尔滨工业大学,从事分布式系统、机器学习系统研发工作多年,目前专注于AI训练与推理加速相关工作,曾就职于百度

 

本文版权归OPPO公司所有,如需转载请在后台留言联系

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注