AI算法模型线上部署方法总结

AI算法模型线上部署方法总结

  • (推荐)PMML介绍及使用
  • 一、机器学习算法线上部署方法
    • 1.1 三种场景
    • 1.2 如何转换PMML,并封装PMML
    • 1.3 接下来说一下各个算法工具的工程实践
      • 1.3.1 python模型上线:我们目前使用了模型转换成PMML上线方法。
      • 1.3.2 R模型上线-这块我们用的多,可以用R model转换PMML的方式来实现。
      • 1.3.3 Spark模型上线-好处是脱离了环境,速度快。
    • 1.4 只用Linux的Shell来调度模型的实现方法—简单粗暴
    • 1.5 说完了部署上线,说一下模型数据流转的注意事项
  • 二、机器学习算法的部署
    • 实时小规模
    • 实时大规模
    • 离线计算
  • 三、谈一谈AI算法部署的一些经验
  • 四、老潘的AI部署以及工业落地学习之路(深度学习)
    • 4.1 AI部署
    • 4.2 聊聊AI部署
    • 4.3 需要什么技术呢/li>
    • 4.4 需要的深度学习基础知识
    • 4.5 常用的框架
    • Caffe
    • Libtorch (torchscript)
    • TensorRT
    • OpenVINO
    • NCNN/MNN/TNN/TVM
    • PaddlePaddle
    • 还有很多框架
    • 4.6 AI部署中的提速方法
      • 4.6.1 模型结构
      • 4.6.2 剪枝
      • 4.6.3 蒸馏
      • 4.6.4 稀疏化
      • 4.6.4 量化训练
    • 4.7 常见部署流程
    • 4.8 后记
  • 五、算法模型在服务端的部署
    • 谈谈算法模型在服务端的部署
    • 5.1 关于模型部署框架的两大类型
    • 5.2 关于两种类型的成因思考
    • 5.3 那么请问……
    • 5.4 关于我们目前的解决方案
    • 5.5 为啥不上Kubeflow

一、机器学习算法线上部署方法

来自:机器学习算法线上部署方法
?

我们经常会碰到一个问题:用了复杂的GBDT或者xgboost大大提升了模型效果,可是在上线的时候又犯难了,工程师说这个模型太复杂了,我没法上线,满足不了工程的要求,你帮我转换成LR吧,直接套用一个公式就好了,速度飞速,肯定满足工程要求。这个时候你又屁颠屁颠用回了LR,重新训练了一下模型,心里默骂千百遍:工程能力真弱。
这些疑问,我们以前碰到过,通过不断的摸索,试验出了不同的复杂机器学习的上线方法,来满足不同场景的需求。在这里把实践经验整理分享,希望对大家有所帮助。(我们的实践经验更多是倾向于业务模型的上线流程,广告和推荐级别的部署请自行绕道)。
首先在训练模型的工具上,一般三个模型训练工具,Spark、R、Python。这三种工具各有千秋,以后有时间,我写一下三种工具的使用心得。针对不同的模型使用场景,为了满足不同的线上应用的要求,会用不同的上线方法。

1.1 三种场景

  • 如果是实时的、小数据量的预测应用,则采用的SOA调用Rserve或者python-httpserve来进行应用;这种应用方式有个缺点是需要启用服务来进行预测,也就是需要跨环境,从Java跨到R或者Python环境。对于性能,基本上我们用Rserver方式,针对一次1000条或者更少请求的预测,可以控制95%的结果在100ms内返回结果,100ms可以满足工程上的实践要求。更大的数据量,比如10000/次,100000/次的预测,我们目前评估下来满足不了100ms的要求,建议分批进行调用或者采用多线程请求的方式来实现。
  • 如果是实时、大数据量的预测应用,则会采用SOA,训练好的模型转换成PMML(关于如何转换,我在下面会详细描述),然后把模型封装成一个类,用Java调用这个类来预测。用这种方式的好处是SOA不依赖于任何环境,任何计算和开销都是在Java内部里面消耗掉了,所以这种工程级别应用速度很快、很稳定。用此种方法也是要提供两个东西,模型文件和预测主类;
  • 如果是Offline(离线)预测的,D+1天的预测,则可以不用考虑第1、2种方式,可以简单的使用Rscript x.R或者python x.py的方式来进行预测。使用这种方式需要一个调度工具,如果公司没有统一的调度工具,你用shell的crontab做定时调用就可以了。

