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 die automatische Paketerstellung ausführen. Benutzerdefinierte Trainingsjobs in Vertex AI verwenden Container. Wenn Sie kein eigenes Image erstellen möchten, können Sie Autopackaging verwenden. Dabei wird ein benutzerdefiniertes Docker-Image basierend auf Ihrem Code erstellt, das Image in Container Registry hochgeladen und ein CustomJob auf der Grundlage des Images gestartet.

Lerninhalte

Die folgenden Themen werden behandelt:

Die Gesamtkosten für das Lab in Google Cloud belaufen sich auf 2$.

2. Anwendungsfall – Übersicht

Sie können ein Bert-Modell für das IMDB-Dataset mithilfe von Bibliotheken aus Hugging Face abstimmen. Das Modell sagt vorher, ob eine Filmrezension positiv oder negativ ist. Das Dataset wird aus der Hugging Face-Dataset-Bibliothek und das Bert-Modell aus der Hugging Face-Transformer-Bibliothek heruntergeladen.

3. Einführung in Vertex AI

In diesem Lab wird das neueste KI-Produktangebot von Google Cloud verwendet. Vertex AI bindet die ML-Angebote in Google Cloud in eine nahtlose Entwicklungsumgebung ein. Zuvor waren mit AutoML trainierte und benutzerdefinierte Modelle über separate Dienste zugänglich. Das neue Angebot vereint beides in einer einzigen API sowie weitere neue Produkte. Sie können auch vorhandene Projekte zu Vertex AI migrieren. Wenn Sie uns Feedback geben möchten, besuchen Sie die Supportseite.

Vertex AI enthält 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. Folgen Sie dieser Anleitung, um ein Projekt zu erstellen.

Schritt 1: Compute Engine API aktivieren

Gehen Sie zu Compute Engine und wählen Sie Aktivieren aus, falls dies noch nicht geschehen ist.

Schritt 2: Vertex AI API aktivieren

Rufen Sie den Bereich Vertex AI in der Cloud Console 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 noch nicht geschehen. Damit erstellen Sie einen Container für Ihren benutzerdefinierten Trainingsjob.

Schritt 4: Vertex AI Workbench-Instanz erstellen

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

Vertex AI-Menü

Klicke dort auf VERWALTETE NOTEBOOKS:

Notebooks_UI

Wählen Sie dann NEUES NOTEBOOK aus.

new_notebook

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

create_notebook

Aktivieren Sie unter „Erweiterte Einstellungen“ das Herunterfahren bei Inaktivität und legen Sie die Anzahl der Minuten auf 60 fest. Das bedeutet, dass Ihr Notebook bei Nichtgebrauch automatisch heruntergefahren wird, sodass Ihnen keine unnötigen Kosten entstehen.

idle_timeout

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

Klicken Sie dann auf Erstellen.

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

open_jupyterlab

Wenn Sie zum ersten Mal eine neue Instanz verwenden, werden Sie zur Authentifizierung aufgefordert.

Authentifizieren

5. Trainingscode schreiben

Öffnen Sie dazu im Launcher-Menü ein Terminalfenster in Ihrer Notebookinstanz:

launcher_terminal

Erstellen Sie ein neues Verzeichnis mit dem Namen autopkg-codelab und fügen Sie es mit cd ein.

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 die Sie den Code einfügen:

mkdir trainer
touch trainer/task.py

In Ihrem autopkg-codelab/-Verzeichnis sollte nun Folgendes vorhanden sein:

+ trainer/
    + task.py

Öffnen Sie als Nächstes die soeben erstellte Datei task.py und kopieren Sie den unten stehenden 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()

Wichtige Hinweise zum Code:

  • CHECKPOINT ist das Modell, das abgestimmt werden soll. In diesem Fall verwenden wir Bert.
  • Die Methode TFAutoModelForSequenceClassification lädt die angegebene Sprachmodellarchitektur und Gewichtungen in TensorFlow und fügt oben einen Klassifizierungskopf mit zufällig initialisierten Gewichtungen hinzu. In diesem Fall gibt es ein binäres Klassifizierungsproblem (positiv oder negativ), also geben wir num_labels=2 für diesen Klassifikator 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 ähnlich wie in Vertex AI Training ausgeführt. So können Sie Probleme mit Ihrem Code beheben, bevor Sie benutzerdefiniertes Training in Vertex AI ausführen.

