得物AI平台

得物AI平台-KubeAI推理训练引擎设计和通常

KubeAI平台从得物AI业务场景的实践需求登程,以三大外围引擎为树立目的,着力处置AI模型研发环节中的训练、推理性能疑问,以及模型版本迭代环节中的效率疑问。

1、KubeAI引见

KubeAI是得物AI平台,是咱们在容器化环节中,逐渐搜集和开掘公司各业务域在AI模型钻研和消费迭代环节中的需求,逐渐树立而成的一个云原生AI平台。KubeAI以模型为主线提供了从模型开发,到模型训练,再到推理(模型)服务控制,以及模型版本继续迭代的整个生命周期内的处置打算。

在数据方面,KubeAI提供基于cvat的标注工具,与数据处置及模型训练流程买通,助力线上模型极速迭代;提供义务/Pipeline编排性能,对接ODPS/NAS/CPFS/OSS数据源,为用户提供一站式AI上班站。平台自研推理引擎助力业务在提高模型服务性能的同时还能控制老本;自研训练引擎提高了模型训练义务吞吐量,缩短了模型的训练时长,协助模型开发者减速模型迭代。

此外,随着AIGC的炽热开展,咱们经过调研公司外部AI辅佐消费相关需求,上线了AI制图性能,为得物海报、营销优惠、设计师团队等业务场景提供了基础才干和通用AI制图才干。

此前,咱们经过一文读懂得物云原生AI平台-KubeAI的落地通常环节一文,向大家引见了KubeAI的树立和在业务中的落地环节。本文,咱们将重点引见下KubeAI平台在推理、训练和模型迭代环节中的外围引擎才干通常阅历。

2、AI推理引擎设计成功

2.1 推理服务现状及性能瓶颈剖析

Python言语以其灵敏轻捷的特点,以及其在神经网络训练与推理畛域提供了丰盛的库允许,在模型钻研和开发畛域被宽泛经常使用,所以模型推理服务也关键以Python GPU推理为主。模型推理环节普通触及预处置、模型推理、后处置环节,单体进程的形式下CPU前/后处置环节,与GPU推理环节须要串行,或许假并行的形式启动上班,大抵流程如下图所示:

上述架构的长处是代码写起来比拟深刻易懂,但在性能上有很大的弊病,所能承载的QPS比拟低。经过在CV域的模型上启动压测,咱们发现推理QPS很难到达5,深化剖析发现形成这一疑问的要素如下:

(1)复线程形式下,CPU逻辑与GPU逻辑相互期待,GPU Kernel函数调度无余,造成GPU经常使用率不高,不可充沛优化服务QPS。这种状况下只能开启更多进程来优化QPS,然而更多进程会带来更大的GPU显存开支。

(2)多线程形式下,由于Python的GIL锁的要素,Python的多线程实践上是伪的多线程,并不是真正的并发口头,而是多个线程经过争抢GIL锁来口头,这种状况下GPU Kernel Launch线程不能失掉充沛的调度。此外,在Python推理服务中开启多线程反而会造成GPU Kernel Launch线程频繁被CPU的线程打断,所以GPU算力也会不时“朝气蓬勃”,继续低下。

以上疑问使得 假设推理服务想要撑持更多的流量,只能做横向的参与服务虚例数,随同着老本的下跌。

2.2 自研推理服务一致框架kubeai-inference-framework

针对以上疑问,KubeAI的处置打算是把CPU逻辑与GPU逻辑分别在两个不同的进程中:CPU进程关键担任图片的前处置与后处置,GPU进程则关键担任口头CUDA Kernel 函数,即模型推理。

为了繁难模型开发者更极速地接入咱们的优化打算,咱们基于Python开发了一个CPU与GPU进程分别的一致框架kubeai-inference-framework,旧有Flask或Kserve的服务,稍作修正即可接入推理引擎一致框架,新增服务依照框架成功指定function即可。推理服务一致框架构如下图所示:

如前所述,推理服务一致框架的关键思绪是把GPU逻辑与CPU逻辑分别到两个进程,除此之外,还会拉起一个Proxy进程做路由转发。

CPU进程

CPU进程关键担任推理服务中的CPU相关逻辑,包括前处置与后处置。前处置普通为图片解码,图片转换,后处置普通为推理结果决定等逻辑。CPU进程在前处置完结后,会调用GPU进程启动推理,而后继续启动后处置相关逻辑。CPU进程与GPU进程经过共享内存或网络启动通讯,共享内存可以缩小图片的网络传输。

GPU进程

GPU进程关键担任运转GPU推理相关的逻辑,它启动的时刻会加载很多模型到显存,而后在收到CPU进程的推理恳求后,间接触发Kernel Lanuch调用模型启动推理。

