使用 AIStor、MLflow 和 KServe 将模型部署到 Kubernetes

在之前几篇关于 MLOps 工具的文章中,我展示了有多少流行的 MLOps 工具跟踪与模型训练实验相关的指标。我还展示了他们如何使用 MinIO 来存储作为模型训练管道一部分的非结构化数据。但是,一个好的 MLOps 工具应该做的不仅仅是管理您的实验、数据集和模型。它应该能够在组织的各种环境中部署您的模型,将它们移动到开发、测试和生产环境。此外,在 MinIO,我们注意到人们对我们的 MLOps 内容的兴趣高于平均水平。我们的许多合作伙伴都看到了同样的情况。也许 2025 年是企业在机器学习项目中占据主导地位并将其拉入由 MLOps 工具管理的正式 CI/CD 管道的一年。在本文中,我将重点介绍 MLflow,并展示如何使用 MLserve(Mlflow 提供的用于测试模型的 RESTful 接口的简单工具)在本地托管经过训练的模型。最后,我将展示如何使用 KServe 将模型部署到 Kubernetes 集群。KServe 是专为 Kubernetes 设计的开源模型服务框架,专门用于大规模部署和服务机器学习 (ML) 模型。它提供了一个标准化的无服务器推理平台,支持各种 ML 框架,包括 TensorFlow、PyTorch、XGBoost 和 Scikit-Learn。

MLFlow 设置

查看使用 MLFlow 和 MinIO 设置开发计算机,在开发计算机上设置 MLflow。本文提供了 MLflow 的一些背景知识,介绍了它在后台使用的产品(PostgreSQL 和 MinIO),最后展示了如何创建和加载 docker-compose 文件以进行本地仿真。下图显示了 MLflow 跟踪服务器、PostreSQLm 和 MinIO 之间的关系。

KServe 设置

要设置 KServe,您需要安装 kind 和 Helm。您还需要克隆 KServe 存储库并在其中运行安装脚本。我将在下面提供一个安装所有内容的配方,这样您就不必在互联网上搜索各种安装说明。如果您不熟悉这些工具或需要更多信息,请查看我提供的链接。

1 . 安装种类

Kind 的下载方式会有所不同,具体取决于您的芯片架构。因此,您需要做的第一件事是使用以下命令确定您的芯片架构。

uname -m

您应该会看到类似 arm64、amd64 或 x86_64 的内容。对于 amd64 或 x86_64请运行以下命令下载 AMD 安装。这将创建一个名为 kind 的新子目录,该子目录将包含运行 kind 所需的一切。

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.26.0/kind-linux-amd64

对于 arm64,请使用以下命令。这还将创建一个新的子目录。

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.26.0/kind-linux-arm64

最后,更改此目录的权限,以便其中包含的文件可以执行代码。然后将其移动到 usr/local/bin 目录。

chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

2 . 设置 Kubernetes 集群

我们现在可以使用 kind 来创建 Kubernetes 集群。运行下面的三个命令来创建名为 ‘kind’ 的默认集群,使用默认的 ‘kind-kind’ 上下文,并为我们的部署创建一个命名空间。

kind create cluster
kubectl config use-context kind-kind
kubectl create namespace mlflow-kserve-test

下面是一些其他用于管理集群的有用 kind 和 kubectl 命令。

kind create cluster --name <cluster_name> 
kubectl config get-contexts
kind get clusters
kind delete cluster

3 . 安装 Helm

要安装 Helm,请运行以下三个命令,这些命令将下载 Helm shell 安装脚本,更改其权限以便它可以运行,然后运行它。

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

4 . 安装 KServe

KServe 的本地 Kubernetes 集群上的 KServe 入门在线指南中,指向其快速安装脚本的链接已断开。为了在链接修复之前解决此问题,我们将克隆 KServe GitHub 存储库并直接导航到安装脚本。

git clone https://github.com/kserve/kserve.git
cd hack
bash quick_install.sh

此命令需要一段时间才能完成。它安装 KServe 和所有 KServe 依赖项:Istio、Knative 和 Cert-manager。这些依赖项如下所述。

Istio 是一个开源服务网格,可帮助管理云原生应用程序中的微服务。它允许应用程序安全地通信和共享数据。

Knative 是一个开源项目,它扩展了 Kubernetes,以帮助用户构建、运行和管理无服务器函数。Knative 是 AWS Lambda 和 Azure Functions 等专有无服务器解决方案的替代方案。

