隨著機器學習技術的快速發展,模型服務領域也在不斷演進。我認為未來幾年將出現以下趨勢:

  1. 框架統一:業界將逐步形成更統一的模型服務標準,減少當前的碎片化狀態
  2. 無伺服器推理:按需擴充套件的無伺服器模型推理將變得更加普及,特別適合負載變化大的應用
  3. 邊緣裝置佈署:隨著邊緣計算的發展,更多模型將佈署到邊緣裝置上,需要更輕量級的服務框架
  4. 自適應監控:模型監控系統將變得更加人工智慧,能夠自動識別異常並提出修正建議

機器學習模型的服務佈署是整個ML生命週期中極為關鍵的一環。選擇合適的服務架構、實施有效的監控策略以及規劃靈活的模型更新機制,共同構成了成功的模型維運基礎。隨著技術的不斷發展,我們有理由期待未來模型服務領域會變得更加標準化、自動化和人工智慧化,進一步釋放機器學習的商業價值。

模型推論服務的核心需求與實作策略

在機器學習系統中,將訓練好的模型佈署到生產環境是整個流程中極為關鍵的一環。然而,模型推論服務並非僅是簡單地提供預測介面,還需要考慮多種複雜因素,包括模型更新策略、監控機制和服務穩定性等。

模型更新需求

模型更新是機器學習系統中不可避免的環節。隨著新資料的收集和業務需求的變化,模型需要定期更新以保持其準確性和相關性。因此,推論服務必須支援簡單與靈活的模型更新策略。

在設計模型更新機制時,玄貓認為以下幾點尤為重要:

  1. 佈署策略切換的簡便性:從固定版本佈署到金絲雀佈署的切換應該是簡單直接的。這可以透過抽象化服務層面來實作,使流量路由變得更加靈活。

  2. 版本變更的測試與驗證:在新模型版本正式上線前,必須經過充分的測試和驗證,並且所有升級操作都應該被記錄下來,以便追蹤和回溯。

  3. 支援複雜的佈署策略:推論服務應該能夠支援圖形推論中常見的複雜佈署策略,如藍綠佈署、A/B測試等。

當這些模型服務、監控和更新的需求都得到滿足時,推論解決方案就能完整支援模型開發生命週期(MDLC),讓模型從實驗室順利過渡到生產環境,並能夠根據需要進行調整和修改。

持續學習的考量

有些機器學習實踐者認為持續學習(Continuous Learning,CL)是生產環境中機器學習系統的基礎。持續學習是指模型能夠從流資料中不斷學習的能力。本質上,模型會在新資料進入時自主學習和適應。有些人甚至將其稱為AutoML。

透過完整的MDLC解決方案,結合管道(pipelines)和金絲雀佈署(canary deployments),可以使用Kubeflow中的工具設計出這樣的系統。在玄貓多年的實踐中,發現持續學習系統雖然概念上吸引人,但實際實作時需要謹慎考慮資源消耗和系統複雜度的平衡。

Kubeflow中的模型推論方案

在Kubeflow生態系統中,有多種模型推論解決方案可供選擇。每種解決方案都有其獨特的特點和適用場景。接下來,玄貓將介紹幾種主要的推論方案:TensorFlow Serving、Seldon Core和KFServing。

推論方案比較

解決方案特點與方法
TensorFlow Serving• 僅支援單一模型型別(TensorFlow)
• 提供部分監控指標支援(Prometheus)
• 自2.3版本起,透過模型版本標籤支援金絲雀佈署
• 基礎設施依賴最簡單
Seldon Core• 為TensorFlow、H2O、XGBoost、MXNet等流行函式庫提供最佳化的Docker容器
• 提供語言包裝器,可將Python檔案或Java JAR轉換為功能完備的微服務
• 支援由模型、轉換器、組合器和路由器組成的推論管道
• 支援監控指標和可稽核的請求日誌
• 支援高階佈署技術—金絲雀、藍綠佈署等
• 支援高階ML洞察:直譯器、異常檢測器和對抗攻擊檢測器
• 基礎設施依賴較複雜
KFServing• 在Seldon Core基礎上增加無伺服器(Knative)和標準化推論體驗,同時為其他模型伺服器提供擴充套件性
• 基礎設施依賴最複雜

