当前,深度学习的应用越来越多样化,随之涌现出诸多优秀的计算框架。其中TensorFlow,PyTorch,MXNeT作为广泛使用的框架更是备受瞩目。在将深度学习应用于实际业务的过程中,往往需要结合数据处理相关的计算框架如:模型训练之前需要对训练数据进行加工生成训练样本,模型预测过程中需要对处理数据的一些指标进行监控等。在这样的情况下,数据处理和模型训练分别需要使用不同的计算引擎,增加了用户使用的难度。
本文将分享如何使用一套引擎搞定机器学习全流程的解决方案。
先介绍一下典型的机器学习工作流程。如图所示,整个流程包含特征工程、模型训练、离线或者是在线预测等环节。
在此过程中,无论是特征工程、模型训练还是模型预测,中间都会产生日志。需要先用数据处理引擎比如Flink对这些日志进行分析,然后进入特征工程。再使用深度学习的计算引擎TensorFlow进行模型训练和模型预测。当模型训练好了以后再用TensorFlowserving做在线的打分。
上述流程虽然可以跑通,但也存在一定的问题,比如:
同一个机器学习项目在做特征工程、模型训练、模型预测时需要用到Flink和TensorFlow两个计算引擎,部署相对而言更复杂。
TensorFlow在分布式的支持上还不够友好,运行过程中需要指定机器的IP地址和端口号;而实际生产过程经常是运行在一个调度系统上比如Yarn,需要动态分配IP地址和端口号。
TensorFlow的分布式运行缺乏自动的failover机制。
针对以上问题,我们通过结合Flink和TensorFlow,将TensorFlow的程序跑在Flink集群上的这种方式来解决,整体流程如下:
特征工程用Flink去执行,模型训练和模型的准实时预测目标使TensorFlow计算引擎可以跑在Flink集群上。这样就可以用Flink一套计算引擎去支持模型训练和模型的预测,部署上更简单的同时也节约了资源。
Flink是一款开源大数据分布式计算引擎,在Flink里所有的计算都抽象成operator,如上图所示,数据读取的节点叫sourceoperator,输出数据的节点叫sinkoperator。source和sink中间有多种多样的Flinkoperator去处理,上图的计算拓扑包含了三个source和两个sink。
机器学习分布式运行拓扑如下图所示:
在一个机器学习的集群当中,经常会对一组节点(node)进行分组,如上图所示,一组节点可以是worker(运行算法),也可以是ps(更新参数)。
如何将Flink的operator结构与MachineLearning的node、ApplicationManager角色结合起来?下面将详细讲解flink-ai-exted的抽象。
首先,对机器学习的cluster进行一层抽象,命名为MLframework,同时机器学习也包含了MLoperator。通过这两个模块,可以把Flink和MachineLearningCluster结合起来,并且可以支持不同的计算引擎,包括TensorFlow。
如下图所示:
在Flink运行环境上,抽象了MLFramework和MLOperator模块,负责连接Flink和其他计算引擎。
MLFramework分为2个角色。
ApplicationManager(以下简称am)角色,负责管理所有node的节点的生命周期。
node角色,负责执行机器学习的算法程序。
在上述过程中,还可以对ApplicationManager和node进行进一步的抽象,ApplicationManager里面我们单独把statemachine的状态机做成可扩展的,这样就可以支持不同类型的作业。深度学习引擎,可以自己定义其状态机。从node的节点抽象runner接口,这样用户就可以根据不同的深度学习引擎去自定义运行算法程序。
MLOperator模块提供了两个接口:
addAMRole,这个接口的作用是在Flink的作业里添加一个ApplicationManager的角色。ApplicationManager角色如上图所示就是机器学习集群的管理节点。
addRole,增加的是机器学习的一组节点。
利用MLOperator提供的接口,可以实现FlinkOperator中包含一个ApplicationManager及3组node的角色,这三组node分别叫rolea、roleb,、rolec,三个不同角色组成机器学习的一个cluster。如上图代码所示。Flink的operator与机器学习作业的node一一对应。
机器学习的node节点运行在Flink的operator里,需要进行数据交换,原理如下图所示:
Flinkoperator是java进程,机器学习的node节点一般是python进程,java和python进程通过共享内存交换数据。
TensorFlow分布式训练一般分为worker和ps角色。worker负责机器学习计算,ps负责参数更新。下面将讲解TensorFlow如何运行在Flink集群中。
Batch模式下,样本数据可以是放在HDFS上的,对于Flink作业而言,它会起一个source的operator,然后TensorFlow的work角色就会启动。如上图所示,如果worker的角色有三个节点,那么source的并行度就会设为3。同理下面ps角色有2个,所以pssource节点就会设为2。
如上图所示,前面有两个sourceoperator,然后接joinoperator,把两份数据合并为一份数据,再加自定义处理的节点,生成样本数据。在stream模式下,worker的角色是通过UDTF或者flatmap来实现的。
同时,TensorFlowworkernode有3个,所以flatmap和UDTF相对应的operator的并行度也为3,由于ps角色并不去读取数据,所以是通过flinksourceoperator来实现。
下面我们再讲一下,如果已经训练好的模型,如何去支持实时的预测。
在预测的情况下,通过读取模型,将所有的参数加载到ps里面去,然后上游的数据还是经过和训练时候一样的处理形式,数据流入到worker这样一个角色中去进行处理,将预测的分数再写回到flinkoperator,并且发送到下游operator。
如图所示,模型单机进行预测时就没必要再去起ps节点,单个worker就可以装下整个模型进行预测,尤其是使用TensorFlow导出savemodel。同时,因为savedmodel格式包含了整个深度学习预测的全部计算逻辑和输入输出,所以不需要运行Python的代码就可以进行预测。
此外,还有一种方式可以进行预测。前面source、join、UDTF都是对数据进行加工处理变成预测模型可以识别的数据格式,在这种情况下,可以直接在Java进程里面通过TensorFlowJavaAPI,将训练好的模型load到内存里,这时会发现并不需要ps角色,worker角色也都是Java进程,并不是Python的进程,所以我们可以直接在Java进程内进行预测,并且可以将预测结果继续发给Flink的下游。
在本文中,我们讲解了flink-ai-exted原理,以及Flink结合TensorFlow如何进行模型训练和预测。希望通过本文大分享,大家能够使用flink-ai-exted,通过Flink作业去支持模型训练和模型的预测。
版权声明:本站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请举报,一经查实,本站将立刻删除。