kubeai-inference-framework框架中对模型开发者提供了一个Model类接口,他们不须要关心前面的调用逻辑,只要要填充其中的前处置,后处置的业务逻辑,就可以极速上线模型服务,智能拉起这些进程。

Proxy进程

Proxy进程是推理服务入口,对外提供调用接口,担任路由散发与肥壮审核。当Proxy进程收到恳求后,会轮询调用CPU进程,散发恳求给CPU进程启动处置。

自研的推理服务一致框架,把CPU逻辑(图片解码,图片后处置等)与GPU逻辑(模型推理)分别到两个不同的进程中后,有效处置了Python GIL锁带来的GPU Kernel Launch调度疑问,优化了GPU应用率,提高了推理服务性能。针对线上的某个推理服务,经常使用咱们的框架启动了CPU与GPU进程分别,压测得出的数据如下表所示,可以看到QPS优化了近7倍。

推理服务框架类型

耗时(s)

GPU算力经常使用率(%)

传统多线程架构

自研推理服务框架(6个CPU进程+1个GPU进程)

2.3 做的更好 — 引入TensorRT优化减速

在允许推理服务接入kubeai-inference-framework一致框架的环节中,咱们继续尝试在模型自身做优化优化。经过调研和验证,咱们将现有pth格局模型经过转成TensorRT格局,并开启FP16,在推理阶段取得了更好的QPS优化,最高可到10倍优化。

TensorRT是由英伟达公司推出的一款用于高性能深度学习模型推理的软件开发工具包,可以把经过优化后的深度学习模型构建成推理服务部署在实践的消费环境中,并提供基于配件级别的推理引擎性能优化。业内最罕用的TensorRT优化流程,是把pytorch / tensorflow等模型先转成onnx格局,而后再将onnx格局转成TensorRT(trt)格局启动优化,如下图所示:

TensorRT所做的上班关键在两个时期,一个是网络构建期,另外一个是模型运转期。

为了更好地协助模型开发者经常使用TensorRT优化,KubeAI平台提供了kubeai-trt-helper工具,用户可以经常使用该工具把模型转成TensorRT格局,假设在模型转换的环节中产生精度失落等疑问,也可以经常使用该工具启动疑问定位与处置。kubeai-trt-helper关键在两个阶段为用户提供协助:一个是疑问定位,另一个阶段是模型转换。

疑问定位

疑问定位阶段关键是为了处置模型转TensorRT开启FP16形式时产生的精度失落疑问。普通分类模型,对精度的要求不是极致的状况下,尽量开启FP16,FP16形式下,NVIDIA关于FP16有专门的Tensor Cores可以启动矩阵运算,相比FP32来说吞吐量优化一倍以上。比如在转TensorRT时,开启FP16产生了精度失落疑问,kubeai-trt-helper工具在疑问定位阶段的大抵上班流程如下:

第1步:设定模型转换精度要求后,标志一切算子为输入,而后对比一切算子的输入精度。

第2步:找到最早的不合乎精度要求的算子,对该算子启动如下几种形式干预。

循环经过以上2个步骤,最终找到合乎目的精度要求的模型参数。这些参数比如:须要额外开启FP32的那些算子等。相关参数会输入到性能文件中,如下:

性能项

释义

FP32_LAYERS_FOR_FP16

开启FP16形式下,哪些算子须要额外开启FP32

TRT_EXCLUDE_TACTIC

TensorRT算子须要疏忽的tactic战略(tactic可参考TensorRT相关资料)

相对误差

相对误差

check-error-stat

误差的计算方法包括:mean, median, max

模型转换

模型转换阶段则间接经常使用下面疑问定位阶段失掉的参数,调用TensorRT相关接口与工具启动转换。此外,咱们在模型转换阶段,针对TensorRT原有参数与API过于复杂的疑问也做了一些封装,提供了更为繁复的接口,比如工具可以智能解析onnx,判别模型的输入与输入shape,不须要用户再提供相关shape消息等。

2.4 落地通常成绩

在实践运行中,咱们协助算法域的模型开发同窗,能够对一个推理基于自研推理服务一致框架启动成功的同时,也开启TensorRT优化,这样往往可以失掉QPS两次优化的叠加效果。

2.4.1 分类模型,CPU与GPU分别,TensorRT优化,并开启FP16,失掉10倍QPS优化

线上某个基于Resnet的分类模型,对精度损失可以接受误差在0.001(误差定义:median,atol,rtol)范围内。因此咱们对该推理服务启动了3项性能优化:

经过以上优化,最终失掉了10倍QPS的优化(与原来Pytorch间接推理比拟),服务老本大幅增添。

2.4.2 检测模型,CPU与GPU分别,TensorRT模型优化,QPS优化4-5倍左右。

线上某个基于Yolo的审核模型,由于对精度要求比拟高,所以不能开启FP16,咱们间接在FP32的形式下启动了TensorRT优化,并经常使用kubeai-inference-framework一致框架对GPU进程与CPU进程分别,最终失掉QPS 4-5倍的优化。

