模型部署(1)【draft】概述
机器学习(一):模型训练及线上部署相关笔记
https://www.shangmayuan.com/a/2331a95928b344d782ac08ac.html
- GBDT+LR模型训练及线上部署
- Java调用jpmml类
一、离线模型(Offline)
离线模型存在于很多业务场景中,其中最常见的业务场景就是用在推荐系统的召回阶段,由于在推荐系统中,召回并不要求是实时的,可以根据业务的需要,调整成每天一次,或者每几个小时跑一次即可,因此,这类的模型,一般我们只需要使用Linux下的crontab定时任务脚本,每隔一段时间来启动一次就可以,然后将log文件输出到指定的文件下即可。这种方式一般来讲仅限离线模型的部署,其本质上就是一段定时任务的代码。
二、在线(Online)/近似在线(NearLine)模型
在生产系统中,实时推理和预测是最常见的需求,也是对于很多深度学习模型来说所必须达到的点。下面简介一些深度学习模型在实时预测时常见的几种部署方法:
2.1 将模型预测直接打包成http接口
将模型直接打包成一个http接口的形式是在企业中比较常见的模型上线的方式,所谓的将预测直接打包成http接口实际上一般是指将我们训练好的模型直接在线上进行预测。我们来试想一个场景,当一个模型训练好之后,我们如果想要验证这个模型的好坏,我们首先能想到的办法就是找一批数据来测试一下。实际上,将模型预测直接打包成http接口也是利用了这样的思路。
在这里,我们可以将训练好的模型提前进行加载,并初始化若干个消息队列和worker,当有新的待预测数据进入的时候,我们直接将数据通过消息队列传入到模型中进行推理和预测,最终得到结果。
而对于外层接收输入,我们一般可以将接收的地方使用flask打包成一个http接口,等待传入即可。
使用这种方式直接打包成http接口的好处在于打包和部署相对比较方便,对于一些相对比较轻量级且对并发量要求不是很高的情况下相对还是比较好用的。使用值得注意的是,如果对于一个相对比较大的模型来讲,这种方式推理的时间相对就会比较长,从用户输入到结果返回可能需要200ms左右。
2.2 PMML
使用PMML部署机器学习模型 : https://zhuanlan.zhihu.com/p/79197337
PMML (Predictive Model Markup Language) 是一套通用的且与平台和环境无关的模型表示语言,机器学习在模型部署方面的一种标准部署方案,其形式是采用XML语言标记形式。我们可以将自己训练的机器学习模型打包成PMML模型文件的形式,然后使用目标环境的解析PMML模型的库来完成模型的加载并做预测。PMML是一套基于XML的标准,通过 XML Schema 定义了使用的元素和属性,主要由以下核心部分组成:
数据字典(Data Dictionary),描述输入数据。
数据转换(Transformation Dictionary和Local Transformations),应用在输入数据字段上生成新的派生字段。
模型定义 (Model),每种模型类型有自己的定义。
输出(Output),指定模型输出结果。
目前,大部分机器学习库都支持直接打包成PMML模型文件的相关函数,例如在Python中的LightGBM库,XGBoost库,Keras库等,都有对PMML的支持,直接使用相应的命令就可以生成,而在Java、R等语言中,也有相关的库可以进行PMML文件生成的命令。一般来讲,使用PMML文件进行预测的过程如下:
由于其平台无关性,导致PMML可以实现跨平台部署,是企业中部署机器学习模型的常见解决方案。
2.3 TensorFlow Serving
使用TensorFlow Serving进行服务部署,一般需要2台以上机器。
- 其中一台作为TensorFlow Serving的服务器,这台服务器是专门来做模型部署和预测用,对于这台服务器,一般建议使用GPU服务器,这样会使整个推理预测的过程变得很快;
- 另外一台服务器是业务服务器,也就是接收用户的输入以及其他业务处理的服务器。我们可以把模型部署到TensorFlow Serving的服务器上,而一般我们只需要先在服务器上使用docker创建一个TensorFlow Serving服务,然后将模型文件上传上去,当有请求进来的时候,业务服务会直接对模型所在的服务器发起服务调用,并得到模型预测的结果。
三、实际用时的一些部署方法组合
3.1 R+pmml+spark+airflow调度
用R语言训练模型并转为pmml文件,然后使用spark将这个pmml文件封装为jar,使用airflow提交到yarn。
1 | val is: InputStream = fs.open(path) |
3.2 python+sklearn+airflow调度
使用python训练好sklearn模型,并joblib.dumps()保存,然后在python文件中joblib.load()加载改文件,使用airflow离线调度。
3.3 xgboost+spark+xgb4j
- 使用分布式的spark版的xgboost,训练好的模型直接保存为model.booster.saveModel(hdfsOutStream)二进制文件.然后xgboost4j加载该文件XGBoost.loadModel(is)实现线上实时预测。
3.4 tensorflow+tensorflow的java库
四、不同需求对应的不同平台部署方案
1、放到服务器上跑,要求吞吐和时延(重点是吞吐)这种应用在互联网企业居多,一般是互联网产品的后端AI计算,例如人脸验证、语音服务、应用了深度学习的智能推荐等。
由于一般是大规模部署,这时不仅仅要考虑吞吐和时延,还要考虑功耗和成本。所以除了软件外,硬件也会下功夫,比如使用推理专用的NVIDIA P4、寒武纪MLU100等。这些推理卡比桌面级显卡功耗低,单位能耗下计算效率更高,且硬件结构更适合高吞吐量的情况软件上,一般都不会直接上深度学习框架。对于NVIDIA的产品,一般都会使用TensorRT来加速(不仅可以加速前传,还包含调度功能)。TensorRT用了CUDA、CUDNN,而且还有图优化、fp16、int8量化等。
五、模型部署时一些常用的trick
5.1 模型压缩
基于参数修剪和共享的方法针对模型参数的冗余性,试图去除冗余和不重要的项。基于低秩因子分解的技术使用矩阵/张量分解来估计深度学习模型的信息参数。基于传输/紧凑卷积滤波器的方法设计了特殊的结构卷积滤波器来降低存储和计算复杂度。知识蒸馏方法通过学习一个蒸馏模型,训练一个更紧凑的神经网络来重现一个更大的网络的输出。
一般来说,参数修剪和共享,低秩分解和知识蒸馏方法可以用于全连接层和卷积层的CNN,但另一方面,使用转移/紧凑型卷积核的方法仅支持卷积层。低秩因子分解和基于转换/紧凑型卷积核的方法提供了一个端到端的流水线,可以很容易地在CPU/GPU环境中实现。相反参数修剪和共享使用不同的方法,如矢量量化,二进制编码和稀疏约束来执行任务,这导致常需要几个步骤才能达到目标。