Kubeflow 项目是基于容器和 Kubernetes 构建,旨在为数据科学家、机器学习工程师、系统运维人员提供面向机器学习业务的敏捷部署、开发、训练、发布和管理平台
介绍
kubeflow 是 Kubernetes 机器学习工具包,使机器学习 (ML) 工作流在 Kubernetes 上的部署变得简单、可移植和可扩展,kubeflow 是 2017 年开发的
Kubeflow 是一个开源的机器学习平台,旨在让在 Kubernetes 上部署、监控和管理机器学习(ML)工作流变得简单、可移植和可扩展。您可以将其视为一个面向数据科学家和机器学习工程师的瑞士军刀
,将一系列强大的工具集成到一个统一的平台中,以简化和自动化从数据准备到模型部署和监控的整个机器学习生命周期。
Kubeflow 的核心理念是利用 Kubernetes 的强大功能,例如容器化、自动伸缩和资源管理,来解决机器学习工作流中常见的挑战。通过将机器学习工作流的每个步骤都容器化,Kubeflow 实现了环境的一致性、可重复性和可移植性,无论您是在本地开发、在云端训练,还是在生产环境中部署。
Kubeflow 的核心架构和组件
Kubeflow 的架构是模块化的,由一系列松散耦合的组件构成,每个组件都专注于机器学习生命周期的特定阶段。这种设计使得用户可以根据自己的需求选择和组合使用不同的组件。以下是 Kubeflow 中一些最重要和最常用的组件:
Kubeflow Pipelines
- Kubeflow Pipelines: 用于构建和部署可移植、可扩展的端到端机器学习工作流。您可以将工作流中的每个步骤(例如数据预处理、模型训练、模型评估)定义为一个独立的组件,然后使用 Python SDK 将这些组件串联成一个有向无环图(DAG),形成一个完整的流水线。
- Kubeflow Pipelines (KFP) 是 Kubeflow 的核心组件之一,它允许用户构建、部署和管理多步骤的 ML 工作流。
- 定义管道: 使用 Python SDK 定义 ML 管道,将每个步骤封装为独立的组件(例如,一个组件用于数据加载,另一个用于模型训练)。
- 编排执行: KFP 会将管道编译成一个 YAML 文件,然后将其提交到 Kubernetes 集群执行。每个组件都作为一个独立的容器运行。
- 可视化和监控: KFP UI 提供了管道执行的可视化界面,可以实时查看每个步骤的状态、输入/输出以及日志,方便调试和监控。
- 版本控制和可重复性: 管道定义可以进行版本控制,确保每次运行都具有可重复性。
KServe
-
KServe (原 KFServing): 提供了一个标准化的模型部署和服务框架。它支持多种主流的机器学习框架(如 TensorFlow, PyTorch, Scikit-learn, XGBoost 等),并提供了诸如服务发现、自动伸缩、流量路由(例如金丝雀发布)和模型可解释性等高级功能。
-
KFServing (现在是 Kubeflow 的一部分,也可以作为独立的 Knative Serving 扩展) 提供了一个标准的、高性能的机器学习模型服务平台。
- 部署模型: 用户可以轻松地将训练好的模型(例如,TensorFlow SavedModel、ONNX 模型)部署为 RESTful API。
- 自动伸缩: KFServing 支持基于请求负载的自动伸缩,当请求量增加时自动扩容,当请求量减少时自动缩容到零。
- 灰度发布和 A/B 测试: 支持流量路由和版本管理,方便进行模型更新的灰度发布和 A/B 测试。
- 性能监控: 提供指标和日志,方便监控模型服务的性能和健康状况。
-
KServe vs Knative
- KServe 构建在 Knative 之上,并利用了 Knative 的核心功能来提供其机器学习模型服务的能力
- 可以将 Knative 看作是 Kubeflow 在模型服务和无服务器能力方面的重要基础设施。Kubeflow 聚焦于提供端到端的机器学习平台,而 Knative 则提供了底层的高效、弹性的无服务器运行时,两者结合使得在 Kubernetes 上运行机器学习工作负载更加高效和便捷。
Katib
- Katib: 一个用于超参数调优和神经网络架构搜索(NAS)的组件。它可以帮助您自动地为您的模型找到最佳的超参数组合,从而显著提升模型性能。Katib 支持多种搜索算法,包括网格搜索、随机搜索和贝叶斯优化。
- Katib 是一个基于 Kubernetes 的超参数调优和神经网络结构搜索 (NAS) 系统。
- 定义实验: 用户定义一个超参数调优实验,包括要搜索的超参数范围、目标指标(例如,验证准确率)和搜索算法(例如,网格搜索、贝叶斯优化)。
- 自动化调优: Katib 会根据定义的实验参数自动启动多个训练任务(通常是并行执行),每个任务使用不同的超参数组合。
- 结果跟踪和可视化: Katib 会跟踪每个训练任务的结果,并在 UI 中可视化不同超参数组合下的模型性能,帮助用户找到最佳配置。
Jupyter Notebooks
-
Jupyter Notebooks: Kubeflow 提供了集成的 Jupyter Notebook 环境,使数据科学家可以方便地进行交互式的数据探索、代码编写和实验。这些 Notebooks 运行在 Kubernetes 的 Pod 中,可以轻松访问集群资源和数据。
-
Kubeflow 提供了 JupyterHub 的集成,允许用户在 Kubernetes 集群中快速部署和管理 Jupyter Notebook 服务器。
- 部署 Notebook 服务器: 用户可以根据自己的需求(例如,选择 GPU 支持的镜像、分配 CPU 和内存)轻松地在 Kubeflow UI 中启动一个 Jupyter Notebook 服务器。
- 共享与协作: 团队成员可以访问各自的 Notebooks,并且可以通过版本控制系统(如 Git)进行协作。
- 访问集群资源: Notebooks 可以直接访问集群内部的数据存储和计算资源。
其他
部署
常见的使用示例
下面我们将通过一些常见的示例来展示如何使用 Kubeflow 的核心组件来解决实际的机器学习问题。
示例一:使用 Kubeflow Pipelines 构建和自动化机器学习流水线
假设我们需要构建一个简单的图像分类模型,从数据加载到模型训练,再到模型评估。使用 Kubeflow Pipelines,我们可以将这个过程定义为一个自动化的流水线。
首先,我们需要定义流水线中的每个步骤。在 Kubeflow Pipelines 中,每个步骤都是一个 Python 函数,并使用 @dsl.component
装饰器进行标记。
from kfp import dsl
from kfp.dsl import Input, Output, Dataset, Model
@dsl.component(
base_image='python:3.9',
packages_to_install=['pandas', 'scikit-learn']
)
def load_data(iris_dataset: Output[Dataset]):
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
data = pd.DataFrame(iris.data, columns=iris.feature_names)
data['target'] = iris.target
data.to_csv(iris_dataset.path, index=False)
@dsl.component(
base_image='python:3.9',
packages_to_install=['pandas', 'scikit-learn']
)
def train_model(
iris_dataset: Input[Dataset],
model_artifact: Output[Model]
):
import pandas as pd
from sklearn.linear_model import LogisticRegression
import pickle
data = pd.read_csv(iris_dataset.path)
X = data.drop('target', axis=1)
y = data['target']
model = LogisticRegression(max_iter=200)
model.fit(X, y)
with open(model_artifact.path, 'wb') as f:
pickle.dump(model, f)
@dsl.component(
base_image='python:3.9',
packages_to_install=['pandas', 'scikit-learn']
)
def evaluate_model(
iris_dataset: Input[Dataset],
model_artifact: Input[Model]
) -> float:
import pandas as pd
import pickle
from sklearn.metrics import accuracy_score
data = pd.read_csv(iris_dataset.path)
X = data.drop('target', axis=1)
y = data['target']
with open(model_artifact.path, 'rb') as f:
model = pickle.load(f)
y_pred = model.predict(X)
accuracy = accuracy_score(y, y_pred)
print(f"Model Accuracy: {accuracy}")
return accuracy
@dsl.pipeline(
name='iris-classification-pipeline',
description='A simple pipeline for iris classification.'
)
def iris_pipeline():
load_data_task = load_data()
train_model_task = train_model(iris_dataset=load_data_task.outputs['iris_dataset'])
evaluate_model_task = evaluate_model(
iris_dataset=load_data_task.outputs['iris_dataset'],
model_artifact=train_model_task.outputs['model_artifact']
)
然后,我们可以将这个 Python 文件编译成 YAML 格式,并通过 Kubeflow UI 或命令行工具上传并运行这个流水线。Kubeflow 的界面会直观地展示流水线的执行过程和每个步骤的产出。
示例二:使用 Katib 进行超参数调优
要为我们的逻辑回归模型找到最佳的 max_iter
和 C
(正则化强度)参数,我们可以使用 Katib。我们需要定义一个 Experiment
的 YAML 文件,来描述我们的调优任务。
apiVersion: 'kubeflow.org/v1beta1'
kind: Experiment
metadata:
namespace: kubeflow
name: iris-hyperparameter-tuning
spec:
objective:
type: maximize
goal: 0.99
objectiveMetricName: accuracy
algorithm:
algorithmName: random
parallelTrialCount: 3
maxTrialCount: 12
maxFailedTrialCount: 3
parameters:
- name: --max_iter
parameterType: int
feasibleSpace:
min: '100'
max: '500'
- name: --C
parameterType: double
feasibleSpace:
min: '0.1'
max: '1.0'
trialTemplate:
primaryContainerName: training-container
trialSpec:
apiVersion: 'batch/v1'
kind: Job
spec:
template:
spec:
containers:
- name: training-container
image: your-training-image:latest # 替换为包含训练代码的镜像
command:
- 'python'
- '/app/train.py'
- '--max_iter=${trialParameters.max_iter}'
- '--C=${trialParameters.C}'
restartPolicy: Never
在这个 Experiment
中,我们定义了优化的目标(最大化准确率)、搜索算法(随机搜索)、并发试验数以及超参数的搜索空间。Katib 会根据这些配置自动地创建多个 Trial
(即训练任务),并根据返回的 accuracy
指标来寻找最佳的参数组合。
示例三:使用 KServe 部署和服务模型
一旦我们训练好并找到了最佳的模型,就可以使用 KServe 将其部署为一个可供调用的 API 服务。我们需要创建一个 InferenceService
的 YAML 文件。
apiVersion: 'serving.kserve.io/v1beta1'
kind: 'InferenceService'
metadata:
name: 'iris-classifier'
spec:
predictor:
sklearn:
storageUri: 'gs://your-bucket/path/to/your/model' # 替换为您的模型存储路径
在这个 InferenceService
中,我们指定了模型的类型(scikit-learn)和存储模型的路径(例如 Google Cloud Storage)。KServe 会自动地拉取模型,并创建一个包含模型服务的 Pod。部署成功后,KServe 会提供一个 URL,我们可以通过发送 HTTP 请求来调用我们的模型进行预测。
# 获取服务的 URL
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export SERVICE_HOSTNAME=$(kubectl -n default get inferenceservice iris-classifier -o jsonpath='{.status.url}' | cut -d "/" -f 3)
# 发送预测请求
curl -v -H "Host: ${SERVICE_HOSTNAME}" http://${INGRESS_HOST}/v1/models/iris-classifier:predict -d '{
"instances": [
[6.8, 2.8, 4.8, 1.4],
[6.0, 3.4, 4.5, 1.6]
]
}'
Kubeflow 的优势总结
- 端到端的 MLOps: Kubeflow 提供了一套完整的工具,覆盖了从数据到生产的整个机器学习生命周期。
- 可移植性和可扩展性: 基于 Kubernetes,Kubeflow 工作流可以轻松地在不同的云平台和本地环境之间迁移,并根据需求进行扩展。
- 可重复性和版本控制: 通过将代码、数据和环境容器化,Kubeflow 保证了实验的可重复性,便于追踪和版本管理。
- 模块化和灵活性: 用户可以根据自己的需求选择和组合使用不同的组件,也可以集成自己的工具。
总而言之,Kubeflow 为机器学习团队提供了一个强大而灵活的平台,帮助他们更高效地构建、部署和管理机器学习系统,从而加速从想法到价值的转化过程。