返回文章列表

訓練程式碼佈署Python套件與容器化策略

本文探討在短暫基礎設施上佈署機器學習訓練程式碼的兩種方法:Python 套件和容器化,分析其優缺點及適用場景。文章涵蓋了分散式訓練策略、超引數調校技巧以及如何利用 TensorBoard 監控模型訓練過程,並提供實務上的程式碼範例和組態說明,以協助讀者選擇最佳佈署方案並提升模型效能。

機器學習 雲端運算

在機器學習專案中,將訓練程式碼佈署到短暫的基礎設施上,Python 套件和容器化是兩種常見的選擇。Python 套件易於安裝和維護,能與 Vertex Training 等平台提供的機器和框架最佳化容器良好整合。容器化則提供更高的靈活性,適用於需要自定義環境或使用特定依賴項的場景,例如舊版軟體或專有元件。選擇哪種方案取決於專案需求,效率優先則選擇 Python 套件,靈活性優先則選擇容器化。對於分散式訓練, TensorFlow 提供了 OneDeviceStrategyMirroredStrategyMultiWorkerMirroredStrategyTPUStrategy 等策略,可根據硬體組態選擇合適的策略。文章也提供了一個利用 Python 錯誤處理機制,動態建立分佈策略的程式碼範例。

訓練程式碼的佈署:Python 套件還是容器?

在短暫的基礎設施上執行訓練程式碼時,將程式碼封裝成 Python 套件或容器化是兩種常見的方法。兩者都能實作自動化安裝和佈署,但各自有不同的優缺點。

為何選擇 Python 套件或容器?

將訓練程式碼放入 Python 套件的主要目的是為了便於在短暫的基礎設施上安裝。由於無法登入這些機器並互動式安裝軟體套件,因此需要自動化安裝訓練軟體。Python 套件提供了這種能力。

另一種捕捉依賴關係的方法是將訓練程式碼容器化。容器是一個輕量級的軟體包,包含了執行應用程式所需的一切,除了 Python 程式碼外,還包括 Python 安裝本身、所需的系統工具和系統函式庫,以及所有設定(如組態檔案、身份驗證金鑰和環境變數)。

由於 Vertex Training 接受 Python 模組和容器映像,因此可以透過構建包含訓練程式碼以及所需 Python 和 TensorFlow 版本的容器映像來捕捉 Python 和 TensorFlow 的依賴關係。在容器中,還可以安裝程式碼所需的所有額外套件。為了簡化容器建立過程,TensorFlow 提供了一個基礎容器映像。

選擇 Python 套件還是容器?

使用 Python 套件進行訓練可以幫助更好地組織程式碼,促進重用和可維護性。此外,如果向 Vertex Training 提供 Python 套件,它將在機器和框架最佳化的容器上安裝該套件,這是構建自己的容器所難以做到的。

另一方面,使用容器進行訓練更加靈活。例如,在需要使用舊版或不受支援的執行時版本,或需要安裝專有軟體元件(如內部系統的資料函式庫聯結器)的專案中,容器是一個好的選擇。

因此,選擇取決於您更看重什麼:效率(在這種情況下,您會選擇 Python 套件)還是靈活性(在這種情況下,您會選擇容器)。

分散式訓練策略

在訓練程式碼中,應建立 OneDeviceStrategy

strategy = tf.distribute.OneDeviceStrategy('/cpu:0')

使用 gcloud 命令啟動訓練作業,可以輕鬆地將模型訓練納入指令碼中,從 Cloud Functions 呼叫訓練作業,或使用 Cloud Scheduler 排程訓練作業。

多 GPU 上的執行

要在具有一個、兩個、四個或更多 GPU 的單台機器上執行,可以在 YAML 組態檔案中新增如下片段:

workerPoolSpecs:
  machineSpec:
    machineType: n1-standard-4
    acceleratorType: NVIDIA_TESLA_T4
    acceleratorCount: 2
  replicaCount: 1

然後像之前一樣啟動 gcloud 命令,確保在 --config 中指定此組態檔案。

在訓練程式碼中,應建立 MirroredStrategy 例項。

多 GPU 分佈

要在多個工作機上執行,每個工作機具有多個 GPU,組態 YAML 檔案應包括類別似於以下的行:

workerPoolSpecs:
  - machineSpec:
      machineType: n1-standard-4
      acceleratorType: NVIDIA_TESLA_T4
      acceleratorCount: 1
  - machineSpec:
      machineType: n1-standard-4
      acceleratorType: NVIDIA_TESLA_T4
      acceleratorCount: 1
    replicaCount: 1

