针对Kubeflow组件较多,容易搞不清每个组件是干什么的,本文先对Kubeflow
进行一个系统的概括,让大家明白各个组件分别的用处,并对组件间的关系进行理顺,帮助大家合理快速的选择自己需要的组件,随后会对每个组件的底层架构和流程分别进行详细的介绍和剖析,供大家针对性的进一步学习。
什么是Kubeflow?
Kubeflow是Kubernetes
的机器学习工具包。Kubeflow
是运行在K8S
之上的一套技术栈,这套技术栈包含了很多组件,组件之间的关系比较松散,我们可以配合起来用,也可以单独用其中的一部分。下图是官网显示Kubeflow
作为在Kubernetes
上安排ML系统组件的平台:
我们先大体看一眼Kubeflow
都有哪些组件,是不是很多?接下来我会带大家逐步了解每个组件都有哪些作用。
当我们开发和部署ML系统时,ML工作流程通常包括几个阶段。开发ML系统是一个反复的过程。我们需要评估ML工作流各个阶段的输出,并在必要时对模型和参数进行更改,以确保模型不断产生所需的结果。
为了便于理解,下图按顺序显示了工作流程阶段,并将Kubeflow
添加到工作流中,显示在每个阶段都有哪些Kubeflow
组件有用。工作流末尾的箭头指向流程,以表示流程的迭代性质:
- 在实验阶段,我们将基于初始假设来开发模型,并反复测试和更新模型以产生所需的结果:
- 确定我们要ML系统解决的问题。
- 收集和分析训练ML模型所需的数据。
- 选择一个ML框架和算法,并为模型的初始版本编码。
- 试验数据并训练模型。
- 调整模型超参数以确保最有效的处理和最准确的结果。
- 在生产阶段,我们将部署执行以下过程的系统:
- 将数据转换为训练系统所需的格式(为了确保我们的模型在训练和预测过程中行为始终一致,转换过程在实验阶段和生产阶段必须相同)。
- 训练ML模型。
- 服务模型以进行在线预测或以批处理模式运行。
- 监督模型的性能,并将结果输入到我们的程序中,以调整或重新训练模型。
由此可以看出,Kubeflow
的目标是基于K8S
,构建一整套统一的机器学习平台,覆盖最主要的机器学习流程(数据->特征->建模->服务→监控),同时兼顾机器学习的实验探索阶段和正式的生产环境。
Kubeflow组件
Kubeflow
提供了一大堆组件,涵盖了机器学习的方方面面,为了对Kubeflow
有个更直观深入的了解,先整体看一下Kubeflow
都有哪些组件,并对Kubeflow
的主要组件进行简单的介绍:
- Central Dashboard:
Kubeflow
的dashboard
看板页面 - Metadata:用于跟踪各数据集、作业与模型
- Jupyter Notebooks:一个交互式业务IDE编码环境
- Frameworks for Training:支持的ML框架
- Chainer
- MPI
- MXNet
- PyTorch
- TensorFlow
- Hyperparameter Tuning:
Katib
,超参数服务器 - Pipelines:一个ML的工作流组件,用于定义复杂的ML工作流
- Tools for Serving:提供在
Kubernetes
上对机器学习模型的部署- KFServing
- Seldon Core Serving
- TensorFlow Serving(TFJob):提供对
Tensorflow
模型的在线部署,支持版本控制及无需停止线上服务、切换模型等 - NVIDIA Triton Inference Server(Triton以前叫TensorRT)
- TensorFlow Batch Prediction
- Multi-Tenancy in Kubeflow:Kubeflow中的多租户
- Fairing:一个将
code
打包构建image
的组件Kubeflow
中大多数组件的实现都是通过定义CRD
来工作。目前Kubeflow
主要的组件有: - Operator是针对不同的机器学习框架提供资源调度和分布式训练的能力(
TF-Operator
,PyTorch-Operator
,Caffe2-Operator
,MPI-Operator
,MXNet-Operator
); - Pipelines是一个基于
Argo
实现了面向机器学习场景的流水线项目,提供机器学习流程的创建、编排调度和管理,还提供了一个Web UI
。 - Katib是基于各个
Operator
实现的超参数搜索和简单的模型结构搜索的系统,支持并行搜索和分布式训练等。超参优化在实际的工作中还没有被大规模的应用,所以这部分的技术还需要一些时间来成熟; - Serving支持部署各个框架训练好的模型的服务化部署和离线预测。
Kubeflow
提供基于TFServing
,KFServing
,Seldon
等好几种方案。由于机器学习框架很多,算法模型也各种各样。工业界一直缺少一种能真正统一的部署框架和方案。这方面Kubeflow
也仅仅是把常见的都集成了进来,但是并没有做更多的抽象和统一。
以上,我对Kubeflow
组件进行了系统的概括,来帮助我们对各个组件有一个基本的了解和整体的把握。趁热打铁,接下来我们详细介绍每一个组件的架构和工作流程。
Jupyter Notebooks
Jupyter
本身包含很多组件。对于个人用户,使用JupyterLab
+ Notebook
就足够了。但是如果把Jupyter
当成一个公司级的平台来看待的话就远远不够了。这时候需要考虑的事情就比较多了,比如多用户、资源分配、数据持久化、数据隔离、高可用、权限控制等等。而这些问题恰恰是K8S
的特长。因此把Jupyter
和K8S
结合起来使用就非常顺理成章。JupyterHub
是一个多用户的Jupyter
门户,在设计之初就把多用户创建、资源分配、数据持久化等功能做成了插件模式。其工作机制如下图所示:
既然JupyterHub
是个框架,因此出现了各种各样的插件。比如可以单机部署利用OS
用户实现多用户和数据隔离;也可以使用OAuth
完成用户鉴权等。当然,将整个JupyterHub
和K8S
结合起来,是最完美的姿势。Kubeflow
中的Multi-Tenancy in Kubeflow
多租户组件我还没看,后面可以对比研究一下是否是基于此实现的。
下面我们再来说说Kubeflow
,因为缺乏隔离和资源限制,目前仅适用数据科学家的solo
场景,无法支持数据科学家团队合作场景。所以平心而论,它还未获得用户的信任。Kubeflow
将default-editor ServiceAccount
分配给Jupyter notebook Pod
。该服务帐户绑定到kubeflow-edit ClusterRole
,它对许多Kubernetes
资源具有命名空间范围的权限,其中包括:
Pod
Deployment
Service
Job
TFJob
PyTorchJob
因此,可以直接从Kubeflow
中的Jupyter notebook
创建上述Kubernetes
资源。 notebook
中已预装了Kubernetes kubectl
命令行工具,可以说也是非常简单了。
将Jupyter notebook
绑定在Kubeflow
中时,可以使用Fairing
库使用TFJob
提交训练作业。训练作业可以运行在单个节点,也可以分布在同一个Kubernetes
集群上,但不能在notebook pod
内部运行。通过Fairing
库提交作业可以使数据科学家清楚地了解Docker
容器化和pod
分配等流程。
总体而言,Kubeflow-hosted notebooks
可以更好地与其他组件集成,同时提供notebook image
的可扩展性。
Pipelines
在Kubeflow v0.1.3
之后, pipeline
已经成为Kubeflow
的核心组件。Kubeflow
的目的主要是为了简化在Kubernetes
上运行机器学习任务的流程,最终希望能够实现一套完整可用的流水线, 来实现机器学习从数据到模型的一整套端到端的过程。 而pipeline
是一个工作流平台,能够编译部署机器学习的工作流。所以从这个层面来说,pipeline
能够成为Kubeflow
的核心组件一点也不意外。kubeflow/pipelines
实现了一个工作流模型。所谓工作流,或者称之为流水线(pipeline
),可以将其当做一个有向无环图(DAG
)。其中的每一个节点被称作组件(component
)。组件处理真正的逻辑,比如预处理,数据清洗,模型训练等。每一个组件负责的功能不同,但有一个共同点,即组件都是以Docker
镜像的方式被打包,以容器的方式被运行的。
下图显示了Kubeflow Pipelines UI中管道的运行时执行图:
实验(experiment
)是一个工作空间,在其中可以针对流水线尝试不同的配置。用户在执行的过程中可以看到每一步的输出文件,以及日志。步(step
)是组件的一次运行,输出工件(step output artifacts
)是在组件的一次运行结束后输出的,能被系统的前端理解并渲染可视化的文件。
Pipelines架构
下图是官方提供的Kubeflow Pipelines
架构图:
看起来还是比较复杂的,但整体可以将pipeline主要划分为八部分:
- Python SDK: 用于创建
kubeflow pipelines
组件的特定语言(DSL)。 - DSL compiler: 将
Python
代码转换成YAML
静态配置文件(DSL编译器 )。 - Pipeline Web Server:
pipeline
的前端服务,它收集各种数据以显示相关视图:当前正在运行的pipeline
列表,pipeline
执行的历史记录,有关各个pipeline
运行的调试信息和执行状态等。 - Pipeline Service:
pipeline
的后端服务,调用K8S
服务从YAML
创建pipeline
运行。 - Kubernetes Resources: 创建CRDs运行
pipeline
。 - Machine Learning Metadata Service: 用于监视由
Pipeline Service
创建的Kubernetes
资源,并将这些资源的状态持久化在ML元数据服务中(存储任务流容器之间的input
/output
数据交互)。 - Artifact Storage: 用于存储
Metadata
和Artifact
。Kubeflow Pipelines
将元数据存储在MySQL
数据库中,将工件存储在Minio服务器或Cloud Storage等工件存储中。 - Orchestration Controllers:任务编排,比如 **Argo Workflow**控制器,它可以协调任务驱动的工作流。
Pipelines工作原理
流水线的定义可以分为两步,首先是定义组件,组件可以从镜像开始完全自定义。这里介绍一下自定义的方式:首先需要打包一个Docker
镜像,这个镜像是组件的依赖,每一个组件的运行,就是一个Docker
容器。其次需要为其定义一个python
函数,描述组件的输入输出等信息,这一定义是为了能够让流水线理解组件在流水线中的结构,有几个输入节点,几个输出节点等。接下来组件的使用就与普通的组件并无二致了。
实现流水线的第二步,就是根据定义好的组件组成流水线,在流水线中,由输入输出关系会确定图上的边以及方向。在定义好流水线后,可以通过 python
中实现好的流水线客户端提交到系统中运行。
虽然kubeflow/pipelines
的使用略显复杂,但它的实现其实并不麻烦。整个的架构可以分为五个部分,分别是ScheduledWorkflow CRD
以及其operator
流水线前端,流水线后端,Python SDK
和persistence agent
。
ScheduledWorkflow CRD
扩展了argoproj/argo
的Workflow
定义。这也是流水线项目中的核心部分,它负责真正地在Kubernetes
上按照拓扑序创建出对应的容器完成流水线的逻辑。Python SDK
负责构造出流水线,并且根据流水线构造出ScheduledWorkflow
的YAML
定义,随后将其作为参数传递给流水线系统的后端服务。- 后端服务依赖关系存储数据库(如
MySQL
)和对象存储(如S3
),处理所有流水线中的CRUD
请求。 - 前端负责可视化整个流水线的过程,以及获取日志,发起新的运行等。
Persistence agent
负责把数据从Kubernetes Master
的etcd
中sync
到后端服务的关系型数据库中,其实现的方式与CRD operator
类似,通过informer
来监听Kubernetes apiserver
对应资源实现。
Pipelines
提供机器学习流程的创建、编排调度和管理,还提供了一个Web UI
。这部分主要基于Argo Workflow
。我相信这会是Kubeflow
后续要大力发展的部分。
Fairing
Kubeflow Fairing
是一个Python
软件包,可轻松在Kubeflow
上训练和部署ML模型。Fairing
还可以扩展为在其他平台上进行训练或部署。目前,Fairing
已扩展为可在Google AI Platform上进行训练。Fairing
简化了在混合云环境中构建,训练和部署机器学习(ML)训练job的过程。通过使用Fairing
并添加几行代码,可以直接从Jupyter notebook
在本地或在云中使用Python
代码运行ML训练作业。训练工作完成后,可以使用Fairing
将训练后的模型部署为预测端点。
上面介绍了Kubeflow
代码编辑器Jupyter Notebooks
,用于将代码打包构建image
的Fairing
,以及工作流组件Pipelines
核心组件,下面我们再介绍用来调参的Katib
和发布部署服务的KFServing
。
Katib
在了解katib
的处理流程之前,先介绍下katib
目前有哪些组件:
- Experiment Controller:提供对
Experiment CRD
的生命周期管理。 - Trial Controller:提供对
Trial CRD
的生命周期管理。 - Suggestions:以
Deployment
的方式部署,用Service
方式暴露服务,提供超参数搜索服务。目前有随机搜索,网格搜索,贝叶斯优化等。 - Katib Manager:一个
GRPC server
,提供了对Katib DB
的操作接口,同时充当Suggestion
与Experiment
之间的代理。 - Katib DB:数据库。其中会存储
Trial
和Experiment
,以及Trial
的训练指标。目前默认的数据库为MySQL
。
Katib架构
Katib工作原理
当一个Experiment
被创建的时候,Experiment Controller
会先通过Katib Manager
在Katib DB
中创建一个Experiment
对象,并且打上Finalizer
表明这一对象使用了外部资源(数据库)。随后,Experiment Controller
会根据自身的状态和关于并行的定义,通过Katib Manager
提供的GRPC
接口,让Manager
通过 Suggestion
提供的GRPC
接口获取超参数取值,然后再转发给Experiment Controller
。在这个过程中,Katib Manager
是一个代理的角色,它代理了Experiment Controller
对Suggestion
的请求。拿到超参数取值后,Experiment Controller
会根据Trial Template
和超参数的取值,构造出Trial
的定义,然后在集群中创建它。Trial
被创建后,与Experiment Controller
的行为类似,Trial Controller
同样会通过Katib Manager
在Katib DB
中创建一个Trial
对象。随后会构造出期望的Job
(如batchv1 Job
,TFJob
,PyTorchJob
等)和Metrics Collector Job
,然后在集群上创建出来。这些Job
运行结束后,Trial Controller
会更新Trial
的状态,进而Experiment Controller
会更新Experiment
的状态。
然后Experiment
会继续下一轮的迭代。之前的Trial
已经被训练完成,而且训练的指标已经被收集起来了。Experiment
会根据配置,判断是否要再创建新的Trial
,如果需要则再重复之前的流程。
下图是从网络上(知乎@高策)找到的Katib
竞品对比分析图,可供参考:
超参优化是一种AutoML
的方法。KubeFlow
把Katib
集成进来作为超参优化的一种方案。超参优化在实际的工作中还没有被大规模的应用,所以这部分的技术还需要一些时间来成熟。
KFServing
对于深度学习的产品化来说,训练只是手段不是目的,目的是将通过训练产生的模型放到手机的程序里或者互联网的应用中,用于语音或者文字的识别等应用场景中。
模型的服务化部署和离线预测也是机器学习流程中非常重要的部分。KubeFlow
组件中可以看到,它提供基于TF Serving
,KFServing
,Seldon Core Serving
等好几种方案。由于机器学习框架很多,算法模型也各种各样。工业界一直缺少一种能真正统一的部署框架和方案。这方面KubeFlow
也仅仅是把常见的都集成了进来,但是并没有做更多的抽象和统一。Kubeflow
提供两个支持多框架的模型服务工具:KFServing
和Seldon Core Serving
。或者,可以使用独立的模型服务系统,以便可以选择最能满足模型服务要求的框架。
对于TensorFlow模型,可以使用TensorFlow Serving
将TFJob
导出的模型进行实时预测。但是,如果打算使用多个框架,则应考虑如上所述使用KFServing
或Seldon Core Serving
。KFServing
是Kubeflow
项目生态系统的一部分,Seldon Core Serving
是Kubeflow
支持的外部项目。看起来KubeFlow
社区更倾向KFServing
这套方案。
KFServing
提供了Kubernetes
CRD,用于在任意框架上服务机器学习(ML)模型。它旨在通过为常见ML框架(Tensorflow
,XGBoost
,ScikitLearn
,PyTorch
和ONNX
等)提供高性能,高抽象的接口来解决模型服务用例。
NVIDIA Triton Inference Server
是一项REST
和GRPC
服务,用于对TensorRT
,TensorFlow
,Pytorch
,ONNX
和Caffe2
模型进行深度学习推理。该服务器经过优化,可以在GPU和CPU上大规模部署机器学习算法。Triton
推理服务器以前称为TensorRT
推理服务器。
我们可以将NVIDIA Triton Inference Server
用作独立系统,但如上所述,更应该考虑使用KFServing
。KFServing
也包括对NVIDIA Triton Inference Server
的支持。
赞!现在我们终于知道如何发布我们训练好的服务了!
虽然kubeflow
最开始只是基于tf-operator
,但后来随着项目发展最后变成一个基于云原生构建的机器学习任务工具大集合。从数据采集,验证,到模型训练和服务发布,几乎所有步骤Kubeflow
都提供解决方案的组件。
上面这张图中的组件我几乎全部介绍了一遍,由于篇幅限制,除了TF-Operator
,Metadata
,Prometheus
,加上剩下的其它组件(Argo
,Istio
…),我会在后续一一进行解剖介绍,TFJob甚至会深入到源码分析,如果对Kubeflow
感兴趣不要忘记点赞转发或直接关注我~
其它干货(必备技能):