In unserem Trainingsjob exportieren Sie 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 bereits einen Bucket haben, können Sie diesen 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 lokalen Befehl „run“ erstellt wurde.

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

Unser Trainingscode verwendet die Hugging Face-Datasets und Transformer-Bibliotheken. Diese Bibliotheken sind nicht in dem Image enthalten, das wir als Basis-Image ausgewählt haben. Daher müssen wir sie als Anforderungen angeben. Dazu erstellen wir eine requirements.txt-Datei in unserem autopkg-codelab-Verzeichnis.

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

touch requirements.txt

In Ihrem autopkg-codelab-Verzeichnis sollte nun Folgendes vorhanden sein:

+ requirements.txt
+ trainer/
    + task.py

Öffnen Sie die Anforderungsdatei und fügen Sie Folgendes ein:

datasets==1.18.2
transformers==4.16.2

Führen Sie abschließend den Befehl gcloud ai custom-jobs local-run aus, um das Training der von Workbench verwalteten 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

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

local_training

Da wir eine GPU nicht lokal verwenden, dauert das Modelltraining sehr lange. Sie können Strg + C drücken und das lokale Training 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 verpacken zu müssen.

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

7. Einen benutzerdefinierten Job erstellen

Nachdem Sie den lokalen Modus getestet haben, verwenden wir die Funktion zur automatischen Paketerstellung, um unseren benutzerdefinierten Trainingsjob in Vertex AI Training zu starten. Mit einem einzigen Befehl können Sie für diese Funktion Folgendes tun:

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

Kehren Sie zum Terminal zurück und klicken Sie mit „cd“ eine Ebene über dem Verzeichnis autopkg-codelab nach oben.

+ 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 erstellt dieser Befehl ein benutzerdefiniertes Docker-Image basierend auf dem Trainingscode. Das Basis-Image ist der vorkonfigurierte Vertex AI Training-Container, den wir als BASE_GPU_IMAGE festgelegt haben. Die Funktion zur automatischen Paketerstellung installiert dann die Datasets und Transformer-Bibliotheken wie in unserer requirements.txt-Datei angegeben per 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

Sehen wir uns das Argument worker-pool-spec an. Definiert die vom benutzerdefinierten Job verwendete Worker-Pool-Konfiguration. Sie können mehrere Worker-Pool-Spezifikationen angeben, um einen benutzerdefinierten Job mit mehreren Worker-Pools für verteiltes Training zu erstellen. In diesem Beispiel geben wir nur einen einzelnen Worker-Pool an, da der Trainingscode nicht für verteiltes Training konfiguriert ist.

Hier sind einige der wichtigsten Felder dieser Spezifikation:

  • machine-type (erforderlich): Der Maschinentyp. Klicken Sie hier, um sich unterstützte Typen anzusehen.
  • replica-count: Die Anzahl der Worker-Replikate, die für diesen Worker-Pool verwendet werden sollen. Der Standardwert ist 1.
  • accelerator-type: Der GPU-Typ. Klicken Sie hier, um sich unterstützte Typen anzusehen. 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. Der Standardwert ist 1.
  • executor-image-uri: Der URI eines Container-Images, das das bereitgestellte Paket ausführt. Dies 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 angegebenen Paket ausgeführt werden soll.

Ähnlich wie bei der Ausführung des lokalen Befehls sehen Sie, wie das Docker-Image erstellt wird und dann der Trainingsjob gestartet wird. Außer statt der Ausgabe des Trainingsjobs wird 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 per Push übertragen wurde.

training_started

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

training_job

Die Ausführung des Jobs dauert etwa 20 Minuten.

Anschließend sollten die folgenden gespeicherten Modellartefakte im Verzeichnis model_output Ihres Buckets angezeigt werden.

model_output

🎉 Glückwunsch! 🎉

Sie haben gelernt, wie Sie mit Vertex AI Folgendes tun können:

  • Trainingscode lokal containerisieren und ausführen
  • Trainingsjobs mit automatischer Paketerstellung 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 nach 60 Minuten Inaktivität eine Zeitüberschreitung auftritt, müssen wir uns nicht um das Herunterfahren der Instanz kümmern. Wenn Sie die Instanz manuell herunterfahren möchten, klicken Sie in der Console im Abschnitt Vertex AI Workbench auf die Schaltfläche „Stop“. Wenn Sie das Notizbuch vollständig löschen möchten, klicken Sie auf Löschen.

Löschen

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

Speicher löschen