Vertex AI:在 Vertex AI 訓練中,使用自動封裝功能透過 Hugging Face 微調 Bert

1. 總覽

在本實驗室中,您將瞭解如何使用自動封裝功能,在 Vertex AI Training 上執行自訂訓練工作。Vertex AI 中的自訂訓練工作會使用容器。如果不想自行建構映像檔,則可使用包裝,依據程式碼建構自訂 Docker 映像檔、將映像檔推送至 Container Registry,並根據映像檔啟動 CustomJob

課程內容

學習重點:

在 Google Cloud 中執行這個實驗室的總費用約為 $2 美元。

2. 用途簡介

使用Hugging Face 的程式庫時,您會微調 IMDB 資料集上的 BERT 模型。模型會預測電影評論是正面還是負面。系統會從 Hugging Face 資料集資料庫下載資料集,並從 Hugging Face 轉換器資料庫下載 Bert 模型。

3. Vertex AI 簡介

這個實驗室使用 Google Cloud 最新推出的 AI 產品服務。Vertex AI 整合了 Google Cloud 中的機器學習產品,提供流暢的開發體驗。先前,使用 AutoML 訓練的模型和自訂模型必須透過不同的服務存取。新產品將這兩項功能與其他新產品整合至單一 API。您也可以將現有專案遷移至 Vertex AI。如有任何意見,請參閱支援頁面

Vertex AI 提供許多不同的產品,可支援端對端機器學習工作流程。本實驗室將著重於訓練和 Workbench。

Vertex 產品總覽

4. 設定環境

您需要已啟用計費功能的 Google Cloud Platform 專案,才能執行這個程式碼研究室。如要建立專案,請按照這篇文章中的操作說明進行。

步驟 1:啟用 Compute Engine API

前往「Compute Engine」,然後選取「啟用」 (如果尚未啟用)。

步驟 2:啟用 Vertex AI API

前往 Cloud 控制台的 Vertex AI 專區,然後按一下「啟用 Vertex AI API」

Vertex AI 資訊主頁

步驟 3:啟用 Container Registry API

前往「Container Registry」,然後選取「Enable」(啟用) (如果尚未啟用)。您將使用這個檔案為自訂訓練工作建立容器。

步驟 4:建立 Vertex AI Workbench 執行個體

在 Cloud 控制台的 Vertex AI 專區中,按一下「Workbench」:

Vertex AI 選單

接著按一下「MANAGED NOTEBOOKS」

Notebooks_UI

然後選取「新增筆記本」

new_notebook

為筆記本命名,然後按一下「進階設定」

create_notebook

在「進階設定」下方,啟用閒置關機功能,並將分鐘數設為 60。也就是說,筆記型電腦會在閒置時自動關機,避免產生不必要的費用。

idle_timeout

您可以保留其他進階設定。

接著,按一下「建立」

建立執行個體後,選取「Open JupyterLab」

open_jupyterlab

首次使用新執行個體時,系統會要求您進行驗證。

驗證

5. 編寫訓練程式碼

首先,請在 Launcher 選單中開啟筆記本執行個體的終端機視窗:

launcher_terminal

建立名為 autopkg-codelab 的新目錄,然後切換至該目錄。

mkdir autopkg-codelab
cd autopkg-codelab

在終端機中執行下列指令,為訓練程式碼建立目錄,並建立 Python 檔案以便新增程式碼:

mkdir trainer
touch trainer/task.py

autopkg-codelab/ 目錄現在應該會包含以下內容:

+ trainer/
    + task.py

接著,開啟您剛才建立的 task.py 檔案,然後複製下方程式碼。

import argparse

import tensorflow as tf
from datasets import load_dataset
from transformers import AutoTokenizer
from transformers import TFAutoModelForSequenceClassification

CHECKPOINT = "bert-base-cased"

def get_args():
  '''Parses args.'''

  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--epochs',
      required=False,
      default=3,
      type=int,
      help='number of epochs')
  parser.add_argument(
      '--job_dir',
      required=True,
      type=str,
      help='bucket to store saved model, include gs://')
  args = parser.parse_args()
  return args