在選擇推論解決方案時,需要根據專案的具體需求、團隊的技術能力和基礎設施的現狀來決定。下面,玄貓將探討每種解決方案的實作細節。

TensorFlow Serving深度解析

TensorFlow Serving(TFServing)是根據TensorFlow匯出格式的模型服務實作,也是最受歡迎的服務實作之一。它為機器學習模型提供了靈活、高效能的服務系統,專為生產環境設計。

TFServing架構

TFServing使用匯出的TensorFlow模型作為輸入,並支援透過HTTP或gRPC執行預測。TFServing可以設定為使用:

  • 模型的單一(最新)版本
  • 模型的多個特定版本

TFServing可以在本地使用,也可以在Kubernetes中使用。Kubeflow中的典型TFServing實作包括以下元件:

  1. 一個執行所需副本數量的Kubernetes佈署
  2. 一個提供對佈署存取的Kubernetes服務
  3. 一個透過Istio入口閘道器暴露服務的Istio虛擬服務
  4. 一個定義路由到服務的流量策略的Istio目標規則(這些規則可以指定負載平衡、連線池大小和異常檢測設定的設定,以便檢測並從負載平衡池中驅逐不健康的主機)

實作範例:推薦系統模型佈署

讓玄貓透過擴充套件推薦系統範例來演示這些元件的實作方式。為了簡化初始推論服務,範例TFServing例項將限定為一個佈署和一個啟用HTTP存取的服務。

這個範例的Helm圖表定義了一個Kubernetes佈署和服務。佈署使用"標準"TFServing Docker映像,並在其設定規範中指向S3源位置的序列化模型。這個S3儲存桶由本地MinIO例項管理。服務在Kubernetes叢集內部暴露這個佈署。

可以使用以下命令佈署圖表(假設使用Helm 3):

helm install <chart_location>

佈署圖表後,需要一種與推論解決方案互動的方式。一種方法是轉發服務連線埠,使流量可以重定向到本地主機進行測試:

kubectl port-forward service/recommendermodelserver 8501:8501

這樣,流量將被重新路由到localhost:8051。

現在可以與TFServing推論解決方案進行互動了。首先,透過從服務請求模型佈署訊息來驗證佈署:

curl http://localhost:8501/v1/models/recommender/versions/1

預期輸出如下:

{
  "model_version_status": [
    {
      "version": "1",
      "state": "AVAILABLE",
      "status": {
        "error_code": "OK",
        "error_message": ""
      }
    }
  ]
}

也可以透過發出以下curl命令取得模型的中繼資料,包括其簽名定義:

curl http://localhost:8501/v1/models/recommender/versions/1/metadata

現在模型已可用與具有正確的簽名定義,可以使用以下命令對服務進行預測:

curl -X POST http://localhost:8501/v1/models/recommender/versions/1:predict \
-d '{"signature_name":"serving_default","inputs": \
{"products": [[1],[2]],"users" : [[25], [3]]}}'

這個curl命令向TensorFlow Serving傳送一個POST請求,要求對兩組輸入資料進行預測。請求包含:

  1. 模型名稱(recommender)和版本(1)
  2. 簽名稱(serving_default)
  3. 輸入資料:products(產品ID為1和2)和users(使用者ID為25和3)

執行此命令的結果如下:

{
  "outputs": {
    "model-version": [
      "1"
    ],
    "recommendations": [
      [
        0.140973762
      ],
      [
        0.0441606939
      ]
    ]
  }
}

這個輸出包含推薦分數:

  • 使用者25與產品1的推薦分數為0.140973762
  • 使用者3與產品2的推薦分數為0.0441606939

這些分數表示模型預測的使用者對產品的喜好程度,可用於排序和推薦決策。

TensorFlow Serving的優缺點評估

TensorFlow Serving使佈署新的TensorFlow演算法和實驗變得容易,同時保持相同的伺服器架構和API。但這只是開始,還有更多需要考慮的方面。例如,上述佈署指令建立了一個服務,但沒有啟用從叢集外部的存取。

如果只需要以最低的基礎設施要求佈署TensorFlow模型,TFServing是理想選擇。然而,這種方案在處理複雜推論需求時存在一定限制。

