2019.04.09 丨 壹佰案例

视频+PPT | 爱奇艺基于CPU的深度学习推理服务优化实践

2019.04.09 丨 壹佰案例

本文内容节选自由msup主办的第七届TOP100summit,时任爱奇艺技术产品中心计算云团队助理研究员张磊分享的《基于CPU的深度学习推理部署优化实践》实录。


分享者张磊,就职于爱奇艺技术产品中心计算云团队担任助理研究员,负责云平台上深度学习应用的优化落地方案。加入爱奇艺之前在英特尔亚太研发有限公司担任图形软件工程师,负责底层软件设计和实现,对CPU,GPU 上应用性能分析和优化有丰富的经验。



编者按:2018年11月30日-12月3日,第七届全球软件案例研究峰会在北京国家会议中心盛大开幕,现场解读2018年「壹佰案例榜单」。本文为爱奇艺技术产品中心计算云团队助理研究员张磊分享的《爱奇艺基于CPU的深度学习推理服务优化实践》案例实录。



提纲:


  • 案例来源

  • 深度学习推理服务及优化

  • 基于CPU深度学习推理服务优化实践

  • 案例结果及分析

  • 启示与展望



01案例来源


爱奇艺与AI

爱奇艺是一家以在线视频播放为主要业务的互联网公司,内部有很多视频应用的场景。为了给用户提供更好的视频播放体验,我们已将AI技术深入到业务线每一个领域,通过深度学习或AI的技术,让视频生产和播放过程更加智能与高效。


加速视频生产过程

典型的视频生产过程,包括视频拆分,视频编目,内容的审核,以及视频的发布,这些环节以前都是由人工去完成的,不仅花费了大量的人力成本,而且容易产生错误。我们希望利用深度学习的技术把这些环节自动化,不仅可以提高效率,而且可以节约大量的人力成本。



对基础架构的挑战

(1) 框架与模型的挑战

典型的深度学习框架模型有许多种,例如tensorflow,caffe,pytoch,keras等,不同的框架有不同的模型,它们的格式、部署方式都不太一致。我们需要能够支持不同的框架和模型,这对基础架构提出了挑战。

 

(2) 计算资源的挑战

GPU计算资源的紧缺,难以满足内部业务的快速增长。除此之外,GPU资源的利用率也是一个很大的问题,有些服务存在特殊的性能需求指标,没有办法把所有的服务整合在一个服务节点上以提高GPU资源的利用率。对于这类服务,我们通过迁移到CPU上来实现GPU资源的释放。

 

(3) 低延时高吞吐量的挑战

视频类业务的数据量非常大,对服务的吞吐量要求非常高,而且很多在线类的服务,通常具有低延时的要求。许多服务的端到端响应,通常需要控制在毫秒以内,留给深度学习服务做推理的时间非常少。

 

(4) 算法的快速迭代

算法迭代非常快。服务化的部署也需要应对算法的快速的部署和迭代。 



02深度学习推理服务及优化


深度学习在线推理服务

一个深度学习Serving系统,可以响应外部的client基于gRPC或HTTP的请求。上图是一个典型的在线推理服务系统,这样的Serving系统内部实现了模型的加载、模型的版本管理、以及对Batch或Stream管理,最后向外提供一个gRPC或HTTP接口。


分类与指标

(1) 分类

推理服务有很多应用场景,对于不同类型的深度学习的服务,需要优化的点是不一样的,因此需要对推理服务进行分类。我们可以基于系统资源和服务质量进行分类,比如说从系统资源角度,可以分为是I/O密集的深度学习服务或计算密集型的深度学习服务。I/O密集型通常数据的特征维度都非常大,数据集也非常大,对I/O的要求非常高;计算密集型是基于CNN的视频类的算法,对于计算资源的需求非常大。计算密集通常需要基于平台做计算资源的加速。从服务质量深度学习又可以分为延时敏感类和大吞吐量类,其中延时敏感类,一般是在线类的服务,是需要跟用户有交互的一类服务;大吞吐量则是后台的批处理业务。


(2) 指标

上图展示了三类常用指标,延时、吞吐量和精度。前两类的指标是做服务化比较关心的指标,直接影响服务的质量。关于吞吐量通常用QPS来定义一个平均的和一个峰值的指标。精度是算法工程师比较关心的指标。只有精度达到了一定要求的算法,才可以部署上线


性能优化

