隨著ChatGPT的發(fā)布,人們越來越難以回避利用機(jī)器學(xué)習(xí)的相關(guān)技術(shù)。從消息應(yīng)用程序上的文本預(yù)測到智能門鈴上的面部識別,機(jī)器學(xué)習(xí)(ML)幾乎可以在我們今天使用的每一項(xiàng)技術(shù)中找到。
如何將機(jī)器學(xué)習(xí)技術(shù)交付給消費(fèi)者是企業(yè)在開發(fā)過程中必須解決的眾多挑戰(zhàn)之一。機(jī)器學(xué)習(xí)產(chǎn)品的部署策略對產(chǎn)品的最終用戶有重大影響。這可能意味著,iPhone上的Siri和網(wǎng)絡(luò)瀏覽器中的ChatGPT之間將存在重大差異。
除了ChatGPT流暢的用戶界面和過于自信的聊天對話之外,還隱藏了部署大型語言機(jī)器學(xué)習(xí)模型所需的復(fù)雜機(jī)制。ChatGPT建立在一個(gè)高度可擴(kuò)展的框架上,該框架旨在當(dāng)模型呈指數(shù)級被應(yīng)用期間提供和支持該模型。事實(shí)上,實(shí)際的機(jī)器學(xué)習(xí)模型只占整個(gè)項(xiàng)目的一小部分。此類項(xiàng)目往往是跨學(xué)科的,需要數(shù)據(jù)工程、數(shù)據(jù)科學(xué)和軟件開發(fā)方面的專業(yè)知識。因此,簡化模型部署過程的框架在向生產(chǎn)交付模型方面變得越來越重要,因?yàn)檫@將有助于企業(yè)節(jié)省時(shí)間和金錢。
如果沒有適當(dāng)?shù)倪\(yùn)營框架來支持和管理ML模型,企業(yè)在試圖擴(kuò)大生產(chǎn)中機(jī)器學(xué)習(xí)模型的數(shù)量時(shí)往往會遇到瓶頸。
雖然在高度飽和的MLOps工具包市場上,沒有一個(gè)工具能成為明顯的贏家,但KServe正成為一個(gè)越來越受歡迎的工具,幫助企業(yè)滿足機(jī)器學(xué)習(xí)模型的可擴(kuò)展性要求。
一、什么是KServe?
KServe是一個(gè)用于Kubernetes的高度可擴(kuò)展的機(jī)器學(xué)習(xí)部署工具包。它是一個(gè)構(gòu)建在Kubernetes之上的編排工具,并利用了另外兩個(gè)開源項(xiàng)目,Knative-Serving和Istio;稍后將對此進(jìn)行詳細(xì)介紹。
圖片
圖片來源于KServe(https://kserve.github.io/website/0.10/)
KServe通過將部署統(tǒng)一到一個(gè)資源定義中,大大簡化了機(jī)器學(xué)習(xí)模型在Kubernetes集群中的部署過程。它使機(jī)器學(xué)習(xí)部署成為任何機(jī)器學(xué)習(xí)項(xiàng)目的一部分,易于學(xué)習(xí),并最終降低了進(jìn)入壁壘。因此,使用KServe部署的模型比使用需要Flask或FastAPI服務(wù)的傳統(tǒng)Kubernetes部署的模型更容易維護(hù)。
借助于KServe,在使用HTTPs協(xié)議通過因特網(wǎng)公開模型之前,不需要將模型封裝在FastAPI或Flask應(yīng)用程序中。KServe內(nèi)置的功能基本上復(fù)制了這個(gè)過程,但不需要維護(hù)API端點(diǎn)、配置pod副本或配置Kubernetes上的內(nèi)部路由網(wǎng)絡(luò)。我們所要做的就是將KServe指向您的模型,然后由它來處理其余的部分。
除了簡化部署過程之外,KServe還提供了許多功能,包括金絲雀部署(譯者注:這是一種流行的持續(xù)部署策略,其中將一小部分機(jī)隊(duì)更新為應(yīng)用程序的新版本)、推理自動(dòng)縮放和請求批處理。這些功能將不會被討論,因?yàn)樗隽吮疚牡姆秶?;然而,本文有望為進(jìn)一步探索相關(guān)知識的理解奠定基礎(chǔ)。
首先,我們來談?wù)凨Serve附帶的兩個(gè)關(guān)鍵技術(shù),Istio和Knative。
1、Istio
如果沒有Istio,KServe帶來的許多功能將很難實(shí)現(xiàn)。Istio是一個(gè)服務(wù)網(wǎng)格,用于擴(kuò)展部署在Kubernetes中的應(yīng)用程序。它是一個(gè)專用的基礎(chǔ)設(shè)施層,增加了可觀察性、流量管理和安全性等功能。對于那些熟悉Kubernetes的人來說,Istio將取代通常在Kubernete集群中找到的標(biāo)準(zhǔn)入口定義。
管理流量和維護(hù)可觀察性的復(fù)雜性只會隨著基于Kubernetes的系統(tǒng)的擴(kuò)展而增加。Istio最好的功能之一是集中控制服務(wù)級別的通信。這使開發(fā)人員能夠?qū)Ψ?wù)之間的通信進(jìn)行更大的控制和透明度。
有了Istio,開發(fā)人員不需要專門開發(fā)那些需要能夠處理流量身份驗(yàn)證或授權(quán)的應(yīng)用程序。最終,Istio有助于降低已部署應(yīng)用程序的復(fù)雜性,并使開發(fā)人員能夠?qū)W⒂趹?yīng)用程序的重要組件。
通過利用Istio的網(wǎng)絡(luò)功能,KServe能夠帶來包括金絲雀部署、推理圖和自定義轉(zhuǎn)換器在內(nèi)的功能。
2、KNative
另一方面,KNative是一個(gè)開源的企業(yè)級解決方案,用于構(gòu)建無服務(wù)器和事件驅(qū)動(dòng)的應(yīng)用程序。Knative構(gòu)建在Istio之上,帶來了類似于AWS Lambdas和Azure Functions提供的無服務(wù)器代碼執(zhí)行功能。Knative是一個(gè)與平臺無關(guān)的解決方案,用于在Kubernetes中運(yùn)行無服務(wù)器部署。
KNative最好的功能之一是可擴(kuò)展到零的功能,當(dāng)沒有需求時(shí),該功能會自動(dòng)縮減部署。這是KServe擴(kuò)大或縮小ML模型部署能力的一個(gè)關(guān)鍵組成部分,也是最大限度地提高資源利用率和節(jié)省成本的一個(gè)組成部分。
3、我應(yīng)該使用KServe嗎?
與許多其他工具一樣,KServe不是一個(gè)適合您的企業(yè)所要求的一刀切式的解決方案。它的入門成本很高,因?yàn)樾枰脩艟邆湟恍┦褂肒ubernetes的經(jīng)驗(yàn)。如果你剛開始使用Kubernetes,網(wǎng)上有很多資源,我強(qiáng)烈建議你在Youtube上查看DevOps(https://www.youtube.com/channel/UCFe9-V_rN9nLqVNiI8Yof3w)之類的資源。盡管如此,即使不深入了解Kubernetes,也可以學(xué)習(xí)使用KServe。
在已經(jīng)利用Kubernetes的企業(yè)中,KServe將是理想的選擇,因?yàn)檫@些企業(yè)在使用Kubernete方面已經(jīng)擁有現(xiàn)有的知識。它還可能適合那些希望放棄或補(bǔ)充SageMaker或Azure機(jī)器學(xué)習(xí)等托管服務(wù)的組織,以便對您的模型部署過程有更大的控制權(quán)。所有權(quán)的增加可以顯著降低成本,并提高可配置性,以滿足項(xiàng)目的特定要求。
盡管如此,正確的云基礎(chǔ)設(shè)施決策將取決于具體情況,因?yàn)椴煌镜幕A(chǔ)設(shè)施要求不同。
二、預(yù)備知識
本文接下來將帶您了解設(shè)置KServe所需的步驟。您將了解安裝KServe并為您的第一個(gè)模型提供服務(wù)的步驟。
在繼續(xù)之前,需要滿足幾個(gè)先決條件。您將需要準(zhǔn)備以下內(nèi)容:
- lKuectl(https://kubernetes.io/docs/tasks/tools/)安裝
- lHelm(https://helm.sh/docs/intro/install/)安裝
- lKuectx(https://github.com/ahmetb/kubectx)安裝(可選)
1、Kubernetes集群
在本教程中,我建議使用Kind工具(https://kind.sigs.k8s.io/)對Kubernetes集群進(jìn)行實(shí)驗(yàn)。它是一個(gè)運(yùn)行本地Kubernetes集群的工具,無需啟動(dòng)云資源。此外,如果您在多個(gè)集群中工作,我強(qiáng)烈推薦把Kuectx作為一種工具,它能夠幫助您在Kubernetes上下文之間輕松切換。
但是,在運(yùn)行生產(chǎn)工作負(fù)載時(shí),您需要訪問功能齊全的Kubernetes集群來配置DNS和HTTPS。
使用Kind工具部署Kubernetes集群的命令如下:
kind create cluster --name kserve-demo
然后,您可以使用以下命令切換到正確的Kubernetes上下文:
kubectx kind-kserve-demo
2、安裝
以下步驟將安裝Istio v1.16、Knative Serving v1.7.2和KServe v0.10.0。這些版本最適合本教程,因?yàn)镵native v1.8以后的版本將需要對入口進(jìn)行DNS配置,這增加了一層超出目前范圍的復(fù)雜性。
1)安裝Istio:
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.16.0 TARGET_ARCH=x86_64 sh -istioctl install --set profile=default -y
2)安裝KNative Serving:
#安裝Knative Serving組件
export KNATIVE_VERSION="v1.7.2"
kubectl apply -f https://github.com/knative/serving/releases/download/knative-$KNATIVE_VERSION/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/download/knative-$KNATIVE_VERSION/serving-core.yaml
#安裝istio-controller for knative
kubectl apply -f https://github.com/knative/net-istio/releases/download/knative-v1.7.0/net-istio.yaml
3)安裝證書管理器。需要證書管理器來管理HTTPs流量的有效證書。
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.11.0 --set installCRDs=true
4)為模型創(chuàng)建一個(gè)命名空間。
kubectl create namespace kserve
5)克隆KServe存儲庫。
git clone git@github.com:kserve/kserve.git
6)將KServe定制資源定義和KServe運(yùn)行時(shí)安裝到集群中的模型命名空間中。
cd kserve
helm install kserve-crd charts/kserve-crd -n kserve
helm install kserve-resources charts/kserve-resources -n kserve
我們現(xiàn)在已經(jīng)在集群上安裝了KServe。接下來,讓我們開始部署吧!
三、第一個(gè)推理服務(wù)
為了確保部署順利進(jìn)行,讓我們部署一個(gè)演示推理服務(wù)。您可以在鏈接https://kserve.github.io/website/0.10/get_started/first_isvc/#1-create-a-namespace處找到部署的完整源代碼。
kubectl apply -n kserve -f - <<EOF
apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:
name: "sklearn-iris"
spec:
predictor:
model:
modelFormat:
name: sklearn
storageUri: "gs://kfserving-examples/models/sklearn/1.0/model"
EOF
上面的yaml資源定義部署了一個(gè)測試推理服務(wù),該服務(wù)來源于使用SciKit學(xué)習(xí)庫訓(xùn)練的公開可用模型。KServe支持許多不同風(fēng)格的機(jī)器學(xué)習(xí)庫(https://kserve.github.io/website/0.10/modelserving/v1beta1/serving_runtime/)。
其中包括MLFlow、PyTorch或XGBoost模型;每次發(fā)布時(shí)都會添加更多的類似支持。如果這些現(xiàn)成的庫都不能滿足您的要求,KServe還支持自定義預(yù)測器(https://kserve.github.io/website/0.10/modelserving/v1beta1/custom/custom_model/)。
注意,您可以通過獲取命名空間中的可用pod數(shù)量來監(jiān)控當(dāng)前部署的狀態(tài)。
kubectl get pods -n kserve
圖片
如果在部署中遇到問題,請使用以下方法進(jìn)行調(diào)試:
kubectl describe pod-n kserve
我們還可以通過以下方式檢查推理服務(wù)部署的狀態(tài):
kubectl get isvc -A
圖片
如果推理服務(wù)被標(biāo)記為true,我們就可以執(zhí)行我們的第一個(gè)預(yù)測了。
四、執(zhí)行預(yù)測
為了進(jìn)行預(yù)測,我們需要確定我們的Kubernetes集群是否在支持外部負(fù)載均衡器的環(huán)境中運(yùn)行。
kubectl get svc istio-ingressgateway -n istio-system
1、Kind群集
值得注意的是,使用Kind部署的集群不支持外部負(fù)載均衡器;因此,您將擁有一個(gè)與下面類似的入口網(wǎng)關(guān)。
圖片
Kind外部負(fù)載均衡器(圖片由作者提供)
在這種情況下,我們必須轉(zhuǎn)發(fā)istio-ingressgateway,這將允許我們通過localhost訪問它。
端口將istio-ingress網(wǎng)關(guān)服務(wù)轉(zhuǎn)發(fā)到本地主機(jī)上的端口8080,使用如下命令:
kubectl port-forward -n istio-system service/istio-ingressgateway 8080:80
然后設(shè)置入口主機(jī)和端口:
export INGRESS_HOST=localhost
export INGRESS_PORT=8080
2、Kubernetes集群
如果外部IP有效且未顯示<pending>,那么我們可以通過IP地址的互聯(lián)網(wǎng)發(fā)送推理請求。
圖片
入口網(wǎng)關(guān)IP地址(圖片由作者提供)
將入口主機(jī)和端口設(shè)置為:
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}')
3、進(jìn)行推理
為推理請求準(zhǔn)備一個(gè)輸入請求json文件。
cat <"./iris-input.json"
{
"instances": [
[6.8, 2.8, 4.8, 1.4],
[6.0, 3.4, 4.5, 1.6]
]
}
EOF
然后用curl命令進(jìn)行推理:
SERVICE_HOSTNAME=$(kubectl get inferenceservice sklearn-iris -n kserve -o jsonpath='{.status.url}' | cut -d "/" -f 3)
curl -v -H "Host: ${SERVICE_HOSTNAME}" "http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/sklearn-iris:predict" -d @./iris-input.json
該請求將通過istio-ingress網(wǎng)關(guān)發(fā)送到KServe部署。如果一切正常,我們將從推理服務(wù)中獲得一個(gè)json回復(fù),其中每個(gè)實(shí)例的預(yù)測值為[1,1]。
圖片
五、零擴(kuò)展
通過利用KNative的功能,KServe支持零擴(kuò)展功能。該功能通過將未使用的pod擴(kuò)展為零,從而有效地管理集群中有限的資源。將功能擴(kuò)展到零允許創(chuàng)建一個(gè)響應(yīng)請求的反應(yīng)式系統(tǒng),而不是一個(gè)始終處于運(yùn)行狀態(tài)的系統(tǒng)。這將有助于在集群中部署比傳統(tǒng)部署配置更多的模型。
然而,請注意,對于已經(jīng)縮小擴(kuò)展的pod副本,存在一個(gè)冷啟動(dòng)“處罰”。“處罰”程度將根據(jù)圖像/模型的大小和可用的集群資源而變化。如果集群需要擴(kuò)展額外的節(jié)點(diǎn),冷啟動(dòng)可能需要5分鐘,如果模型已經(jīng)緩存在節(jié)點(diǎn)上,則需要10秒。
讓我們修改現(xiàn)有的scikit-learn推理服務(wù),并通過定義minReplicas:0來啟用零擴(kuò)展(scale to zero)功能。
kubectl apply -n kserve -f - < <EOF< span> </EOF<>
apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:
name: "sklearn-iris"
spec:
predictor:
minReplicas: 0
model:
modelFormat:
name: sklearn
storageUri: "gs://kfserving-examples/models/sklearn/1.0/model"
EOF
通過將minReplicas設(shè)置為0,這將命令Knative在沒有HTTP流量時(shí)將推理服務(wù)縮減為零。你會注意到,30秒后,Sklearn鳶尾花模型的pod副本將縮小。
kubectl get pods -n kserve
Sklearn鳶尾花預(yù)測因子降到零
若要重新初始化推理服務(wù),請向同一個(gè)端點(diǎn)發(fā)送預(yù)測請求。
SERVICE_HOSTNAME=$(kubectl get inferenceservice sklearn-iris -n kserve -o jsonpath='{.status.url}' | cut -d "/" -f 3)
curl -v -H "Host: ${SERVICE_HOSTNAME}" "http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/sklearn-iris:predict" -d @./iris-input.json
圖片
這將從冷啟動(dòng)觸發(fā)pod副本初始化并返回預(yù)測。
六、結(jié)論
總體來看,KServe能夠簡化機(jī)器學(xué)習(xí)部署過程,縮短生產(chǎn)路徑。當(dāng)與Knative和Istio相結(jié)合時(shí),KServe還有一個(gè)額外的好處,那就是高度可定制,并帶來了許多可以輕松與托管云解決方案相媲美的功能。
當(dāng)然,在內(nèi)部遷移模型部署過程存在其固有的復(fù)雜性。然而,平臺所有權(quán)的增加將在滿足項(xiàng)目特定要求方面提供更大的靈活性。憑借正確的Kubernetes專業(yè)知識,KServe可以成為一個(gè)強(qiáng)大的工具,使企業(yè)能夠輕松地在任何云提供商中擴(kuò)展其機(jī)器學(xué)習(xí)部署,以滿足日益增長的需求。
譯者介紹
朱先忠,51CTO社區(qū)編輯,51CTO專家博客、講師,濰坊一所高校計(jì)算機(jī)教師,自由編程界老兵一枚。