請記住,如果使用多個工作機,則應透過宣告將被視為一個 epoch 的訓練示例數量來使用虛擬 epoch。還需要進行洗牌。GitHub 上的 serverlessml 中的程式碼示例同時做了這兩件事。

在訓練程式碼中,應建立 MultiWorkerMirroredStrategy 例項。

TPU 分佈

要在 Cloud TPU 上執行,組態檔案 YAML 看起來像這樣(選擇在您閱讀本文時最合適的 TPU 版本):

workerPoolSpecs:
  - machineSpec:
      machineType: n1-standard-4
      acceleratorType: TPU_V2
      acceleratorCount: 8

在訓練程式碼中,應建立 TPUStrategy 例項。

您可以使用 Python 的錯誤處理機制建立一個樣板方法,用於建立適合硬體組態的分佈策略:

def create_strategy():
    try:
        # detect TPUs
        tpu = tf.distribute.cluster_resolver.TPUClusterResolver().connect()
        return tf.distribute.experimental.TPUStrategy(tpu)
    except ValueError:
        # detect GPUs
        return tf.distribute.MirroredStrategy()

超引數調優

在建立 ML 模型的過程中,我們做出了許多任意的選擇:隱藏節點的數量、批次大小、學習率、L1/L2 正則化的數量等。可能的組合總數非常龐大,因此最好採用最佳化方法,指定預算(例如,“嘗試 30 種組合”),並讓超引數最佳化技術選擇最佳設定。

完全託管的超引數訓練服務提供了一組引數值給訓練程式,訓練程式然後訓練模型並報告效能指標(準確率、損失等)。因此,超引數調優服務要求我們:

  • 指定要調優的引數集、搜尋空間(每個引數可以採用的值範圍,例如學習率必須在 0.0001 和 0.1 之間)和搜尋預算。
  • 將給定的引陣列合納入訓練程式。
  • 報告使用該引陣列合時的模型效能。

超引數調優的重要性

超引數調優是機器學習模型開發中的一個重要步驟。透過最佳化超引數,可以顯著提高模型的效能。Vertex AI 提供了完全託管的超引數調優服務,使得調優過程變得更加簡單和高效。

超引數調校在Vertex AI上的應用

在這一部分,我們將討論如何在Vertex AI上進行超引數調校,以此作為相關運作的例項。

定義搜尋空間

我們在提供給Vertex AI的YAML組態檔案中定義搜尋空間。舉例來說:

displayName: "FlowersHpTuningJob"
maxTrialCount: 50
parallelTrialCount: 2
studySpec:
  metrics:
  - metricId: accuracy
    goal: MAXIMIZE
  parameters:
  - parameterId: l2
    scaleType: UNIT_LINEAR_SCALE
    doubleValueSpec:
      minValue: 0
      maxValue: 0.2
  - parameterId: batch_size
    scaleType: SCALE_TYPE_UNSPECIFIED
    discreteValueSpec:
      values:
      - 16
      - 32
      - 64
  algorithm: ALGORITHM_UNSPECIFIED

在此YAML檔案中,我們指定了(請嘗試找到對應的行):

  • 目標是最大化訓練器報告的準確度
  • 總預算是50次試驗,每次同時進行2次
  • 若試驗看起來不太可能比已經看到的結果更好,則提前停止試驗
  • 兩個引數:l2batch_size
    • 可能的L2正則化強度(介於0和0.2之間)
    • 批次大小,可以是16、32或64
  • 演算法型別,若未指定則使用貝葉斯最佳化

組態檔案解讀:

該組態檔案定義了超引數調校的目標、預算、引數範圍以及使用的演算法。透過這種方式,Vertex AI能夠自動搜尋最佳的超引陣列合。

使用引數值

Vertex AI將呼叫我們的訓練器,並將特定的l2batch_size值作為命令列引數傳遞。因此,我們確保使用argparse列出它們:

parser.add_argument(
    '--l2',
    help='L2 regularization', default=0., type=float)
parser.add_argument(
    '--batch_size',
    help='Number of records in a batch', default=32, type=int)

我們必須將這些值納入訓練程式中。例如,我們將使用批次大小如下:

train_dataset = create_preproc_dataset(
    'gs://...' + opts['pattern'],
    IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS
).batch(opts['batch_size'])

程式碼解說:

這段程式碼展示瞭如何使用命令列引數來控制訓練過程中的超引數,例如L2正則化和批次大小。

回報準確度