这是一个进行性能优化的瀑布流程,性能优化之前,首先需要对服务的性能指标有一个定义, 第二步进行服务性能的基准测试,在一个标准的系统环境下,对这个算法以及它的整个服务做性能基准测试,检测这个服务是不是能满足线上业务的需求。


CPU上的优化

若测试结果无法满足需求、我们会针对不同的性能瓶颈进行算法级、应用级、系统级的优化。系统级主要是针对硬件平台上做的一些性能优化的方法,应用级是跟特定应用相关的分析以及优化的方法,算法级是针对算法的优化,例如模型的裁剪,模型的量化。


03基于CPU深度学习推理服务优化实践


系统级优化

在CPU 上的系统级的优化目前采用两种方案,一种是基于MKL-DNN的数学库优化,另一种是基于厂商发布的深度学习的优化套件,我们的CPU主要是Intel CPU,所以使用了Open VINO。如图,针对于三个典型网络,蓝色部分是使用MKL-DNN做完优化,它比原生的框架通常会有一到三倍的性能提升,橘色的部分是基于Open VINO SDK的优化方式,它的优化幅度会比MKL-DNN多1倍左右。


MKL-DNN使用方法比较简单的,可以使用开源的官方镜像,或者是源。另一种方式是在编译时,指定相应的编译选项, MKL-DNN是基于原生框架的,所以不需要对模型做任何的转换,训练好的模型可以直接去使用,部署上线。


另一类优化方法是基于Open VINO的SDK方法,它的优化力度更深,它的实现通常需要模型转换,在通过通用框架训练得到一个原始模型后,通过SDK的模型转换工具,转化成中间格式model,得到这个中间模型之后,调用SDK的相应的API来封装整个深度学习的服务,进而进行服务化的部署。


这种优化方式模型转换会带来一些副作用,例如有某些深度学习层的操作不支持,整个模型转换就会失败,没有办法得到一个中间模型进行模型的转化和部署。


为了解决这类不支持的问题,我们针对模型转化工具做了一些优化,包括操作层的替换,自定义操作的实现等。


使用以上两种优化方式,有一些影响性能的因素。第一个是OpenMP的设置。 OpenMP有三个比较重要的设置,包括 KMP-BLOCKTIME,KMP-AFFINITY, OMP-NUM-THREADS。OMP-NUM-THREAS 参数决定了起多少路的线程来做同步的加速,BLOCKTIME决定线程要等待多久的时间进入到休眠的状态,AFFINITY,会决定OMP的线程如何分布到不同的CPU核上去,并通过CPU核数的堆叠,做到性能的成倍的提升。


右图列出了OMP在不同的设置下对性能的影响。我们发现只有THREADS与CPU的核数设置相等时,服务的吞吐量可以达到最大。


第二个是CPU核数与性能的关系, CPU在服务器端通常都是多核的,我们对核数与性能做了一个测试,可以看到,CPU的核数对性能的影响跟Batchsize相关,当 batchsize较小时,提高 CPU 核数到一定程度,性能已无法保持线性增长;当batchsize 较大时,即使 CPU 核数提升到比较高,例如24核,推理性能还是会随着CPU核数有一个线性的增长。


第三个影响性能的因素是CPU的型号,我们线上目前主要是两代 CPU类型,一类是Boardwell,一类是skylake。Skylake相比 broadwell,相同核数,性能提升在 2 倍左右。我们可以在线上服务时区分不同CPU集群,在进行服务部署时,选择不同的CPU集群来部署不同类型的服务。


第四个影响性能的因素是输入数据格式的影响,优化后的深度学习框架,推荐的输入数据格式化是NCHW,这种格式在进行数学运算时可以做更好的向量化的操作,对性能会有更大的帮助。


最后一个是NUMA的影响,服务器端的CPU与 PC上有些差异,它一般是多个CPU,每个CPU有自己内部独立的Memory以及cache和Bus,两个socket之间通过dsm的网络进行交互,代价比在单一的CPU上进行通信的代价要大,对性能的影响会比较多。


应用级优化

这是一个视频质量打分的例子,下面这张图是通过性能分析工具抓取的,我们可以看到,有8路OMPworker threads在做深度学习的推理,但是只有一路的opencv thread在做解码和预处理,一直处于busy的状态,它没有办法给推理部分提供足够的数据。针对这种情况,我们把预处理的部分做了一个并发。用多路进程来做解码,针对不同的视频帧,同时并发的做预处理,会把预处理的结果,加一个统一的缓存队列组成一个Batch,统一丢给后端的深度学习推理算法来做一个统一的推理。


