準備訓練程式碼

在 Gemini Enterprise Agent Platform 執行無伺服器訓練,在雲端執行自己的機器學習 (ML) 訓練程式碼,而非使用 AutoML。本文說明編寫訓練程式碼時應考量的最佳做法。

選擇訓練程式碼結構

首先,請決定機器學習訓練程式碼要採用的結構。您可以透過下列其中一種形式,將訓練程式碼提供給 Agent Platform:

  • 與預先建構容器搭配使用的 Python 指令碼。使用 Agent Platform SDK 建立自訂工作。這個方法可讓您以單一 Python 指令碼的形式提供訓練應用程式。

  • 與預先建構容器搭配使用的 Python 訓練應用程式。建立 Python 原始碼發行套件,其中包含訓練機器學習模型並匯出至 Cloud Storage 的程式碼。這項訓練應用程式可以使用預先建構容器中的任何依附元件,只要您打算搭配使用即可。

    如果 Agent Platform 的預先建構訓練容器包含訓練所需的所有依附元件,請使用這個選項。舉例來說,如果您想使用 PyTorch、scikit-learn、TensorFlow 或 XGBoost 進行訓練,這可能是較佳的選項。

    如要瞭解這個選項的最佳做法,請參閱建立 Python 訓練應用程式指南。

  • 自訂容器映像檔。建立 Docker 容器映像檔,其中包含訓練機器學習模型並匯出至 Cloud Storage 的程式碼。在容器映像檔中加入程式碼所需的任何依附元件。

    如要使用 Agent Platform 預先建構的訓練容器中未包含的依附元件,請選取這個選項。舉例來說,如果您想使用預先建構容器中未提供的 Python 機器學習架構訓練模型,或想使用 Python 以外的程式設計語言訓練模型,這個選項會更合適。

    如要瞭解這個選項的最佳做法,請參閱建立自訂容器映像檔指南。

本文其餘部分將說明這兩種訓練程式碼結構的最佳做法。

所有無伺服器訓練程式碼的最佳做法

為 Agent Platform 編寫無伺服器訓練程式碼時,請注意,程式碼會在Google Cloud管理的一或多個虛擬機器 (VM) 執行個體上執行。本節說明適用於所有自訂訓練程式碼的最佳做法。

在程式碼中存取 Google Cloud 服務

以下幾節將說明如何透過程式碼存取其他 Google Cloud服務。如要存取 Google Cloud 服務,請編寫訓練程式碼,以便使用應用程式預設憑證 (ADC)。許多 Google Cloud 用戶端程式庫預設會使用 ADC 進行驗證。您不需要設定任何環境變數,Agent Platform 會自動設定 ADC,以專案的 Gemini Enterprise Agent Platform 自訂程式碼服務代理 (預設) 或自訂服務帳戶 (如有設定) 進行驗證。

不過,在程式碼中使用 Google Cloud 用戶端程式庫時,Agent Platform 預設不一定會連線至正確的Google Cloud 專案。如果遇到權限錯誤,可能是因為連線到錯誤的專案。

發生這個問題的原因是,Agent Platform 不會直接在 Google Cloud 專案中執行程式碼。相反地,Agent Platform 會在 Google 管理的幾個獨立專案中執行程式碼。Agent Platform 只會將這些專案用於與您專案相關的操作。因此,請勿嘗試從訓練或推論程式碼中的環境推論專案 ID,而是明確指定專案 ID。

如果不想在訓練程式碼中硬式編碼專案 ID,可以參照 CLOUD_ML_PROJECT_ID 環境變數:Agent Platform 會在每個無伺服器訓練容器中設定這個環境變數,其中包含您啟動無伺服器訓練的專案專案編號。許多 Google Cloud 工具在接受專案 ID 的地方,也能接受專案編號。

舉例來說,如果您想使用 BigQuery 的 Python 用戶端存取相同專案中的 BigQuery 資料表,請勿嘗試在訓練程式碼中推論專案:

隱含專案選取

from google.cloud import bigquery

client = bigquery.Client()

請改用明確選取專案的程式碼:

明確選取專案

import os

from google.cloud import bigquery

project_number = os.environ["CLOUD_ML_PROJECT_ID"]

