概述
为了将训练好的模型部署、上线, 首先需要确认训练模型与接入的应用服务所使用的编程语言是否一致, 其次考虑模型应用于产品服务的方式。在调试模型时,大多使用PyCharm、Spyder工具中的控制台来输出训练结果,或者使用Jupyter NoteBook进行交互。将模型部署于产品常用的方式有两种-----基于 HTTP服务或基于预测标型标记语言(Predictive ModelMarkup Language, PMML )。其中,基于HTTP服务是指在生产环境中部署Python环境以及Python的机器学习包,然后把数据预处理和模型部分导出为PKL文件并部署在HTTP服务上。基于PMML是指将机器学习模型打包成PMML文件,然后部署到生产环境中。
为了降低模型上线(部署)的风险,模型发布可采用分级发布的方式(如预上线、小流量、灰度至全量)。此外,也可采用A/B测试等方式。线上模型服务后,需要有一套完整的监控系统以对模型的效果、服务质量、性能指标等进行监控,同时备有效的回滚、降级、 容灾预案机制,保障模型在线上稳定运行。模型项目的流程如图所示。
数据处理==》构建模型==》模型训练==》模型评估模型服务==》模型监控
模型发布方式
模型部署架构和具体的技术组件选型需结合公司已有技术、业界的发展趋势、部署运维成本等因素综合考虑。模型发布的方式同样受多种因素影响。一方面,应考虑是否跨多种编程语言,如接入的产品使用Java编程语言,而模型训练采用Python语言; 另一方面,应考虑是在线预测还是离线预测,如采用在线预测,还要关注性能问题。
下图所示为某金融公司的风控模型部署架构。其选用Nginx + uWSGI + Flask 部署,客户端是指移动设备端App、Web浏览器或第三方应用。Nginx 是负载均衡器,它的作用是把请求分发到模型服务,提高响应速度。uWSGI搭配Nginx实现响应速度快、内存占用率低、高可用定制、自带详尽日志等功能,支持平滑重启。Flask完全兼容WSGI (WebServer Gateway Interface )标准,便于搭建微服务框架,完全基于Unicode编码,无须处理编码问题。
1、模型发布技术栈简介
1)PMML标准
PMML是一种事实标准语言 。预测分析模型和数据挖掘模型指的是代数模型术语,这些模型采用统计技术了解大量历史数据中隐藏的模式。预测分析模型使用在模型训练过程中获的知识来预测新数据中是否有已知的模式。PMML允许在不同的应用程序之间轻松共享预测分析模型。模型训练可以是单独的系统,通过这个单独的系统把模型生成的PMML文件移到产品系统中,这样就可实现跨平台在线或离线预测。
PMML是一套基于XML的标准,所使用的元素和属性是通过XML Schema 来定义的。PMML数据挖掘分析流程如图所示。首先输入准备好的数据,其次根据输入的数据进行数据预处理,在源数据字段上产生新的派生字段。之后进行预测模型,预测后处理。最后进行预测值输出。PMML支持由Python、R等语言生成PMML文件的模型转换库,也支持Spark、Java、 Python 的模型评估库,以读取PMML文件。PMML的优缺点如表所示:
2)微服务框架
Python提供的微型Web框架有Fask、 Bootle、 web2py等,开发者可以用它们开发响应请求的API或者Web应用,具体可以根据产品需求和技术架构进行选择。
3)模型部署常用的服务与组件
Gunicore是一个高性能的Python WSGI UNIX HTTP服务器,具有实现简单、轻量级、获取高性能的特点,与大多数的Web框架兼容。
2、模型服务的部署方式
模型服务的部署方式有多种,此处主要介绍两种。一种是微服务(SOA)部署方式,另一种是使用 TensorFlow Serving的部署方式。模型应用的场景包括在线预测不跨语言、在线预测跨语言、离线预测不跨语言、离线预测跨语言。对于不同的使用场景和不同的接入产品,最后选择不同的部署方式,部署模型服务的重点和关注点也有差异。
TensorFlow Serving是一个针对机器学习模型服务部署的灵活 、高性能的服务系统,专为生产环境而设计。在机器学习的推理方面,它在训练和模型关联生命周期之后进行建模,通过高性能的参考计数查找表为客户提供版本化访问。TensorFlow Serving在服务器架构不变的情况下,实现了模型服务部署的简单化。它还具有支持多模型服务、新模型热部署、支持Canarying新版本和A/B测试等特性。另外,TensorFlow Serving还提供调度服务,可以将推理请求分为几批,以便在GPU上联合执行。
1 )在线预测不跨语言场景
模型训练与预测使用的编程语言一样, 好处是无须进行模型PMML标准化,可把训练好的模型导出为HDF5 (Hierarchical Data Fomate Version5)文件。此场景需要考虑如何可处理多并发和响应时间的问题。根据项目情况选择合适的高并发Web框架部署SOA模式的预测服务,加载由模型保存的文件,实现线上预测。可选择的Python Web框架有Flask、Tornado、 py2web 等。
例如,模型训练和预测都使用Python语言,使用XGBoost导出训练模型,使用XGBoost4j加载模型,使用Nginx+uWSGl+Flask微服务形式进行模型预测服务的部署,从而实现高并发、响应时间短、实时预测的效果。
2 )在线预测跨语言场景
若模型训练时使用的编程语言与接入产品所使用的编程语言不一致,则需要考虑使用跨语言解决方案。如果搭建实时小批量数据预测服务,则可采用SOA调用预测服务PythonServer。若搭建大数据量的实时预测服务,又涉及跨语言的问题(如从Java跨到R或Python语言),则需要把训练模型进行PMML标准化,并导出PMML文件,然后把模型封装成一个类,使用Java调用这个模型类进行预测。
3)离线预测不跨语言场景
离线预测般采用(T+1)天的预测方式。在模型预测服务进行部署时无须考虑多共发时间响应问题,相比离线预测跨语言 ,其场景简单。虽然实现一个调度脚本就可以进行产品预测,但有必要配置统一的调用服务 (AirFlow 或Celery )。在项目时间紧迫的情况下,也可以使用Shell脚本的Crontab定时任务工具配置定时任务。
4)离线预测跨语言场景
离线预测跨语言场景需要解决的是跨语言和调度任务问题。与在线跨预测跨语言场景的处理方式一样,把训练模型转换成PMML文件,解决跨语言环境的问题。使用AirFlow或Celery配置统一-的调用服务以进行预测。
3、模型部署、上线实践
下面以“在线识别垃圾邮件”(简称EMG )项目为例,讲述模型部署、上线实践, 这个项目属于在线预测不跨语言场景。用户端输入邮件内容,调用预测接口把邮件内容传给训练好的模型,然后把预测结果呈现在结果页面。对于EMG项目,使用朴素贝叶斯定理构建了一个邮件内容分类模型,通过机器学习来检测邮件内容,以判断检测的邮件是垃圾还是非垃圾邮件。EMG项目的请求流程如图12-11所示。
下面是模型训练的modelTrain方法。首先获取离线数据进行离线模型训练,然后导出二进制文件R3_model.pkl。代码如下:
def modelTrain(data):
pt=os.getcwd()
path=pt+"/data/SMSSpamCollection.txt"
df=pd.read_csv(path,delimiter='\t',header=None,skipinitialspace=True,names=['label','message'])
df['label']=df.label.map({'ham':0,'spam':1})
M=df['message']
L=df['label']
#创建词袋数据结构
cv=CountVectorizer()
#使用CountVectorizer的fit_transform方法将文本中的词语转换成词频矩阵
M=cv.fit_transform(M)
M_train,M_test,L_train,L_test=train_test_split(M,L,test_size=0.33,random_stat=42)
mlp=MultinomialNB()
mlp.fit(M_train,L_train)
mlp.score(M_test,L_test)
#导出模型
joblib.dump(mlp,pt+'/model/test_model.pkl')
在Flask框架中实现对外访问模型的REST API接口预测,通过skleam库的joblib.加载已经训练好的模型 R3_model.pkl。把客户端传入的参数格式化后,进行在线预测,并把结果返回。接口代码如下所示。
@app.route('/predict', methods=['POST'])
def predict():
pt = os.getcwd()
#获取输入数据
message = request.form['message']
data = [message]
#加载test model.pkl模型
test_model = open(pt + '/mode1/test model.pkl', 'rb')
mlp=joblib.load(test_model)
cv = Countvectorizer()
# 转换成数组的特征向量
vect= cv. transform(data).toarray()
# 输出预测值
predic_res = mlp.predict(vect)
return render_template('ml_result.html', prediction=predic_res)
在NGINX代理请求转发配置时,在nginx/conf/中新增emg.conf文件,重启Nginx。
server{
listen 80;
listen 443 ssl;
server_name www.emg.com;
access_log logs/emg.log;
error_log logs/emg.error.log
default_type text/html;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
index index.html;
location {
proxy_pass http://127.0.0.1:5000;
}
}
模型线上监控
模型部署线上后,模型是否稳定运行直接影响模型预测值的准确性,所以需要实施模型线上监控。
监控一般分为系统级别和业务级别的监控。若再细分,则可以把监控分为应用层、用户层、数据层、网络层等的监控。系统级别的监控内容大致相同,一般监控CPU、磁盘、内存、网络等方面,由开发或运维工程师跟进监控呈现的问题,并加以解决。业务级别的监控内容与业务性质有关。监控的内容包括接口、框架、服务的响应时间、请求量、错误率等,一般由开发人员跟进并解决这些问题。项目经理和产品经理一般比较关注与用户、产品相关的功能层面的一系列监控。单模型监控与系统级别、业务级别的监控指标有所不同,并且单模型监控有自己关注的指标。
1、模型线上监控内容
线上监控一般有模型本身监控和模型接入产品的业务监控。模型本身监控指在模型发布后,在线上运行并提供服务后,每隔一段时间对模型本身的性能进行监控,根据模型运行效果呈现指标(AUC、PSI、KS、MSE值等)来判断模型是否可以继续使用
业务监控与业务性质紧密相关,业务类型不同,监控指标也不一样。以风控领域为例
监控指标 | 描述 |
Vintage分析 | 把不同时期的数据放在一起比较,直观地看数据差异 |
迁移率 | 贷款逾期根据逾期的天数分为M0~M7这8个阶段。迁移率这里指从一个逾期阶段向另一个逾期阶段转化的比例 |
滚动率 | 以一个时间点为参考点,观测用户在这个时间点最坏的逾期阶段,跟进其在之后的时间是否有向逾期的其他阶段发展的趋势 |
首期逾期率 | 在还款日,在没有按时还款的用户中,第一期逾期未还款的用户占比 |
2、容错机制
虽经过预发布、小流量、灰度、全量阶段充分验证后,模型成功部署、上线,但不能完全保证模型运行一直稳定,总会有请求超时、服务器宕机等发生,如何预防、防止发生崩溃,快速止损就是容错机制需要考虑的内容,可使用隔离处理、降级、补偿、重试等方法来进行异常兼容。