这张图展示了并发整个的解码时间,预处理的时间缩短了1倍以上。每个应用,它的性能瓶颈是不一样的,我们需要通过分析工具去定位到它的瓶颈,做一些并发的Pipeline设计,从而达到性能的提升。



算法级优化


第三类优化是算法级的优化,通常我们拿到模型之后,需要结合硬件平台优化一下Batchsize的选择,另外就是通过量化的方法来进行优化。


我们测试了不同的Batchsize对整个服务性能的影响,如果选定一个特定的CPU的核数,随着Batchsize的增加,服务的吞吐量会有一个提升的过程,但如果Batchsize继续增大,会导致吞吐量的下降。 


Batchsize的选取不仅对吞吐量有影响,对服务的延时也有很大的影响,越大的Batchsize,服务延时也会越大。所以对Batchsize选取通常要结合服务的需求,来选择不同的Batchsize。


模型量化有两个好处,一是减小模型的大小,通常一个量化模型的size会缩小三分之一到四分之一。二是现在处理器对于低精度的乘加运算有很多加速的指令。经过量化后我们可以很好地利用加速指令来做性能提升,量化的方法有两类,一类是post-Training 的量化,另一类Training-aware的量化,post-Training是拿到训练好的模型之后直接去做量化,跟整个训练过程没有关系;Training-aware会在训练过程中对量化做一些优化和抵消,可以很大程度上去避免对精度的影响。


性能方面,不同框架量化的方法也是不一样的,我们使用TF-lite网络模型,在CPU性能上可以做到2到5倍的提升。在不影响模型精度的情况下,Caffe内部对特定算法,使用量化的8 bit整型模型,性能也会有1到3倍的提升。


深度服务云平台方案


我们在公司内部实现了一个统一的深度学习平台,来支持异构计算、支持不同类型的深度学习框架。这是一个基于容器的推理和训练一站式平台。


这是深度学习服务云平台的框架图,从下往上分为四层,最底下是基础架构层,往上是资源的管理和调度层,然后是框架和服务层,最上面各种视频业务。


基础架构方面,我们有CPU、GPU、FPGA,同时会支持公有云,以及不同的网络和存储的支持。


系统调度是用Mesos来做统一的资源管理和调度。所有的任务都是基于容器的方式,通过Mesos调度到统一的计算资源上面去。 框架和服务层,我们会提供统一的训练和推理的服务接口,方便直接使用。


我们提供两类服务化的方式,第一类是业务部门根据自己的业务制定的应用系统,我们已经把VINO 的SDK封装成一个标准的一个docker的形式,来提供给业务部门服务化的同学直接使用。第二类是Tensorflow Serving,它是谷歌发布的基于Tensorflow 的一个系统,我们把它做了容器化,并使用了MKL-DNN的加速,模型训练完之后,也可以通过Tensorflow Serving直接去进行线上部署。


这部分是对于推理服务部署的一个性能测试的方法,基于LOCUST,可以在单机上实现对深度学习服务更好的并发的压测。 



04案例结果及分析

以上是进行CPU优化后的结果,四个应用,经过优化之后,推理服务性能在 CPU 上分别得到了 4到20倍的提升。 


这是服务器端部署的规模,已经有数十个算法完成CPU上的优化落地,部署的规模也达到了上千核CPU,等效100多个GPU的资源节省。



05启示与展望



优化过程的一些启示:


服务性能需求的定义是优化的第一步。

方法栈工具集能帮助有效分析和定位服务性能瓶颈。

系统级优化帮助最大化CPU集群算力。

应用级优化帮助服务进行端到端的优化。

算法级优化针对特定算法实现性能优化。

深度学习部署平台帮助服务部署的自动化和性能对比。

优化无止境,按需求优化。


未来我们还可以进一步优化的方向: 


当前的优化主要是深度学习计算部分的优化,未来还可以进一步加速预处理部分,例如解码及图像处理;

集群的角度我们需要进一步优化调度算法,避免深度学习部署过程中产生的计算资源碎片化;

第三个是服务的弹性扩缩容,能根据线上业务量自动增加或减少服务节点;

最后一个是更多的异构资源计算加速。



以上内容来自张磊老师的分享。


视频


点击此处 ,即可查看视频。

媒体联系

票务咨询:赵丹丹 15802217295

赞助咨询:郭艳慧 13043218801

媒体支持:景    怡 13920859305

提交需求