Vertex AI: Nutzen Sie die automatische Paketerstellung, um Bert mit „Hugging Face“ in Vertex AI Training zu optimieren

1. Übersicht

In diesem Lab erfahren Sie, wie Sie einen benutzerdefinierten Trainingsjob in Vertex AI Training mit der Funktion für das automatische Verpacken ausführen. Benutzerdefinierte Trainingsjobs in Vertex AI verwenden Container. Wenn Sie kein eigenes Image erstellen möchten, können Sie die Funktion für das automatische Verpacken verwenden. Dadurch wird ein benutzerdefiniertes Docker-Image auf Basis Ihres Codes erstellt, das Image wird in Container Registry hochgeladen und ein CustomJob wird auf Basis des Images gestartet.

Lerninhalte

Die folgenden Themen werden behandelt:

Die Gesamtkosten für die Ausführung dieses Labs in Google Cloud betragen etwa 2$.

2. Anwendungsfall

Mithilfe von Bibliotheken von Hugging Face stimmen Sie ein BERT-Modell auf das IMDB-Dataset ab. Das Modell sagt voraus, ob eine Filmkritik positiv oder negativ ist. Das Dataset wird aus der Hugging Face-Datasets-Bibliothek und das BERT-Modell aus der Hugging Face-Transformers-Bibliothek heruntergeladen.

3. Einführung in Vertex AI

In diesem Lab wird das neueste KI-Produkt von Google Cloud verwendet. Vertex AI vereint die ML-Angebote von Google Cloud in einer nahtlosen Entwicklungsumgebung. Bisher musste auf mit AutoML trainierte und benutzerdefinierte Modelle über verschiedene Dienste zugegriffen werden. Das neue Angebot kombiniert diese und weitere, neue Produkte zu einer einzigen API. Sie können auch vorhandene Projekte zu Vertex AI migrieren. Wenn Sie Feedback haben, lesen Sie die Supportseite.

Vertex AI umfasst viele verschiedene Produkte zur Unterstützung von End-to-End-ML-Workflows. In diesem Lab konzentrieren wir uns auf Training und Workbench.

Vertex-Produktübersicht

4. Umgebung einrichten

Sie benötigen ein Google Cloud Platform-Projekt mit aktivierter Abrechnung, um dieses Codelab auszuführen. Eine Anleitung zum Erstellen eines Projekts finden Sie hier.

Schritt 1: Compute Engine API aktivieren

Rufen Sie Compute Engine auf und wählen Sie Aktivieren aus, falls die API noch nicht aktiviert ist.

Schritt 2: Vertex AI API aktivieren

Rufen Sie in der Cloud Console den Bereich „Vertex AI“ auf und klicken Sie auf **Vertex AI API aktivieren**.

Vertex AI-Dashboard

Schritt 3: Container Registry API aktivieren

Rufen Sie Container Registry auf und wählen Sie Aktivieren aus, falls die API noch nicht aktiviert ist. Damit erstellen Sie einen Container für Ihren benutzerdefinierten Trainingsjob.

Schritt 4: Vertex AI Workbench-Instanz erstellen

Klicken Sie in der Cloud Console im Bereich „Vertex AI“ auf „Workbench“:

Vertex AI-Menü

Klicken Sie auf VERWALTETE NOTEBOOKS:

Notebooks_UI

Wählen Sie dann NEUES NOTEBOOK aus.

new_notebook

Geben Sie Ihrem Notebook einen Namen und klicken Sie dann auf Erweiterte Einstellungen.

create_notebook

Aktivieren Sie unter „Erweiterte Einstellungen“ die Option „Herunterfahren bei Inaktivität“ und legen Sie die Anzahl der Minuten auf 60 fest. Das bedeutet, dass Ihr Notebook automatisch heruntergefahren wird, wenn es nicht verwendet wird, damit keine unnötigen Kosten entstehen.

idle_timeout

Sie können alle anderen erweiterten Einstellungen unverändert lassen.

Klicken Sie dann auf Erstellen.

Nachdem die Instanz erstellt wurde, wählen Sie JupyterLab öffnen aus.

open_jupyterlab

Wenn Sie eine neue Instanz zum ersten Mal verwenden, werden Sie aufgefordert, sich zu authentifizieren.

Authentifizieren

5. Trainingscode schreiben

Öffnen Sie im Launcher-Menü ein Terminalfenster in Ihrer Notebook-Instanz:

launcher_terminal

Erstellen Sie ein neues Verzeichnis mit dem Namen autopkg-codelab und wechseln Sie zu diesem Verzeichnis.

mkdir autopkg-codelab
cd autopkg-codelab

