深度學習系統設計需考量多個導向,包含系統需求、資源限制及可擴充套件性。一個好的設計應能滿足多數需求,並具備靈活性以適應未來變化。本文參考典型深度學習系統架構,闡述其核心元件,如應用程式介面(API)、資料集管理器、模型訓練器、模型服務、後設資料和成品儲存、工作流程協調,以及互動式資料科學環境。API 作為系統入口點,支援多種使用者角色和應用程式。資料集管理器負責資料的收集、組織、描述和儲存,與資料收集器和工作流程協調服務緊密互動。模型訓練器提供計算資源,執行模型訓練程式碼,並將模型上傳至後設資料和成品儲存。模型服務則負責模型佈署和提供預測服務。後設資料和成品儲存追蹤各個實體之間的關係,包含模型、程式碼、資料集等。工作流程協調自動化執行計算任務,例如模型訓練、資料處理等。互動式資料科學環境提供安全的遠端環境,供資料科學家進行資料探索、模型原型設計和故障排除。
深度學習系統設計概述
在設計深度學習系統時,需要考慮多個因素,如系統需求、限制條件和可擴充套件性。一個好的設計應該能夠滿足盡可能多的需求,並且具有足夠的靈活性來適應未來的變化。
參考系統架構
圖1.3展示了一個典型的深度學習系統的高層次概述。該系統有兩個主要部分:應用程式介面(API)和系統元件集合。API是系統的入口點,而系統元件集合則包括了多個矩形框所代表的元件。
系統元件
- API(框A):系統的入口點,支援多種使用者角色和應用程式。
- 資料集管理器(框B):負責收集、組織、描述和儲存資料。
- 模型訓練器(框C):用於訓練深度學習模型。
- 模型服務(框D):負責佈署和提供模型服務。
- 後設資料和工件儲存(框E):儲存模型的後設資料和工件。
- 工作流程協調(框F):協調和管理深度學習工作流程。
- 互動式資料科學環境(框G):提供互動式環境供資料科學家使用。
關鍵元件
應用程式介面
API是系統的入口點,需要支援多種使用者角色和應用程式。可以透過多種方式實作API,例如使用API閘道器或直接與每個元件互動。
資料集管理器
資料集管理器是深度學習系統的核心元件,負責收集、組織、描述和儲存資料。它與其他元件有多個關係,例如:
- 資料收集器將原始資料推播到資料集管理器以建立或更新資料集。
- 工作流程協調服務執行資料處理管線,從資料集管理器中提取資料以增強訓練資料集或轉換資料格式,並將結果推回。
內容解密:
此圖示展示了資料集管理器與其他元件之間的關係。資料收集器將原始資料推播到資料集管理器,而工作流程協調服務則執行資料處理管線並與資料集管理器互動。
深度學習系統設計概述
在深度學習系統中,資料科學家、研究人員和資料工程師使用 Jupyter Notebook(圖1.3中的G框)從資料管理器提取資料進行探索和檢查。模型訓練服務(圖1.3中的C框)則從資料管理器提取訓練資料進行模型訓練。
模型訓練器
模型訓練器(亦稱為模型訓練服務;圖1.3中的C框)負責提供基礎計算資源,如CPU、RAM和GPU,以及作業管理邏輯,以執行模型訓練程式碼並產生模型檔案。在圖1.3中,我們可以看到工作流程協調服務(圖1.3中的F框)指示模型訓練器執行模型訓練程式碼。訓練器從資料集管理器(圖1.3中的B框)取得輸入訓練資料並產生模型。然後,它將模型與訓練指標和後設資料上傳到後設資料和成品儲存(圖1.3中的E框)。
內容解密:
- 提供基礎計算資源:模型訓練器需要具備足夠的計算能力來處理大量的資料和複雜的模型架構。
- 作業管理邏輯:這涉及到管理工作流程中的任務排程和資源分配,以確保模型訓練的高效進行。
- 執行模型訓練程式碼:這是模型訓練的核心步驟,需要根據特定的演算法和框架來執行訓練過程。
- 產生模型檔案:訓練完成後,模型訓練器會輸出模型檔案,這些檔案將用於後續的預測和評估。
要生成高品質的深度學習模型,通常需要在大型資料集上執行密集的計算。採用新的演算法和訓練函式庫/框架也是關鍵要求。這些要求在多個層面上帶來了挑戰:
- 減少模型訓練時間的能力:儘管訓練資料的大小和模型架構的複雜性不斷增長,訓練系統仍必須保持合理的訓練時間。
- 水平擴充套件能力:一個有效的生產訓練系統應該能夠同時支援來自不同應用程式和使用者的多個訓練請求。
- 採用新技術的成本:深度學習社群非常活躍,不斷更新和改進演算法和工具(SDK、框架)。訓練系統應該足夠靈活,以便在不幹擾現有工作負載的情況下輕鬆適應新的創新。
模型服務
模型可以用於各種場景,例如用於即時預測的線上推斷或用於大批次輸入資料的離線推斷。這就是模型服務出現的地方——當一個系統託管模型,接收輸入預測請求,執行模型預測,並將預測結果傳回給使用者。有幾個關鍵問題需要回答:
- 推斷請求是否來自網路? 或者它們是否來自需要本地服務的感測器?
- 可接受的延遲是多少? 推斷請求是臨時的還是流式的?
- 有多少個模型正在被服務? 每個模型是否單獨服務一種推斷請求,還是多個模型的集合來提供服務?
- 模型的規模有多大? 需要多少記憶體容量?
- 需要支援哪些模型架構? 是否需要GPU?需要多少計算資源來產生推斷?是否有其他支援服務元件——例如嵌入、正規化、聚合等?
- 是否有足夠的資源讓模型保持線上? 或者是否需要交換策略(例如在記憶體和磁碟之間移動模型)?
內容解密:
- 推斷請求來源:瞭解推斷請求的來源有助於設計合適的服務架構。
- 可接受的延遲:不同的應用對延遲有不同的要求,這影響了服務設計。
- 模型數量和規模:這決定了所需的資源和服務策略。
- 計算資源需求:根據模型架構和大小,可能需要特定的硬體資源,如GPU。
後設資料和成品儲存
在一個支援多種型別使用者、多個資料集、程式碼和模型的深度學習系統中,需要一個元件來跟蹤各個實體之間的關係。後設資料和成品儲存正是這樣一個元件。成品包括訓練模型的程式碼和產生推斷的程式碼,以及任何生成的資料,如訓練好的模型、推斷結果和指標。後設資料是描述成品或成品之間關係的任何資料。
內容解密:
- 跟蹤關係:後設資料和成品儲存幫助管理不同實體之間的複雜關係。
- 成品和後設資料的例子:包括訓練程式碼的作者和版本、輸入訓練資料集的參考、訓練好的模型的訓練指標等。
此圖示展示了深度學習系統中各個元件之間的互動關係,包括資料管理器、模型訓練服務、工作流程協調服務、模型服務以及後設資料和成品儲存。
內容解密:
- 元件互動:圖表展示了各個元件如何協同工作來完成深度學習任務。
- 工作流程:從資料提取到模型訓練,再到模型服務,每一步都涉及多個元件的互動。
深度學習系統設計概述
在深度學習系統中,後設資料和工件儲存(Metadata and Artifacts Store)扮演著至關重要的角色。它負責追蹤和管理系統中的各種後設資料和工件,例如:
- 模型特定的指標,如模型版本、模型血統(用於訓練的資料和程式碼)以及效能指標
- 生成特定推斷的模型、請求和推斷程式碼
- 工作流程歷史,追蹤模型訓練和資料處理管道執行的每個步驟
這些只是後設資料和工件儲存函式庫可以幫助追蹤的幾個例子。您應該根據團隊或組織的需求定製此元件。
在圖1.3中,其他生成後設資料和工件的元件都會流入後設資料和工件儲存函式庫(E框)。該儲存函式庫在模型服務中也發揮著重要作用,因為它為模型服務(D框)提供模型檔案及其後設資料。雖然圖中未顯示,但通常在使用者介面層構建自定義工具,用於追蹤血統和故障排除,這些工具由後設資料和工件儲存函式庫提供支援。
工作流程協調
工作流程協調(圖1.3,F框)在許多系統中無處不在,它幫助自動啟動由程式條件觸發的計算任務。在機器學習系統的背景下,工作流程協調是深度學習系統中所有自動化的驅動力。它允許人們定義工作流程或管道——有向無環圖(DAG)——將個別任務按照執行順序連線起來。工作流程協調元件負責協調這些工作流程的任務執行。一些典型的例子包括:
- 當新的資料集構建完成時啟動模型訓練
- 監控上游資料來源,增強新資料,轉換其格式,通知外部標註者,並將新資料合併到現有資料集中
- 如果訓練後的模型透過某些接受標準,則將其佈署到模型伺服器
- 不斷監控模型效能指標,並在檢測到效能下降時提醒開發人員
互動式資料科學環境
出於合規性和安全原因,客戶資料和模型不能從生產環境下載到本地工作站。為了讓資料科學家能夠互動式地探索資料、故障排除工作流程協調中的管道執行並除錯模型,需要在深度學習系統內部設定遠端互動式資料科學環境(圖1.3,G框)。
公司通常透過使用開源Jupyter Notebooks(https://jupyter.org/)或利用雲端供應商的根據JupyterLab的解決方案(如Amazon SageMaker Studio,https://aws.amazon.com/sagemaker/studio/)來建立自己的受信任資料科學環境。
典型的互動式資料科學環境應提供以下功能:
- 資料探索——為資料科學家提供對客戶資料的安全存取,同時保持資料的安全和合規;不會發生資料洩漏,且任何未經授權的資料存取都將被拒絕。
- 模型原型設計——為資料科學家提供必要的工具,以便在深度學習系統內部快速開發POC模型。
- 故障排除——使工程師能夠除錯深度學習系統內發生的任何活動,例如下載模型並分析其行為,或檢查失敗管道中的所有輸入/輸出工件(中間資料集或組態)。
關鍵使用者場景
為了更好地理解深度學習系統如何在開發週期(圖1.1)中使用,我們準備了一些示例場景來說明它們如何被使用。讓我們從程式化消費者開始,如圖1.4所示。推播資料到系統的資料收集器通常會透過API到達資料管理服務,該服務收集和組織原始資料以進行模型訓練。
深度學習應用程式通常會呼叫模型推斷服務以從訓練後的模型中取得推斷結果,這些結果用於為終端使用者提供深度學習功能。圖1.5顯示了這種互動的順序。指令碼或甚至成熟的管理服務也可以是程式化消費者。由於它們是可選的,為了簡單起見,我們在圖中省略了它們。
程式化消費者場景
此圖示展示了資料如何從源或收集器推播,透過API到達資料管理服務,以及深度學習應用如何透過API請求推斷結果並獲得傳回的推斷結果。
研究人員使用場景
研究人員可以使用系統來查詢可用的資料,以嘗試新的建模技術。他們存取使用者介面並存取資料探索和視覺化部分,該部分從資料管理服務中提取資料。可能涉及大量手動資料處理,以將其轉換為可以被新的訓練技術使用的形式。一旦研究人員確定了技術,他們就可以將其封裝為函式庫,供他人使用。
此圖示展示了研究人員如何透過使用者介面存取資料管理服務以檢索資料。
內容解密:
- 深度學習系統的核心元件:本章節介紹了深度學習系統設計中的幾個關鍵元件,包括後設資料和工件儲存、工作流程協調以及互動式資料科學環境。
- 後設資料和工件儲存的重要性:它負責追蹤和管理系統中的各種後設資料和工件,如模型版本、效能指標等,對模型的開發和維護至關重要。
- 工作流程協調的作用:自動化了模型的訓練、佈署等過程,提高了開發效率,並能及時監控模型效能。
- 互動式資料科學環境的功能:允許資料科學家在安全可控的環境中探索資料、開發模型原型以及進行故障排除。
- 關鍵使用者場景的介紹:透過具體的使用場景展示了深度學習系統如何支援不同使用者(如研究人員、資料科學家)的需求。
- Plantuml圖表的使用:透過視覺化的方式展示了不同元件之間的互動流程,使得複雜的技術概念更容易被理解。
內容解密:
本章節對深度學習系統設計的核心概念進行了解密,主要包括以下幾個方面:
- 後設資料和工件儲存:負責儲存模型的相關資訊,如版本、血統等,是系統的重要組成部分。
- 工作流程協調:使得自動化流程得以實作,例如自動訓練模型、監控效能等,大大提高了效率。
- 互動式環境:為開發者提供了便利,使得他們可以在受控環境中進行各種操作,如除錯、原型開發等。
- 使用者場景:描述了不同角色在使用系統時的典型操作,有助於理解系統的實際應用價值。
- 視覺化展示:利用Plantuml圖表清晰地展示了各個元件之間的關係及工作流程,提升了內容的可讀性。
1.2 深度學習系統設計概述
推導自有的設計
既然已經介紹完參考系統架構的所有方面,那麼就讓我們來討論一些自定義版本系統的指導方針。
收集目標和需求
設計任何成功的系統設計的第一步,是擁有一套明確的目標和需求。這些目標和需求最好直接或間接地來自系統的使用者,或是產品管理團隊或工程管理階層。這份簡短的目標和需求清單將幫助你形成對系統外觀的設想。而這個設想,反過來,應該是指導你在整個系統設計和開發階段的準則。
有時候,工程師被要求開發一個系統,以支援一個或多個已經存在的深度學習應用。在這種情況下,你可以先識別這些應用之間的共同需求,以及如何設計你的系統,以便快速為這些應用帶來創新。
要收集系統的目標和需求,你需要識別系統的不同型別的使用者和利益相關者,或稱為使用者角色。這是一個可以應用於大多數系統設計問題的通用概念。畢竟,是使用者將幫助你闡明系統的目標和需求。
我們的建議是,如果你不確定一個好的起點,那麼就從使用案例或應用需求開始。以下是一些你可以向使用者提出的問題範例:
- 對資料工程師和產品經理:系統是否允許應用程式收集訓練資料?系統是否需要處理串流輸入資料?正在收集多少資料?
- 對資料科學家和工程師:我們如何處理和標記資料?系統是否需要為外部供應商提供標記工具?我們如何評估模型?我們如何處理測試資料集?是否需要互動式筆記本使用者介面進行資料科學工作?
- 對研究人員和資料科學家:需要多大體積的資料進行模型訓練?模型訓練執行的平均時間是多少?研究和資料科學需要多少計算和資料容量?系統應該支援什麼樣的實驗?需要收集什麼後設資料和指標來評估不同的實驗?
- 對產品經理和軟體工程師:模型服務是在遠端伺服器還是在客戶端進行?是實時模型推斷還是離線批次預測?是否有延遲要求?
- 對產品經理:我們正在嘗試解決組織中的什麼問題?我們的商業模式是什麼?我們將如何衡量我們的實施效果?
- 對安全團隊:您的系統需要什麼級別的安全性?資料存取是否開放還是嚴格受限/隔離?是否有稽核要求?是否有系統需要達到的合規或認證級別(例如,通用資料保護法規、系統和組織控制2等)?
自定義參考架構
一旦設計需求和範圍明確,我們就可以開始自定義圖1.3中的參考架構。首先,我們可以決定是否需要新增或刪除任何元件。例如,如果需求純粹是管理遠端伺服器群中的模型訓練,我們可以刪除工作流程管理元件。如果資料科學家希望使用生產資料有效地評估模型效能,他們還可以新增實驗管理元件。此元件允許資料科學家使用系統中已經存在的全規模資料進行訓練和驗證,並對生產流量中以前未見的資料進行線上A/B測試。
第二步是根據您的具體需求設計和實作每個關鍵元件套件。根據需求,您可能會從資料集管理服務中排除資料串流API,並新增分散式訓練支援(如果訓練速度是一個問題)。您可以從頭開始構建每個關鍵元件,或使用開源軟體。在本文的其餘部分,我們將介紹每個關鍵元件的兩種選擇,以確保您知道該怎麼做。
提示:保持系統設計簡單易用。建立這樣一個大型深度學習系統的目的是提高深度學習開發的生產力,因此在設計時請牢記這一點。我們希望讓資料科學家能夠輕鬆構建高品質的模型,而無需瞭解底層系統中發生的事情。
在Kubernetes上構建元件
我們已經介紹了一系列被實作為服務的關鍵元件。有了這麼多的服務,您可能希望在基礎設施級別使用一個複雜的系統(如Kubernetes)來管理它們。
Kubernetes是一個開源系統,用於自動化佈署、擴充套件和管理容器化應用程式,這些應用程式執行在隔離的執行環境中,例如docker容器。我們已經看到許多建立在Kubernetes上的深度學習系統。有些人在不知道為什麼使用Kubernetes執行深度學習服務的情況下學會瞭如何使用它,所以我們想解釋背後的思考。如果你熟悉Kubernetes,請隨意跳過本文。
管理計算資源的挑戰
在一台遠端伺服器上執行一個docker容器似乎是一項簡單的任務,但是在30台不同的伺服器上執行200個容器就是另一回事了。有很多挑戰,例如監控所有遠端伺服器以確定在哪一台上執行容器,需要將容器容錯移轉到健康的伺服器,在容器卡住時重新啟動它,跟蹤每個容器的執行並在完成時收到通知等。為了應對這些挑戰,我們必須監控硬體、OS程式、容器執行狀態等。
圖表說明
此圖示展示了深度學習系統中資料科學家定義模型訓練工作流程、執行它並檢視結果的使用順序。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title 深度學習系統設計核心元件與實務應用
package "Kubernetes Cluster" {
package "Control Plane" {
component [API Server] as api
component [Controller Manager] as cm
component [Scheduler] as sched
database [etcd] as etcd
}
package "Worker Nodes" {
component [Kubelet] as kubelet
component [Kube-proxy] as proxy
package "Pods" {
component [Container 1] as c1
component [Container 2] as c2
}
}
}
api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2
note right of api
核心 API 入口
所有操作經由此處
end note
@enduml
此圖示呈現了深度學習系統中的不同元件之間的互動關係,包括資料管理服務、工作流程管理服務、模型訓練服務、後設資料和工件儲存等。透過這個圖表,可以清楚地看到各個元件如何協同工作,以支援深度學習模型的開發和佈署。
內容解密:
- 圖表展示了深度學習系統中不同服務之間的互動流程。
- 資料管理服務負責提供資料給深度學習系統API。
- 工作流程管理服務定義了模型訓練的工作流程。
- 模型訓練服務負責訓練模型並將結果儲存在後設資料和工件儲存中。
- 後設資料和工件儲存提供了模型的後設資料和工件給深度學習系統API。
- 深度學習系統API將結果呈現給使用者介面,供資料科學家檢視和分析。
程式碼範例
import kubernetes
# 初始化Kubernetes客戶端
k8s_client = kubernetes.client.ApiClient()
# 定義一個Deployment物件
deployment = kubernetes.client.V1Deployment(
metadata=kubernetes.client.V1ObjectMeta(name="model-training"),
spec=kubernetes.client.V1DeploymentSpec(
replicas=3,
selector=kubernetes.client.V1LabelSelector(match_labels={"app": "model-training"}),
template=kubernetes.client.V1PodTemplateSpec(
metadata=kubernetes.client.V1ObjectMeta(labels={"app": "model-training"}),
spec=kubernetes.client.V1PodSpec(
containers=[
kubernetes.client.V1Container(
name="model-training",
image="model-training:latest"
)
]
)
)
)
)
# 建立Deployment
k8s_client.create_namespaced_deployment(namespace="default", body=deployment)
內容解密:
- 程式碼使用Kubernetes Python客戶端函式庫來與Kubernetes叢集互動。
- 定義了一個名為
model-training的Deployment物件,指定了副本數量為3。 - 使用
V1LabelSelector來選擇具有特定標籤的Pod。 - 定義了Pod範本,指定了容器名稱、映像名稱等。
- 使用
create_namespaced_deployment方法在預設名稱空間中建立Deployment。
透過這個程式碼範例,可以看到如何使用Kubernetes Python客戶端函式庫來建立和管理Deployment物件,以支援深度學習模型的訓練和佈署。