client = bigquery.Client(project=project_number)

如果以這種方式設定程式碼後遇到權限錯誤,請參閱程式碼可存取的資源一節,調整訓練程式碼可用的權限。

程式碼可存取的資源

根據預設,訓練應用程式可以存取專案中 Gemini Enterprise Agent Platform Custom Code Service Agent (CCSA) 可用的任何 Google Cloud 資源。您可以按照「授予 Gemini Enterprise Agent Platform 服務代理其他資源的存取權」一節的操作說明,授予 CCSA (也就是訓練應用程式) 存取有限數量的其他資源。如果訓練應用程式需要對該頁面未列出的 Google Cloud資源進行讀取層級以上的存取,則必須取得具有 https://www.googleapis.com/auth/cloud-platform 範圍的 OAuth 2.0 存取權杖,這只能透過自訂服務帳戶完成。

舉例來說,請考量訓練程式碼對 Cloud Storage 資源的存取權:

根據預設,Agent Platform 可存取 Google Cloud 專案中執行無伺服器訓練的任何 Cloud Storage bucket。您也可以將其他專案中 Cloud Storage bucket 的存取權授予 Agent Platform,或使用自訂服務帳戶,精確自訂特定工作可存取的 bucket。

使用 Cloud Storage FUSE 讀取及寫入 Cloud Storage 檔案

在所有無伺服器訓練工作中,Agent Platform 會將您有權存取的 Cloud Storage bucket 掛接至每個訓練節點檔案系統的 /gcs/ 目錄。除了使用 Cloud Storage 的 Python 用戶端或其他程式庫存取 Cloud Storage 之外,您也可以直接在本機檔案系統中讀取及寫入資料,以便從 Cloud Storage 讀取資料或將資料寫入 Cloud Storage。例如,如要從 gs://BUCKET/data.csv 載入資料,可以使用下列 Python 程式碼:

file = open('/gcs/BUCKET/data.csv', 'r')

Agent Platform 會使用 Cloud Storage FUSE 掛接儲存空間 bucket。請注意,Cloud Storage FUSE 掛接的目錄不符合 POSIX 標準。

您用於無伺服器訓練的憑證,會決定您能以這種方式存取哪些 bucket。上一節程式碼可存取的資源,詳細說明瞭預設可存取的 bucket,以及如何自訂這項存取權。

載入輸入資料

機器學習程式碼通常會對訓練資料執行操作,以便訓練模型。無論是建立 Python 訓練應用程式或自訂容器映像檔,都請勿將訓練資料與程式碼儲存在一起。將資料與程式碼儲存在一起,可能會導致專案結構混亂、難以在不同資料集上重複使用程式碼,以及大型資料集發生錯誤。

您可以從 Agent Platform 代管資料集載入資料,也可以自行編寫程式碼,從 Agent Platform 以外的來源 (例如 BigQuery 或 Cloud Storage) 載入資料。

如要從 Cloud Storage 載入資料,並獲得最佳效能,請使用執行無伺服器訓練的區域中的 bucket。如要瞭解如何在 Cloud Storage 中儲存資料,請參閱「建立儲存空間 bucket」和「上傳物件」。

如要瞭解可以從哪些 Cloud Storage bucket 載入資料,請參閱上一節,瞭解程式碼可以存取哪些資源。

如要在訓練程式碼中從 Cloud Storage 載入資料,請使用上一節所述的 Cloud Storage FUSE 功能,或使用任何支援 ADC 的程式庫。您不需要在程式碼中明確提供任何驗證憑證。

舉例來說,您可以使用 Cloud Storage 指南中下載物件一節示範的其中一個用戶端程式庫。預先建構的容器中特別包含 Cloud Storage 適用的 Python 用戶端。TensorFlow 的 tf.io.gfile.GFile 類別也支援 ADC。

載入大型資料集

視您打算在無伺服器訓練期間使用的機器類型而定,VM 可能無法將整個大型資料集載入記憶體。

如果需要讀取的資料太大,無法放入記憶體,請串流資料或逐步讀取。不同的機器學習框架有不同的最佳做法。例如,TensorFlow 的 tf.data.Dataset 類別可以從 Cloud Storage 串流 TFRecord 或文字資料。