在我們使用提供的超引數訓練模型之後,我們需要向超引數調校服務回報結果。我們回報的內容是在YAML檔案中指定的超引數度量標籤:

hpt = hypertune.HyperTune()
accuracy = ...
hpt.report_hyperparameter_tuning_metric(
    hyperparameter_metric_tag='accuracy',
    metric_value=accuracy,
    global_step=nepochs)

回報機制:

這段程式碼展示瞭如何向超引數調校服務回報模型的準確度,以便進行後續的最佳化。

結果與分析

提交作業後,超引數調校被啟動,並同時進行50次試驗,每次2次。這些試驗的超引數是使用貝葉斯最佳化方法選擇的。每次試驗完成後,最佳化器會決定輸入空間的哪個部分需要進一步探索,並啟動新的試驗。

結果呈現:

結果顯示在網頁控制檯上(見圖7-6)。根據調校結果,最高的準確度(0.89)是在以下設定下獲得的:l2=0batch_size=64num_hidden=24with_color_distort=0crop_ratio=0.70706

繼續調校

檢視這些結果時,值得注意的是,num_hiddenbatch_size的最佳值是我們嘗試過的最高值。鑒於此,繼續超引數調校過程並探索更高的值可能是個好主意。同時,我們可以透過使crop_ratio成為一組離散值來減少其搜尋空間(0.70706應該只是0.7)。

繼續調校的策略:

這次,我們不需要貝葉斯最佳化。我們只是希望超引數服務進行45種可能組合的網格搜尋(這也是預算)。

佈署模型

現在我們已經有了一個訓練好的模型,讓我們將其佈署以進行線上預測。TensorFlow SavedModel格式受到TensorFlow Serving的支援。有一個TensorFlow Serving的Docker容器可供您佈署在容器協調系統中,如Google Kubernetes Engine、Google Cloud Run、Amazon Elastic Kubernetes Service、AWS Lambda、Azure Kubernetes Service,或在本地使用Kubernetes。TensorFlow Serving的託管版本在多個雲端平台上都可用。

佈署策略:

這部分內容闡述瞭如何將訓練好的模型佈署到生產環境中,以提供線上預測服務。透過使用TensorFlow Serving,我們可以方便地在不同的環境中佈署模型。

模型品質與持續評估

在前面的章節中,我們已經涵蓋了視覺模型的設計與實作。本章將探討監控與評估的重要主題。除了從一開始就擁有高品質的模型外,我們還需要維持其品質。為了確保最佳的運作狀態,透過監控取得洞察、計算指標、瞭解模型的品質以及持續評估其效能是非常重要的。

監控

我們已經在數百萬張圖片上訓練了模型,並且對其品質感到滿意。將其佈署到雲端後,我們就可以坐下來,放鬆地等待它永遠做出優秀的預測… 對嗎?錯!就像我們不會讓小孩獨自管理自己一樣,我們也不想讓我們的模型在外界無人監管。持續監控其品質(使用準確率等指標)和運算效能(每秒查詢次數、延遲等)是非常重要的,尤其是在不斷地使用新資料重新訓練模型時,這些新資料可能會包含分佈變化、錯誤等問題,而我們需要意識到這些問題。

TensorBoard

很多機器學習從業者在訓練模型時往往不會考慮所有的細節。他們提交訓練任務,然後偶爾檢查一下,直到任務完成。接著,他們使用訓練好的模型進行預測,以檢視其效能。如果訓練任務只需要幾分鐘,這似乎不是什麼大問題。然而,許多電腦視覺專案,尤其是那些包含數百萬張圖片的資料集,訓練任務可能需要數天或數週。如果訓練初期出了問題,而我們直到訓練完成或嘗試使用模型進行預測時才發現,那就太糟糕了。

TensorFlow 提供了一個名為 TensorBoard 的優秀監控工具,可以幫助我們避免這種情況。TensorBoard 是一個互動式儀錶板(見圖 8-1),顯示在模型訓練和評估期間儲存的摘要資訊。可以用它作為已執行實驗的歷史記錄,用於比較不同版本的模型或程式碼,以及分析訓練任務。

TensorBoard 的主要功能

TensorBoard 允許我們監控損失曲線,以確保模型訓練仍在進展中,並且沒有停止改進。我們還可以顯示和互動其他評估指標,例如準確率、精確率或 AUC。例如,我們可以對多個序列進行篩選、平滑和異常值移除,並且可以放大和縮小。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 訓練程式碼佈署Python套件與容器化策略

