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 mit der Funktion zum automatischen Paketieren einen benutzerdefinierten Trainingsjob in Vertex AI Training ausführen. Für benutzerdefinierte Trainingsjobs in Vertex AI werden Container verwendet. Wenn Sie kein eigenes Image erstellen möchten, können Sie das Autopackaging verwenden. Dabei wird ein benutzerdefiniertes Docker-Image basierend auf Ihrem Code erstellt, das Image in die Container Registry hochgeladen und ein CustomJob basierend auf dem Image gestartet.

Lerninhalte

Die folgenden Themen werden behandelt:

  • Verwenden Sie den lokalen Modus, um Ihren Code zu testen.
  • Konfigurieren und starten Sie einen benutzerdefinierten Trainingsjob mit Auto-Paketierung.

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

2. Anwendungsfall – Übersicht

Mithilfe von Bibliotheken von Hugging Face optimieren Sie ein Bert-Modell anhand des IMDB-Datasets. Das Modell sagt vorher, ob eine Filmrezension 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-Produktangebot von Google Cloud verwendet. Vertex AI bindet die ML-Angebote in Google Cloud in eine nahtlose Entwicklungsumgebung ein. Bisher konnten auf mit AutoML trainierte Modelle und benutzerdefinierte Modelle über separate Dienste zugegriffen werden. Das neue Angebot vereint beides in einer einzigen API sowie weitere neue Produkte. Sie können auch vorhandene Projekte zu Vertex AI migrieren. Wenn du Feedback hast, sieh auf der Supportseite nach.

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

Vertex-Produktübersicht

4. Umgebung einrichten

Sie benötigen ein Google Cloud-Projekt mit aktivierter Abrechnung, um dieses Codelab ausführen zu können. Folgen Sie dieser Anleitung, um ein Projekt zu erstellen.

Schritt 1: Compute Engine API aktivieren

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

Schritt 2: Vertex AI API aktivieren

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

Vertex AI-Dashboard

Schritt 3: Container Registry API aktivieren

Rufen Sie die Container Registry auf und wählen Sie Aktivieren aus, falls noch nicht geschehen. Sie verwenden es, um einen Container für Ihren benutzerdefinierten Trainingsjob zu erstellen.

Schritt 4: Vertex AI Workbench-Instanz erstellen

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

Vertex AI-Menü

Klicken Sie dort auf VERWALTETE NOTEBOOKS:

Notebooks_UI

Wählen Sie dann NEUES NOTEBOOK aus.

new_notebook

Geben Sie einen Namen für das Notebook ein und klicken Sie dann 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 Notebook wird also automatisch heruntergefahren, wenn es nicht verwendet wird, sodass keine unnötigen Kosten entstehen.

idle_timeout

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

Klicken Sie dann auf Erstellen.

Wählen Sie nach dem Erstellen der Instanz JupyterLab öffnen aus.

open_jupyterlab

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

Authentifizieren

5. Trainingscode schreiben

Öffnen Sie zuerst über das Launcher-Menü ein Terminalfenster in Ihrer Notebook-Instanz:

launcher_terminal

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

mkdir autopkg-codelab
cd autopkg-codelab

Führen Sie im Terminal Folgendes 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 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()

Hinweise zum Code:

  • CHECKPOINT ist das Modell, das wir optimieren möchten. In diesem Fall verwenden wir Bert.
  • Mit der Methode TFAutoModelForSequenceClassification wird die angegebene Architektur des Sprachmodells und die Gewichte in TensorFlow geladen und ein Klassifizierungs-Head mit zufällig initialisierten Gewichten hinzugefügt. 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 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, nutzen 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 Container für Vertex AI Training.

Führen Sie Folgendes aus, um den URI eines Docker-Images als Basis des Containers festzulegen.

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 „local run“ erstellt wird.

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

Unser Trainingscode verwendet die Datasets und Transformers-Bibliotheken 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 requirements.txt-Datei im Verzeichnis autopkg-codelab.

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

touch requirements.txt

Ihr autopkg-codelab-Verzeichnis sollte jetzt so aussehen:

+ 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 abschließend den Befehl gcloud ai custom-jobs local-run aus, um das Training auf unserer 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

Das Docker-Image wird erstellt. Die Abhängigkeiten, die wir der Datei requirements.txt hinzugefügt haben, werden mit pip installiert. Wenn Sie diesen Befehl zum ersten Mal ausführen, kann das einige Minuten dauern. Sobald das Image erstellt wurde, wird die task.py-Datei ausgeführt und Sie sehen das Modelltraining. Auf dem Bildschirm sollte Folgendes zu sehen sein:

local_training

Da wir lokal keine GPU verwenden, dauert das Modelltraining sehr 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 zum automatischen Paketieren, um unseren benutzerdefinierten Trainingsjob in Vertex AI Training zu starten. Mit dieser Funktion können Sie mit nur einem Befehl 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 wechseln Sie mit „cd“ eine Ebene über das Verzeichnis autopkg-codelab.

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

Geben Sie das vorkonfigurierte 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. Mit diesem Befehl wird zuerst ein benutzerdefiniertes Docker-Image basierend auf dem Trainingscode erstellt. Das Basis-Image ist der vordefinierte Container für Vertex AI Training, den wir als BASE_GPU_IMAGE festgelegt haben. Die Funktion für die automatische 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 unser Trainingscode nicht für das verteilte 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. Standardmäßig ist der Wert „1“.
  • accelerator-type: Der Typ der GPUs. Hier finden Sie eine Liste der unterstützten Typen. 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 soll. Standardmäßig ist der Wert „1“.
  • executor-image-uri: Der URI eines Container-Images, in dem das bereitgestellte Paket ausgeführt wird. Dieser Wert ist auf unser Basisbild 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 beim Ausführen des lokalen Befehls sehen Sie, wie das Docker-Image erstellt und dann der Trainingsjob gestartet wird. Anstatt die 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 gepusht 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.

Danach sollten Sie die folgenden gespeicherten Modellartefakte im Verzeichnis model_output in Ihrem Bucket sehen.

model_output

🎉 Glückwunsch! 🎉

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

  • Trainingscode lokal containerisieren und ausführen
  • Trainingsjobs mit automatischem Paketieren an Vertex AI Training senden

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

8. Bereinigen

Da wir das Notebook so konfiguriert haben, dass nach 60 Minuten Inaktivität ein Zeitlimit erreicht wird, müssen wir uns keine Gedanken über das Herunterfahren der Instanz machen. Wenn Sie die Instanz manuell herunterfahren möchten, klicken Sie in der Console im Bereich „Vertex AI Workbench“ auf die Schaltfläche „Beenden“. Wenn Sie das Notizbuch vollständig löschen möchten, klicken Sie auf die Schaltfläche „Löschen“.

Löschen

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

Speicher löschen