在多個 VM 上執行無伺服器訓練,並採用資料平行處理,是減少每個 VM 載入記憶體資料量的另一種方法。請參閱本文的「編寫分散式訓練程式碼」一節。

匯出訓練完成的機器學習模型

機器學習程式碼通常會在訓練結束時,以一或多個模型構件的形式匯出訓練模型。接著,您可以使用模型構件取得推論。

無伺服器訓練完成後,您就無法再存取執行訓練程式碼的 VM。因此,訓練程式碼必須將模型構件匯出至 Agent Platform 以外的位置。

建議您將模型構件匯出至 Cloud Storage bucket。如前一節「程式碼可存取的資源」所述,Agent Platform 可存取執行無伺服器訓練的 Google Cloud 專案中任何 Cloud Storage bucket。使用支援 ADC 的程式庫匯出模型構件。例如,用於儲存 Keras 模型的 TensorFlow API 可以直接將構件匯出至 Cloud Storage 路徑。

如要使用訓練好的模型在 Agent Platform 上提供推論,程式碼必須以與預建推論容器相容的格式匯出模型構件。詳情請參閱匯出模型構件以進行推論和說明的指南。

特殊 Cloud Storage 目錄的環境變數

如果您指定 baseOutputDirectory API 欄位,Agent Platform 會在執行訓練程式碼時設定下列環境變數:

這些環境變數的值會因是否使用超參數調整而略有不同。詳情請參閱 baseOutputDirectory 的 API 參考資料。

使用這些環境變數,可以更輕鬆地多次重複使用相同的訓練程式碼 (例如使用不同的資料或設定選項),並將模型構件和檢查點儲存到不同的位置,只要變更 baseOutputDirectory API 欄位即可。不過,您不一定要在程式碼中使用環境變數。例如,您也可以硬式編碼儲存檢查點和匯出模型構件的位置。

此外,如果您使用 TrainingPipeline 進行自訂訓練,且未指定 modelToUpload.artifactUri 欄位,Agent Platform 會使用 AIP_MODEL_DIR 環境變數的值做為 modelToUpload.artifactUri。(如果是超參數調整,Agent Platform 會使用最佳試驗的 AIP_MODEL_DIR 環境變數值)。

確保重新啟動時的韌性

執行訓練程式碼的 VM 會不時重新啟動。例如,Google Cloud 可能需要重新啟動 VM 進行維護。VM 重新啟動時,Agent Platform 會從頭開始再次執行程式碼。

如果預期訓練程式碼會執行超過四小時,請在程式碼中加入多項行為,讓程式碼在重新啟動時具有復原能力:

  • 請經常將訓練進度匯出至 Cloud Storage (至少每四小時一次),以免 VM 重新啟動時遺失進度。

  • 在訓練程式碼開頭,檢查匯出位置是否已有任何訓練進度。如果是,請載入儲存的訓練狀態,而不是從頭開始訓練。

四小時是參考值,並非硬性限制。如果確保韌性是首要任務,建議您將這些行為加入程式碼,即使您不預期程式碼會執行那麼久。

如何完成這些行為取決於您使用的機器學習架構。舉例來說,如果您使用 TensorFlow Keras,請瞭解如何使用 ModelCheckpoint 回呼來達到這個目的。

如要進一步瞭解 Agent Platform 如何管理 VM,請參閱「瞭解自訂訓練服務」。

選用無伺服器訓練功能的最佳做法

如要使用某些選用的無伺服器訓練功能,可能需要進一步修改訓練程式碼。本節說明超參數調整、GPU、分散式訓練和 Vertex AI TensorBoard 的程式碼最佳做法。

編寫程式碼來啟用自動記錄功能

您可以使用 Python 適用的 Agent Platform SDK 啟用自動記錄功能,在提交自訂工作時自動擷取參數和成效指標。詳情請參閱「執行訓練工作並追蹤實驗」。

編寫程式碼來傳回容器記錄

從服務或工作寫入記錄時,只要記錄寫入下列任一位置,Cloud Logging 就會自動擷取記錄:

大多數開發人員應使用標準輸出內容和標準錯誤寫入記錄。