在玄貓的實踐經驗中,TensorFlow Serving非常適合那些僅使用TensorFlow模型與佈署需求相對簡單的場景。它的優勢在於佈署簡單、資源消耗低,但在處理多模型型別、複雜推論管道或需要高階佈署策略時,可能需要考慮其他解決方案。

選擇合適的推論服務

在選擇推論服務時,需要考慮多種因素:

  1. 模型型別:如果僅使用TensorFlow模型,TFServing可能足夠;如果需要支援多種模型型別,Seldon Core或KFServing會是更好的選擇。

  2. 佈署複雜性:TFServing的佈署最為簡單,而KFServing則需要更複雜的基礎設施支援。

  3. 功能需求:如果需要推論管道、高階監控或複雜佈署策略,Seldon Core或KFServing會提供更多功能。

  4. 資源限制:在資源受限的環境中,TFServing的輕量級特性可能更為適合。

  5. 團隊專業知識:選擇與團隊技術背景相符的解決方案可以減少學習曲線和實施困難。

在實際專案中,玄貓發現有時候混合使用這些工具也是一種有效策略。例如,可以使用TFServing來服務核心TensorFlow模型,同時使用Seldon Core來處理更複雜的推論邏輯和佈署策略。

模型推論的最佳實踐

根據多年的實踐經驗,玄貓總結了以下模型推論的最佳實踐:

1. 監控與可觀測性

無論選擇哪種推論服務,都應該建立完善的監控系統。這包括:

  • 技術指標:延遲、吞吐量、錯誤率等
  • 業務指標:預測準確性、模型漂移等
  • 資源使用:CPU、記憶體、GPU使用率等

2. 版本控制與回復策略

應該為模型建立嚴格的版本控制系統,並制定明確的回復策略:

  • 每個模型版本應有唯一識別符號
  • 保留模型的完整佈署歷史
  • 建立快速回復機制,以應對模型表現異常的情況

3. 漸進式佈署

避免直接將新模型佈署到所有生產流量:

  • 使用金絲雀佈署先測試小部分流量
  • 逐步增加新模型的流量比例
  • 密切監控關鍵指標,確保模型表現符合預期

4. 負載測試

在生產佈署前進行充分的負載測試:

  • 模擬峰值流量條件
  • 測試系統在高負載下的穩定性
  • 確定適當的資源設定和自動擴充套件策略

5. 服務隔離

考慮將不同型別或重要程度的模型佈署到隔離的服務中:

  • 關鍵模型應有專用資源
  • 實驗性模型應與生產模型隔離
  • 高計算需求的模型可能需要特殊硬體支援

機器學習模型的推論服務是連線模型開發和實際業務價值的關鍵橋樑。透過選擇合適的推論解決方案並遵循最佳實踐,可以確保模型能夠穩定、高效地為業務提供價值。隨著模型複雜度和佈署規模的增加,推論服務的設計和實施將變得越來越重要。

在機器學習系統的整個生命週期中,推論服務不僅是一個技術元件,更是連線演算法創新與業務價值的關鍵環節。透過精心設計的推論服務,可以使模型真正發揮其潛力,為組織創造實際價值。

模型推論系統的抉擇:TensorFlow Serving與Seldon Core

在機器學習模型從開發到生產環境的過程中,選擇合適的模型推論系統至關重要。這不僅影響模型的效能表現,更決定了整個AI系統的可擴充套件性與可維護性。在眾多選擇中,TensorFlow Serving和Seldon Core是兩個備受關注的方案,各有其優勢與侷限。

我曾在多個專案中使用這兩種系統,發現它們各自適合不同的應用場景。本文將深入比較這兩種系統,幫助你在實際專案中做出明智的技術選擇。

TensorFlow Serving的優勢與侷限

專為TensorFlow最佳化但缺乏彈性

TensorFlow Serving作為Google專為TensorFlow模型設計的推論系統,在處理TensorFlow模型時表現出色,但這也成為其最大的限制。經過我的實際測試,發現它在以下方面存在明顯優勢與侷限:

模型佈署能力分析

TensorFlow Serving僅對TensorFlow提供生產級支援,這使其缺乏作為框架無關推論服務所需的彈性。不過,它確實支援REST、gRPC、GPU加速、mini-batching,以及用於邊緣裝置的「輕量」版本。