2.4.3 模型推理进程多实例化,充沛应用GPU算力资源

在实践的场景中,往往GPU的算力是短缺的,而GPU显存是不够的。经过TensorRT优化后,模型运转时须要的显存大小普通会降落到原来的1/3到1/2。所以为了充沛应用GPU算力,kubeai-inference-framework一致框架进一步优化,允许可以把GPU进程在一个容器内复制多份,这种架构即保证了CPU可以提供短缺的恳求给GPU,也保证了GPU算力充沛应用。

线上某个模型,经过TensorRT优化后,显存由原来的2.4G降落到只要要1.2G。在坚持推理服务性能5G显存不变的状况下,咱们将GPU进程为复制4份,充沛应用了5G显存,使得服务吞吐到达了原来的4倍。

3、AI训练引擎优化通常

3.1 PyTorch框架详情

PyTorch是近年来较为火爆的深度学习框架,简直占据了CV(Computer Vision,计算机视觉)、NLP(Natural Language Processing,人造言语处置)畛域各业务方向,算法同窗基本都在经常使用PyTorch框架来启动模型训练。下图是基于PyTorch框架启动模型训练时的代码基本流程:

第1步:从pytorch>第2步:将失掉到的数据,例如:样本图片、样本标签的tensor等数据,复制到GPU显存里。

第3步:开局正式的模型训练:前向计算、计算损失、计算梯度、 降级参数。

整个训练环节的耗时,也关键散布在下面3个步骤。通常第2步不会是瓶颈,由于大局部训练样本图片都是被resize变小之后才从内存拷贝到到GPU显存上的。但由于模型的差同性、训练数据的差同性,经常是第1、2步会在训练环节中产生性能瓶颈,造成训练耗时长,GPU应用率低下,影响模型迭代效率。

3.2>PyTorch训练读取数据局部关键是经过Dataset、Dataloader的形式成功的,其中Dataset为用户自定义读取数据的类(承袭自 torch.utils.data.Dataset),而Dataloader是PyTorch成功的在训练环节中对Dataset的调度器。
torchutilsdataloadertorchutilsDatasettrain_loader  torchutilsDataLoader MyDatasetbatch_sizenum_workersshuffledrop_lastpin_memoryval_loader  torchutilsDataLoaderMyDatasetbatch_sizebatch_sizenum_workersshuffle

参数解释如下:

上述参数中,比拟关键的是num_workers,Dataloader在结构的时刻,会启动num_workers个worker进程,而后主进程会向worker进程散发读取义务,worker进程读到数据之后,再把数据放到队列中供主进程取用。多进程形式经常使用的是torch.multiprocessing接口,可以成功worker进程与主进程之间共享内存,而且共享内存中可以寄存tensor,这样进程中假设前往tensor,可以经过共享内存的形式间接将结果前往给主进程,缩小多进程间的通讯开支。

当num_workers为0 的时刻:get_data()流程与train_model()环节是串行,效率十分低下,如下图所示:

当num_workers大于0开启多进程读取数据, 并且读取一个batch数据的时期小于一个step训练的时期时效率最高,GPU算力被充沛应用,如下图所示:

当num_workers大于0开启多进水平数据, 然而读取一个batch数据的时期大于一个step训练的时期时,会产生GPU训练环节期待数据拉取,就会产生GPU算力闲暇,训练耗时参与,如下图所示:

由此可见Dateset中的__getitem__函数十分关键,详细剖析它的源码成功后咱们发现,该函数的耗时关键蕴含2段

3.2.2 解疑问 — 设置正当的参数很关键

经过上一小节的剖析,训练时相关参数的选用至关关键。总结如下:

优化案例一

线上一个基于MMDetection框架(其底层也是调用PyTorch框架)的CV模型训练义务,在做参数调整之前,单个step耗时不稳固,平均在1.12s左右,其中拉取数据时长在0.3s左右:

mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: 

调整参数之后,单个step耗时稳固,平均在0.78 s左右,其中拉取数据耗时0.004s,基本可以疏忽。

mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: mmengine  INFO  Epochtrain : data_time: 

该模型训练义务,经过上述优化调整,数据拉取时期缩短为0,单个step的耗时从原来的1.12s降到0.78s,全体训练时期缩小30%(从2天缩短到33小时),效果清楚。

优化案例二

线上某个多模态模型(输入蕴含图片和文字)训练义务,经常使用2卡V100训练,参数调整如下:

batch_sizeCPU  numworkers  

调整后训练300 step总消耗时405s,全体训练时期缩小45%左右(从10天缩短到5天左右)。

优化案例三

线上某YoloX模型训练义务,经常使用单卡A100训练,参数调整如下:

batch size :numworkers   