package "Docker 架構" {
    actor "開發者" as dev

    package "Docker Engine" {
        component [Docker Daemon] as daemon
        component [Docker CLI] as cli
        component [REST API] as api
    }

    package "容器運行時" {
        component [containerd] as containerd
        component [runc] as runc
    }

    package "儲存" {
        database [Images] as images
        database [Volumes] as volumes
        database [Networks] as networks
    }

    cloud "Registry" as registry
}

dev --> cli : 命令操作
cli --> api : API 呼叫
api --> daemon : 處理請求
daemon --> containerd : 容器管理
containerd --> runc : 執行容器
daemon --> images : 映像檔管理
daemon --> registry : 拉取/推送
daemon --> volumes : 資料持久化
daemon --> networks : 網路配置

@enduml

此圖示展示了使用 TensorBoard 進行模型訓練監控的流程。

使用 TensorBoard 的好處

透過使用 TensorBoard,我們可以及時發現訓練過程中的問題,並進行調整,從而提高模型的品質和效能。這對於大型電腦視覺專案尤其重要,因為它們通常需要大量的計算資源和時間。

內容解密:

本章節主要闡述了模型監控與持續評估的重要性,以及如何利用TensorBoard進行有效的模型監控。TensorBoard作為一個互動式儀錶板,能夠顯示模型訓練過程中的各種指標,有助於及時發現並解決問題,從而提升模型的整體品質與效能。持續的監控與評估是確保模型長期穩定運作的關鍵步驟。

下一步

在下一章中,我們將探討如何改進模型的服務體驗,包括如何讓模型直接接受圖片檔案內容等。

TensorBoard 的強大監控功能:模型品質與訓練過程的最佳化

TensorBoard 是一個強大的視覺化工具,能夠幫助我們深入瞭解模型的訓練過程、權重分佈、以及其他重要的模型指標。本文將探討如何使用 TensorBoard 來監控模型的訓練過程,並提供一些實用的技巧來最佳化模型的效能。

權重直方圖:瞭解模型的訓練狀態

在 TensorBoard 中,我們可以使用直方圖來監控權重的分佈。權重的分佈可以告訴我們模型的訓練狀態是否正常。理想情況下,權重的分佈應該趨近於高斯分佈。如果權重的分佈出現了偏差,例如趨近於零或非常大的值,那麼可能表示模型存在某些問題。

權重分佈不佳的解決方案

如果權重的分佈不佳,我們可以嘗試以下幾種方法來改善:

  • 將輸入值從 [0, 1] 縮放到 [-1, 1],以避免權重趨近於零。
  • 在中間層新增批次正規化(Batch Normalization),以穩定權重的分佈。
  • 新增正規化(Regularization)或增加資料集的大小,以避免過度擬合。
  • 嘗試不同的初始化方法,以改善權重的初始分佈。

裝置組態:瞭解模型的計算資源使用情況

TensorBoard 可以顯示 TensorFlow 模型圖的視覺化,讓我們瞭解模型的計算資源使用情況。透過裝置組態檢視,我們可以看到哪些節點被分配到哪些裝置上,並且可以檢查 TPU 的相容性。

資料視覺化:瞭解模型的訓練資料

TensorBoard 可以顯示特定型別的資料,例如影像或音訊。透過影像視覺化,我們可以瞭解模型的生成影像是否合理。對於分類別問題,TensorBoard 還可以顯示混淆矩陣(Confusion Matrix),讓我們瞭解模型的分類別效能。

訓練事件:監控模型的訓練過程

我們可以將 TensorBoard 的回呼函式新增到模型中,以監控模型的訓練過程。透過設定 log_dirhistogram_freqwrite_graph 等引數,我們可以控制 TensorBoard 的輸出內容。

tensorboard_callback = tf.keras.callbacks.TensorBoard(
    log_dir='logs', 
    histogram_freq=0, 
    write_graph=True,
    write_images=False, 
    update_freq='epoch', 
    profile_batch=2,
    embeddings_freq=0, 
    embeddings_metadata=None
)

設定 TensorBoard 的回呼函式

在模型訓練過程中,我們可以將 TensorBoard 的回呼函式新增到 model.fit() 中,以監控模型的訓練過程。

history = model.fit(
    train_dataset,
    epochs=10,
    batch_size=1,
    validation_data=validation_dataset,
    callbacks=[tensorboard_callback]
)

啟動 TensorBoard

要啟動 TensorBoard,我們可以在終端機中執行以下指令:

tensorboard --logdir=<path_to_your_logs>

這樣就可以在瀏覽器中檢視 TensorBoard 的視覺化結果。