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

1. 總覽

在本研究室中,您將瞭解如何透過自動封裝功能在 Vertex AI 訓練中執行自訂訓練工作。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 選單

接著,按一下「代管的筆記本」

Notebooks_UI

然後選取「新增筆記本」

new_notebook

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

create_notebook

在進階設定下方啟用閒置關閉,並將時間長度設為 60。也就是說,您的筆記本在未使用時自動關閉,因此不會產生不必要的費用。

idle_timeout

其他進階設定皆可保持原樣。

接著點選「建立」

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

open_jupyterlab

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

驗證

5. 編寫訓練程式碼

如要開始使用,請透過「啟動器」選單開啟筆記本執行個體中的「終端機」視窗:

launcher_terminal

建立名為 autopkg-codelab 的新目錄,然後使用 cd 功能。

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 訓練上執行訓練程式碼,協助您在 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 訓練中執行自訂訓練工作時,我們使用的是 GPU。不過,我們並未指定含有 GPU 的 Workbench 執行個體,因此會使用以 CPU 為基礎的映像檔進行本機測試。在這個範例中,我們使用預先建構的 Vertex AI 訓練容器

執行下列指令,設定要用做容器基礎的 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 映像檔。系統會安裝 pip 安裝至 requirements.txt 檔案的依附元件。首次執行這個指令時,可能需要幾分鐘才能完成。圖片建構完成後,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 訓練中啟動自訂訓練工作。透過單一指令,這項功能就能:

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

返回終端機,然後將 cd 置於 autopkg-codelab 目錄的上方。

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

指定預先建構的 Vertex AI 訓練 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 訓練預先建構容器。接著,自動封裝功能會透過 pip 安裝 requirements.txt 檔案中指定的資料集和轉換器程式庫。

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 引數。這會定義自訂工作使用的工作站集區設定。您可以指定多個工作站集區規格,以建立具備多個工作站集區的自訂工作,進行分散式訓練。在這個範例中,我們只會指定單一工作站集區,因為訓練程式碼並未設定為分散式訓練。

以下為這個規格的部分重要欄位:

  • machine-type (必要):機器類型。如要瞭解支援的類型,請按這裡
  • replica-count:這個工作站集區要使用的工作站備用資源數量,預設值為 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. 清除

因為我們設定了筆記本在 60 分鐘閒置後逾時,所以我們不必擔心如何關閉執行個體。如要手動關閉執行個體,請前往控制台的「Vertex AI Workbench」專區,然後按一下「Stop」按鈕。如想完全刪除筆記本,請按一下「刪除」按鈕。

刪除

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

刪除儲存空間