def create_datasets():
    '''Creates a tf.data.Dataset for train and evaluation.'''

    raw_datasets = load_dataset('imdb')
    tokenizer = AutoTokenizer.from_pretrained(CHECKPOINT)
    tokenized_datasets = raw_datasets.map((lambda examples: tokenize_function(examples, tokenizer)), batched=True)

    # To speed up training, we use only a portion of the data.
    # Use full_train_dataset and full_eval_dataset if you want to train on all the data.
    small_train_dataset = tokenized_datasets['train'].shuffle(seed=42).select(range(1000))
    small_eval_dataset = tokenized_datasets['test'].shuffle(seed=42).select(range(1000))
    full_train_dataset = tokenized_datasets['train']
    full_eval_dataset = tokenized_datasets['test']

    tf_train_dataset = small_train_dataset.remove_columns(['text']).with_format("tensorflow")
    tf_eval_dataset = small_eval_dataset.remove_columns(['text']).with_format("tensorflow")

    train_features = {x: tf_train_dataset[x] for x in tokenizer.model_input_names}
    train_tf_dataset = tf.data.Dataset.from_tensor_slices((train_features, tf_train_dataset["label"]))
    train_tf_dataset = train_tf_dataset.shuffle(len(tf_train_dataset)).batch(8)

    eval_features = {x: tf_eval_dataset[x] for x in tokenizer.model_input_names}
    eval_tf_dataset = tf.data.Dataset.from_tensor_slices((eval_features, tf_eval_dataset["label"]))
    eval_tf_dataset = eval_tf_dataset.batch(8)

    return train_tf_dataset, eval_tf_dataset


def tokenize_function(examples, tokenizer):
    '''Tokenizes text examples.'''

    return tokenizer(examples['text'], padding='max_length', truncation=True)


def main():
    args = get_args()
    train_tf_dataset, eval_tf_dataset = create_datasets()
    model = TFAutoModelForSequenceClassification.from_pretrained(CHECKPOINT, num_labels=2)

    model.compile(
        optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),
        loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
        metrics=tf.metrics.SparseCategoricalAccuracy(),
    )

    model.fit(train_tf_dataset, validation_data=eval_tf_dataset, epochs=args.epochs)
    model.save(f'{args.job_dir}/model_output')


if __name__ == "__main__":
    main()

關於這段程式碼,請注意以下幾點:

  • CHECKPOINT 是要微調的模型。在本例中,我們使用 Bert。
  • TFAutoModelForSequenceClassification 方法會在 TensorFlow 中載入指定的語言模型架構和權重,並在頂端加入分類頭,並隨機初始化權重。在本例中,我們遇到二元分類問題 (正面或負面),因此為此分類器指定 num_labels=2

6. 在本機進行容器化及執行訓練程式碼

您可以使用 gcloud ai custom-jobs local-run 指令,根據訓練程式碼建構 Docker 容器映像檔,並在本機電腦上以容器形式執行映像檔。在本機執行容器時,訓練程式碼的執行方式與在 Vertex AI Training 上執行的方式類似,因此在 Vertex AI 上執行自訂訓練前,您可以先對程式碼進行偵錯。

在訓練工作中,我們會將經過訓練的模型匯出至 Cloud Storage 值區。在終端機執行下列指令,定義專案的環境變數;請務必將 your-cloud-project 替換為您的專案 ID:

PROJECT_ID='your-cloud-project'

然後建立值區。如果您已有值區,請改用該值區。

BUCKET_NAME="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET_NAME

在 Vertex AI Training 上執行自訂訓練工作時,我們會使用 GPU。不過,由於我們並未指定具有 GPU 的 Workbench 執行個體,因此我們會使用 CPU 映像檔進行本機測試。在本例中,我們使用 Vertex AI Training 預建容器

執行以下指令,設定 Docker 映像檔的 URI,以做為容器的基礎。

BASE_CPU_IMAGE=us-docker.pkg.dev/vertex-ai/training/tf-cpu.2-7:latest

接著,為本機執行指令所建構的 Docker 映像檔設定名稱。

OUTPUT_IMAGE=$PROJECT_ID-local-package-cpu:latest

我們的訓練程式碼會使用 Hugging Face 資料集和轉換器程式庫。這些程式庫並未包含在我們選取做為基本映像檔的映像檔中,因此我們需要將這些程式庫做為必要條件提供。為此,我們會在 autopkg-codelab 目錄中建立 requirements.txt 檔案。

確認您位於 autopkg-codelab 目錄,然後在終端機中輸入下列指令。

touch requirements.txt

autopkg-codelab 目錄現在應該會包含以下內容:

+ requirements.txt
+ trainer/
    + task.py

開啟需求檔案,然後貼上以下內容

datasets==1.18.2
transformers==4.16.2

最後,執行 gcloud ai custom-jobs local-run 指令,在 Workbench 管理的執行個體上啟動訓練。

gcloud ai custom-jobs local-run \
--executor-image-uri=$BASE_CPU_IMAGE \
--python-module=trainer.task \
--output-image-uri=$OUTPUT_IMAGE \
-- \
--job_dir=$BUCKET_NAME

您應該會看到正在建構的 Docker 映像檔。我們在 requirements.txt 檔案中新增的依附元件會透過 pip 安裝。第一次執行這項指令可能需要幾分鐘的時間才能完成。映像檔建構完成後,task.py 檔案就會開始執行,您會看到模型訓練作業。畫面應如下所示:

local_training

由於我們不會在本機使用 GPU,因此模型訓練作業會耗費很長的時間。您可以按 Ctrl+C 取消本機訓練,而不用等待工作完成。

請注意,如要進一步測試,您也可以直接執行上方建構的映像檔,不必重新封包。

gcloud beta ai custom-jobs local-run \
--executor-image-uri=$OUTPUT_IMAGE \
-- \
--job_dir=$BUCKET_NAME \
--epochs=1

7. 建立自訂工作

本節課程已測試本機模式,接下來我們將使用自動封裝功能,在 Vertex AI Training 上啟動自訂訓練工作。這項功能可透過單一指令執行下列操作:

  • 根據您的程式碼建構自訂 Docker 映像檔。
  • 將映像檔推送至 Container Registry。
  • 根據圖片啟動 CustomJob

返回終端機,並在 autopkg-codelab 目錄上方向上移動一個層級。

+ autopkg-codelab
  + requirements.txt
  + trainer/
      + task.py

指定 Vertex AI Training 預建的 TensorFlow GPU 映像檔,做為自訂訓練工作的基礎映像檔。

BASE_GPU_IMAGE=us-docker.pkg.dev/vertex-ai/training/tf-gpu.2-7:latest

接著,執行 gcloud ai custom-jobs create 指令。首先,這個指令會根據訓練程式碼建構自訂 Docker 映像檔。基本映像檔是我們設為 BASE_GPU_IMAGE 的 Vertex AI 訓練預先建構容器。接著,自動封裝功能會依照 requirements.txt 檔案中指定的方式,使用 pip 安裝資料集和轉換器程式庫。

gcloud ai custom-jobs create \
--region=us-central1 \
--display-name=fine_tune_bert \
--args=--job_dir=$BUCKET_NAME \
--worker-pool-spec=machine-type=n1-standard-4,replica-count=1,accelerator-type=NVIDIA_TESLA_V100,executor-image-uri=$BASE_GPU_IMAGE,local-package-path=autopkg-codelab,python-module=trainer.task

讓我們來看看 worker-pool-spec 引數。這會定義自訂工作所使用的 worker pool 設定。您可以指定多個工作站集區規格,藉此建立含有多個工作站集區的自訂工作,以便進行分散式訓練。在這個範例中,我們只會指定單一工作站集區,因為訓練程式碼並未設定為分散式訓練。

以下是此規格的一些重要欄位:

  • machine-type (必要):機器類型。如要瞭解支援的類型,請按這裡
  • replica-count:這個 worker pool 要使用的 worker 備用資源數量,預設值為 1。
  • accelerator-type:GPU 的類型。如要瞭解支援的類型,請按這裡。在這個範例中,我們指定了一個 NVIDIA Tesla V100 GPU。
  • accelerator-count:工作站集區中每個 VM 使用的 GPU 數量,預設值為 1。
  • executor-image-uri:將執行提供的套件的容器映像檔 URI。這項屬性已設為我們的基本映像檔。
  • local-package-path:包含訓練程式碼的資料夾本機路徑。
  • python-module:要在提供的套件中執行的 Python 模組名稱。

與執行本機指令時類似,您會看到建立 Docker 映像檔,然後啟動訓練工作。除了查看訓練工作的輸出內容之外,您會看到以下訊息,確認訓練工作已經啟動。請注意,首次執行 custom-jobs create 指令時,可能需要幾分鐘的時間才能建構及推送映像檔。

training_started

返回 Cloud 控制台的 Vertex AI 訓練專區,您應該會在「自訂工作」下方看到正在執行的工作。

training_job

這項工作大約需要 20 分鐘。

完成後,您應該會在值區的 model_output 目錄中看到下列已儲存的模型構件。

model_output

🎉 恭喜!🎉

您已瞭解如何使用 Vertex AI 執行下列作業:

  • 在本機進行容器化及執行訓練程式碼
  • 使用自動封包功能,將訓練工作提交至 Vertex AI 訓練

如要進一步瞭解 Vertex AI 的其他部分,請參閱說明文件

8. 清理

由於我們已將 Notebook 設為在閒置 60 分鐘後逾時,因此不必擔心關閉執行個體。如果您想手動關閉執行個體,請按一下控制台 Vertex AI Workbench 專區中的「停止」按鈕。如要完全刪除筆記本,請按一下「刪除」按鈕。

刪除

如要刪除 Storage 值區,請使用 Cloud 控制台中的導覽選單前往「Storage」(儲存空間)、選取值區,然後點選「Delete」(刪除):

刪除儲存空間