返回文章列表

深度學習訓練服務架構與Kubernetes實作

本文探討如何利用 Kubernetes 建構強健的深度學習訓練服務,涵蓋資源管理、效能監控、演算法整合以及 Kubeflow 的應用。文章詳細說明瞭如何使用 Kubernetes

深度學習 Kubernetes

Kubernetes 提供了良好的資源管理和隔離機制,讓深度學習訓練服務能更有效率地運作。透過名稱空間的劃分,不同使用者的訓練任務可以有效隔離,避免互相干擾。Kubernetes 的資源追蹤功能可以即時監控資源使用情況,動態調整資源分配,確保訓練任務的穩定執行。除了資源管理,監控也是訓練服務的重要環節。模型訓練執行指標,例如資源飽和率、任務執行時間和失敗率,可以幫助我們評估服務的健康狀況。而模型效能指標,例如損失值、準確率和 F1 分數,則可以評估模型的學習品質。為了支援新的演算法和版本,需要建立一個對映機制,將使用者的訓練請求對應到正確的訓練程式碼。可以使用資料函式庫來管理演算法名稱和程式碼的對映關係,並提供 API 讓資料科學家可以自行註冊新的訓練程式碼,而無需修改服務的 API。

深度學習訓練服務的架構與實作

在深度學習的領域中,訓練服務扮演著至關重要的角色。一個好的訓練服務能夠有效地管理資源、隔離不同使用者的訓練任務,並且提供良好的擴充套件性。在本章中,我們將探討如何使用 Kubernetes 來搭建一個強壯的訓練服務。

使用 Kubernetes 管理訓練叢集

當使用者提交訓練請求時,訓練服務首先會根據使用者的資訊找到正確的名稱空間(namespace),然後呼叫 Kubernetes 的 API 將訓練執行檔放置在該名稱空間中。由於 Kubernetes 能夠即時追蹤系統資源的使用情況,因此它能夠判斷某個名稱空間是否有足夠的容量。如果名稱空間已經滿載,Kubernetes 將會拒絕啟動新的訓練任務。

內容解密:

  • 使用 Kubernetes 管理訓練叢集可以將資源容量追蹤和資源隔離管理的責任從訓練服務中解除安裝下來。
  • Kubernetes 的即時資源追蹤功能確保了訓練任務的資源分配是動態且有效的。

故障排除與效能監控

在訓練服務中,監控是非常重要的。我們通常定義兩種型別的指標:模型訓練執行指標和模型效能指標。

模型訓練執行指標

包括資源飽和率、訓練任務的執行可用性、平均訓練任務執行時間和任務失敗率等。這些指標幫助我們確保訓練服務的健康運作。

模型效能指標

衡量模型學習的品質,包括每個訓練迭代(epoch)的損失值和評估分數,以及最終模型的評估結果,如準確率、精確率和 F1 分數等。

內容解密:

  • 模型訓練執行指標和模型效能指標對於監控訓練服務的健康狀態和模型品質至關重要。
  • 將這些指標儲存在一個有組織的方式中,可以方便我們搜尋資訊和比較不同訓練過程之間的效能。

支援新的演算法或版本

要將新的訓練程式碼加入我們的訓練服務中,我們需要定義一個正式的合約,將使用者的訓練請求對映到實際的訓練程式碼上。一個簡單的方法是使用資料函式庫來管理演算法名稱和訓練程式碼之間的對映關係,並提供 API 來管理這種對映。

內容解密:

  • 定義一個清晰的對映機制可以讓資料科學家以自助的方式註冊新的訓練程式碼。
  • 提供 API 如 createAlgorithmMappingupdateAlgorithmVersion 可以讓資料科學家新增或更新演算法,而不需要修改服務的公眾 API。

Kubeflow 訓練運算元:開源方案

Kubeflow 是一個成熟的開源機器學習系統,適用於生產環境。它提供了高品質、可擴充套件和穩健的訓練服務。Kubeflow 訓練運算元可以直接在任何 Kubernetes 叢集上設定和使用。

內容解密:

  • Kubeflow 提供了一個完整的機器學習功能集合,從筆記本和管道到訓練和服務。
  • 使用 Kubeflow 可以讓你的深度學習系統具備更好的擴充套件性和穩定性。