Cert-manager 是一种开源工具,可自动管理 Kubernetes 和 OpenShift 工作负载的 TLS 证书。

记录和注册模型

本文的其余部分将使用一个使用如下所示的 sklearn 代码创建的简单模型。此训练函数创建一个 sklearn 模型,该模型采用一瓶葡萄酒的 13 个特征并预测它是红葡萄酒还是白葡萄酒。

import mlflowimport numpy as np
from sklearn import datasets, metrics
from sklearn.linear_model import ElasticNet
from sklearn.model_selection import train_test_splitdef eval_metrics(pred, actual):rmse = np.sqrt(metrics.mean_squared_error(actual, pred))mae = metrics.mean_absolute_error(actual, pred)r2 = metrics.r2_score(actual, pred)return rmse, mae, r2def train_model():# Set th experiment namemlflow.set_experiment("wine-quality")mlflow.set_tracking_uri('http://localhost:5001')# Enable auto-logging to MLflow#mlflow.sklearn.autolog()# Load wine quality datasetX, y = datasets.load_wine(return_X_y=True)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)# Start a run and train a modelwith mlflow.start_run(run_name="default-params"):model = ElasticNet()model.fit(X_train, y_train)y_pred = model.predict(X_test)rmse, mae, r2 = eval_metrics(y_pred, y_test)mlflow.log_metrics({"rmse": rmse, "r2": r2, "mae": mae})# Log and register the model.model_signature = mlflow.models.infer_signature(X_test, y_pred)mlflow.sklearn.log_model(model, "model", registered_model_name="wine-quality-model", signature=model_signature)return metrics

此代码在 MLflow(突出显示的代码)模型注册表中记录和注册模型。指定 registered_model_name 参数后,log_model 函数将记录并注册模型。这是我们在将模型部署到 KServe 时将拉取模型的位置。下面的屏幕截图显示了 MLflow UI 中记录的模型。路径显示此模型在 MinIO 中的位置,model_uri显示部署模型时需要使用的 URI。此代码在 MLflow(突出显示的代码)模型注册表中记录和注册模型。指定 registered_model_name 参数后,log_model 函数将记录并注册模型。这是我们在将模型部署到 KServe 时将拉取模型的位置。下面的屏幕截图显示了 MLflow UI 中记录的模型。路径显示此模型在 MinIO 中的位置,model_uri显示部署模型时需要使用的 URI。

使用 MLServe 测试模型部署

MLflow 附带一个方便的命令行工具,让您只需一个命令即可运行本地推理服务器。请记住使用 enable-mlserver 标志,该标志指示 MLflow 使用 MLServer 作为推理服务器。这可确保模型以与在 Kubernetes 中相同的方式运行。下面的命令会将记录的模型部署到 MLServer。模型 URI(突出显示)必须与上面屏幕截图中显示的模型 URI 匹配。

export MLFLOW_TRACKING_URI=http://localhost:5000
mlflow models serve -m runs:/dc00cbfeb5cd41ae831009edee45b767/model -p 1234 --enable-mlserver

如果要部署已注册的模型,请使用以下命令。此处,模型引用的格式为 “models/{model name}/{version}”。模型名称是在注册模型时分配的。

mlflow models serve -m models:/wine-quality-model/1 -p 1234 --enable-mlserver

下面的代码片段将向服务发送示例输入并返回预测。模型更喜欢批量输入;因此,下面的 input 是一个列表(或 Matrix)的列表。如果指定简单列表 (或向量) ,则服务将引发错误。

import requests
import jsonurl = f"http://localhost:1234/invocations"payload = json.dumps({"inputs": [[14.23, 1.71, 2.43, 15.6, 127.0, 2.8, 3.06, 0.28, 2.29, 5.64, 1.04, 3.92, 1065.0]],}
)
response = requests.post(url=url,data=payload,headers={"Content-Type": "application/json"},
)
print(response.json())

输出应类似于下面的文本,它表示输入要素表示一瓶红酒的概率。输出应类似于下面的文本,它表示输入要素表示一瓶红酒的概率。

{'predictions': [0.4097722993507402]}

构建 Docker 镜像

在本教程中,我将创建一个 docker 镜像,其中包含我们在上面训练的模型。此映像最终将部署到 Kubernetes 并通过 KServe 运行。MLflow 有一个很好的命令行实用程序,它将引用我们记录的(或注册的)模型并使用它创建一个 docker 镜像。此命令如下所示。在本教程中,我将创建一个 docker 镜像,其中包含我们在上面训练的模型。此映像最终将部署到 Kubernetes 并通过 KServe 运行。MLflow 有一个很好的命令行实用程序,它将引用我们记录的(或注册的)模型并使用它创建一个 docker 镜像。此命令如下所示。

