在 Vertex AI 中執行自訂訓練工作,以便在雲端執行自有機器學習訓練程式碼,而不是使用 AutoML。本文說明編寫訓練程式碼時應考量的最佳做法。
。選擇訓練代碼結構
首先,請決定機器學習訓練程式碼的結構。您可以透過下列其中一種形式,將訓練程式碼提供給 Vertex AI:
要搭配預先建構的容器使用的 Python 指令碼。使用 Vertex AI SDK 建立自訂工作。這個方法可讓您以單一 Python 指令碼的形式提供訓練應用程式。
搭配預先建立的容器使用的 Python 訓練應用程式。建立Python 原始碼發行套件,內含訓練機器學習模型並匯出至 Cloud Storage 的程式碼。這個訓練應用程式可以使用預先建構容器中包含的任何依附元件,您打算搭配使用這些依附元件。
如果 Vertex AI 預建訓練容器包含訓練所需的所有依附元件,請使用這個選項。舉例來說,如果您想使用 PyTorch、scikit-learn、TensorFlow 或 XGBoost 進行訓練,這可能是較好的選擇。
如要瞭解這個選項的相關最佳做法,請參閱建立 Python 訓練應用程式指南。
自訂容器映像檔。建立 Docker 容器映像檔,內含訓練 ML 模型並匯出至 Cloud Storage 的程式碼。在容器映像檔中加入程式碼所需的任何依附元件。
如果您想使用 Vertex AI 預建訓練容器未納入的依附元件,請選用這個選項。舉例來說,如果您想使用預先建立的容器中並未提供的 Python 機器學習架構訓練模型,或者想使用 Python 以外的程式設計語言訓練模型,那麼這個選項會更適合您。
如要瞭解這個選項的最佳做法,請參閱建立自訂容器映像檔指南。
本文的其餘部分將說明與這兩種訓練程式碼結構相關的最佳做法。
所有自訂訓練程式碼的最佳做法
為 Vertex AI 編寫自訂訓練程式碼時,請注意程式碼會在Google Cloud管理的一或多個虛擬機器 (VM) 執行個體上執行。本節說明適用於所有自訂訓練程式碼的最佳做法。
在程式碼中存取 Google Cloud 服務
以下各節將說明如何從程式碼存取其他 Google Cloud服務。如要存取 Google Cloud 服務,請編寫訓練程式碼,使用應用程式預設憑證 (ADC)。許多 Google Cloud 用戶端程式庫預設會使用 ADC 進行驗證。您不需要設定任何環境變數;Vertex AI 會自動設定 ADC,以專案的Vertex AI 自訂程式碼服務代理 (預設) 或自訂服務帳戶 (如有設定) 進行驗證。
不過,在程式碼中使用 Google Cloud 用戶端程式庫時,Vertex AI 可能不會預設連線至正確的Google Cloud 專案。如果發生權限錯誤,可能是連線到錯誤的專案。
發生這個問題的原因是 Vertex AI 不會直接在 Google Cloud 專案中執行程式碼,Vertex AI 會在 Google 管理的其中一個獨立專案中執行程式碼。Vertex AI 只會將這些專案用於與您專案相關的作業。因此,請勿嘗試從訓練或推論程式碼中的環境推斷專案 ID,而是明確指定專案 ID。
如不想在訓練程式碼中硬式編碼專案 ID,可以參照 CLOUD_ML_PROJECT_ID
環境變數:Vertex AI 會在每個自訂訓練容器中設定這個環境變數,以包含您啟動自訂訓練的專案專案編號。許多 Google Cloud 工具接受專案 ID 的位置,也接受專案編號。
舉例來說,如果您想使用 Python Client for Google BigQuery 存取同一專案中的 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)
如果以這種方式設定程式碼後發生權限錯誤,請參閱下節內容,瞭解程式碼可存取的資源,並調整訓練程式碼可用的權限。
程式碼可存取的資源
根據預設,訓練應用程式可以存取專案的 Vertex AI 自訂程式碼服務代理 (CCSA) 可用的任何 Google Cloud 資源。您可以按照「授予 Vertex AI 服務代理程式其他資源的存取權」一文中的操作說明,授予 CCSA (以及訓練應用程式) 存取有限數量的其他資源。如果訓練應用程式需要讀取層級以上的存取權,才能存取該頁面未列出的 Google Cloud資源,則必須使用 https://www.googleapis.com/auth/cloud-platform 範圍取得 OAuth 2.0 存取權杖,而這只能透過自訂服務帳戶完成。
舉例來說,請考量訓練程式碼對 Cloud Storage 資源的存取權:
根據預設,Vertex AI 可以存取 Google Cloud 專案中您執行自訂訓練的任何 Cloud Storage 值區。您也可以授予 Vertex AI 對其他專案中 Cloud Storage 值區的存取權,或使用自訂服務帳戶,精確自訂特定工作可存取的值區。
使用 Cloud Storage FUSE 讀取及寫入 Cloud Storage 檔案
在所有自訂訓練工作中,Vertex AI 會在每個訓練節點檔案系統的 /gcs/
目錄中,掛接您有權存取的 Cloud Storage 值區。您可以直接讀取及寫入本機檔案系統,從 Cloud Storage 讀取資料或將資料寫入 Cloud Storage,不必使用 Python Client for Cloud Storage 或其他程式庫存取 Cloud Storage,十分方便。舉例來說,如要從 gs://BUCKET/data.csv
載入資料,可以使用下列 Python 程式碼:
file = open('/gcs/BUCKET/data.csv', 'r')
Vertex AI 使用 Cloud Storage FUSE 掛接儲存空間 bucket。請注意,Cloud Storage FUSE 掛接的目錄不符合 POSIX 標準。
您用於自訂訓練的憑證,會決定您能以這種方式存取哪些值區。前一節說明程式碼可存取的資源,其中詳細介紹了您預設可存取的 bucket,以及如何自訂這項存取權。
載入輸入資料
機器學習程式碼通常會處理訓練資料,藉此訓練模型。無論是建立 Python 訓練應用程式或自訂容器映像檔,都請勿將訓練資料與程式碼一併儲存。使用程式碼儲存資料可能會導致專案組織不當,難以在不同資料集重複使用程式碼,並造成大型資料集發生錯誤。
您可以從 Vertex AI 管理的資料集載入資料,也可以自行編寫程式碼,從 Vertex AI 以外的來源載入資料,例如 BigQuery 或 Cloud Storage。
如要從 Cloud Storage 載入資料,並獲得最佳效能,請使用執行自訂訓練作業的地區中的 bucket。如要瞭解如何在 Cloud Storage 中儲存資料,請參閱「建立儲存空間 bucket」和「上傳物件」。
如要瞭解可從哪些 Cloud Storage 值區載入資料,請參閱上一節,瞭解程式碼可存取哪些資源。
如要在訓練程式碼中載入 Cloud Storage 的資料,請使用前一節所述的 Cloud Storage FUSE 功能,或使用任何支援 ADC 的程式庫。您不需要在程式碼中明確提供任何驗證憑證。
舉例來說,您可以按照 Cloud Storage 指南的說明,使用其中一個用戶端程式庫下載物件。預先建構的容器中會包含 Cloud Storage 適用的 Python 用戶端。TensorFlow 的 tf.io.gfile.GFile
類別也支援 ADC。
載入大型資料集
視您在自訂訓練期間使用的機器類型而定,VM 可能無法將大型資料集完整載入記憶體。
如果需要讀取的資料過大,無法放入記憶體,請串流傳輸資料或以漸進方式讀取。不同的 ML 架構有不同的最佳做法。舉例來說,TensorFlow 的 tf.data.Dataset
類別可以從 Cloud Storage 串流傳輸 TFRecord 或文字資料。
在多個 VM 上使用資料平行處理執行自訂訓練,也是減少每個 VM 載入記憶體資料量的方法。請參閱本文的「編寫分散式訓練的程式碼」一節。
匯出訓練好的機器學習模型
機器學習程式碼通常會在訓練結束時,以一或多個模型構件的形式匯出訓練好的模型。接著,您可以使用模型構件取得推論結果。
自訂訓練完成後,您就無法再存取執行訓練程式碼的 VM。因此,訓練程式碼必須將模型構件匯出至 Vertex AI 以外的位置。
建議您將模型構件匯出至 Cloud Storage bucket。 如前一節所述,Vertex AI 可以存取您執行自訂訓練的 Google Cloud 專案中的任何 Cloud Storage 值區。使用支援 ADC 的程式庫匯出模型構件。舉例來說,用於儲存 Keras 模型的 TensorFlow API 可直接將構件匯出至 Cloud Storage 路徑。
如要在 Vertex AI 上使用訓練好的模型提供推論結果,程式碼必須以與推論專用預建容器相容的格式匯出模型構件。詳情請參閱匯出模型構件以進行推論和說明指南。
特殊 Cloud Storage 目錄的環境變數
如果您指定 baseOutputDirectory
API 欄位,Vertex AI 會在執行訓練程式碼時設定下列環境變數:
AIP_MODEL_DIR
:用於儲存模型構件的目錄 Cloud Storage URI。AIP_CHECKPOINT_DIR
:用於儲存檢查點的目錄 Cloud Storage URI。AIP_TENSORBOARD_LOG_DIR
:用於儲存 TensorBoard 記錄的目錄 Cloud Storage URI。請參閱「使用 Vertex AI TensorBoard 進行自訂訓練」。
這些環境變數的值會因您是否使用超參數調整功能而略有不同。詳情請參閱 baseOutputDirectory
的 API 參考資料。
使用這些環境變數,可輕鬆重複使用相同的訓練程式碼多次 (例如搭配不同的資料或設定選項),並將模型構件和檢查點儲存至不同位置,只要變更 baseOutputDirectory
API 欄位即可。不過,如果您不想在程式碼中使用環境變數,則不必這麼做。舉例來說,您可以改為將檢查點和匯出模型構件的位置寫死。
此外,如果您使用 TrainingPipeline
進行自訂訓練,但未指定 modelToUpload.artifactUri
欄位,則 Vertex AI 會使用 AIP_MODEL_DIR
環境變數的值做為 modelToUpload.artifactUri
。(如果是超參數調整,Vertex AI 會使用最佳試驗的 AIP_MODEL_DIR
環境變數值)。
確保重新啟動後仍可正常運作
執行訓練程式碼的 VM 偶爾會重新啟動。舉例來說,Google Cloud 可能需要基於維護原因重新啟動 VM。VM 重新啟動時,Vertex AI 會從頭開始再次執行程式碼。
如果預期訓練程式碼的執行時間會超過四小時,請在程式碼中加入幾項行為,確保程式碼在重新啟動後仍可正常運作:
請經常將訓練進度匯出至 Cloud Storage,至少每四小時一次,以免 VM 重新啟動時遺失進度。
在訓練程式碼的開頭,檢查匯出位置是否已有任何訓練進度。如果是,請載入已儲存的訓練狀態,而非從頭開始訓練。
四小時是參考值,並非實際上限。如果確保韌性是首要之務,即使您不希望程式碼執行這麼久,也建議在程式碼中加入這些行為。
如何達成這些行為,取決於您使用的機器學習架構。舉例來說,如果您使用 TensorFlow Keras,請瞭解如何使用 ModelCheckpoint
回呼函式達成此目的。
如要進一步瞭解 Vertex AI 如何管理 VM,請參閱「瞭解自訂訓練服務」。
選用自訂訓練功能的最佳做法
如要使用某些選用的自訂訓練功能,可能需要對訓練程式碼進行額外變更。本節說明超參數調整、GPU、分散式訓練和 Vertex AI TensorBoard 的程式碼最佳做法。
編寫程式碼以啟用自動記錄功能
您可以使用 Vertex AI SDK for Python 啟用自動記錄功能,在提交自訂工作時自動擷取參數和成效指標。詳情請參閱「執行訓練工作並追蹤實驗」。
編寫程式碼來傳回容器記錄
當您寫入服務或工作的記錄時,只要將記錄寫入以下任一位置,Cloud Logging 就會自動收集記錄:
- 標準輸出 (
stdout
) 或標準錯誤 (stderr
) 串流 /var/log-storage/
中的記錄檔,且符合output*.log
命名慣例。- 系統記錄檔 (
/dev/log
) - 使用 Cloud Logging 用戶端程式庫寫入的記錄,該用戶端程式庫適用於許多常用語言。
多數開發人員應使用標準輸出和標準錯誤來寫入記錄。
寫入這些支援位置的容器記錄會自動與 Vertex AI 自訂訓練服務、修訂版本和位置建立關聯,或是與自訂訓練工作建立關聯。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
屬性會做為記錄項目的主要顯示文字。
建立容器記錄與要求記錄間的關聯 (僅限服務)
在記錄檔探索工具中,以相同 trace
關聯的記錄可用「父子關係」格式來查看:當您按一下要求記錄項目左側的三角形圖示,就會以巢狀方式,在要求記錄下方顯示與該要求相關的容器記錄。
除非您使用 Cloud Logging 用戶端程式庫,否則容器記錄不會自動與要求記錄產生關聯。如要在不使用用戶端程式庫的情況下,將容器記錄與要求記錄建立關聯,可以使用包含 logging.googleapis.com/trace
欄位的結構化 JSON 記錄行,這個欄位會顯示從 X-Cloud-Trace-Context
標頭擷取的追蹤 ID。
查看記錄
如要在 Google Cloud 控制台中查看容器記錄,請執行下列操作:
前往 Google Cloud 控制台的「Vertex AI custom jobs」(Vertex AI 自訂工作) 頁面。
按一下要查看記錄的自訂作業名稱。
按一下「查看記錄」。
編寫超參數調整程式碼
Vertex AI 可對機器學習訓練程式碼執行超參數調整作業。進一步瞭解 Vertex AI 的超參數調整功能運作方式,以及如何設定HyperparameterTuningJob
資源。
如要使用超參數調整,訓練程式碼必須執行下列操作:
剖析指令列引數 (這些引數代表您要調整的超參數),然後使用剖析的值設定訓練的超參數。
間歇性地將超參數調整指標回報給 Vertex AI。
剖析指令列引數
進行超參數調整時,Vertex AI 會多次執行訓練程式碼,每次使用不同的指令列引數。訓練程式碼必須剖析這些指令列引數,並將其做為訓練的超參數。舉例來說,如要調整最佳化工具的學習率,您可能需要剖析名為 --learning_rate
的指令列引數。瞭解如何設定 Vertex AI 提供的指令列引數。
建議使用 Python 的 argparse
程式庫剖析命令列引數。
回報超參數調整指標
訓練程式碼必須間歇性地向 Vertex AI 回報您嘗試最佳化的超參數指標。舉例來說,如果想盡可能提高模型準確率,您可能會想在每個訓練週期結束時回報這項指標。Vertex AI 會根據這項資訊,決定下一次訓練試驗要使用的超參數。進一步瞭解如何選取及指定超參數調整指標。
使用 cloudml-hypertune
Python 程式庫回報超參數調整指標。所有預先建構的訓練容器都包含這個程式庫,您也可以使用 pip
在自訂容器中安裝這個程式庫。
如要瞭解如何安裝及使用這個程式庫,請參閱 cloudml-hypertune
GitHub 存放區,或參閱 Vertex AI:超參數調整程式碼研究室。
編寫 GPU 程式碼
您可以選取搭載圖形處理器 (GPU) 的 VM,執行自訂訓練程式碼。進一步瞭解如何設定自訂訓練,以使用支援 GPU 的 VM。
如要使用 GPU 訓練模型,請確認訓練程式碼可善用 GPU。視您使用的機器學習架構而定,這可能需要變更程式碼。舉例來說,如果您使用 TensorFlow Keras,只有在想使用多個 GPU 時,才需要調整程式碼。部分機器學習架構完全無法使用 GPU。
此外,請確認容器支援 GPU:選取支援 GPU 的預先建構訓練容器,或在自訂容器上安裝 NVIDIA CUDA Toolkit 和 NVIDIA cuDNN。其中一種做法是使用 nvidia/cuda
Docker 存放區的基本映像檔;另一種做法是使用深度學習容器執行個體做為基本映像檔。
撰寫分散式訓練的程式碼
如要使用大型資料集訓練模型,您可以在 Vertex AI 管理的分散式叢集中,透過多部 VM 執行程式碼。瞭解如何設定多個 VM 進行訓練。
某些機器學習架構 (如 TensorFlow 和 PyTorch) 可讓您在多部機器上執行相同的訓練程式碼,並根據每部機器上設定的環境變數,自動協調分工方式。瞭解 Vertex AI 是否設定環境變數,讓機器學習架構能夠執行這項操作。
或者,您也可以在多個工作站集區中分別執行不同的容器。工作站集區是一組 VM,您可設定這些 VM 使用相同的運算選項和容器。在這種情況下,您可能仍想依賴 Vertex AI 設定的環境變數,協調 VM 之間的通訊。您可以自訂每個工作站集區的訓練程式碼,執行任何任意工作;具體做法取決於您的目標和使用的機器學習架構。
使用 Vertex AI TensorBoard 追蹤自訂訓練實驗並以視覺化方式呈現
Vertex AI TensorBoard 是 TensorBoard 的受管理版本,後者是 Google 的開放原始碼專案,用於以視覺化方式呈現機器學習實驗。您可以使用 Vertex AI TensorBoard 追蹤、以視覺化方式呈現及比較機器學習實驗,然後與團隊分享。您也可以使用 Cloud Profiler 找出並修正效能瓶頸,以更快且更經濟實惠的方式訓練模型。
如要使用 Vertex AI TensorBoard 進行自訂訓練,請務必完成下列步驟:
在專案中建立 Vertex AI TensorBoard 執行個體,以便儲存實驗 (請參閱「建立 TensorBoard 執行個體」)。
設定服務帳戶,以適當權限執行自訂訓練工作。
調整自訂訓練程式碼,將相容於 TensorBoard 的記錄寫入 Cloud Storage (請參閱「訓練指令碼的變更」)
如需逐步指南,請參閱「使用 Vertex AI TensorBoard 進行自訂訓練」。
後續步驟
如果不確定是否要執行自訂訓練,請參閱自訂訓練與 AutoML 的比較。