Kubeflow 訓練運算元:開源模型的實踐方法

Kubeflow 提供了一系列訓練運算元,如 TensorFlow 運算元、PyTorch 運算元、MXNet 運算元及 MPI 運算元。這些運算元涵蓋了主要的訓練框架,每個運算元都具備啟動和監控特定訓練框架所寫的訓練程式碼(容器)的能力。

為何選擇 Kubeflow 訓練運算元?

如果你計劃在 Kubernetes 叢集中執行模型訓練,並希望建立自己的訓練服務以降低營運成本,那麼 Kubeflow 訓練運算元是理想的選擇。以下是三個主要原因:

  1. 易於安裝和維護:Kubeflow 運算元開箱即用,只需執行幾行 Kubernetes 命令即可在叢集中執行。
  2. 相容多數訓練演算法和框架:只要將訓練程式碼容器化,就可以使用 Kubeflow 運算元執行。
  3. 易於與現有系統整合:由於 Kubeflow 訓練運算元遵循 Kubernetes 運算元的設計模式,因此可以使用 Kubernetes 的宣告式 HTTP API 提交訓練任務請求並檢查任務執行狀態和結果。同時,也可以使用 RESTful 查詢與這些運算元互動。

Kubernetes 運算元/控制器模式

Kubeflow 訓練運算元遵循 Kubernetes 運算元(控制器)設計模式。瞭解這一模式後,執行 Kubeflow 訓練運算元和閱讀其原始碼將變得簡單明瞭。圖 3.11 說明瞭控制器模式的設計圖。

圖 3.11:Kubernetes 運算元/控制器模式

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 圖 3.11:Kubernetes 運算元/控制器模式

rectangle "控制迴路" as node1
rectangle "實際資源" as node2

node1 --> node2

@enduml

此圖示展示了 Kubernetes 運算元/控制器模式如何透過無限控制迴路觀察特定 Kubernetes 資源的實際狀態和期望狀態,並嘗試將實際狀態轉變為期望狀態。

Kubeflow 訓練運算元的設計

Kubeflow 訓練運算元(TensorFlow 運算元、PyTorch 運算元、MPI 運算元)遵循 Kubernetes 運算元的設計。每個訓練運算元監視其自己的客戶資源定義物件(如 TFJob、PyTorchJob 和 MPIJob),並建立實際的 Kubernetes 資源來執行訓練。

圖 3.12:Kubeflow 訓練運算元的工作流程

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 圖 3.12:Kubeflow 訓練運算元的工作流程

rectangle "建立 TFJob CRD 物件" as node1
rectangle "檢測 TFJob CRD 物件" as node2
rectangle "執行 TensorFlow 訓練映象" as node3
rectangle "更新 TFJob CRD 物件狀態" as node4
rectangle "相同的流程處理 PyTorchJob CRD 物件" as node5

node1 --> node2
node2 --> node3
node3 --> node4
node4 --> node5

@enduml

#### 內容解密:

圖3.12展示了Kubeflow訓練運算元的工作流程。首先,使用者建立一個定義了訓練請求的TFJob CRD物件。然後,TensorFlow運算元檢測到這個物件並建立實際的Pod來執行TensorFlow訓練映象。同時,TensorFlow運算元也會監控Pod的狀態並更新其狀態到TFJob CRD物件中。同樣的流程也適用於PyTorch運算元處理PyTorchJob CRD物件。

每個 Kubeflow 運算元還處理任務佇列管理。由於 Kubeflow 運算元遵循 Kubernetes 運算元的模式,並在 Pod 級別建立 Kubernetes 資源,因此訓練 Pod 的容錯移轉得到了很好的處理。

#### 內容解密:

Kubeflow運算元的設計允許每個運算元執行其特定訓練框架的訓練Pod。例如,TensorFlow運算元知道如何為使用TensorFlow編寫的訓練程式碼設定分散式訓練Pod群組。該運算元從CRD定義中讀取使用者請求,建立訓練Pod,並將正確的環境變數和命令列引數傳遞給每個訓練Pod/容器。您可以檢視每個運算元的reconcileJobsreconcilePods函式以取得更多細節。