Führen Sie im Terminal den folgenden Befehl aus, um ein Verzeichnis für den Trainingscode und eine Python-Datei zu erstellen, in der Sie den Code hinzufügen:

mkdir trainer
touch trainer/task.py

Das Verzeichnis autopkg-codelab/ sollte jetzt Folgendes enthalten:

+ trainer/
    + task.py

Öffnen Sie als Nächstes die gerade erstellte Datei task.py und kopieren Sie den folgenden Code.

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()

Einige Hinweise zum Code:

  • CHECKPOINT ist das Modell, das wir abstimmen möchten. In diesem Fall verwenden wir BERT.
  • Die Methode TFAutoModelForSequenceClassification lädt die angegebene Sprachmodellarchitektur und die Gewichte in TensorFlow und fügt oben einen Klassifizierungskopf mit zufällig initialisierten Gewichten hinzu. In diesem Fall haben wir ein binäres Klassifizierungsproblem (positiv oder negativ). Daher geben wir für diesen Klassifikator num_labels=2 an.

6. Trainingscode lokal containerisieren und ausführen

Mit dem Befehl gcloud ai custom-jobs local-run können Sie ein Docker-Container-Image basierend auf Ihrem Trainingscode erstellen und das Image als Container auf Ihrem lokalen Computer ausführen. Wenn Sie einen Container lokal ausführen, wird Ihr Trainingscode auf ähnliche Weise ausgeführt wie in Vertex AI Training. So können Sie Probleme mit dem Code beheben, bevor Sie ein benutzerdefiniertes Training in Vertex AI durchführen.

In unserem Trainingsjob exportieren wir das trainierte Modell in einen Cloud Storage-Bucket. Führen Sie im Terminal den folgenden Befehl aus, um eine Umgebungsvariable für Ihr Projekt zu definieren. Ersetzen Sie dabei your-cloud-project durch die ID Ihres Projekts:

PROJECT_ID='your-cloud-project'

Erstellen Sie dann einen Bucket. Wenn Sie einen vorhandenen Bucket haben, können Sie diesen stattdessen verwenden.

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

Wenn wir den benutzerdefinierten Trainingsjob in Vertex AI Training ausführen, verwenden wir eine GPU. Da wir unsere Workbench-Instanz jedoch nicht mit GPUs angegeben haben, verwenden wir für lokale Tests ein CPU-basiertes Image. In diesem Beispiel verwenden wir einen vordefinierten Vertex AI Training-Container.

Führen Sie den folgenden Befehl aus, um den URI eines Docker-Images festzulegen, das als Basis des Containers verwendet werden soll.

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

Legen Sie dann einen Namen für das resultierende Docker-Image fest, das mit dem Befehl für die lokale Ausführung erstellt wird.

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

Unser Trainingscode verwendet die Bibliotheken „datasets“ und „transformers“ von Hugging Face. Diese Bibliotheken sind nicht im Image enthalten, das wir als Basis-Image ausgewählt haben. Daher müssen wir sie als Anforderungen angeben. Dazu erstellen wir eine Datei requirements.txt im Verzeichnis autopkg-codelab.

Achten Sie darauf, dass Sie sich im Verzeichnis autopkg-codelab befinden, und geben Sie Folgendes im Terminal ein.

touch requirements.txt

Das Verzeichnis autopkg-codelab sollte jetzt Folgendes enthalten:

+ requirements.txt
+ trainer/
    + task.py

Öffnen Sie die Datei „requirements“ und fügen Sie Folgendes ein:

datasets==1.18.2
transformers==4.16.2

Führen Sie schließlich den Befehl gcloud ai custom-jobs local-run aus, um das Training in unserer verwalteten Workbench-Instanz zu starten.

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

Das Docker-Image wird erstellt. Die Abhängigkeiten, die wir der Datei requirements.txt hinzugefügt haben, werden mit pip installiert. Beim ersten Ausführen dieses Befehls kann es einige Minuten dauern. Sobald das Image erstellt wurde, wird die Datei task.py ausgeführt und das Modelltraining beginnt. Auf dem Bildschirm sollte Folgendes zu sehen sein:

local_training

Da wir lokal keine GPU verwenden, dauert das Modelltraining lange. Sie können das lokale Training mit Strg + C abbrechen, anstatt auf den Abschluss des Jobs zu warten.

Wenn Sie weitere Tests durchführen möchten, können Sie das oben erstellte Image auch direkt ausführen, ohne es neu zu verpacken.

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

7. Einen benutzerdefinierten Job erstellen