以上三种做法,都会用SOA里面进行数据处理和变换,只有部分变换会在提供的Function或者类进行处理,一般性都建议在SOA里面处理好,否则性能会变慢。
大概场景罗列完毕,简要介绍一下各不同工具的线上应用的实现方式。
?

1.2 如何转换PMML,并封装PMML

大部分模型都可以用PMML的方式实现,PMML的使用方法调用范例见:

  • jpmml的说明文档:GitHub – jpmml/jpmml-evaluator: Java Evaluator API for PMML;
  • Java调用PMML的范例(PPJUtils/java/pmml at master · pjpan/PPJUtils · GitHub),此案例是我们的工程师写的范例,大家可以根据此案例进行修改即可;
  • Jpmml支持的转换语言,主流的机器学习语言都支持了,深度学习类除外;
  • 从下图可以看到,它支持R、python和spark、xgboost等模型的转换,用起来非常方便。

1.5 说完了部署上线,说一下模型数据流转的注意事项

  1. 区分offline和realtime数据,不管哪种数据,我们根据key和不同的更新频次,把数据放在redis里面去,设置不同的key和不同的过期时间;
  2. 大部分redis数据都会存放两个批次的数据,用来预防无法取到最新的数据,则用上一批次的数据来进行填充;
  3. 针对offline数据,用调度工具做好依赖,每天跑数据,并生成信 文件让redis来进行读取;
  4. 针对realtime数据,我们区分两种类型,一种是历史+实时,比如最近30天的累计订单量,则我们会做两步,第一部分是D+1之前的数据,存成A表,今天产生的实时数据,存储B表,A和B表表结构相同,时效性不同;我们分别把A表和B表的数据放在Redis上去,然后在SOA里面对这两部分数据实时进行计算;
  5. 模型的输入输出数据进行埋点,进行数据跟踪,一是用来校验数据,二来是用来监控API接口的稳定性,一般性我们会用ES来进行log的查看和性能方面的监控
  6. 任何接口都需要有容灾机制,如果接口超时,前端需要进行容灾,立即放弃接口调用数据,返回一个默认安全的数值,这点对于工程上非常重要。

二、机器学习算法的部署

来自:机器学习算法的部署

算法工程师和业务开发工程师掌握的技术集和工具是不同的,特别是当两者运用的语言不同的时候更严重。算法辛苦作出的模型业务开发用不了会极大影响很多事情的落地。
常见的合作模式如下算法负责模型训练和导出模型,业务开发导入模型并且做预测。一般算法使用python,R等,而业务开发使用java。可选的部署方法有以下几种:

实时小规模

可以简单点直接用Rserver或者python-httpserver,这种需要额外的服务,也存在调用问题,即引入了 络超时,重试等问题。性能上的话小数量可以保证95%在100ms返回,但是数据量大了就需要仔细控制。

实时大规模

这种情况考虑到基础设施的情况,特别是RPC框架等情况,同时要考虑水平扩展,最好使用PMML。这种额外依赖外部环境的方式可以提供较高的工程稳定性但是PMML必然导致一些算法精度的损耗

离线计算

对于T+1的计算和产出,部署上无疑最简单,直接使用脚本搭配一个监控和调度平台就可以获得较好的收益。
对于PMML,java中的选择是https://github.com/jpmml,对于各种语言和模型都有较好的支持。当然由于较高的通用性,PMML会丧失特殊模型的特殊优化,例如上线XGBoost模型,也可以使用XGBoost4J,该包会链接一个本地环境编译的 .so 文件,C++实现的核心代码效率很高。不过PMML格式通用性,在效率要求不高的场景可以发挥很大作用。
?