然而,無論底層硬體如何,這種支援並不延伸到串流輸入或內建的自動擴充套件功能。更重要的是,除了公平指標(Fairness Indicator)外,擴充套件推論圖以包含更進階的ML洞見的能力並未以一流方式支援。雖然為TensorFlow模型提供基本的服務和模型分析功能,但這種推論解決方案無法滿足更進階的服務需求。

監控能力評估

TensorFlow Serving透過與Prometheus的整合支援傳統監控。這暴露了系統訊息(如CPU、記憶體和網路)和TFServing特定的指標;不幸的是,檔案非常有限。此外,它與Kibana等資料視覺化工具或Jaeger等分散式追蹤函式庫沒有一流的整合。因此,TFServing並不提供所需的受管網路可觀察效能力。

在模型漂移和可解釋性等進階模型服務洞見方面,TensorFlow 2.0中提供了其中一些功能。然而,對專有服務解決方案的供應商鎖定使模型洞見元件的可插拔性變得複雜。由於TFServing的佈署策略使用Kubeflow的基礎設施堆積積疊,它利用了微服務方法。這使TFServing佈署可以輕鬆地與輔助ML元件耦合。

模型更新機制

TFServing在啟用金絲雀(canary)、固定(pinned)甚至回復佈署策略方面相當先進。然而,這些策略僅限於手動標記現有模型版本,不支援引入執行中的模型版本。因此,版本升級沒有安全佈署保證。最後,這些策略嵌入在伺服器中,無法擴充套件到TFServing之外可能存在的其他佈署策略。

TensorFlow Serving為TensorFlow模型提供極其高效與複雜的開箱即用整合,但在啟用更進階功能(如框架可擴充套件性、進階遙測和可插拔佈署策略)方面卻不足。看到這些需求未得到滿足,接下來我們將探討Seldon Core如何嘗試填補這些差距。

Seldon Core:推論圖的靈活構建

Seldon Core不僅是在端點後面提供單一模型,而是透過將機器學習程式碼或工件轉換為微服務,使資料科學家能夠構建複雜的執行時推論圖。

Seldon Core的核心概念

推論圖可以由以下元件組成:

模型

一個或多個ML模型的執行時推論可執行檔案

路由器

將請求路由到子圖,例如啟用A/B測試或多臂老虎機

組合器

組合來自子圖的回應,例如模型整合

轉換器

轉換請求或回應,例如轉換特徵請求

Seldon Core的關鍵元件

為了理解Seldon如何實作這一點,我們將探索其核心元件和功能集:

  1. 預包裝模型伺服器:為TensorFlow、XGBoost、H2O等流行函式庫最佳化的Docker容器,可以載入和提供模型工件/二進位檔案

  2. 語言包裝器:使用一組CLI工具,使資料科學家能夠將Python檔案或Java JAR轉換為功能完備的微服務

  3. 標準化API:可以是REST或gRPC的開箱即用API

  4. 開箱即用可觀察性:監控指標和可審核的請求日誌

  5. 進階機器學習洞見:將直譯器、異常檢測器和對抗性攻擊檢測器等複雜ML概念抽象為可在需要時擴充套件的基礎設施元件

設計Seldon推論圖

使用Seldon Core設計推論圖的過程相當靈活,我通常按以下步驟進行:

1. 決定元件組成

首先,需要決定推論圖由哪些元件組成。是僅一個模型伺服器,還是要向模型伺服器增加一組轉換器、直譯器或異常檢測器?幸運的是,根據需要增加或移除元件非常容易,因此可以從一個簡單的模型伺服器開始。

2. 容器化處理步驟

需要容器化處理步驟。可以使用「模型即資料」或「模型即程式碼」構建推論圖的每個步驟:

  • 模型即資料:使用預包裝模型伺服器載入模型工件/二進位檔案,避免每次模型變更時都構建Docker容器
  • 模型即程式碼:根據自定義實作構建自己的預包裝模型伺服器

實作透過語言包裝器啟用,它將程式碼容器化,為模型邏輯提供高階介面。這可用於更複雜的情況,甚至可能需要特定於作業系統的依賴項或外部系統依賴項的使用案例。

3. 測試實作

