使用 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.pswp.cn/diannao/72935.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72935.shtml
英文地址,請注明出處:http://en.pswp.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…