寫入這些支援位置的容器記錄,會自動與 Gemini Enterprise Agent Platform 無伺服器訓練服務、修訂版本和位置,或無伺服器訓練工作建立關聯。Error Reporting 會擷取並回報這些記錄中的例外狀況。

在記錄中使用純文字與結構化 JSON

寫入記錄時,您可以傳送純文字字串,或傳送單行序列化 JSON (也稱為「結構化」資料)。Cloud Logging 會擷取並剖析此行內容,然後將其置入 jsonPayload。相較之下,純文字訊息會放在 textPayload 中。

寫入結構化記錄檔

您可以透過多種方式傳遞結構化 JSON 記錄。最常見的方法是使用 Python Logging 程式庫,或使用 print 傳遞原始 JSON。

Python 記錄程式庫

import json
import logging
from pythonjsonlogger import jsonlogger

class CustomJsonFormatter(jsonlogger.JsonFormatter):
 """Formats log lines in JSON."""
  def process_log_record(self, log_record):
    """Modifies fields in the log_record to match Cloud Logging's expectations."""
    log_record['severity'] = log_record['levelname']
    log_record['timestampSeconds'] = int(log_record['created'])
    log_record['timestampNanos'] = int(
        (log_record['created'] % 1) * 1000 * 1000 * 1000)

    return log_record

def configure_logger():
  """Configures python logger to format logs as JSON."""
  formatter = CustomJsonFormatter(
        '%(name)s|%(levelname)s|%(message)s|%(created)f'
        '|%(lineno)d|%(pathname)s', '%Y-%m-%dT%H:%M:%S')
  root_logger = logging.getLogger()
  handler = logging.StreamHandler()
  handler.setFormatter(formatter)
  root_logger.addHandler(handler)
  root_logger.setLevel(logging.WARNING)

logging.warning("This is a warning log")

原始 JSON

import json

def log(severity, message):
  global_extras = {"debug_key": "debug_value"}
  structured_log = {"severity": severity, "message": message, **global_extras}
  print(json.dumps(structured_log))

def main(args):
  log("DEBUG", "Debugging the application.")
  log("INFO", "Info.")
  log("WARNING", "Warning.")
  log("ERROR", "Error.")
  log("CRITICAL", "Critical.")

訊息中的特殊 JSON 欄位

以 JSON 字典形式提供結構化記錄時,某些特殊欄位會從 jsonPayload 中移除,並如特殊欄位說明文件所述,寫入系統所產生 LogEntry 的對應欄位。

例如,若 JSON 含有 severity 屬性,系統會從 jsonPayload 將其移除,並改以記錄項目的 severity 形式顯示。如果存在 message 屬性,則會用作記錄項目的主要顯示文字。

將容器記錄與要求記錄建立關聯 (僅限服務)

在 Logs Explorer 中,由相同 trace 關聯的記錄檔會以「父項-子項」格式顯示:點選要求記錄項目左側的三角形圖示時,與該要求相關的容器記錄檔會顯示在要求記錄檔下方。

除非您使用 Cloud Logging 用戶端程式庫,否則容器記錄不會自動與要求記錄建立關聯。如要在不使用用戶端程式庫的情況下,將容器記錄與要求記錄建立關聯,您可以使用結構化 JSON 記錄行,其中包含 logging.googleapis.com/trace 欄位,以及從 X-Cloud-Trace-Context 標頭擷取的追蹤 ID。

查看記錄

如要在 Google Cloud 控制台查看容器記錄,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Gemini Enterprise Agent Platform custom jobs」(Gemini Enterprise Agent Platform 自訂工作) 頁面。

    前往「Custom jobs」(自訂工作) 頁面

  2. 按一下要查看記錄的自訂工作名稱。

  3. 按一下「查看記錄」。

編寫超參數調整程式碼

Agent Platform 可對機器學習訓練程式碼執行超參數調整。進一步瞭解 Agent Platform 的超參數調整機制,以及如何設定 HyperparameterTuningJob 資源。

如要使用超參數調整功能,訓練程式碼必須執行下列操作:

  • 剖析代表要調整的超參數的指令列引數,並使用剖析的值設定訓練的超參數。

  • 間歇性向 Agent Platform 回報超參數調整指標。

