模型上線後,監控模型效能對於維持機器學習系統的穩定性至關重要。除了監控預測服務本身,還需關注模型漂移,即知識領域分佈變化導致模型效能下降。指標收集和品質門檻設定是工程師可著力之處,透過現有遙測和日誌系統收集預測追蹤、預測日期、模型版本、觀察值及觀察率等指標,並與資料科學家合作建立模型品質門檻,自動化故障排除步驟。此外,管理後設資料和工件對於模型可重現性與實驗比較至關重要,良好的後設資料管理系統應包含工件儲存、後設資料儲存以及兩者之間的關聯。開源工具如 ML Metadata 和 MLflow 提供了便捷的後設資料管理方案。中繼資料在深度學習中扮演關鍵角色,涵蓋模型訓練執行、一般成品、模型檔案和協調流程等類別,有助於模型故障排除、比較和重現。設計良好的中繼資料和成品儲存系統應具備顯示模型沿襲和版本控制、易於存取封裝模型以及視覺化模型訓練追蹤和比較等功能,以提升模型開發和維護效率。
模型上線後的監控
相較於監控其他服務(如資料管理),機器學習系統中的工作在模型上線後並未真正結束。我們不僅需要監控和維護預測服務本身,還要關注服務所提供的模型的效能。模型漂移是指知識領域分佈的變化,它不再與訓練資料集相匹配,導致模型效能下降。這種情況可能發生在預測服務完全健康的情況下,因為模型推理與預測服務是獨立執行的。
7.6.1 指標收集和品質門檻
工程師可以發揮作用的兩個最重要的領域是模型指標收集和模型品質門檻設定。讓我們來解釋一下。
指標收集
為了進行分析以檢測模型漂移,資料科學家需要資料來進行分析,而工程師可以找到方法來提供必要的資料(指標)。儘管工程師需要建立一個單獨的資料管道來收集模型效能指標,但在大多數情況下,這樣做有些過度。通常,模型效能指標可以透過現有的遙測系統(如 Datadog)和日誌系統(如 Sumo 和 Splunk)進行收集和視覺化。因此,與其投入大量精力構建新的指標系統,不如充分利用現有的日誌和指標系統。
品質門檻設定
工程師還可以幫助建立模型品質門檻。工程師可以與資料科學家合作,自動化他們的故障排除步驟,例如檢查資料品質和生成模型推理分析報告。在給定閾值的情況下,這些檢查最終將形成模型品質門檻。
7.6.2 需要收集的指標
理論上,我們需要至少收集五種指標來支援模型效能測量。它們分別是預測追蹤、預測日期、模型版本、觀察值和觀察率及日期。讓我們逐一看看:
- 預測追蹤:我們通常透過為每個預測請求分配一個唯一的請求 ID 來跟蹤它。但是,這還不夠。對於一些複雜的場景,例如 PDF 掃描,我們將不同型別的模型預測組合在一起以產生最終結果。例如,我們首先將 PDF 檔案傳送到 OCR(光學字元識別)模型以提取文字資訊,然後將文字傳送到 NLP(自然語言處理)模型以識別目標實體。在這種情況下,除了為父預測請求分配一個唯一的請求 ID 外,我們還可以為每個子/子預測請求分配一個
groupRequestID,這樣我們就可以在故障排除時將所有相關的預測請求分組。 - 預測日期:通常,預測請求在一秒內完成。要跟蹤預測的日期,我們可以使用預測開始時間或完成時間,因為兩者差別不大。但是對於像欺詐檢測這樣的案例,預測完成時間戳可能會與預測開始時間戳有很大差異,因為它可以將多天的使用者活動作為輸入。
- 模型版本:為了將模型效能資料對映到確切的模型檔案,我們需要知道模型版本。此外,當我們組合多個模型來服務一個預測請求時,每個模型的版本都需要被記錄在日誌中。
- 觀察值:預測結果需要與預測輸入一起記錄下來,以便未來進行比較。此外,我們可以為客戶提供反饋或調查 API,以便他們報告模型效能問題。透過使用反饋 API,客戶可以報告模型 ID、預期預測結果和當前預測結果。
- 觀察日期和觀察率:很多時候,觀察值是手動收集的,因此需要記錄觀察的頻率。資料科學家需要觀察日期和觀察率來決定這些資料是否能夠在統計上代表模型的整體效能。
# 以下是一個簡單的範例程式碼,用於記錄模型的預測結果和相關資訊
import logging
from datetime import datetime
def log_prediction(model_version, request_id, input_data, prediction_result):
logging.info(f"Model Version: {model_version}")
logging.info(f"Request ID: {request_id}")
logging.info(f"Input Data: {input_data}")
logging.info(f"Prediction Result: {prediction_result}")
logging.info(f"Prediction Date: {datetime.now()}")
# 使用範例
model_version = "v1.0"
request_id = "req_12345"
input_data = "這是一個測試輸入"
prediction_result = "這是一個測試預測結果"
log_prediction(model_version, request_id, input_data, prediction_result)
內容解密:
此範例程式碼展示了一個簡單的日誌記錄功能,用於記錄模型的預測結果和相關資訊。其中包括了模型版本、請求 ID、輸入資料、預測結果和預測日期。這個功能可以用於收集上述提到的指標,例如模型版本、預測日期和觀察值等。透過這種方式,可以更方便地監控模型的效能,並檢測潛在的模型漂移問題。
圖表說明:
此圖表展示了模型的服務架構,其中前端 API 負責接收請求並將其轉發給後端的 TorchServe 或 Triton 伺服器。後端伺服器負責載入和執行模型,最終傳回預測結果。這種架構允許開發者根據需求選擇合適的後端服務,並靈活地擴充套件和維護系統。
管理後設資料與工件以提升模型可重現性與實驗比較
在深度學習專案中,資料科學家需要進行大量的實驗,以找出最佳的模型。這涉及到嘗試不同的資料集、資料處理技術和訓練演算法。在這個過程中,會產生大量的工件(artifacts)和後設資料(metadata)。工件包括資料集、模型檔案、程式碼等,而後設資料則包括模型演算法、超引數、訓練指標和模型版本等資訊。
後設資料與工件的定義
工件是指在模型訓練過程中,作為輸入或輸出的檔案和物件。它們是模型可重現性的基礎。工件可以包括原始訓練資料、標註資料集、資料處理管線的結果資料等。為了支援模型的可重現性,工件必須與描述其事實和血統的後設資料一起儲存。
後設資料是結構化的參考資料,提供有關其他資料或物件的資訊。在深度學習的背景下,後設資料包括模型演算法、超引數、訓練指標和模型版本等。
後設資料管理的重要性
後設資料管理對於模型的效能監控和實驗比較至關重要。透過儲存實驗的後設資料和工件,資料科學家可以輕鬆地選擇最佳模型,或快速找出模型效能下降的根本原因。
設計後設資料管理系統
設計一個良好的後設資料管理系統,需要考慮以下幾個方面:
- 工件儲存:工件檔案儲存在檔案伺服器或雲端儲存服務中,如 Amazon Simple Storage Service 或 Azure Blob Storage。
- 後設資料儲存:後設資料儲存在單獨的儲存服務中的後設資料儲存區。
- 關聯工件與後設資料:工件與其後設資料在後設資料儲存區中關聯,以便進行搜尋和檢索。
內容解密:
- 工件儲存:將工件儲存在檔案伺服器或雲端儲存服務中,可以確保工件的安全性和可擴充套件性。
- 後設資料儲存:使用單獨的儲存服務來儲存後設資料,可以提高後設資料的管理效率和查詢效能。
- 關聯工件與後設資料:透過在後設資料儲存區中關聯工件與其後設資料,可以實作工件的快速搜尋和檢索。
開源後設資料管理工具
有兩種開源的後設資料管理工具:ML Metadata 和 MLflow。
- ML Metadata:ML Metadata 是一個用於管理後設資料的工具,它提供了豐富的功能來儲存、查詢和管理後設資料。
- MLflow:MLflow 是一個機器學習生命週期管理工具,它提供了多種功能,包括後設資料管理、模型管理和實驗比較。
內容解密:
- ML Metadata:ML Metadata 提供了一種結構化的方式來儲存和管理後設資料,使得查詢和分析變得更加容易。
- MLflow:MLflow 提供了一種全面的方式來管理機器學習生命週期,包括後設資料管理、模型管理和實驗比較。
中繼資料與成品儲存系統在深度學習中的應用
在機器學習(ML)和深度學習領域,中繼資料(Metadata)扮演著至關重要的角色。它不僅是描述模型訓練過程、流程、模型、資料集和其他成品的資料,更是實作模型重現、比較和故障排除的關鍵。
為何需要中繼資料?
對於任何分散式系統,我們都會以日誌和指標的形式追蹤服務層級的中繼資料。例如,CPU 使用率、活躍使用者數量和失敗的 Web 請求數量等指標,對於系統監控、故障排除和觀察至關重要。在深度學習系統中,除了服務層級的指標外,我們還收集中繼資料以便於模型故障排除、比較和重現。可以將深度學習中繼資料視為日誌和指標的特殊子集,用於監控和追蹤系統中的每一個深度學習活動,包括資料解析、模型訓練和模型服務。
常見的中繼資料類別
雖然中繼資料的定義有些任意,但對於深度學習系統的工程師來說,建議將中繼資料分為以下四類別:模型訓練執行、一般成品、模型檔案和協調流程。
模型訓練執行的中繼資料
為了重現模型、分析模型效能和進行模型故障排除,我們需要追蹤模型訓練執行的所有輸入和輸出資料及成品。這包括:
- 資料集 ID 和版本:用於模型訓練的資料集唯一識別碼。
- 超引數:訓練過程中使用的超引數,例如學習率和迭代次數。
- 硬體資源:訓練過程中分配和實際使用的 CPU、GPU、TPU、記憶體和磁碟空間。
- 訓練程式碼版本:用於模型訓練的訓練程式碼快照唯一識別碼。
- 訓練程式碼組態:用於重現訓練程式碼執行環境的組態,例如 conda.yml、Dockerfile 和 requirement.txt。
- 訓練指標:顯示模型訓練進度的指標,例如每個訓練迭代的損失值。
- 模型評估指標:顯示模型效能的指標,例如 F-score 和均方根誤差(RMSE)。
# 訓練程式碼範例
import tensorflow as tf
# 定義超引數
learning_rate = 0.001
epochs = 100
# 載入資料集
dataset = tf.data.Dataset.load('dataset_id')
# 定義模型
model = tf.keras.models.Sequential([...])
# 編譯模型
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate), loss='mean_squared_error')
# 訓練模型
history = model.fit(dataset, epochs=epochs)
#### 內容解密:
1. `learning_rate` 和 `epochs` 是超引數,分別控制模型的學習率和訓練迭代次數。
2. `dataset` 是載入的資料集,用於模型的訓練。
3. `model.compile` 方法定義了模型的最佳化器和損失函式。
4. `model.fit` 方法啟動模型的訓練過程,並記錄訓練歷史。
一般成品的中繼資料
成品可以是任意檔案,例如資料集、模型和預測結果。為了能在成品儲存中找到成品,我們需要追蹤以下中繼資料:
- 檔案位置:成品儲存的路徑,例如 Amazon S3 檔案路徑或內部檔案系統路徑。
- 檔案版本:用於區分不同檔案更新的唯一識別碼。
- 描述:描述成品檔案內容的額外資訊。
- 稽核歷史:關於誰建立了成品版本、何時建立以及如何建立的資訊。
模型檔案的中繼資料
模型是一種特殊的成品,由於它是每個深度學習系統的主要產物,因此建議將模型中繼資料與其他成品分開追蹤。定義模型中繼資料時,最好考慮兩個角度:模型訓練和模型服務。
對於模型訓練,為了實作模型的血統追蹤,我們需要保持模型與產生它的模型訓練執行之間的對映關係。對於模型服務,我們需要追蹤模型的執行資料,以便於未來的模型效能分析。
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 模型檔案的中繼資料
rectangle "Produces" as node1
rectangle "Stored In" as node2
rectangle "Metadata" as node3
node1 --> node2
node2 --> node3
@enduml
此圖示顯示了模型訓練、模型檔案和模型中繼資料之間的關係。
流程的中繼資料
當我們想要自動化多步驟的模型訓練任務時,需要使用流程或工作流程。對於流程中繼資料,我們通常追蹤流程執行歷史和流程輸入輸出,這些資料可以為未來的故障排除提供稽核資訊。
為什麼需要管理中繼資料?
由於中繼資料通常以日誌或指標的形式被檢測或記錄,因此可能會疑惑為什麼需要單獨管理深度學習中繼資料。難道不能直接從日誌檔案中擷取深度學習中繼資料嗎?
事實上,擁有一個專門用於管理深度學習系統中的中繼資料的元件是非常必要的。透過一個真實的故事,我們可以更好地理解這一點。Julia(資料工程師)、Ravi(資料科學家)和 Jianguo(系統開發者)共同合作開發了一個用於聊天機器人應用程式的意圖分類別模型的深度學習系統。
深度學習中的中介資料管理
在專案開發和測試階段,Julia 和 Ravi 共同建立了一個實驗性的訓練流程來產生意圖模型。模型建立後,Ravi 將其傳遞給 Jianguo,以便將實驗模型佈署到預測服務並使用真實的客戶請求進行測試。
當 Ravi 對實驗結果感到滿意時,他會將訓練演算法從實驗流程提升到自動化的生產訓練流程。該流程在生產環境中執行,並以客戶資料作為輸入來產生意圖模型。同時,該流程也會自動將模型佈署到預測服務。圖 8.2 說明瞭整個故事的背景。
幾週後,Ravi 發布了最新的意圖分類別演算法後,一家名為 BestFood Inc. 的聊天機器人客戶向 Ravi 報告了模型效能下降的問題。在調查請求中,BestFood 提到在使用新資料集後,他們的機器人的意圖分類別準確度下降了 10%。
為了排查報告的模型效能下降問題,Ravi 需要驗證大量資訊。首先,他需要檢查目前在預測服務中被 BestFood 使用的模型版本,然後檢查當前模型的沿襲,例如在訓練流程中使用的資料集版本和程式碼版本。之後,Ravi 可能還需要重現模型以進行本地除錯。他需要比較當前模型和之前的模型,以測試資料分佈的影響(當前新資料集與之前的資料集)。
Ravi 是一位自然語言處理(NLP)專家,但他對其訓練程式碼執行的深度學習系統知之甚少。為了繼續他的調查,他不得不請 Jianguo 和 Julia 提供相關的模型、資料集和程式碼資訊。由於每個人對模型訓練應用程式和底層深度學習系統/基礎設施只有片段的知識,因此對於每次模型效能排查,Ravi、Julia 和 Jianguo 都必須共同合作以掌握完整的背景,這既耗時又低效。
這個故事當然是過於簡化了。在實踐中,深度學習專案開發是由資料、演算法、系統/執行時開發和硬體管理組成的。整個專案由不同的團隊擁有,很少有人知道一切。在企業環境中,依靠跨團隊協作來排查與模型相關的問題是不現實的。
圖 8.2 中缺少的關鍵因素是一種在集中位置搜尋和連線深度學習中介資料的有效方法,以便 Julia、Ravi 和 Jianguo 可以輕鬆獲得模型中介資料。在圖 8.3 中,我們增加了缺失的部分——中介資料和成品儲存(中間的灰色框)——以提高可除錯性。
中介資料和成品儲存的設計
如果你將圖 8.3 與圖 8.2 進行比較,你會看到在圖 8.3 的中間引入了一個新的元件(中介資料和成品儲存)。我們在第 8.2.1 節中描述的所有深度學習中介資料,無論是來自實驗流程還是生產流程,都被收集並儲存在這個中介資料儲存中。
中介資料儲存為深度學習系統中的每項資料科學活動提供了中介資料的整體檢視。模型、流程/訓練執行和成品的中介資料不僅被儲存,而且在該儲存中相互關聯,因此人們可以輕鬆獲得相關資訊。例如,由於模型檔案和模型訓練執行在儲存中是連結的,因此人們可以輕鬆確定給定模型的沿襲。
現在,資料科學家 Ravi 可以使用中介資料儲存 UI 列出系統中的所有模型和訓練執行。然後,他可以深入到中介資料儲存中,以查詢過去訓練執行中使用的輸入引數、資料集和訓練指標,這些對於評估模型非常有幫助。更重要的是,Ravi 可以快速、完整地檢索中介資料,而無需瞭解模型訓練和服務的底層基礎設施。
設計原則
中介資料和成品儲存的設計目的是為了促進模型效能排查和實驗比較。它儲存了各種中介資料,並將其圍繞模型和訓練執行進行聚合,以便資料科學家可以快速獲得任意模型的相關模型沿襲和模型訓練中介資料。一個好的中介資料儲存應該滿足以下四個原則。
原則 1:顯示模型沿襲和版本控制
當接收到一個模型名稱時,中介資料儲存應該能夠確定該模型的版本以及每個模型版本的沿襲,例如哪個訓練執行產生了該模型,以及輸入引數和資料集是什麼。模型版本和沿襲對於模型排查至關重要。當客戶報告模型問題時,例如模型效能下降,我們首先要問的問題是:什麼時候產生了該模型?訓練資料集是否已更改?使用了哪個版本的訓練程式碼?在哪裡可以找到訓練指標?我們可以在模型沿襲資料中找到所有這些答案。
設計後設資料與工件儲存系統:實作深度學習模型的追蹤與重現
在深度學習系統的開發過程中,模型的訓練、評估和佈署涉及大量的後設資料和工件(artifacts),如訓練引數、模型評估指標、模型檔案等。為了實作模型的追蹤、重現和比較,需要設計一個後設資料和工件儲存系統。
後設資料儲存系統的設計原則
- 實作模型重現:儲存模型訓練所需的後設資料,如訓練組態、輸入資料集和演算法程式碼版本,以實作模型的重現。
- 易於存取封裝模型:提供簡單的方式讓資料科學家存取模型檔案,無需瞭解複雜的後端系統。
- 視覺化模型訓練追蹤和比較:提供視覺化工具,以方便資料科學家比較和分析模型實驗結果。
後設資料儲存系統的設計方案
根據上述設計原則,提出了一個通用的後設資料和工件儲存系統設計方案,如圖8.4所示。該系統由四個元件組成:客戶端SDK、Web伺服器、後端儲存和Web UI。
後設資料儲存架構
- 客戶端SDK:提供給深度學習工作流程中的每個元件和步驟,用於向後設資料儲存系統傳送後設資料。
- Web伺服器:提供RESTful介面,用於後設資料的接收和查詢。
- 後端儲存:儲存後設資料和工件,支援不同的儲存後端,如雲端物件儲存、本地檔案和SQL伺服器。
- Web UI:視覺化後設資料儲存系統的RESTful介面,提供後設資料查詢、模型效能指標視覺化和不同模型訓練執行之間的比較。
後設資料儲存模式
後設資料儲存模式定義了後設資料的結構和序列化方式,如圖8.5所示。該模式以模型訓練執行(Training_Runs 物件)為中心,包含以下實體:
Training_Runs:記錄模型訓練執行的詳細資訊,如執行ID、名稱、狀態、開始和結束時間等。Metrics和Parameters:分別儲存模型訓練過程中的評估指標和輸入引數。Experiments:用於組織和分組模型訓練執行,一個實驗可以包含多個訓練執行。Models:儲存模型檔案的後設資料,如模型版本、型別和階段。
這些實體之間透過關聯關係相互連線,方便進行後設資料查詢和模型訓練執行的追蹤。
實作細節
在實作上,後設資料儲存系統需要提供抽象的後設資料和工件儲存層,以支援不同的儲存後端。同時,需要提供客戶端SDK和Web UI,以方便資料科學家使用。
程式碼範例
import sqlite3
# 連線資料函式庫
conn = sqlite3.connect('metadata.db')
cursor = conn.cursor()
# 建立Training_Runs表格
cursor.execute('''
CREATE TABLE Training_Runs (
ID INTEGER PRIMARY KEY,
Name TEXT NOT NULL,
Status TEXT NOT NULL,
Start_at TEXT NOT NULL,
End_at TEXT,
Code_Project TEXT,
Artifact_URI TEXT,
Experiment_ID INTEGER
)
''')
# 建立Metrics表格
cursor.execute('''
CREATE TABLE Metrics (
TrainingRun_ID INTEGER NOT NULL,
Key TEXT NOT NULL,
Value REAL NOT NULL,
Timestamp TEXT NOT NULL,
PRIMARY KEY (TrainingRun_ID, Key),
FOREIGN KEY (TrainingRun_ID) REFERENCES Training_Runs(ID)
)
''')
# 插入Training_Runs資料
cursor.execute('''
INSERT INTO Training_Runs (ID, Name, Status, Start_at, End_at, Code_Project, Artifact_URI, Experiment_ID)
VALUES (1, 'Model Training 1', 'Completed', '2023-01-01 00:00:00', '2023-01-01 01:00:00', 'Project A', '/artifacts/model1', 1)
''')
# 插入Metrics資料
cursor.execute('''
INSERT INTO Metrics (TrainingRun_ID, Key, Value, Timestamp)
VALUES (1, 'Accuracy', 0.9, '2023-01-01 00:30:00')
''')
# 提交變更並關閉連線
conn.commit()
conn.close()
內容解密:
- 建立資料函式庫連線:使用
sqlite3模組連線到SQLite資料函式庫。 - 建立表格:使用SQL陳述式建立
Training_Runs和Metrics表格,定義欄位及其資料型別。 - 插入資料:使用SQL陳述式向
Training_Runs和Metrics表格插入範例資料。 - 提交變更並關閉連線:使用
commit()方法提交變更,並使用close()方法關閉資料函式庫連線。