可以在本地執行實作,利用Seldon工具驗證其正確工作。本地開發由Kubernetes的底層可移植性和Seldon與Kubeflow基礎設施堆積積疊的相容性實作。

4. 啟用Seldon Core擴充套件

一些擴充套件包括:Jaeger追蹤整合、ELK請求日誌整合、Seldon Core分析整合或Istio/Ambassador入口整合等。

5. 佈署到Kubernetes叢集

完成本地測試後,可以將本地圖佈署提升為在實時Kubernetes叢集上託管。

6. 連線到CI/CD管道

Seldon元件允許無縫整合到CI/CD工作流程中,使你能夠使用首選的CI工具將模型源連線到Seldon Core。

Seldon Core設定

Seldon Core 1.0預先封裝在Kubeflow中,因此應該已經可用。Seldon Core安裝將建立一個Kubernetes操作器,它將監視描述推論圖的SeldonDeployment資源。

自定義Seldon Core版本安裝

如果需要安裝自定義版本的Seldon Core,可以使用以下Helm命令:

helm install seldon-core-operator \
--repo https://storage.googleapis.com/seldon-charts \
--namespace default \
--set istio.gateway=istio-system/seldon-gateway \
--set istio.enabled=true

這段命令使用Helm(Kubernetes的套件管理器)安裝Seldon Core操作器。它指定了倉函式庫位置、安裝的名稱空間,並設定了Istio相關的引數。Istio是一個服務網格,為Seldon提供流量管理、安全和可觀察性功能。

名稱空間設定

必須確保將佈署模型的名稱空間有Istio閘道器和InferenceServing名稱空間標籤。標籤應用範例:

kubectl label namespace kubeflow serving.kubeflow.org/inferenceservice=enabled

這條命令為kubeflow名稱空間增加了一個標籤,告訴系統該名稱空間允許佈署推論服務。這是Seldon Core正常工作的必要條件。

Istio閘道器設定

以下是Seldon Core Istio閘道器的範例:

kind: Gateway
metadata:
  name: seldon-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
      - '*'
      port:
        name: http
        number: 80
        protocol: HTTP

這個YAML定義了一個Istio閘道器,它作為外部流量進入Kubernetes叢集中Seldon服務的入口點。它設定在istio-system名稱空間中,接受所有主機的HTTP流量,並將其路由到指定的ingressgateway。

應該將此範例儲存到檔案中,並使用kubectl應用它。

模型封裝策略

使用Seldon Core執行模型時,可以使用預包裝模型伺服器或語言包裝器封裝模型。目前支援的預包裝伺服器包括MLflow伺服器、SKLearn伺服器、TensorFlow serving和XGBoost伺服器。在語言伺服器方面,Python已得到完全支援,而Java、R、NodeJS和Go則處於孵化階段。

在我的實踐中,預包裝模型伺服器非常適合標準模型,而語言包裝器則為需要自定義處理邏輯的情況提供了更大的靈活性。

TensorFlow Serving與Seldon Core的對比思考

在多個專案實踐中,我發現這兩個系統的選擇主要取決於以下幾個因素:

  1. 模型多樣性:如果僅使用TensorFlow模型,TF Serving可能是最佳選擇;但如果需要支援多種框架或自定義模型,Seldon Core明顯更具優勢。

  2. 佈署複雜度:TF Serving設定簡單,適合快速佈署;Seldon Core雖然初始設定較複雜,但提供了更強大的擴充套件能力。

  3. 監控與可觀察性:Seldon Core在這方面明顯領先,提供了更完整的整合選項。

  4. 資源效率:對於資源受限的環境,TF Serving可能更輕量;而在企業級佈署中,Seldon Core的微服務架構可提供更好的資源隔離。

  5. 團隊技能組合:如果團隊熟悉Kubernetes和微服務架構,Seldon Core會更容易採用;純TensorFlow團隊可能更喜歡TF Serving的直接性。

結論與實踐建議

TensorFlow Serving和Seldon Core代表了模型佈署的兩種不同哲學:一種是專注於特定框架的高度最佳化解決方案,另一種是靈活的框架無關系統。

在實際應用中,我發現初創企業和小型團隊往往從TensorFlow Serving開始,因為它易於設定與維護成本低。隨著模型種類別增加和佈署需求變得更複雜,許多團隊會遷移到Seldon Core或類別似的框架無關系統。