剖析指令列引數

在超參數調整階段,Agent Platform 會多次執行訓練程式碼,每次使用不同的指令列引數。訓練程式碼必須剖析這些指令列引數,並將其做為訓練的超參數。舉例來說,如要調整最佳化工具的學習率,您可能需要剖析名為 --learning_rate 的指令列引數。瞭解如何設定 Agent Platform 提供的指令列引數。

建議您使用 Python 的 argparse 程式庫剖析指令列引數。

回報超參數調整指標

訓練程式碼必須不時向 Agent Platform 回報您要最佳化的超參數指標。舉例來說,如果您想盡可能提高模型的準確率,可以在每個訓練週期結束時回報這項指標。Agent Platform 會根據這項資訊,決定下一個訓練試驗要使用的超參數。進一步瞭解如何選取及指定超參數調整指標。

使用 cloudml-hypertune Python 程式庫回報超參數調整指標。所有預先建構的訓練容器都包含這個程式庫,您可以使用 pip 將其安裝在自訂容器中。

如要瞭解如何安裝及使用這個程式庫,請參閱 cloudml-hypertune GitHub 存放區,或參閱 Agent Platform:超參數調整程式碼實驗室。

編寫 GPU 程式碼

您可以選取具備圖形處理器 (GPU) 的 VM,執行自訂訓練程式碼。進一步瞭解如何設定無伺服器訓練,以使用支援 GPU 的 VM。

如要使用 GPU 進行訓練,請確認訓練程式碼可充分運用 GPU。視您使用的機器學習架構而定,可能需要變更程式碼。舉例來說,如果您使用 TensorFlow Keras,只有在想使用多個 GPU 時,才需要調整程式碼。部分機器學習框架完全無法使用 GPU。

此外,請確認容器支援 GPU:選取支援 GPU 的預先建構訓練容器,或在自訂容器上安裝 NVIDIA CUDA Toolkit 和 NVIDIA cuDNN。其中一種方法是使用 nvidia/cuda Docker 存放區中的基本映像檔;另一種方法是使用深度學習容器執行個體做為基本映像檔。

編寫分散式訓練程式碼

如要訓練大型資料集,您可以在 Agent Platform 管理的分散式叢集中,透過多個 VM 執行程式碼。瞭解如何設定多個 VM 進行訓練。

某些機器學習架構 (如 TensorFlow 和 PyTorch) 可讓您在多部機器上執行相同的訓練程式碼,並根據每部機器上設定的環境變數,自動協調分工。瞭解 Agent Platform 是否設定環境變數,讓機器學習架構能執行這項操作。

或者,您也可以在多個 worker 集區中分別執行不同的容器。worker 集區是一組 VM,設定為使用相同的運算選項和容器。在這種情況下,您可能仍需要依賴 Agent Platform 設定的環境變數,協調 VM 之間的通訊。您可以自訂每個 worker 集區的訓練程式碼,執行任何所需工作。具體做法取決於您的目標和使用的機器學習架構。

使用 Vertex AI TensorBoard 追蹤無伺服器訓練實驗,並以圖表呈現

Vertex AI TensorBoard 是 TensorBoard 的代管版本,TensorBoard 是 Google 開放原始碼專案,用於以圖表呈現機器學習實驗。您可以使用 Vertex AI TensorBoard 追蹤、視覺化呈現及比較機器學習實驗,然後與團隊分享。您也可以使用 Cloud Profiler 找出並修正效能瓶頸,以更快的速度和更低的成本訓練模型。

如要搭配使用 Vertex AI TensorBoard 和無伺服器訓練,請務必完成下列操作:

  • 在專案中建立 Vertex AI TensorBoard 執行個體,以便儲存實驗 (請參閱「建立 TensorBoard 執行個體」)。

  • 設定服務帳戶,以適當權限執行無伺服器訓練工作。

  • 調整無伺服器訓練程式碼,將與 TensorBoard 相容的記錄寫入 Cloud Storage (請參閱「訓練指令碼變更」)

如需逐步指南,請參閱「搭配使用 Vertex AI TensorBoard 和無伺服器訓練」。

後續步驟