三、谈一谈AI算法部署的一些经验

来自:谈一谈AI算法部署的一些经验
?

  • 再次强调一下训练集、验证集和测试集在训练模型中实际的角色:训练集相当于老师布置的作业,验证集相当于模拟试卷,测试集相当于考试试卷,做完家庭作业直接上考卷估计大概率考不好,但是做完作业之后,再做一做模拟卷就知道大体考哪些、重点在哪里,然后调整一下参数啥的,最后真正考试的时候就能考好;训练集中拆分出一部分可以做验证集、但是测试集千万不要再取自训练集,因为我们要保证测试集的”未知“性;验证集虽然不会直接参与训练,但我们依然会根据验证集的表现情况去调整模型的一些超参数,其实这里也算是”学习了“验证集的知识;千万不要把测试集搞成和验证集一样,”以各种形式“参与训练,要不然就是信息泄露。我们使用测试集作为泛化误差的近似,所以不到最后是不能将测试集的信息泄露出去的。
  • 数据好坏直接影响模型好坏;在数据量初步阶段的情况下,模型精度一开始可以通过改模型结构来提升,加点注意力、加点DCN、增强点backbone、或者用点其他巧妙的结构可以增加最终的精度。但是在后期想要提升模型泛化能力就需要增加训练数据了,为什么呢为此时你的badcase大部分训练集中是没有的,模型没有见过badcase肯定学不会的,此时需要针对性地补充badcase;那假如badcase不好补充呢时图像生成就很重要了,如何生成badcase场景的训练集图,生成数据的质量好坏直接影响到模型的最终效果;另外图像增强也非常非常重要,我们要做的就是尽可能让数据在图像增强后的分布接近测试集的分布,说白了就是通过图像生成和图像增强两大技术模拟实际中的场景。
  • 当有两个数据集A和B,A有类别a和b,但只有a的GT框;B也有类别a和b,但只有b的GT框,显然这个数据集不能直接拿来用(没有GT框的a和b在训练时会被当成背景),而你的模型要训练成一个可以同时检测a和b框,怎么办种方式:1、训练分别检测a和检测b的模型,然后分别在对方数据集上进行预测帮忙打标签,控制好分数阈值,制作好新的数据集后训练模型;2、使用蒸馏的方式,同样训练分别检测a和检测b的模型,然后利用这两个模型的soft-label去训练新模型;3、修改一下loss,一般来说,我们的loss函数也会对负样本(也就是背景)进行反向传播,也是有损失回传的,这里我们修改为,如果当前图片没有类别a的GT框,我们关于a的损失直接置为0,让这个类别通道不进行反向传播,这样就可以对没有a框的图片进行训练,模型不会将a当成背景,因为模型“看都不看a一眼,也不知道a是什么东东”,大家可以想一下最终训练后的模型是什么样的呢、在模型的最后部分将head头分开,一个负责检测a一个负责检测b,此时模型的backbone就变成了特征提取器。
  • 工作中,有很多场景,你需要通过旧模型去给需要训练的新模型筛选数据,比如通过已经训练好的检测模型A去挑选有类别a的图给新模型去训练,这时就需要搭建一个小服务去实现这个过程;当然你也可以打开你之前的旧模型python库代码,然后回忆一番去找之前的demo.py和对应的一些参数;显然这样是比较麻烦的,最好是将之前模型总结起来随时搭个小服务供内部使用,因为别人也可能需要使用你的模型去挑数据,小服务怎么搭建呢接使用flask+Pytorch就行,不过这个qps请求大的时候会假死,不过毕竟只是筛选数据么,可以适当降低一些qps,离线请求一晚上搞定。
  • 目前比较好使的目标检测框架,无非还是那些经典的、用的人多的、资源多的、部署方便的。毕竟咱们训练模型最终的目的还是上线嘛;单阶段有SSD、yolov2-v5系列、FCOS、CenterNet系列,Cornernet等等单阶段系列,双阶段的faster-rcnn已经被实现了好多次了,还有mask-rcnn,也被很多人实现过了;以及最新的DETR使用transformer结构的检测框架,上述这些都可以使用TensorRT部署;其实用什么无非也就是看速度和精度怎么样,是否支持动态尺寸;不过跑分最好的不一定在你的数据上好,千万千万要根据数据集特点选模型,对于自己的数据集可能效果又不一样,这个需要自己拉下来跑一下;相关模型TensorRT部署资源:https://github.com/grimoire/mmdetection-to-tensorrt 和 https://github.com/wang-xinyu/tensorrtx
  • 再扯一句,其实很多模型最终想要部署,首要难点在于这个模型是否已经有人搞过;如果有人已经搞过并且开源,那直接复制粘贴修改一下就可以,有坑别人已经帮你踩了;如果没有开源代码可借鉴,那么就需要自个儿来了!首先看这个模型的backbone是否有特殊的op(比如dcn、比如senet,当然这两个已经支持了),结构是否特殊(不仅仅是普通的卷积组合,有各种reshape、roll、window-shift等特殊操作)、后处理是否复杂转换过最复杂的模型,backbone有自定义op,需要自己实现、另外,这个模型有相当多的后处理,后处理还有一部分会参与训练,也就是有学习到的参数,但是这个后处理有些操作是无法转换为trt或者其他框架的(部分操作不支持),因此只能把这个模型拆成两部分,一部分用TensorRT实现另一部分使用libtorc实现;其实大部分的模型都可以部署,只不过难度不一样,只要肯多想,法子总是有的。
  • 转换后的模型,不论是从Pytorch->onnx还是onnx->TensorRT还是tensorflow->TFLITE,转换前和转换后的模型,虽然参数一样结构一样,但同样的输入,输出不可能是完全一样的。当然如果你输出精度卡到小数点后4位那应该是一样的,但是小数点后5、6、7位那是不可能完全一模一样的,转换本身不可能是无损的;举个例子,一个检测模型A使用Pytorch训练,然后还有一个转换为TensorRT的模型A`,这俩是同一个模型,而且转换后的TensorRT也是FP32精度,你可以输入一个随机数,发现这两个模型的输出对比,绝对误差和相对误差在1e-4的基准下为0,但是你拿这两个模型去检测的时候,保持所有的一致(输入、后处理等),最终产生的检测框,分数高的基本完全一致,分数低的(比如小于0.1或者0.2)会有一些不一样的地方,而且处于边缘的hardcase也会不一致;当然这种情况一般来说影响不大,但也需要留一个心眼。
  • 模型的理论flops和实际模型执行的速度关系不大,要看具体执行的平台,不要一味的以为flops低的模型速度就快。很多开源的检测库都是直接在Pytorch上运行进行比较,虽然都是GPU,但这个其实是没有任何优化的,因为Pytorch是动态图;一般的模型部署都会涉及到大大小小的优化,比如算子融合和计算图优化,最简单的例子就是CONV+BN的优化,很多基于Pytorch的模型速度比较是忽略这一点的,我们比较两个模型的速度,最好还是在实际要部署的框架和平台去比较;不过如果这个模型参数比较多的话,那模型大概率快不了,理由很简单,大部分的参数一般都是卷积核参数、全连接参数,这些参数多了自然代表这些op操作多,自然会慢。
  • 同一个TensorRT模型(或者Pytorch、或者其他利用GPU跑的模型)在同一个型 卡上跑,可能会因为cuda、cudnn、驱动等版本不同、或者显卡的硬件功耗墙设置(P0、P1、P2)不同、或者所处系统版本/内核版本不同而导致速度方面有差异,这种差异有大有小,我见过最大的,有70%的速度差异,所以不知道为什么模型速度不一致的情况下,不妨考虑考虑这些原因。
  • 转换好要部署的模型后,一般需要测试这个模型的速度以及吞吐量;速度可以直接for循环推理跑取平均值,不过实际的吞吐量的话要模拟数据传输、模型执行以及排队的时间;一般来说模型的吞吐量可以简单地通过1000/xx计算,xx为模型执行的毫秒,不过有些任务假如输入图像特别大,那么这样算是不行的,我们需要考虑实际图像传输的时间,是否本机、是否跨 段等等。

四、老潘的AI部署以及工业落地学习之路(深度学习)

来自:老潘的AI部署以及工业落地学习之路
?

Hello我是老潘,好久不见各位。
最近在复盘今年上半年做的一些事情,不管是训练模型部署模型搭建服务,还是写一些组件代码,零零散散是有一些产出。
虽然有了一点点成果,但仍觉着缺点什么。作为深度学习算法工程师,训练模型和部署模型是最基本的要求,每天都在重复着这个工作,但偶尔静下心来想一想,还是有很多事情需要做的:

  • 模型的结构,因为上线业务需要,更趋向于稳定有经验的,而不是探索一些新的结构
  • 模型的加速仍然不够,还没有压榨完GPU的全部潜力

深感还有很多很多需要学习的地方啊。

4.1 AI部署

AI部署这个词儿大家肯定不陌生,可能有些小伙伴还不是很清楚这个是干嘛的,但总归是耳熟能详了。
近些年来,在深度学习算法已经足够卷卷卷之后,深度学习的另一个偏向于工程的方向–部署工业落地,才开始被谈论的多了起来。当然这也是大势所趋,毕竟AI算法那么多,如果用不着,只在学术圈搞研究的话没有意义。因此很多AI部署相关行业和AI芯片相关行业也在迅速发展,现在虽然已经2021年了,但我认为AI部署相关的行业还未到头,AI也远远没有普及。
简单收集了一下知乎关于“部署”话题去年和今年的一些提问:

AI算法模型线上部署方法总结

提问的都是明白人,随着人工智能逐渐普及,使用神经 络处理各种任务的需求越来越多,如何在生产环境中快速、稳定、高效地运行模型,成为很多公司不得不考虑的问题。不论是通过提升模型速度降低latency提高用户的使用感受,还是加速模型降低服务器预算,都是很有用的,公司也需要这样的人才。
在经历了算法的神仙打架、诸神黄昏、灰飞烟灭等等这些知乎热搜后。AI部署工业落地这块似乎还没有那么卷…相比AI算法来说,AI部署的入坑机会更多些。

当然,AI落地部署和神经 络深度学习的关系是分不开的,就算你是AI算法工程师,也是有必要学习这块知识的。并不是所有人都是纯正的AI算法研究员。

4.2 聊聊AI部署

AI部署的基本步骤

  • 训练一个模型,也可以是拿一个别人训练好的模型
  • 针对不同平台对生成的模型进行转换,也就是俗称的parse、convert,即前端解释器
  • 针对转化后的模型进行优化,这一步很重要,涉及到很多优化的步骤
  • 在特定的平台(嵌入端或者服务端)成功运行已经转化好的模型
  • 在模型可以运行的基础上,保证模型的速度、精度和稳定性

就这样,虽然看起来没什么,但需要的知识和经验还是很多的。
因为实际场景中我们使用的模型远远比ResNet50要复杂,我们部署的环境也远远比实验室的环境条件更苛刻,对模型的速度精度需求也比一般demo要高。
对于硬件公司来说,需要将深度学习算法部署到性能低到离谱的开发板上,因为成本能省就省。在算法层面优化模型是一方面,但更重要的是从底层优化这个模型,这就涉及到部署落地方面的各个知识(手写汇编算子加速、算子融合等等);对于软件公司来说,我们往往需要将算法运行到服务器上,当然服务器可以是布满2080TI的高性能CPU机器,但是如果QPS请求足够高的话,需要的服务器数量也是相当之大的。这个要紧关头,如果我们的模型运行的足够快,可以省机器又可以腾一些buffer上新模型岂不很爽,这个时候也就需要优化模型了,其实优化手段也都差不多,只不过平台从arm等嵌入式端变为gpu等桌面端了。
作为AI算法部署工程师,你要做的就是将训练好的模型部署到线上,根据任务需求,速度提升2-10倍不等,还需要保证模型的稳定性。
是不是很有挑战性/p>

4.3 需要什么技术呢/h2>

需要一些算法知识以及扎实的工程能力
老潘认为算法部署落地这个方向是比较踏实务实的方向,相比_设计模型提出新算法_,对于咱们这种并不天赋异禀来说,只要肯付出,收获是肯定有的(不像设计模型,那些巧妙的结果设计不出来就是设计不出来你气不气)。
其实算法部署也算是开发了,不仅需要和训练好的模型打交道,有时候也会干一些粗活累活(也就是dirty work),自己用C++、cuda写算子(预处理、op、后处理等等)去实现一些独特的算子。也需要经常调bug、联合编译、动态静态库混搭等等。
算法部署最常用的语言是啥,当然是C++了。如果想搞深度学习AI部署这块,C++是逃离不了的。
所以,学好C++很重要,起码能看懂各种关于部署精巧设计的框架(再列一遍:Caffe、libtorch、ncnn、mnn、tvm、OpenVino、TensorRT,不完全统计,我就列过我用过的)。当然并行计算编程语言也可以学一个,针对不同的平台而不同,可以先学学CUDA,资料更多一些,熟悉熟悉并行计算的原理,对以后学习其他并行语言都有帮助。
系统的知识嘛,还在整理,还是建议实际中用到啥再看啥,或者有项目在push你,这样学习的更快一些。
可以选择上手的项目:

  • 好用的开源推理框架:Caffe、NCNN、MNN、TVM、OpenVino
  • 好用的半开源推理框架:TensorRT
  • 好用的开源服务器框架:triton-inference-server
  • 基础知识:计算机原理、编译原理等

4.4 需要的深度学习基础知识

AI部署当然也需要深度学习的基础知识,也需要知道怎么训练模型,怎么优化模型,模型是怎么设计的等等。不然你怎会理解这个模型的具体op细节以及运行细节,有些模型结构比较复杂,也需要对原始模型进行debug。
关于深度学习的基础知识,可以看这篇:

  • 2021年了,我们还可以入门深度学习吗(含资源)

4.5 常用的框架

这里介绍一些部署常用到的框架,也是老潘使用过的,毕竟对于某些任务来说,自己造轮子不如用别人造好的轮子。
哦嘻嘻嘻嘻。
并且大部分大厂的轮子都有很多我们可以学习的地方,因为开源我们也可以和其他开发者一同讨论相关问题;同样,虽然开源,但用于生产环境也几乎没有问题,我们也可以根据自身需求进行魔改。
这里老潘介绍一些值得学习的推理框架,不瞒你说,这些推理框架已经被很多公司使用于生成环境了。

Caffe

Caffe有多经典就不必说了,闲着无聊的时候看看Caffe源码也是受益匪浅。我感觉Caffe是前些年工业界使用最多的框架(还有一个与其媲美的就是darknet,C实现)没有之一,纯C++实现非常方便部署于各种环境。
适合入门,整体构架并不是很复杂。当然光看代码是不行的,直接拿项目来练手、跑起来是最好的。
第一次使用可以先配配环境,要亲手来体验体验。
至于项目,建议拿SSD来练手!官方的SSD就是拿Caffe实现的,改写了一些Caffe的层和组件,我们可以尝试用SSD训练自己的数据集,然后部署推理一下,这样才有意思!
相关资料:

  • Caffe-SSD
  • 封藏的SSD(Single Shot MultiBox Detector)笔记
  • 利用Caffe推理CenterNet(上篇)
  • 声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年10月7日
下一篇 2021年10月7日

相关推荐