對於需要佈署多種模型型別、需要高階監控和可觀察性,或者計劃構建複雜推論管道的團隊,Seldon Core從一開始就可能是更好的選擇,儘管初始學習曲線較陡。

無論選擇哪種系統,關鍵是確保它與整個機器學習基礎設施和工作流程無縫整合,以實作從模型訓練到佈署的順暢過渡。

Seldon Core推論系統:從模型佈署到服務請求

在機器學習工程領域,將訓練好的模型佈署到生產環境並提供穩定的推論服務是一項關鍵挑戰。Seldon Core作為Kubernetes原生的模型服務框架,提供了強大的解決方案來應對這一挑戰。在這篇文章中,玄貓將帶你深入瞭解如何使用Seldon Core建立高效的模型推論系統。

構建推論圖:連線模型元件

在封裝好模型後,下一步是定義推論圖(inference graph),將一系列模型元件連線成單一推論系統。每個模型元件可以是預先封裝的模型伺服器或自定義語言包裝器。Seldon Core將計算結構實作為樹形結構,這使得組合器(combiner)能夠以反向順序執行,組合所有子節點的輸出。

Seldon Core支援多種推論圖模式:

  1. 單一模型 - 最基本的佈署形式
  2. 序列模型 - 兩個模型串聯,第一個模型的輸出作為第二個模型的輸入
  3. 帶轉換器的模型 - 包含輸入轉換器、模型和輸出轉換器的序列
  4. 路由模型 - 路由器決定將請求傳送到模型A還是模型B
  5. 組合模型 - 接收來自模型A和B的回應並組合成單一回應

定義SeldonDeployment資源

SeldonDeployment是Seldon Core的核心資源,用於指定推論圖及其佈署方式。當SeldonDeployment被佈署時,Seldon Core會增加一個服務協調器(service orchestrator)來管理請求和回應在圖中的流動。

以下是一個使用預封裝模型伺服器的簡單SeldonDeployment範例:

apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
  name: seldon-model
spec:
  name: test-deployment
  predictors:
    - componentSpecs:
      graph:
        name: classifier
        type: SKLEARN_SERVER
        modelUri: gs://seldon-models/sklearn/income/model
        children: []
      name: example
      replicas: 1

這個YAML定義了一個基本的SeldonDeployment,它佈署了一個scikit-learn模型伺服器。關鍵元素包括:

  • kind: SeldonDeployment:定義這是一個Seldon Core佈署資源
  • predictors:包含推論圖定義的陣列
  • graph:模型元件的結構,這裡只有一個分類別器節點
  • type: SKLEARN_SERVER:使用Seldon預封裝的scikit-learn模型伺服器
  • modelUri:模型檔案的位置,這裡是Google Cloud Storage路徑
  • replicas: 1:佈署一個副本

每個predictor包含幾個核心欄位:

  1. componentSpecs - Kubernetes PodSpec列表,每個都將用於Kubernetes佈署
  2. graph - 推論圖的表示,包含每個元件的名稱、型別和協定
  3. name - predictor的名稱
  4. replicas - 每個佈署建立的副本數
  5. type - 指定是預封裝模型伺服器還是自定義語言包裝模型
  6. modelUri - 模型二進位檔案或權重的儲存位置

使用自定義語言包裝器

如果你需要更多的彈性,可以使用自定義語言包裝器模型。以下是一個使用自定義包裝器的SeldonDeployment範例:

apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
  name: seldon-model
spec:
  name: test-deployment
  predictors:
    - componentSpecs:
      - spec:
          containers:
          - image: seldonio/mock_classifier_rest:1.3
            name: classifier
      graph:
        children: []
        endpoint:
          type: REST
        name: classifier
        type: MODEL
      name: example
      replicas: 1

這個設定使用了自定義容器而非預封裝伺服器。關鍵差異在於:

  • containers:定義了Kubernetes容器,包括Docker映像和標籤
  • endpoint:指定模型端點是REST還是gRPC
  • type: MODEL:表明這是一個自定義模型而非預封裝伺服器

自定義模型給了你更多控制權,可以實作特定的預處理邏輯、後處理步驟或使用非標準框架。