mlflow models build-docker -m runs:/dc00cbfeb5cd41ae831009edee45b767/model -n keithpij/mlflow-wine-classifier --enable-mlserver

请注意 model 参数 (-m),该参数指定要放入图像中的 MLflow 中的模型。此字符串必须与我们在记录训练的模型后在 MLflow UI 中看到的模型名称匹配。image name 参数 (-n) 用于指定映像的名称。确保此名称的第一部分是您的 docker 用户名,因为我们需要将其推送到 Docker 的镜像注册表。我们接下来会这样做。下面的命令会将我们刚刚创建的镜像推送到 Docker Hub。

docker push keithpij/mlflow-wine-classifier

创建映像并将其推送到 Docker Hub 后,您可以登录 Docker Hub 查看映像。

将推理服务部署到 Kubernetes

要使用 KServe 将我们的镜像部署到 Kubernetes,我们需要创建一个 kubectl 文件。如下所示。

apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:name: "mlflow-wine-classifier"namespace: "mlflow-kserve-test"
spec:predictor:containers:- name: "wine-classifier"image: "keithpij/mlflow-wine-classifier"ports:- containerPort: 8080protocol: TCPenv:- name: PROTOCOLvalue: "v2"

此 kubectl 文件将创建一个 KServe 推理服务。请注意上面突出显示的 namespace 和 image 字段。命名空间必须是之前创建的命名空间。该镜像必须是推送到 Docker Hub 的镜像。假设上面的文件名为 sklearn-wine.yaml,我们可以运行下面的命令来部署镜像。

kubectl apply -f sklearn-wine.yaml

该服务需要一段时间才能部署。部署后,您可以运行以下命令来查看新推理服务的详细信息。

kubectl get inferenceservices -n mlflow-kserve-test

此命令输出的缩写版本如下所示。

NAME                     URL                                                           READY
mlflow-wine-classifier   http://mlflow-wine-classifier.mlflow-kserve-test.example.com  True

以下是一些有用的 Kubernetes 命令,可帮助解决此服务的问题,并在需要重新开始时删除该服务。如果您的服务未启动且上一个命令未报告 ready 状态,则查看 Pod 日志特别有用。

kubectl get namespaces
kubectl get pods -n <namespace>
kubectl -n <namespace> logs <pod-name>
kubectl delete -f sklearn-wine.yaml -n mlflow-kserve-test

确定 Ingress Host 和 Service Host

在向新的 Inference 服务发送请求之前,我们必须确定入口和服务主机。回想一下,当我们安装 KServe 时,它附带了 istio,它将充当我们推理服务的代理。因此,我们需要确定 istio 正在侦听的地址。我们还需要确定推理服务的地址,以便我们可以在标头或请求中包含此地址,以便 istio 可以适当地定向请求。首先,让我们弄清楚 istio 的地址。

kubectl get svc istio-ingressgateway -n istio-system

如果设置了 EXTERNAL-IP 值,则表示您正在具有可用于入口网关的外部负载均衡器的环境中运行。使用以下命令获取入口主机地址和入口端口。

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')

要在像 kind 这样的本地集群上运行,请通过运行以下命令来使用端口转发。

INGRESS_GATEWAY_SERVICE=$(kubectl get svc --namespace istio-system --selector="app=istio-ingressgateway" --output jsonpath='{.items[0].metadata.name}')echo $INGRESS_GATEWAY_SERVICEkubectl port-forward --namespace istio-system svc/${INGRESS_GATEWAY_SERVICE} 8080:80

最后,我们需要指向集群中包含模型 Pod 的服务主机名

SERVICE_HOSTNAME=$(kubectl get inferenceservice mlflow-wine-classifier -n mlflow-kserve-test -o jsonpath='{.status.url}' | cut -d "/" -f 3)
echo $SERVICE_HOSTNAME

测试 Inference 服务