使用 Kubeflow 訓練運算元:開放原始碼的實踐方法

在 Kubernetes 環境中進行深度學習模型訓練時,Kubeflow 訓練運算元提供了一個強大且靈活的解決方案。本文將探討 Kubeflow 訓練運算元的工作原理、使用方法,以及如何將其整合到現有的深度學習系統中。

Kubeflow 訓練運算元的工作原理

Kubeflow 訓練運算元是一種 Kubernetes 自訂資源定義(CRD),旨在簡化深度學習模型訓練的工作流程。它透過監控 CRD 物件的狀態,並根據定義的規格自動建立和管理訓練任務的 Pod,從而實作訓練任務的自動化和高用性。

主要元件與工作流程

  1. CRD 物件:使用者透過定義 CRD 物件(如 PyTorchJob)來描述訓練任務的規格,包括使用的框架、副本數量、重啟策略等。
  2. 訓練運算元:監控 CRD 物件的變化,並根據定義的規格建立和管理訓練任務的 Pod。
  3. Pod:執行實際的訓練任務,根據 CRD 物件中的定義進行組態。

如何使用 Kubeflow 訓練運算元

以下以 PyTorch 運算元為例,介紹使用 Kubeflow 訓練運算元的四個步驟:

  1. 安裝 PyTorch 運算元和 PyTorchJob CRD:首先需要在 Kubernetes 叢集中安裝 PyTorch 運算元和 PyTorchJob CRD。可以參考 PyTorch 運算元的 Git 倉函式庫中的開發者。

    $ kubectl get crd
    NAME                  CREATED AT
    ...
    pytorchjobs.kubeflow.org   2021-09-15T18:33:58Z
    ...
    
  2. 更新訓練容器:修改訓練容器,使其能夠從環境變數和命令列引數中讀取引數輸入。

  3. 建立 PyTorchJob CRD 物件:編寫一個 YAML 檔案(如 pytorchCRD.yaml)來定義 PyTorchJob CRD 物件,然後使用 kubectl create -f pytorchCRD.yaml 命令建立該物件。

    apiVersion: kubeflow.org/v1
    kind: PyTorchJob
    metadata:
      name: pytorch-demo
    spec:
      pytorchReplicaSpecs:
        Master:
          replicas: 1
          restartPolicy: OnFailure
          containers:
          - name: pytorch
            image: pytorch-image
            env:
            - name: credentials
              value: "/etc/secrets/user-gcp-sa.json"
            command:
            - "python3"
            - "-m"
            - "/opt/pytorch-mnist/mnist.py"
            - "--epochs=20"
            - "--batch_size=32"
        Worker:
          replicas: 1
          restartPolicy: OnFailure
          containers:
          - name: pytorch
            image: pytorch-image
    
  4. 監控訓練狀態:使用 kubectl get -o yaml pytorchjobs 命令查詢訓練狀態。

    $ kubectl get -o yaml pytorchjobs pytorch-demo -n kubeflow
    

程式碼解密:

  • PyTorchJob CRD 物件定義:定義了 PyTorch 訓練任務的規格,包括 Master 和 Worker 的副本數量、重啟策略、容器組態等。
  • 環境變數和命令列引數:透過環境變數和命令列引數傳遞給訓練容器,用於組態訓練任務。
  • kubectl 命令:用於建立和查詢 PyTorchJob CRD 物件,從而實作對訓練任務的管理和監控。

如何將 Kubeflow 訓練運算元整合到現有的系統中

透過構建一個包裝服務(wrapper service),可以將 Kubeflow 訓練運算元整合到現有的深度學習系統中。該包裝服務負責將訓練請求轉換為對 CRD 物件的操作,並查詢訓練狀態。

主要步驟:

  1. 構建包裝服務:開發一個包裝服務,用於管理作業佇列、轉換訓練請求為 CRD 物件,以及取得訓練狀態。
  2. 整合包裝服務:將包裝服務整合到現有的深度學習系統中,使得系統能夠透過包裝服務與 Kubeflow 訓練運算元互動。

何時使用公有雲端服務