调整后全体训练时长缩小80%左右(从10天19小时,缩短至1天16小时)。

3.2.3 数据拉取IO瓶颈剖析

,KubeAI平台为训练场景提供3种存储介质:

关于小数据集,可以先将数据一次性性拉取到本地盘,而后每个epoch从本地盘来读数据,这样防止了每一个epoch重复的从远程NAS来拉取数据,相当于整个训练只要要从远程NAS拉取一次性数据。关于大数据集,有2种处置打算:

3.3 TrainingModel优化

数据局部优化后,训练环节中的关键时期开支就在GPU训练局部了。目前业内有一些比拟成熟的方法可以参考,咱们总结如下。

3.3.1 混合精度训练(AMP)

PyTorch混合精度训练在PyTorch官方有详细引见,以及开启混合精度训练的方法,可以浏览这里失掉成功方法。许多CV训练框架曾经允许AMP训练,比如:

须要说明的是,混合精度训练环节中并不是将一切模型参数都转为FP16来计算,只要局部做转换。混合精度之所以能减速训练环节,是由于大局部英伟达GPU机型在FP16这种数据格局的浮点算力比FP32要快一倍;此外,混合精度训练显存占用会更小。

scaler  GradScaler epoch  epochs: input target  :optimizerzero_grad autocastdevice_type dtypetorchfloat16:output  modelinputloss  loss_fnoutput targetscalerscalelossbackwardscalerunscale_optimizertorchnnutilsclip_grad_norm_modelparameters max_normscalerstepoptimizerscaler

3.3.2 单机多卡数据并行训练

Pytorch原生允许多卡数据并行训练,详细开启多卡训练的形式参考官方文档。多卡训练环节中每一张卡的backword计算会多加一次性多卡之间汇合通讯all-reduce操作,用来计算多张卡上的梯度的平均值。

3.4自研训练引擎框架kubeai-training-framework

经过前面的剖析咱们可以看到,只管PyTorch框架自身曾经做的很好了,训练形式、参数允许丰盛,但在实践的模型钻研和消费环节中,由于模型的差同性、训练数据的差同性,以及模型开发者的阅历差同性,PyTorch框架自身的长处不必定能够施展进去。

基于前述剖析和通常,KubeAI平台开发了训练引擎框架kubeai-training-framework,协助模型开发者更好地婚配训练脚本参数,极速接入经常使用适合的训练形式。kubeai-training-framework中蕴含PyTorch>

 torch kubeai_training_frameworkdataloader >(train_loader model criterion optimizer epoch:train_dataset  train_loader  torchutilsDataLoadertrain_dataset batch_sizeargsbatch_size shufflenum_workersargsworkers pin_memorymodeltrainmy_train_loader >(train_loaderinput target  my_train_loader input   None:input target  my_train_loader

4、AI Pipeline引擎助力AI业务极速迭代

通常模型的开发可以演绎为如下图所示的环节:

可以看到,在需求场景确定、第一个模型版本上线之后,模型是须要重复迭代的,以希冀取得更好的业务效果。KubeAI平台在迭代树立的环节中,逐渐上线了Notebook、模型控制、训练义务控制、推理服务控制等一个个相对独立的性能模块。随着业务需求的不时变动,模型迭代效率间接影响了业务的上线效率,KubeAI平台树立了AI Pipeline才干,重点处置AI场景的周期性迭代类需求,提高消费效率。

AI Pipeline是在ArgoWorkflow基础上做了二次开发,以满足模型迭代、推理义务控制、数据处置等对定时需求、义务启动触发形式、通用模板义务、指定节点启动等需求。AI Pipeline上线之前,一个迭代义务或许会被性能为多个扩散的义务,保养上班量大,调试周期长。如下图是做一个相似义务须要独自性能的义务状况:

AI Pipeline可以将整个上班流设计成如下图所示:

Pipeline编排的形式,缩小了模型开发者糜费在反停上班上的时期,可以将更多的时期投入到模型钻研上。同时,经过正当编排义务,可以对有限的资源启动充沛地利用。

5、展望

KubeAI平台从得物AI业务场景的实践需求登程,以三大外围引擎为树立目的,着力处置AI模型研发环节中的训练、推理性能疑问,以及模型版本迭代环节中的效率疑问。

在推理服务性能上,咱们会以kubeai-inference-framework为终点,继续在模型量化、算子优化、图优化等方面启动深化探求。在模型训练方面,咱们会继续在图像数据预处置、Tensorflow GPU训练框架允许、NLP模型训练允许上发力,以kubeai-training-framework训练引擎框架为接口,为模型开发者提供更高效、性能更高的训练框架。此外,AI Pipeline引擎上,咱们会允许更丰盛的预置模型,以满足通用数据处置义务、推理义务等需求。

您可能还会对下面的文章感兴趣: