谈谈机器学习模型的部署_强化学习模型部署时只需要部署策略模型吗-程序员宅基地

技术标签: 机器学习  人工智能  Python  

随着机器学习的广泛应用,如何高效的把训练好的机器学习的模型部署到生产环境,正在被越来越多的工具所支持。我们今天就来看一看不同的工具是如何解决这个问题的。

在这里插入图片描述

上图的过程是一个数据科学项目所要经历的典型的过程。从数据采集开始,经历数据分析,数据变形,数据验证,数据拆分,训练,模型创建,模型验证,大规模训练,模型发布,到提供服务,监控和日志。诸多的机器学习工具如Scikt-Learn,Spark, Tensorflow, MXnet, PyTorch提供给数据科学家们不同的选择,同时也给模型的部署带来了不同的挑战。

我们先来简单的看一看机器学习的模型是如何部署,它又会遇到那些挑战。

模型持久化

模型部署一般就是把训练的模型持久化,然后运行服务器加载模型,并提供REST或其它形式的服务接口。我们以RandomForestClassification为例,看一下Sklearn,Spark和Tensorflow是如何持久化模型。

Sklearn

我们使用Iris数据集,利用RandomForestClassifier分类。

在这里插入图片描述

训练的代码如上。这里模型导出的代码在最后一句。joblib.dump(),参考这里。Sklearn的模型到处本质上是利用Python的Pickle机制。Python的函数进行序列化,也就是说把训练好的Transformer函数序列化并存为文件。

要加载模型也很简单,只要调用joblib.load()就好了。

在这里插入图片描述

Sklearn对Pickle做了一下封装和优化,但这并不能解决Pickle本身的一些限制,例如:
版本兼容问题,不同的Python,Pickle,Sklearn的版本,生成的序列化文件并不兼容。
安全性问题,例如序列化的文件中被人注入恶意代码。
扩展问题,你自己写了一个扩展类,无法序列化,或者你在Python中调用了C函数模型的管理,如果我生成了不同版本的模型,该如何管理?

Spark

Spark的Pipeline和Model都支持Save到文件,然后可以很方便的在另一个Context中加载。

训练的代码如下:

在这里插入图片描述
在这里插入图片描述

模型加载的代码如下:

在这里插入图片描述

调用model的toDebugString方法可以看到分类器的内部细节。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下图是Spark存储的Piple模型的目录结构:
在这里插入图片描述

我们可以看到,它包含了元数据Pipeline的五个阶段的数据,这里的文件都是二进制的数据,只有Spark自己可以加载。

Tensorflow

最后我们来看一下Tensorflow。Tensorflow提供了tf.train.Saver来导出他的模型到元图(MetaGraph)。

在这里插入图片描述

导出的模型会包含以下文件:

在这里插入图片描述

其中checkpoint是元数据,包含其它文件的路径信息。还包含了一个Pickle文件和其它几个checkpiont文件。可以看出,Tensorflow也利用了Python的Pickle机制来存储模型,并在这之外加入了额外的元数据。

模型加载的代码如下:

在这里插入图片描述

这里要注意的是,RandomForest不是tensforflow的核心包,所以在模型加载的时候必须tensorflow.contrib.tensor_forest.python.tensor_forest, 否则模型是无法成功加载的。因为不加载的话tensor_forest中定义的一些属性会缺失。

另外就是Tensorflow也可以存储计算图,调用tf.train.write_graph()方法可以把图定义存储下来。当然也可以在TesnsorBoard中展示该图。

在这里插入图片描述

好了,我们看到,Sklearn,Spark和Tensorflow都提供了自己的模型持久化的方法,那么简单来说,只要使用一个web服务器例如Flask,加一些模型加载和管理的方法,然后暴露REST API就可以提供预测服务了,是不是很简单呢?

其实要在生产环境下提供服务,还需要面对很多其它的挑战,例如:

在云上如何扩展和伸缩
如何进行性能调优
如何管理模型的版本

安全性

如何持续集成和持续部署
如何支持AB测试

为了解决模型部署的挑战,不同的组织开发了一些开源的工具,例如:ClipperSeldonMFlowMLeapOracle GraphpipeMXnet model server 等等,我们就选其中几个看个究竟。

Clipper

Clipper是由UC BerkeleyRISE Lab开发的, 在用户应用和机器学习模型之间的一个提供预测服务的系统,通过解耦合用户应用和机器学习系统的方式,简化部署流程。

它有以下功能:

利用简单标准化的REST接口来简化机器学习系统的集成,支持主要的机器学习框架。
使用开发模型相同的库和环境简化模型部署
利用可适配的Batching,缓存等技术改善吞吐量
通过智能选择和合并模型来改善预测的准确率

Clipper的架构如下图:

在这里插入图片描述

Clipper使用了容器和微服务技术来构架架构。使用 Redis 来管理配置,Prometheus来进行监控。Clipper支持使用Kubernetes或者本地的Docker来管理容器。

Clipper支持以下几种模型:

纯Python函数
PyShark
PyTorch
Tensorflow
MXnet

自定义

Clipper模型部署的基本过程如下,大家可以参考我的这个notebook
创建Clipper集群(使用K8s或者本地Docker)
创建一个应用

训练模型

调用Clipper提供的模型部署方法部署模型,这里不同的工具需要调用不同的部署方法。部署时,会把训练好的Estimator利用CloudPickle之久化,本地构建一个容器镜像,部署到Docker或者K8s。

把模型和应用关联到一起,相当于发布模型。然后就可以调用对应的REST API来做预测了。

我试着把之前的三种工具的RomdomForest的例子用Clipper发布到我的Kubernetes集群,踩到了以下的坑坑:

我本地的 Cloudpickle 的版本太新,导致模型不能反序列化,参考这个 Issue

Tensorflow在Pickle的时候失败,应该是调用了C的code

我的K8s运行在AWS上,我在K8S上使用内部IP失败,clipper连接一直在使用外部的域名,导致无法部署PySpark的模型。

总之,除了Sklearn成功部署之外,Tensorflow和Spark都失败了。

Seldon

Seldon是一家创办于伦敦的公司,致力于提供对于基于开源软件的机器学习系统的控制。Seldon Core 是该公司开源的提供在Kubernetes上部署机器学习模型的工具。它拥有以下功能:

Python/Spark/H2O/R 的模型支持
REST API和gRPC接口

部署基于Model/Routers/Combiner/Transformers的图的微服务

利用K8S来提供扩展,安全性,监控等等DevOps的功能

在这里插入图片描述

Seldon的使用过程如上图,首先在K8s上安装Seldon Core,Seldon利用ksonnet,以CRD的形式安装seldon core

利用S2i(s2i是openshift开源的一款工具,用于把代码构建成容器镜像),构建运行时模型容器,并注册到容器注册表

编写你的运行图,并提交到K8s来部署你的模型

Seldon支持基于四种基本单元,Model,Transformer, Router, Combiner来构建你的运行图,并按照该图在K8s创建对应的资源和实例,来获得AB测试,模型ensemble的功能。

例如下图的几个例子:

AB 测试

在这里插入图片描述

模型ensemble

在这里插入图片描述

复杂图

在这里插入图片描述

图模式是Seldon最大的亮点,可以训练不同的模型,然后利用图来组合出不同的运行时,非常方便。

笔者尝试在K8S上利用Seldon部署之前提到的三种工具生成的模型,都获得了成功(代码在这里)。这里分享一下遇到的几个问题:

Seldon支持Java的Python,然而用运行PySpark,这两个都需要,所以我不得不自己构建了一个镜像,手工在Python镜像上安装Java

因为使用CDR的原因,我没有找到有效改变容器的liveness和readiness的设置,因为Spark初始化模型在Hadoop上,加载模型需要时间,总是readiness超时导致容器无法正常启动,K8s不断的重启容器。所以我只好修改代码,让模型加载变成Lazy Load,但是这样第一次REST Call会比较耗时,但是容器和服务总算是能够正常启动。

MLflow

MLflow是Databricks开发的开源系统,用于管理机器学习的端到端的生命周期。

MLflow提供跟踪,项目管理和模型管理的功能。使用MLFlow来提供一个基于Sklearn的模型服务非常简单,
在这里插入图片描述

调用mlflow.sklearn.log_model(), MLflow创建以下的目录来管理模型:

在这里插入图片描述

我们看到在artifacts目录下有Python的pickle文件和另一个元数据文件,MLModel。

在这里插入图片描述

使用 mlflow sklearn serve -m model 就可以很方便的提供基于sklearn的模型服务了。

虽然MLFlow也号称支持Spark和Tensorflow,但是他们都是基于Python来做,我尝试使用,但是文档和例子比较少,所以没能成功。但原理上都是使用Pickle元数据的方式。大家有兴趣的可以尝试一下。

关于部署功能,MLFlow的一个亮点是和 SagemakerAzureML 的支持。

MLeap

MLeap 的目标是提供一个在Spark和Sklearn之间可移植的模型格式,和运行引擎。它包含:

基于JSON的序列化
运行引擎
Benchmark

MLeap的架构如下图:

在这里插入图片描述

这是一个使用MLeap导出Sklearn模型的例子:

在这里插入图片描述

导出的模型结构如下图所示:

在这里插入图片描述

这个是randonforest的模型json

在这里插入图片描述

我们可以看出MLeap把模型完全序列化成与代码无关的JSON文件,这样就可以在不同的运行时工具Spark/Sklearn之间做到可移植。MLeap对模型提供服务,不需要依赖任何Sklearn或者Spark的代码。只要启动MLeap的Server,然后提交模型就好了。

在这里插入图片描述

下面的代码用Scala在Spark 上训练一个同样的Randonforest分类模型,并利用MLeap持久化模型。
在这里插入图片描述
在这里插入图片描述

导出的模型和之前的Sklearn具有相同的格式。

MLeap的问题在于要支持所有的算法,对于每一个算法都要实现对应的序列化,这也使得它的需要很多的开发来支持客户自定义的算法。

总结

Seldon Core和K8S结合的很好,它提供的运行图的方式非常强大,它也是我实验中唯一一个能够成功部署Sklearn,Spark和Tensorflow三种模型的工具,非常推荐!

Clipper提供基于K8s和Docker的模型部署,它的模型版本管理做得不错,但是代码不太稳定,小问题不少,基于CloudPickle也有不少的限制,只能支持Python也是个问题。推荐给数据科学家有比较多的本地交互的情况。

MLFlow能够提供很方便的基于Python的模型服务,但是缺乏和容器的结合。但是它能够支持和Sagemaker,AzureML等云的支持。推荐给已经在使用这些云的玩家。

MLeap的特色是支持模型的可交互性,也就是说我可以把sklearn训练的模型导出在Spark上运行,这的功能很有吸引力,但是要支持全部的算法,它还有很长的路要走。关于机器学习模型标准化的问题,大家也可以关注PMML。现阶段各个工具对PMML的支持比较有限,随着深度学习的广泛应用,PMML何去何从还未可知。

下表是对以上几个工具的简单总结,供大家参考

Model PersistentML ToolsKubernetest IntegrationVersionLicenseImplementation

Seldon CoreS2i + PickleTensorflow, SKlearn, Keras, R, H2O, Nodejs, PMMLYes0.3.2ApacheDocker + K8s CRD

ClipperPicklePython, PySpark, PyTorch, Tensorflow, MXnet, Customer ContainerYes0.3.0ApacheCPP / Python

MLFlowDirectory + MetadataPython, H2O, Kera, MLeap, PyTorch, Sklearn, Spark, Tensorflow, RNoAlphaApachePython

MLeap JSONSpark,Sklearn, TensorflowNo0.12.0ApacheScala/Java

作者:小牛学堂
链接:https://www.jianshu.com/p/ad2bfc08b9e2
來源:简书

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Harrytsz/article/details/87694080

智能推荐

单片机C语言实例:31、交通灯_交通灯c语言程序设计-程序员宅基地

文章浏览阅读168次。电容C5、C6、C7用于硬件防抖,R20,R21,R22是下拉电阻,按键没按下的时候,对应的IO口下拉位低电平,当按键按下的时候,对应的IO口为高电平。一般交通灯的倒计时在100秒以内,所以只需要两位数码管,就可以显示0--99之间的数字,4个方向,每个方向一个2位数码管,采用共阳数码管。因为有东南西北4个方向,东西方向的两组灯的状态是一样的,南北方向两组灯的状态是一样的。4、按键功能:禁行、东西通行、南北通行、时间加、时间减、切换、确认。2、左侧按键从上到下分别是:设置时间、时间加、时间减、紧急模式。_交通灯c语言程序设计

python矩阵变成图片_Python 实现将数组/矩阵转换成Image类-程序员宅基地

文章浏览阅读1.4k次。先说明一下为什么要将数组转换成Image类。我处理的图像是FITS (Flexible Image Transport System)文件,是一种灰度图像文件,也就是单通道图像。FITS图像的特点是灰度值取值为0~65535,这类图像在python下读成数组首先是不能直接转换成位图,也就不能用OpenCV、Image等方法了。如果是普通的jpg图像,用自带的Image库就能实现很多功能。下方的这幅..._矩阵转换成图片

对ctime和astime的理解_ctime与ascttime的区别-程序员宅基地

文章浏览阅读1.1k次。用同一块buffer,通过下面两个程序测试出来.#include ;#include ;using namespace std;int main(){ time_t now; char * ptime; if(time(&now) { cout exit(-1); }#ifdef _AIX ptime = asctime(gmtime((time_t *)&now));_ctime与ascttime的区别

个人介绍网页代码 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计-程序员宅基地

文章浏览阅读335次,点赞10次,收藏8次。网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程序方面:计划采用最新的网页编程语言HTML5+CSS3+JS程序语言完成网站的功能设计。并确保网站代码兼容目前市面上所有的主流浏览器,已达到打开后就能即时看到网站的效果。网站素材方面:计划收集各大平台好看的图片素材,并精挑细选适合网页风格的图片,然后使用PS做出适合网页尺寸的图片。网站文件方面:网站系统文件种类包含:html网页结构文件、css网页样式文件、js网页特效文件、images网页图片文件;...

wxOneShell:快速生成wxpython多功能图形界面的工具-程序员宅基地

文章浏览阅读225次。首页:http://www.oschina.net/action/project/go?id=39680&p=home wxOneShell是一个快速开发wxPython SDI程序的框架,wxOneShell的设计 目的,是将程序设计中图像界面的例行功能隔离出来,只用ini文件配..._wxone

uva11077(数论)_uva 11077 链接-程序员宅基地

文章浏览阅读644次。题意:给定n,k求出有多少个包含元素[1-n]的序列,交换k次能得到一个[1,2,3...n]的序列思路:递推dp[i][j]表示i个元素需要j次,那么在新加一个元素的时候,添在最后面次数不变,其余位置都是次数+1,这是可以证明的,原序列中有几个循环,需要的次数就是所有循环长度-1的和,那么对于新加一个元素,加在最后就和自己形成一个循环,次数不变,其余位置都会加入其他循环中,次数+1,_uva 11077 链接

随便推点

html给页面整体添加左右边距_HTML CSS + DIV实现整体布局-程序员宅基地

文章浏览阅读972次。HTML CSS + DIV实现整体布局1、技术目标:开发符合W3C标准的Web页面理解盒子模型实现DIV+CSS整体布局2、什么是W3C标准?W3C:World Wide Web Consortium,万维网联盟W3C的职能:负责制定和维护Web行业标准W3C标准包括一系列的标准:HTML内容方面:XHTML样式美化方面:CSS结构文档访问方面:DOM页面交互方面:ECMAScript……等等3..._html div 页边距

2022年武汉市级产业化投资和技术改造专项以及工业智能化改造专项申报开始!13区申报条件、1千万补助_武汉市东西湖区技术改造和智能化-程序员宅基地

文章浏览阅读436次。2022年武汉市级产业化投资和技术改造专项以及工业智能化改造专项申报开始!整理了产业化投资和技术改造专项以及工业智能化改造专项项目申报条件、材料及补助奖励内容,江岸区、江汉区、硚口区、汉阳区、武昌区、青山区、洪山区、蔡甸区、江夏区、黄陂区、新洲区、东西湖区、汉南区企业想要申报可从下文了解:..._武汉市东西湖区技术改造和智能化

cocos2d-x 学习日志(1)之Xcode中c++&Object-C混编,详细介绍如何在cocos2dx中访问object函数以及Apple Api_xcode cocos2d混编设置-程序员宅基地

文章浏览阅读2.4k次。本篇继续介绍另外一个在Cocos2dx中必经之路:在Cocos2dx中调用苹果Api以实现后期iOS的GameCenter和iap的相关操作, 那么这里就跟大家简单分享探讨下;如何在Xcode中进行c++与oc混编吧~参考王哥说的 SimpleAudioEngine 类;首先建立了两个类,一个object-c ,一个c++,详细如下:HSpriteOC.h#impo_xcode cocos2d混编设置

Aerospike C客户端手册———数据扫描—记录扫描_aerospikeclient scanall内存-程序员宅基地

文章浏览阅读922次。记录扫描Aerospike C客户端提供扫描指定namespace和set中所有记录的能力。扫描可使用扫描API定义。使用扫描API,可以初始化和填充一个as_scan对象。以初始化过的as_scan,可用下面任一个操作执行扫描:aerospike_scan_foreach() — 执行扫描并对每个记录调用一个函数。aerospike_scan_backgrou_aerospikeclient scanall内存

Netty源码分析----服务启动之Channel初始化_netty initchannel-程序员宅基地

文章浏览阅读3.6k次。Netty底层也是基于NIO,所以在分析服务启动的流程之前,我们先回顾一下NIO的启动Server的代码,写的一个Server例子如下,只保留和Netty启动相关的代码public class NioServer implements Runnable { public static void main(String[] args) { new Thread(new..._netty initchannel

Unity 游戏实例开发集合 之 JumpJump (简单跳一跳) 休闲小游戏快速实现_跳一跳游戏选题背景介绍unity-程序员宅基地

文章浏览阅读6.1k次,点赞7次,收藏71次。Unity 游戏实例开发集合 之 JumpJump (简单跳一跳) 休闲小游戏快速实现一、简单介绍Unity 游戏实例开发集合,使用简单易懂的方式,讲解常见游戏的开发实现过程,方便后期类似游戏开发的借鉴和复用。本节介绍,JumpJump (简单跳一跳) 休闲小游戏快速实现的方法,希望能帮到你,若有不对,请留言。二、JumpJump (简单跳一跳)游戏内容与操作1、游戏开始,会自动生成平台2、鼠标按下左键角色会自动朝向平台方向,长按住右键进行蓄力3、松开鼠标左键,角色就会根_跳一跳游戏选题背景介绍unity

推荐文章

热门文章

相关标签