主要的公有雲供應商(如 Amazon、Google 和 Microsoft)提供了成熟的深度學習平台,如 Amazon SageMaker、Google Vertex AI 和 Azure Machine Learning Studio。這些平台提供了全託管的服務,支援整個機器學習工作流程。

使用公有雲端服務的優勢:

  • 全託管服務:無需自行管理基礎設施,即可進行模型訓練和佈署。
  • 完整的機器學習工作流程支援:從資料準備到模型佈署,提供一站式的解決方案。

何時使用公有雲端 AI 服務,何時自建訓練服務

在開發人工智慧(AI)與機器學習(ML)應用時,企業常面臨是否使用公有雲端 AI 服務或自建訓練服務的抉擇。公有雲端 AI 服務,如 Amazon SageMaker 和 Google Vertex AI,提供了一站式的解決方案,能夠快速建立、訓練和佈署模型。然而,這些服務是否適合每個企業,取決於多種因素,包括企業的發展階段、特定需求和成本考量。

使用公有雲端 AI 服務的時機

對於新創公司或需要快速驗證業務理念的企業,使用公有雲端 AI 平台是一個不錯的選擇。這些平台處理了底層基礎設施的管理,並提供標準的工作流程,讓企業能夠專注於開發業務邏輯、收集資料和實作模型演算法。這樣可以節省大量建立自身基礎設施的時間,從而實作「快速失敗,快速學習」。

另一個使用公有雲端 AI 平台的原因是,當企業只有少數深度學習場景,且這些場景符合公有雲的標準使用案例。在這種情況下,為了少數應用而建立複雜的深度學習系統並不划算。

自建訓練服務的時機

然而,在某些情況下,自建訓練服務是更好的選擇。如果企業有以下任何一個需求,那麼自建訓練服務是必要的:

雲端無關性

如果企業希望其應用能夠在不同的雲端基礎設施上無縫執行,那麼使用 Amazon SageMaker 或 Google Vertex AI 等雲端特定平台就不是最佳選擇。企業可能需要根據客戶的要求,將資料儲存在特定的雲端環境中。自建訓練服務可以透過使用基礎服務(如虛擬機器和儲存)並在其上構建應用邏輯來實作雲端無關性。

例如,在 Amazon Web Services(AWS)上,可以先設定一個 Kubernetes 叢集(Amazon Elastic Kubernetes Service,Amazon EKS),然後在其上構建自己的訓練服務。這樣,當需要遷移到 Google Cloud Platform(GCP)時,只需將訓練服務應用於 GCP Kubernetes 叢集(Google Kubernetes Engine),大部分服務保持不變。

降低基礎設施成本

使用雲端提供商的 AI 平台相比於自行營運服務會產生更高的費用。雖然在原型設計階段,企業可能不太關注成本,但產品發布後,成本就變得非常重要。以 Amazon SageMaker 為例,在 2022 年時,SageMaker 對 m5.2xlarge 型別機器的收費為每小時 $0.461,而直接啟動 Amazon EC2 例項(虛擬機器)則收費每小時 $0.384。透過自建訓練服務並直接在 Amazon EC2 例項上營運,可以節省近 20% 的模型構建成本。對於有多個團隊每天進行模型訓練的公司來說,自建訓練系統能夠提供競爭優勢。

自定義需求

雖然雲端 AI 平台提供了許多工作流程組態選項,但它們仍然是黑箱方法。由於它們是一體化的方法,這些 AI 平台主要關注最常見的場景。然而,企業總會有需要根據自身業務進行自定義的需求。在這種情況下,如果雲端 AI 平台提供的選擇不多,將會是一件麻煩的事。

另一個問題是,雲端 AI 平台在採用新技術方面總是存在延遲。例如,企業需要等待 SageMaker 團隊決定是否支援某種訓練方法以及何時支援,有時這個決定可能並不符合企業的需求。深度學習是一個快速發展的領域,自建訓練服務能夠幫助企業快速採用最新的研究成果,並在激烈的競爭中保持領先。

合規性審核

