在佈署到生產環境之前,徹底測試模型是至關重要的。Seldon Core提供了多種測試選項:
直接使用Python客戶端執行模型
這種方式允許在叢集外進行簡單的本地測試。假設你的Python模型定義在MyModel.py
檔案中:
class MyModel:
def __init__(self):
pass
def predict(*args, **kwargs):
return ["hello", "world"]
安裝Seldon Core Python模組後,你可以使用微服務CLI執行模型:
seldon-core-microservice MyModel REST --service-type MODEL
這會啟動一個本地伺服器,你可以使用curl傳送請求:
curl -X POST \
-H 'Content-Type: application/json' \
-d '{"data": { "ndarray": [[1,2,3,4]]}}' \
http://localhost:5000/api/v1.0/predictions
伺服器會回傳模型的輸出:
{"data":{"names":[],"ndarray":["hello","world"]},"meta":{}}
這個測試流程讓你不需要Kubernetes就能驗證模型功能:
- 首先定義一個簡單的Python模型類別
- 使用Seldon Core的微服務CLI啟動本地REST服務
- 使用curl傳送包含測試資料的POST請求
- 接收並驗證模型回應
這種方法特別適合開發階段的快速迭代測試。
使用Docker進行本地測試
對於其他語言包裝器構建的模型,你可以透過本地Docker客戶端執行所構建的容器:
docker run --rm --name mymodel -p 5000:5000 mymodel:0.1
這將執行模型並將其暴露在連線埠5000上,然後你可以使用curl傳送請求:
curl -X POST \
-H 'Content-Type: application/json' \
-d '{"data": { "ndarray": [[1,2,3,4]]}}' \
http://localhost:5000/api/v1.0/predictions
Docker測試方法的優勢在於:
- 更接近生產環境,因為你測試的是實際將佈署的容器
- 可以驗證所有依賴項是否正確封裝
- 適用於任何語言的包裝器,不僅限於Python
- 可以測試容器的資源使用情況和效能特性
在Kubernetes開發客戶端中測試
使用KIND等Kubernetes開發客戶端可以測試任何模型,這是確認模型將按預期執行的最終測試。這種方法最接近實際生產佈署,但設定相對複雜,通常在前兩種測試透過後使用。
服務請求
Seldon Core支援兩種入口閘道器:Istio和Ambassador。由於Kubeflow安裝使用Istio,我們將重點關注Seldon Core如何與Istio入口閘道器協作。
假設Istio閘道器位於<istioGateway>
,SeldonDeployment名為<deploymentName>
,位於名稱空間<namespace>
中。REST端點將暴露在:
http://<istioGateway>/seldon/<namespace>/<deploymentName>/api/v1.0/predictions
gRPC端點將暴露在<istioGateway>
,你應該在請求中傳送帶有以下中繼資料的頭訊息:
- 鍵
seldon
和值<deploymentName>
- 鍵
namespace
和值<namespace>
請求格式
這些請求的有效負載將是SeldonMessage。以下是包含簡單ndarray表示的SeldonMessage範例:
{
"data": {
"ndarray": [[1.0, 2.0, 5.0]]
}
}
除了陣列資料,有效負載還可以包括簡單張量、TensorFlow張量以及二進位、字元串或JSON資料。以下是包含JSON資料的請求範例:
{
"jsonData": {
"field1": "some text",
"field2": 3
}
}
Seldon Core支援多種輸入格式,增加了系統的靈活性:
ndarray
:最常見的格式,適用於大多數機器學習模型jsonData
:適用於需要結構化資料的模型- 其他支援的格式包括張量、二進位和字元串資料
這種靈活性使Seldon Core能夠支援從簡單的統計模型到複雜的深度學習系統的各種使用案例。
高階推論圖設定
Seldon Core的強大之處在於它能夠設定複雜的推論流程。讓我們探討一些更高階的推論圖設定:
輸入/輸出轉換器
在實際應用中,原始輸入資料可能需要預處理,而模型輸出可能需要後處理。以下是一個包含輸入和輸出轉換器的設定範例:
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
name: transformer-example
spec:
name: transformer
predictors:
- componentSpecs:
- spec:
containers:
- image: seldonio/transformer-example:0.1
name: transformer
- image: seldonio/sklearn-iris:0.1
name: model
- image: seldonio/output-transformer:0.1
name: output-transformer
graph:
name: transformer
type: TRANSFORMER
children:
- name: model
type: MODEL
children:
- name: output-transformer
type: OUTPUT_TRANSFORMER
children: []
name: default
replicas: 1
這個設定建立了一個三階段處理流程:
- 輸入轉換器處理原始請求資料(例如,標準化特徵)
- 模型處理轉換後的資料進行預測
- 輸出轉換器處理模型輸出(例如,增加解釋或轉換格式)
這種架構非常適合需要複雜資料處理的企業級應用。
模型路由和A/B測試
Seldon Core支援根據路由的推論圖,這對於A/B測試或多模型策略特別有用:
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
name: router-example
spec:
name: router
predictors:
- componentSpecs:
- spec:
containers:
- image: seldonio/router:0.1
name: router
- image: seldonio/model-a:0.1
name: model-a
- image: seldonio/model-b:0.1
name: model-b
graph:
name: router
type: ROUTER
children:
- name: model-a
type: MODEL
children: []
- name: model-b
type: MODEL
children: []
name: default
replicas: 1
這個設定實作了動態路由功能:
- 路由器元件分析輸入請求
- 根據預定義的邏輯(如隨機選擇、根據特徵的決策或流量分配)決定將請求傳送到哪個模型
- 選定的模型處理請求並回傳結果
這種架構使你能夠:
- 實作A/B測試比較不同模型的表現
- 根據請求特徵選擇專門的模型
- 實作金絲雀佈署策略,逐漸將流量從舊模型轉移到新模型
生產環境考量
當你的推論系統投入生產後,還需考慮以下幾個方面:
監控與可觀測性
Seldon Core與Prometheus和Grafana整合,提供了全面的指標監控。你可以跟蹤:
- 請求延遲
- 吞吐量
- 錯誤率
- 資源使用情況
此外,Seldon Core還支援將請求和回應記錄到外部系統,用於稽核和模型效能分析。
擴充套件性與高用性
透過調整replicas引數,你可以水平擴充套件模型佈署以處理更高的負載。Kubernetes的自動擴充套件功能也可以設定為根據CPU使用率或自定義指標自動調整副本數。
為了確保高用性,你可以:
- 在多個可用區佈署副本
- 實施健康檢查和就緒探針
- 設定適當的資源請求和限制
模型版本控制與更新策略
在生產環境中,模型更新是一個關鍵考量。Seldon Core支援多種更新策略:
- 藍綠佈署
- 金絲雀發布
- 滾動更新
透過標記不同版本的模型映像,你可以實作完整的版本控制和回復能力。
Seldon Core提供了一個強大而靈活的框架,用於在Kubernetes上佈署機器學習模型。從簡單的單一模型佈署到複雜的推論圖,它能夠滿足各種機器學習服務需求。
透過本文介紹的SeldonDeployment設定、測試方法和服務請求處理,你現在應該對如何使用Seldon Core構建生產級機器學習推論系統有了全面的瞭解。無論是簡單的預測服務還是複雜的多模型推論管道,Seldon Core都提供了必要的工具和架構來實作高效、可擴充套件的解決方案。
在實際應用中,玄貓建議從簡單的佈署開始,熟悉Seldon Core的工作原理,然後逐步增加更複雜的功能,如轉換器、路由器和組合器。透過這種增量方法,你可以構建出既滿足業務需求又易於維護的機器學習服務系統。
機器學習模型的監控:超越傳統應用監控
在現代機器學習工程中,將模型佈署到生產環境僅是開始,而非終點。當模型投入使用後,有效的監控機制變得至關重要。Seldon Core的設計理念將機器學習模型佈署視為傳統應用佈署的延伸,同樣適用於監控和治理流程。
傳統監控與ML監控的區別
傳統的應用監控指標如請求延遲、負載和狀態碼分佈等,可以透過Prometheus指標在Grafana中輕鬆取得。這些基礎指標對任何線上服務都很重要,但對於機器學習模型來說遠不夠。
作為資料科學家,我們更關心的是:
- 模型在實際資料上的表現如何
- 線上資料與訓練資料之間的關係
- 特定預測結果背後的原因
這些問題遠比簡單的"服務是否線上"更為複雜。正因如此,Seldon Core提供了額外的開放原始碼專案:Alibi:Explain和Alibi:Detect,專門針對這些進階機器學習監控需求。
Alibi生態系統:深度洞察模型行為
Alibi專案實作了一系列核心演算法,專注於:
- 模型解釋性
- 異常檢測
- 資料漂移識別
- 對抗攻擊檢測
接下來,我將透過實際案例展示Seldon Core如何透過整合Alibi:Explain和Alibi:Detect來實作模型解釋性和漂移檢測。
深入理解模型解釋性技術
模型解釋性的核心問題
模型解釋性演算法試圖回答一個基本問題:「為什麼我的模型對這個特定輸入做出了這樣的預測?」
這個看似簡單的問題可以從多個角度解答:
- 哪些特徵對模型預測貢獻最大
- 需要對特徵做出什麼最小變化才能導致不同的預測結果
- 模型的決策邊界在該例項附近的形狀如何
黑盒與白盒解釋方法
解釋性演算法根據對模型的存取程度可分為兩類別:
- 黑盒演算法:只能存取模型的預測端點,無法取得內部架構或引數。在生產環境中最為常見。
- 白盒演算法:可以完全存取模型內部架構,允許更深入的分析(如計算梯度)。
在真實的生產場景中,黑盒情況更為普遍,因此我們將重點關注這類別演算法。
黑盒解釋演算法的工作原理
黑盒解釋演算法通常透過以下方式工作:
- 生成大量與待解釋例項相似的樣本
- 向模型傳送批次和序列請求
- 繪製出模型在原始例項附近的決策過程圖景
因此,直譯器元件需要與底層模型進行通訊以計算解釋結果。
Seldon Core中的直譯器架構
在Seldon Core中,直譯器的實作遵循以下模式:
- 模型作為SeldonDeployment佈署
- 直譯器元件與模型一起佈署,並擁有自己的端點
- 當呼叫直譯器端點時,直譯器內部與模型通訊以生成解釋
+----------------+ +----------------+
| | | |
| 外部請求 +---->+ 直譯器端點 |
| | | |
+----------------+ +--------+-------+
|
v
+--------+-------+
| |
| 模型端點 |
| |
+----------------+
這個架構圖展示瞭直譯器如何工作。當使用者向直譯器端點傳送請求時,直譯器會與模型端點進行內部通訊,以取得必要的預測結果,從而生成解釋。這種設計允許直譯器在不影響原始模型的情況下執行複雜的解釋演算法。
值得注意的是,在實際生產環境中,直譯器通常會與一個獨立但相同的模型佈署(例如在預發環境中)進行通訊,而不是直接與生產推理系統互動。這樣可以確保直譯器的呼叫不會降低生產系統的效能。
實戰案例:情感預測模型解釋
讓我們透過一個實際案例來說明這些技術。第一個例子是一個情感預測模型,該模型在康奈爾大學提供的電影評論資料上訓練。
佈署帶有直譯器的情感分析模型
我們可以使用以下SeldonDeployment設定來佈署模型及其關聯的anchors直譯器:
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
name: movie
spec:
name: movie
annotations:
seldon.io/rest-timeout: "10000"
predictors:
- graph:
children: []
implementation: SKLEARN_SERVER
modelUri: gs://seldon-models/sklearn/moviesentiment
name: classifier
explainer:
type: AnchorText
name: default
replicas: 1
這個YAML設定義了一個名為"movie"的SeldonDeployment。它包含一個使用SKLEARN_SERVER實作的模型,該模型從Google Cloud Storage載入。特別重要的是設定中的explainer
部分,它指定了一個型別為AnchorText的直譯器。AnchorText是一種特別適合文字資料的解釋演算法,能夠識別文字中對預測結果有決定性影響的詞或短語。
注意到seldon.io/rest-timeout
設定為10000,這是因為解釋計算通常需要較長時間。
向模型傳送預測請求
一旦佈署完成,我們可以透過Istio入口向模型傳送簡單的評論:
curl -d '{"data": {"ndarray":["This film has great actors"]}}' \
-X POST http://<istio-ingress>/seldon/seldon/movie/api/v1.0/predictions \
-H "Content-Type: application/json"
模型會回傳如下回應:
{
"data": {
"names": ["t:0","t:1"],
"ndarray": [[0.21266916924914636,0.7873308307508536]]
},
"meta": {}
}
這個回應顯示模型以78.7%的置信度預測這是一個正面評論。ndarray
中的兩個值分別代表負面和正面情感的機率。在這個例子中,模型正確地識別出這是一條正面評論。
解釋模型預測結果
現在,我們可以嘗試解釋這個預測結果:
curl -d '{"data": {"ndarray":["This movie has great actors"]}}' \
-X POST http://<istio-ingress>/seldon/seldon/movie/explainer/api/v1.0/explain \
-H "Content-Type: application/json"
直譯器會回傳如下回應(為簡潔起見,已省略examples部分):
{
"names": [
"great"
],
"precision": 1,
"coverage": 0.5007,
...
"instance": "This movie has great actors",
"prediction": 1
},
"meta": {
"name": "AnchorText"
}
這個解釋結果非常有趣。直譯器識別出單詞"great"是模型預測正面情感的關鍵原因。precision
值為1表示在包含"great"這個詞的句子中,模型100%會預測為正面情感。coverage
值約為0.5,表示這個規則適用於大約50%的資料空間。
這種解釋方式非常直觀,即使是非技術人員也能理解。它揭示了模型的決策邏輯:當評論中出現"great"這個詞時,模型傾向於判斷為正面評論。這種見解可能有助於發現模型的偏見或弱點,例如,如果有人寫"This movie is not great",模型可能會錯誤地判斷為正面評論,因為它過度依賴"great"這個詞。
實戰案例:美國人口普查收入預測模型
第二個例子使用了1996年美國人口普查資料,預測一個人的收入是高還是低。這個例子更加複雜,因為它涉及表格資料而非文字資料。
設定Alibi直譯器
對於這個例子,我們需要讓Alibi直譯器對輸入資料集進行取樣並識別分類別特徵,以便直譯器能夠給出更直觀的結果。Alibi檔案中提供了設定直譯器的詳細訊息。
佈署收入預測模型
SeldonDeployment資源定義如下:
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
name: income
spec:
name: income
annotations:
seldon.io/rest-timeout: "100000"
predictors:
- graph:
children: []
implementation: SKLEARN_SERVER
modelUri: gs://seldon-models/sklearn/income/model
name: classifier
explainer:
type: AnchorTabular
modelUri: gs://seldon-models/sklearn/income/explainer
name: default
replicas: 1
與前一個例子的主要區別在於直譯器型別從AnchorText變為AnchorTabular,這是一種專門為表格資料設計的解釋演算法。此外,直譯器本身也有一個modelUri,指向一個預先訓練的直譯器模型。這是因為AnchorTabular需要預先了解資料的分佈和特徵型別,這些訊息儲存在直譯器模型中。
超時間設定為100000毫秒,比前一個例子更長,反映了表格資料解釋通常比文字解釋更複雜、耗時更長。
向模型傳送預測請求
佈署完成後,我們可以傳送預測請求:
curl -d '{"data": {"ndarray":[[39, 7, 1, 1, 1, 1, 4, 1, 2174, 0, 40, 9]]}}' \
-X POST http://<istio-ingress>/seldon/seldon/income/api/v1.0/predictions \
-H "Content-Type: application/json"
模型回傳的回應是:
{
"data": {
"names":["t:0","t:1"],
"ndarray":[[1.0,0.0]]
},
"meta":{}
}
這個回應表明模型預測該人的收入為低(ndarray
中的第一個值為1.0,表示100%的置信度預測為低收入類別)。輸入陣列中的數字代表了各種特徵,如年齡、教育程度、職業等,但從原始數字很難理解這些特徵的含義。
解釋收入預測結果
現在我們可以請求對這個預測的解釋:
curl -d '{"data": {"ndarray":[[39, 7, 1, 1, 1, 1, 4, 1, 2174, 0, 40, 9]]}}' \
-X POST http://<istio-ingress>/seldon/seldon/income/explainer/api/v1.0/explain \
-H "Content-Type: application/json"
直譯器回傳的結果(為簡潔起見,已縮短):
{
"names": [
"Marital Status = Never-Married",
"Occupation = Admin",
"Relationship = Not-in-family"
],
"precision": 0.9766081871345029,
"coverage": 0.022,
...
}
這個解釋結果非常有啟發性。直譯器識別出三個關鍵特徵對模型的預測起決定性作用:
- 婚姻狀況為"從未結婚"
- 職業為"行政人員"
- 關係狀態為"非家庭成員"
precision
值約為0.977,表示當這三個條件同時滿足時,模型有97.7%的可能性預測為低收入。coverage
值為0.022,表示這個規則適用於約2.2%的資料空間。
這種解釋方式將抽象的數字特徵轉化為人類可理解的特徵描述,大提高了模型解釋的可用性。它揭示了模型的決策邏輯:未婚、從事行政工作與不與家人同住的人很可能被模型預測為低收入群體。這種見解可能有助於理解模型是否存在社會偏見或其他問題。
模型監控的更多維度
除了解釋性之外,有效的模型監控還應包括其他幾個關鍵維度:
資料漂移檢測
線上資料與訓練資料之間的分佈差異可能導致模型效能下降。Alibi:Detect提供了多種演算法來檢測這種漂移,包括:
- 單變數漂移檢測:監控單個特徵的分佈變化
- 多變數漂移檢測:監控特徵之間的相關性變化
- 對抗漂移檢測:使用對抗性方法檢測更微妙的漂移
異常檢測
識別異常輸入對於保護模型免受惡意攻擊或處理極端情況至關重要。Alibi:Detect支援多種異常檢測方法:
- 根據密度的方法:檢測低密度區域的資料點
- 根據距離的方法:檢測與訓練資料距離較遠的點
- 根據重構的方法:檢測難以重構的資料點
效能監控
除了傳統的精確度指標外,在生產環境中還應監控:
- 預測分佈的變化:模型是否突然開始偏向特定類別
- 置信度分佈:模型的不確定性是否增加
- 業務指標的相關性:模型預測如何影響實際業務指標
實施有效的模型監控策略
根據我在多個機器學習系統中的實踐經驗,我建議採用以下策略來實施有效的模型監控:
分層監控架構
建立分層監控系統,包括:
- 基礎設施層:監控計算資源、延遲、吞吐量
- 模型層:監控預測分佈、置信度、解釋性指標
- 業務層:監控模型決策對業務指標的影響
警示與閾值設定
為不同的監控指標設定適當的閾值,當指標超出閾值時觸發警示:
- 資料漂移警示:當輸入分佈顯著變化時
- 效能下降警示:當關鍵指標低於預期時
- 解釋性變化警示:當模型決策邏輯出現顯著變化時
定期模型稽核
即使沒有警示觸發,也應定期審查模型的行為:
- 抽樣檢查模型解釋,確保決策邏輯合理
- 分析邊界案例和失敗案例,找出潛在改進點
- 評估模型是否仍然符合業務需求
在機器學習系統中,佈署只是開始,有效的監控是確保模型持續產生價值的關鍵。Seldon Core透過整合Alibi:Explain和Alibi:Detect,提供了強大的工具來實作模型解釋性和監控。
透過案例分析,我們看到了如何解釋情感分析模型和收入預測模型的決策過程。這些解釋不僅有助於理解模型行為,還能識別潛在的偏見和改進點。
隨著機器學習系統變得越來越複雜和廣泛應用,模型監控和解釋性將變得更加重要。採用本文介紹的技術和策略,可以幫助資料科學家和工程師構建更透明、更可靠的機器學習系統,最終為使用者和業務創造更大的價值。
機器學習模型推論系統的進化之路
在機器學習模型從開發到生產環境的過程中,推論系統扮演著至關重要的角色。當我們需要將訓練好的模型佈署到實際應用環境中,選擇合適的推論框架便成為決定系統整體效能、可靠性和可擴充套件性的關鍵因素。本文將探討兩個主流的推論系統:Seldon Core和KFServing,分析它們的核心功能、架構特點和適用場景。
模型解釋與關鍵特徵識別
在深入推論系統之前,讓我們先了解模型解釋的重要性。以低收入分類別模型為例,當輸入特徵為「婚姻狀況 = 未婚」、「職業 = 行政」和「關係 = 非家庭成員」時,模型有97%的可能性預測為低收入分類別。這種特徵影響力的識別對於理解模型決策至關重要。
Seldon Core:靈活的推論圖架構
異常與漂移檢測的重要性
機器學習模型通常難以對訓練資料分佈之外的資料進行準確推斷,這直接影響了模型漂移問題。要確保模型預測的可靠性和可行性,必須透過不同型別的檢測器監控傳入請求的分佈。
Seldon Core提供了三種主要的檢測機制:
- 異常檢測器:標記不符合原始訓練分佈的個別例項
- 對抗性檢測器:識別並修正精心設計的攻擊,這些攻擊旨在欺騙模型
- 漂移檢測器:檢查傳入請求的分佈是否偏離參考分佈(如訓練資料)
當資料漂移發生時,模型效能可能會惡化,此時應該重新訓練模型。被任何檢測器標記的例項在實際應用中使用前應進行驗證。檢測器通常在例項甚至特徵級別回傳異常分數,若分數超過預定閾值,該例項將被標記。
非同步檢測架構
異常和漂移檢測通常與實際預測請求非同步進行。在Seldon Core中,可以啟用有效載荷日誌記錄,並將請求傳送到外部服務,在主要請求/回應流程之外進行異常和漂移檢測。
上圖展示了一個範例架構,Seldon Core的有效載荷記錄器將請求傳遞給非同步處理這些請求的元件。處理和警示的元件透過Knative Eventing管理,這提供了事件源和事件消費者的後期繫結,實作非同步處理。結果可以傳遞給警示系統。
在實際應用中,我發現這種架構特別適合處理高流量的推論服務,因為它將監控與核心推論邏輯分離,避免了監控邏輯對主要服務效能的影響。
Seldon Core的綜合評估
作為推論解決方案,Seldon Core在構建推論圖並同時實作模型服務、監控和更新保證方面表現出色。它有效彌補了TensorFlow Serving的大部分缺口,同時使資料科學家能夠隨著使用案例變得更加複雜而有機地擴充套件他們的推論圖。
模型服務能力
Seldon Core提供了擴充套件推論圖並以一流方式支援高階ML洞察的功能。其架構也足夠靈活,可以利用其管理產品之外的其他高階ML洞察。Seldon Core非常通用,提供了預期的服務靈活性,因為它與框架無關。它支援REST和gRPC,以及GPU加速。它還可以使用Knative Eventing介面流式輸入。
然而,由於SeldonDeployment作為裸Kubernetes佈署執行,它不提供GPU自動擴充套件,這是我們從硬體不可知的自動擴充套件中期望的功能。
模型監控能力
Seldon Core似乎滿足了所有模型監控需求。其佈署策略也使用Kubeflow的基礎架構堆積積堆積疊,因此它利用了微服務方法。這在Seldon Core的直譯器和檢測器中特別明顯,它們在靈活的推論圖中表示為單獨的微服務。Seldon Core透過支援Prometheus和Zipkin使監控成為一流,啟用監控、日誌記錄和跟蹤。
模型更新能力
Seldon Core在支援各種佈署策略方面很先進,包括金絲雀、固定甚至多臂老虎機。然而,與TensorFlow Serving類別似,修訂或版本管理不是以一流方式管理的。這再次意味著版本提升沒有安全回復保證。最後,從圖推理的可用選項可以看出,Seldon Core提供了完全的靈活性,可以擴充套件推論圖以支援更複雜的佈署策略。