Nachdem wir den lokalen Modus getestet haben, verwenden wir die Funktion für das automatische Verpacken, um unseren benutzerdefinierten Trainingsjob in Vertex AI Training zu starten. Mit einem einzigen Befehl führt diese Funktion folgende Schritte aus:

  • Erstellen eines benutzerdefinierten Docker-Image auf Basis Ihres Codes.
  • Laden Sie das Image in Container Registry hoch.
  • Starten eines CustomJob auf der Basis des Images.

Kehren Sie zum Terminal zurück und wechseln Sie eine Ebene über das Verzeichnis autopkg-codelab.

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

Geben Sie das vordefinierte TensorFlow-GPU-Image von Vertex AI Training als Basis-Image für den benutzerdefinierten Trainingsjob an.

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

Führen Sie als Nächstes den Befehl gcloud ai custom-jobs create aus. Zuerst wird mit diesem Befehl ein benutzerdefiniertes Docker-Image auf Basis des Trainingscodes erstellt. Das Basis-Image ist der vordefinierte Vertex AI Training-Container, den wir als BASE_GPU_IMAGE festgelegt haben. Die Funktion für das automatische Verpacken installiert dann die Bibliotheken „datasets“ und „transformers“ mit pip, wie in der Datei requirements.txt angegeben.

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

Sehen wir uns das Argument worker-pool-spec an. Es definiert die Konfiguration des Worker-Pools, die vom benutzerdefinierten Job verwendet wird. Sie können mehrere Worker-Pool-Spezifikationen angeben, um einen benutzerdefinierten Job mit mehreren Worker-Pools für das verteilte Training zu erstellen. In diesem Beispiel geben wir nur einen Worker-Pool an, da unser Trainingscode nicht für das verteilte Training konfiguriert ist.

Hier sind einige der wichtigsten Felder dieser Spezifikation:

  • machine-type (erforderlich): Der Typ der Maschine. Klicken Sie hier, um die unterstützten Typen aufzurufen.
  • replica-count: Die Anzahl der Worker-Replikate, die für diesen Worker-Pool verwendet werden sollen. Standardmäßig ist der Wert 1.
  • accelerator-type: Der Typ der GPUs. Klicken Sie hier, um die unterstützten Typen aufzurufen. In diesem Beispiel haben wir eine NVIDIA Tesla V100-GPU angegeben.
  • accelerator-count: Die Anzahl der GPUs, die für jede VM im Worker-Pool verwendet werden sollen. Standardmäßig ist der Wert 1.
  • executor-image-uri: Der URI eines Container-Images, mit dem das bereitgestellte Paket ausgeführt wird. Dieser Wert ist auf unser Basis-Image festgelegt.
  • local-package-path: Der lokale Pfad eines Ordners, der Trainingscode enthält.
  • python-module: Der Name des Python-Moduls, das im bereitgestellten Paket ausgeführt werden soll.

Ähnlich wie beim Ausführen des lokalen Befehls wird das Docker-Image erstellt und dann der Trainingsjob gestartet. Anstelle der Ausgabe des Trainingsjobs wird jedoch die folgende Meldung angezeigt, die bestätigt, dass der Trainingsjob gestartet wurde. Wenn Sie den Befehl custom-jobs create zum ersten Mal ausführen, kann es einige Minuten dauern, bis das Image erstellt und hochgeladen wurde.

training_started

Kehren Sie in der Cloud Console zum Bereich „Vertex AI Training“ zurück. Unter BENUTZERDEFINIERTE JOBS sollte der Job ausgeführt werden.

training_job

Der Job dauert etwa 20 Minuten.

Nach Abschluss des Jobs sollten im Verzeichnis model_output in Ihrem Bucket die folgenden gespeicherten Modellartefakte zu sehen sein.

model_output

🎉 Das wars! 🎉

Sie haben gelernt, wie Sie Vertex AI für Folgendes verwenden:

  • Trainingscode lokal containerisieren und ausführen
  • Trainingsjobs mit der Funktion für das automatische Verpacken an Vertex AI Training senden

Weitere Informationen zu den verschiedenen Teilen von Vertex AI finden Sie in der Dokumentation.

8. Bereinigen

Da wir das Notebook so konfiguriert haben, dass es nach 60 Minuten Inaktivität beendet wird, müssen wir uns nicht um das Herunterfahren der Instanz kümmern. Wenn Sie die Instanz manuell herunterfahren möchten, klicken Sie im Bereich „Vertex AI Workbench“ der Console auf die Schaltfläche „Beenden“. Wenn Sie das Notebook vollständig löschen möchten, klicken Sie auf die Schaltfläche „Löschen“.

Löschen

Wenn Sie den Storage-Bucket löschen möchten, rufen Sie in der Cloud Console über das Navigationsmenü „Storage“ auf, wählen Sie den Bucket aus und klicken Sie auf „Löschen“:

Speicher löschen