某些業務需要獲得符合特定法律法規的認證,例如 HIPAA(健康保險可攜性和責任法案)或 CCPA(加利福尼亞消費者隱私法案)。這些認證不僅要求企業的程式碼符合要求,還要求其執行的基礎設施符合相關規定。如果企業的應用是建立在 Amazon SageMaker 和 Google Vertex AI 平台上,那麼這些平台也需要符合相關規定。由於雲端供應商是一個黑箱,進行合規性檢查和提供證據是一項令人不愉快的任務。

身份驗證和授權

將身份驗證和授權功能整合到雲端 AI 平台和內部身份驗證服務(本地佈署)需要付出大量努力。許多公司都有自己的身份驗證服務版本,用於驗證和授權使用者請求。如果企業採用 SageMaker 作為 AI 平台,並將其暴露給不同的內部服務用於各種業務目的,那麼將 SageMaker 的身份驗證管理與內部使用者身份驗證管理服務橋接起來並不容易。相反,自建本地佈署的訓練服務要容易得多,因為可以自由更改 API,並簡單地將其整合到現有的身份驗證服務中。

總之,選擇使用公有雲端 AI 服務還是自建訓練服務取決於企業的具體需求和發展階段。對於需要快速驗證業務理念或只有少數深度學習場景的企業,公有雲端 AI 平台是一個不錯的選擇。然而,對於具有特定需求(如雲端無關性、降低成本、自定義需求、合規性審核和身份驗證授權)的企業,自建訓練服務是更好的選擇。

分散式訓練的挑戰與解決方案

在深度學習研究領域,一個明顯的趨勢是透過更大的資料集和更複雜的模型來提升模型效能。然而,更多的資料和更大的模型會導致模型訓練過程變慢,進而拖慢模型開發的速度。為了應對日益增長的資料集和模型引數規模,研究人員開發了各種分散式訓練策略。

分散式訓練的主要型別

  1. 模型平行(Model Parallelism):將神經網路分割成多個順序子網路,每個子網路在不同的裝置(GPU 或 CPU)上執行。這種方法可以訓練大型模型,但存在一個主要問題:訓練過程中只有一個 GPU 處於活動狀態,其他 GPU 處於閒置狀態。

    # 模型平行的簡單範例
    import torch
    import torch.distributed as dist
    
    # 初始化分散式訓練
    dist.init_process_group('nccl', init_method='env://', world_size=4, rank=rank)
    
    # 定義模型並將其分割到不同裝置上
    model = MyLargeModel().to(f'cuda:{rank}')
    

    內容解密:

    • dist.init_process_group 初始化分散式訓練環境,指定後端為 NCCL,並透過環境變數進行初始化。
    • world_size 表示參與訓練的總程式數,此處為 4。
    • rank 表示當前程式的 ID,用於區分不同的 GPU。
  2. Pipeline平行(Pipeline Parallelism):是模型平行的進階版本。透過將每個訓練範例批次劃分為小的微批次,Pipeline平行可以重疊不同層之間的計算,最大化 GPU 的效能,讓不同的 GPU 同時處理不同的微批次,從而提高訓練吞吐量和裝置利用率。

    # Pipeline平行的簡單範例
    from torchgpipe import GPipe
    
    # 定義模型並轉換為 GPipe 格式
    model = MyLargeModel()
    model = GPipe(model, chunks=8)
    

    內容解密:

    • GPipe 將模型轉換為Pipeline平行格式。
    • chunks=8 表示將輸入批次劃分為 8 個微批次。
  3. 資料平行(Data Parallelism):將資料集分割成較小的部分,讓每個裝置單獨訓練這些子資料集。由於每個裝置現在訓練的是較小的資料集,因此訓練速度得到提升。

    # 資料平行的簡單範例
    import torch.nn as nn
    import torch.distributed as dist
    
    # 定義模型並使用 DataParallel 包裝
    model = nn.DataParallel(MyModel(), device_ids=[0, 1, 2, 3])
    

    內容解密:

    • nn.DataParallel 自動將模型複製到指定的多個 GPU 上,並在每個 GPU 上處理不同的資料子集。
    • device_ids=[0, 1, 2, 3] 指定參與訓練的 GPU。

分散式訓練的選擇

雖然資料平行具有許多優勢,但模型平行和Pipeline平行也有其自身的優勢和適用場景。當面對大型模型時,模型平行和Pipeline平行是更好的選擇。