现在,我们已准备好测试在 KServe 中运行的推理服务。下面的代码段与我们之前使用的代码段类似。但是,有效负载略有不同。这是 KServe 的 V2 协议。请小心用于此请求地址的 URL。MLflow 文档指出,此 URL 必须包含模型的名称。当您像我们在这里所做的那样构建自己的映像时,这将不起作用。出于某种原因,模型名称被硬编码为“mlflow-model”。(我花了很长时间才弄清楚。KServe 将使用 host 标头查找您的推理服务。

url = f"http://localhost:8080/v2/models/mlflow-model/infer"payload = json.dumps({"inputs": [{"name": "input","shape": [1,13],"datatype": "FP64","data": [[14.23, 1.71, 2.43, 15.6, 127.0, 2.8, 3.06, 0.28, 2.29, 5.64, 1.04, 3.92, 1065.0]]}]}
)
response = requests.post(url=url,data=payload,headers={"Host": "mlflow-wine-classifier.mlflow-kserve-test.example.com", "Content-Type": "application/json"},
)
print(response.json())

总结

如果您已经走到了这一步,那么您已经端到端地使用了 MLflow。在本文中,我们创建了一个模型,在训练后跟踪其指标,记录模型,并使用我们从头开始安装的 KServe 将其部署到本地 Kubernetes 集群。如果您遵循 MLflow 和 KServe 的在线文档,则会出现一些问题,因此请使用本指南作为起点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/72935.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kali linux web扫描工具

Kali Linux是一款专为网络安全领域而打造的操作系统&#xff0c;提供了众多优秀的安全工具&#xff0c;其中就包括了强大的web扫描工具。Web扫描是网络安全检测的一个重要环节&#xff0c;它可以帮助安全专家检测网站的漏洞&#xff0c;提升网站的安全性。 Kali Linux中集成了…

Linux losetup循环设备

好的&#xff0c;以下是命令的中文解释和使用步骤&#xff1a; 命令解释&#xff1a; losetup -r /dev/loop0 /system/app.bin&#xff1a; losetup 是一个用于将文件与循环设备&#xff08;loop device&#xff09;关联的命令。-r 选项表示将循环设备设置为只读模式。/dev/lo…

【js逆向】

地址&#xff1a;aHR0cHM6Ly93d3cud2VpYm90b3AuY24vMi4wLw f12进入 debugger&#xff0c;过debugger 查看预览数据 全局搜索 请求网址中的 api.weibotop.cn 在下方疑似找到了加密和解密的函数 断点调试 控制台输出 那个n就是 常见的 cryptoJs库 const cryptoJs require(cry…

1.Intel BIOS 开发指南详细介绍

1. 引言 目的: Intel BIOS 开发指南旨在为开发者提供详细的指导,帮助他们理解和实现 Intel 平台上的 BIOS 功能。 适用对象: 适用于希望开发、调试和优化 BIOS 的硬件工程师、软件工程师和系统集成商。 版本信息: 确保你使用的是最新版本的指南,以获取最新的信息和最佳实…

deepseek在pycharm中的配置和简单应用

对于最常用的调试python脚本开发环境pycharm&#xff0c;如何接入deepseek是我们窥探ai代码编写的第一步&#xff0c;熟悉起来总没坏处。 1、官网安装pycharm社区版&#xff08;免费&#xff09;&#xff0c;如果需要安装专业版&#xff0c;需要另外找破解码。 2、安装Ollama…

【论文阅读】多模态——LSeg

文献基本信息 标题&#xff1a;Language-Driven Semantic Segmentation作者&#xff1a;Boyi Li、Kilian Q. Weinberger、Serge Belongie、Vladlen Koltun、Ren Ranftl单位&#xff1a;Cornell University、University of Copenhagen、Apple、Intel Labs会议/期刊&#xff1a;…

【MySQL基础-1】MySQL 用户管理指南:创建用户、修改密码与权限分配

MySQL 作为广泛使用的关系型数据库管理系统&#xff0c;用户管理和权限分配是其核心功能之一。合理创建用户、修改密码以及分配权限&#xff0c;不仅能保障数据库的安全性&#xff0c;还能有效控制用户的操作范围。本文将详细介绍如何在 MySQL 中创建用户、修改用户密码以及分配…

影刀RPA编码版与流程版解析

影刀RPA编码版是影刀RPA的一个高级版本&#xff0c;它结合了流程版的可视化操作和编码版的强大灵活性&#xff0c;以下是对影刀RPA编码版的详细介绍&#xff1a; 1. 功能对比 流程版&#xff1a; 可视化操作&#xff1a;通过拖拽式流程设计器&#xff0c;用户可以像搭积木一样…

20天 - TCP 和 UDP 有什么区别?说说 TCP 的三次握手?TCP 是用来解决什么问题?

TCP 和 UDP 有什么区别&#xff1f; TCP&#xff08;传输控制协议&#xff09;和 UDP&#xff08;用户数据报协议&#xff09;都是传输层的网络协议&#xff0c;它们的主要区别如下&#xff1a; 连接方式 TCP&#xff1a;面向连接的协议&#xff0c;类似于打电话&#xff0c…

【MySQL_05】语法简述(是语法,不详细介绍各种语句)

文章目录 一、基本规则二、标识符规则三、数据类型四、运算符五、关键字六、SQL 语句的通用语法结构 历史文章点击&#x1f449;&#xff1a;SQL &#x1f408;‍⬛github&#xff1a;https://github.com/mysql &#x1f4bb;官网&#xff1a; https://www.mysql.com &#…

JavaScript中的生成器函数详解

在 JavaScript 中&#xff0c;生成器函数 Generator Function 是一种特殊的函数&#xff0c;它允许你在函数执行过程中暂停和恢复。生成器函数通过 function* 语法定义&#xff0c;并使用 yield 关键字来控制函数的执行流程。生成器函数返回一个生成器对象&#xff0c;该对象遵…

计算机网络——交换机

一、什么是交换机&#xff1f; 交换机&#xff08;Switch&#xff09;是局域网&#xff08;LAN&#xff09;中的核心设备&#xff0c;负责在 数据链路层&#xff08;OSI第二层&#xff09;高效转发数据帧。它像一位“智能交通警察”&#xff0c;根据设备的 MAC地址 精准引导数…

Git合并工具在开发中的使用指南

在团队协作开发中&#xff0c;Git 是最常用的版本控制工具&#xff0c;而代码合并&#xff08;Merge&#xff09;是多人协作不可避免的环节。当多个开发者同时修改同一文件的相同区域时&#xff0c;Git 无法自动完成合并&#xff0c;此时需要借助合并工具&#xff08;Merge Too…

实现多语言适配

1.在res下创建多语言资源文件&#xff1a; 2.选择需要的语言 然后得到多种语言适配string文件&#xff1a; 3.代码设置多语言 object LanguageHelper {/*** 获取适配的 Context*/fun getAttachBaseContext(context: Context): Context {return if (Build.VERSION.SDK_INT > …

【学习方法一】

学习方法一 一、通用高效学习法二、学科专项方法三、工具与技术辅助四、习惯与心理策略五、避免常见误区总结六、进阶学习策略七、解决学习痛点八、场景化学习法九、资源与工具推荐十、个性化学习调整十一、长期学习心态十二、常见问题QA十三、应对特殊挑战的学习法十四、健康与…

Golang学习笔记_44——命令模式

Golang学习笔记_41——观察者模式 Golang学习笔记_42——迭代器模式 Golang学习笔记_43——责任链模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 事务管理系统2. 多媒体遥控器3. 操作审计系统 四、Go语言实现示例五、高级应用…

应急响应--流量分析

&#xff08;一&#xff09;Cobalt Strike流量特征分析 1.HTTP特征 源码特征&#xff1a; 在流量中&#xff0c;通过http协议的url路径&#xff0c;在checksum8解密算法计算后&#xff0c;32位的后门得到的结果是92&#xff0c;64位的后门得到的结果是93&#xff0c;该特征符…

CI/CD—Jenkins配置一次完整的jar自动化发布流程

背景&#xff1a; 实现设想&#xff1a; 要创建自动化发布&#xff0c;需要准备一台测试服务器提前安装好java运行所需的环境&#xff0c;JDK版本最好和Windows开发机器上的版本一致&#xff0c;在Jenkins上配置将构建好的jar上传到测试服务器上&#xff0c;测试服务器自动启动…

创建分区表ORA-14037

1、故障现象 在跑脚本的时候创建物化试图提示分区界限过高 2、解决方法 最终原因是&#xff1a;缺少了 这个 r34411分区&#xff0c;加上就好。 判断是物化视图创建的时候需要兼容所有分区的数据&#xff0c;所以报错&#xff0c;而分区表则不存在这种情况 3、测试验证 分区…

转和git subtree管理方式为git submodule的管理方式

将 Git 子树&#xff08;subtree&#xff09;转换为子模块&#xff08;submodule&#xff09;的步骤如下&#xff1a; 1. 确定子树的路径和对应的远程仓库地址 找到当前项目中子树的路径以及对应的远程仓库地址。例如&#xff0c;假设子树的路径为 subtree-folder&#xff0c…