1. Übersicht
In diesem Lab verwenden Sie Vertex AI, um einen Trainingsjob mit mehreren Workern für ein TensorFlow-Modell auszuführen.
Lerninhalte
Die folgenden Themen werden behandelt:
- Trainingsanwendungscode für das Training mit mehreren Workern ändern
- Multi-Worker-Trainingsjob über die Vertex AI-Benutzeroberfläche konfigurieren und starten
- Multi-Worker-Trainingsjob mit dem Vertex SDK konfigurieren und starten
Die Gesamtkosten für die Ausführung dieses Labs in Google Cloud belaufen sich auf etwa 5$.
2. Einführung in Vertex AI
In diesem Lab wird das neueste KI-Angebot von Google Cloud verwendet. Vertex AI integriert die ML-Angebote in Google Cloud für eine nahtlose Entwicklung. Bisher konnten auf mit AutoML trainierte Modelle und benutzerdefinierte Modelle über separate Dienste zugegriffen werden. Das neue Angebot kombiniert beide zusammen mit anderen neuen Produkten in einer einzigen API. 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 den unten aufgeführten Produkten: Training und Workbench.
3. Anwendungsfall – Übersicht
In diesem Lab trainieren Sie mithilfe von Transferlernen ein Bildklassifizierungsmodell auf dem Cassava-Dataset aus TensorFlow Datasets. Sie verwenden ein ResNet50-Modell aus der tf.keras.applications
-Bibliothek, das auf dem ImageNet-Dataset vortrainiert wurde.
Vorteile eines verteilten Trainings
Wenn Sie eine einzelne GPU haben, verwendet TensorFlow diesen Beschleuniger, um das Modelltraining ohne zusätzlichen Aufwand für Sie zu beschleunigen. Wenn Sie jedoch eine zusätzliche Leistungssteigerung durch die Verwendung mehrerer GPUs auf einem einzelnen Computer oder mehreren Computern (jeweils mit potenziell mehreren GPUs) erzielen möchten, müssen Sie tf.distribute
verwenden. Dies ist die TensorFlow-Bibliothek zum Ausführen einer Berechnung auf mehreren Geräten. Ein Gerät bezieht sich auf eine CPU oder einen Beschleuniger wie GPUs oder TPUs auf einem Computer, auf dem TensorFlow Vorgänge ausführen kann.
Der einfachste Einstieg in das verteilte Training ist ein einzelner Computer mit mehreren GPU-Geräten. Eine TensorFlow-Verteilungsstrategie aus dem tf.distribute
-Modul verwaltet die Koordination der Datenverteilung und Gradientenaktualisierungen auf allen GPUs. Wenn Sie das Training auf einem einzelnen Host gemeistert haben und noch weiter skalieren möchten, können Sie mit mehreren Maschinen in Ihrem Cluster eine noch größere Leistungssteigerung erzielen. Sie können einen Cluster von Maschinen verwenden, die nur eine CPU oder eine oder mehrere GPUs haben. In diesem Lab wird der letzte Fall behandelt und gezeigt, wie Sie mit MultiWorkerMirroredStrategy
das Training eines TensorFlow-Modells auf mehrere Maschinen in Vertex AI verteilen.
MultiWorkerMirroredStrategy
ist eine synchrone Datenparallelitätsstrategie, die Sie mit nur wenigen Codeänderungen verwenden können. Auf jedem Gerät in Ihrem Cluster wird eine Kopie des Modells erstellt. Die nachfolgenden Farbverlaufsaktualisierungen erfolgen synchron. Das bedeutet, dass jedes Worker-Gerät die Vorwärts- und Rückwärtsdurchläufe durch das Modell für einen anderen Ausschnitt der Eingabedaten berechnet. Die berechneten Gradienten aus jedem dieser Ausschnitte werden dann über alle Geräte auf einem Computer und alle Maschinen im Cluster aggregiert und in einem Prozess, der als All-Reduce bezeichnet wird, reduziert (normalerweise ein Mittelwert). Der Optimierer führt dann die Parameteraktualisierungen mit diesen reduzierten Gradienten aus und hält die Geräte so synchronisiert. Weitere Informationen zum verteilten Training mit TensorFlow finden Sie im folgenden Video:
4. Umgebung einrichten
Sie benötigen ein Google Cloud-Projekt mit aktivierter Abrechnung, um dieses Codelab ausführen zu können. 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 Option noch nicht aktiviert ist. Sie benötigen sie, um Ihre Notebookinstanz zu erstellen.
Schritt 2: Container Registry API aktivieren
Rufen Sie die Container Registry auf und wählen Sie Aktivieren aus, falls noch nicht geschehen. Damit erstellen Sie einen Container für Ihren benutzerdefinierten Trainingsjob.
Schritt 3: Vertex AI API aktivieren
Rufen Sie den Bereich „Vertex AI“ der Cloud Console auf und klicken Sie auf Vertex AI API aktivieren.
Schritt 4: Vertex AI Workbench-Instanz erstellen
Klicken Sie in der Cloud Console im Bereich „Vertex AI“ auf „Workbench“:
Aktivieren Sie die Notebooks API, falls sie noch nicht aktiviert ist.
Klicken Sie nach der Aktivierung auf VERWALTETE NOTEBOOKS:
Wählen Sie dann NEUES NOTIZBUCH aus.
Geben Sie einen Namen für das Notebook ein und klicken Sie dann auf Erweiterte Einstellungen.
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.
Wählen Sie unter Sicherheit die Option „Terminal aktivieren“ aus, falls sie noch nicht aktiviert ist.
Alle anderen erweiterten Einstellungen können Sie unverändert lassen.
Klicken Sie dann auf Erstellen. Die Bereitstellung der Instanz dauert einige Minuten.
Wählen Sie nach dem Erstellen der Instanz JupyterLab öffnen aus.
Wenn Sie eine neue Instanz zum ersten Mal verwenden, werden Sie zur Authentifizierung aufgefordert. Folgen Sie dazu den Schritten in der Benutzeroberfläche.
5. Code der Trainingsanwendung containerisieren
Sie reichen diesen Trainingsjob bei Vertex ein, indem Sie den Code Ihrer Trainingsanwendung in einen Docker-Container einfügen und diesen Container in die Google Container Registry hochladen. Mit diesem Ansatz können Sie ein Modell trainieren, das mit einem beliebigen Framework erstellt wurde.
Öffnen Sie zuerst über das Launcher-Menü ein Terminalfenster in Ihrer Notebook-Instanz:
Erstellen Sie ein neues Verzeichnis mit dem Namen cassava
und wechseln Sie dorthin:
mkdir cassava
cd cassava
Schritt 1: Dockerfile erstellen
Der erste Schritt zum Containerisieren Ihres Codes besteht darin, ein Dockerfile zu erstellen. Im Dockerfile geben Sie alle Befehle an, die zum Ausführen des Images erforderlich sind. Dadurch werden alle erforderlichen Bibliotheken installiert und der Einstiegspunkt für den Trainingscode eingerichtet.
Erstellen Sie über Ihr Terminal ein leeres Dockerfile:
touch Dockerfile
Öffnen Sie das Dockerfile und fügen Sie Folgendes ein:
FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-7
WORKDIR /
# Copies the trainer code to the docker image.
COPY trainer /trainer
# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]
Dieses Dockerfile verwendet das Deep Learning Container TensorFlow Enterprise 2.7 GPU Docker-Image. Die Deep Learning Container in Google Cloud sind mit vielen gängigen ML- und Data-Science-Frameworks vorinstalliert. Nach dem Herunterladen dieses Images wird in diesem Dockerfile der Einstiegspunkt für den Trainingscode eingerichtet. Sie haben diese Dateien noch nicht erstellt. Im nächsten Schritt fügen Sie den Code zum Trainieren und Optimieren des Modells hinzu.
Schritt 2: Cloud Storage-Bucket erstellen
In diesem Trainingsjob exportieren Sie das trainierte TensorFlow-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'
Führen Sie als Nächstes den folgenden Befehl im Terminal aus, um einen neuen Bucket in Ihrem Projekt zu erstellen.
BUCKET="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET
Schritt 3: Code zum Trainieren des Modells hinzufügen
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 cassava/
-Verzeichnis sollte nun Folgendes vorhanden sein:
+ Dockerfile
+ trainer/
+ task.py
Öffnen Sie als Nächstes die soeben erstellte Datei task.py
und kopieren Sie den folgenden Code. Ersetzen Sie {your-gcs-bucket}
durch den Namen des Cloud Storage-Buckets, den Sie gerade erstellt haben.
import tensorflow as tf
import tensorflow_datasets as tfds
import os
PER_REPLICA_BATCH_SIZE = 64
EPOCHS = 2
# TODO: replace {your-gcs-bucket} with the name of the Storage bucket you created earlier
BUCKET = 'gs://{your-gcs-bucket}/mwms'
def preprocess_data(image, label):
'''Resizes and scales images.'''
image = tf.image.resize(image, (300,300))
return tf.cast(image, tf.float32) / 255., label
def create_dataset(batch_size):
'''Loads Cassava dataset and preprocesses data.'''
data, info = tfds.load(name='cassava', as_supervised=True, with_info=True)
number_of_classes = info.features['label'].num_classes
train_data = data['train'].map(preprocess_data,
num_parallel_calls=tf.data.experimental.AUTOTUNE)
train_data = train_data.shuffle(1000)
train_data = train_data.batch(batch_size)
train_data = train_data.prefetch(tf.data.experimental.AUTOTUNE)
# Set AutoShardPolicy
options = tf.data.Options()
options.experimental_distribute.auto_shard_policy = tf.data.experimental.AutoShardPolicy.DATA
train_data = train_data.with_options(options)
return train_data, number_of_classes
def create_model(number_of_classes):
'''Creates and compiles pretrained ResNet50 model.'''
base_model = tf.keras.applications.ResNet50(weights='imagenet', include_top=False)
x = base_model.output
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = tf.keras.layers.Dense(1016, activation='relu')(x)
predictions = tf.keras.layers.Dense(number_of_classes, activation='softmax')(x)
model = tf.keras.Model(inputs=base_model.input, outputs=predictions)
model.compile(
loss='sparse_categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(0.0001),
metrics=['accuracy'])
return model
def _is_chief(task_type, task_id):
'''Helper function. Determines if machine is chief.'''
return task_type == 'chief'
def _get_temp_dir(dirpath, task_id):
'''Helper function. Gets temporary directory for saving model.'''
base_dirpath = 'workertemp_' + str(task_id)
temp_dir = os.path.join(dirpath, base_dirpath)
tf.io.gfile.makedirs(temp_dir)
return temp_dir
def write_filepath(filepath, task_type, task_id):
'''Helper function. Gets filepath to save model.'''
dirpath = os.path.dirname(filepath)
base = os.path.basename(filepath)
if not _is_chief(task_type, task_id):
dirpath = _get_temp_dir(dirpath, task_id)
return os.path.join(dirpath, base)
def main():
# Create strategy
strategy = tf.distribute.MultiWorkerMirroredStrategy()
# Get data
global_batch_size = PER_REPLICA_BATCH_SIZE * strategy.num_replicas_in_sync
train_data, number_of_classes = create_dataset(global_batch_size)
# Wrap variable creation within strategy scope
with strategy.scope():
model = create_model(number_of_classes)
model.fit(train_data, epochs=EPOCHS)
# Determine type and task of the machine from
# the strategy cluster resolver
task_type, task_id = (strategy.cluster_resolver.task_type,
strategy.cluster_resolver.task_id)
# Based on the type and task, write to the desired model path
write_model_path = write_filepath(BUCKET, task_type, task_id)
model.save(write_model_path)
if __name__ == "__main__":
main()
Bevor Sie den Container erstellen, werfen wir einen genaueren Blick auf den Code, der MultiWorkerMirroredStrategy
aus der tf.distribute.Strategy
API verwendet.
Der Code enthält einige Komponenten, die erforderlich sind, damit der Code mit MultiWorkerMirroredStrategy
funktioniert.
- Die Daten müssen in Shards aufgeteilt werden, d. h., jedem Worker wird ein Teil des gesamten Datensatzes zugewiesen. Daher wird in jedem Schritt eine globale Batchgröße von sich nicht überlappenden Dataset-Elementen von jedem Worker verarbeitet. Diese Sharding-Funktion wird bei
tf.data.experimental.AutoShardPolicy
automatisch aktiviert.tf.data.experimental.AutoShardPolicy
kann aufFILE
oderDATA
gesetzt werden. In diesem Beispiel wird durch die Funktioncreate_dataset()
dieAutoShardPolicy
aufDATA
festgelegt, da das Cassava-Dataset nicht als mehrere Dateien heruntergeladen wird. Wenn Sie die Richtlinie jedoch nicht aufDATA
festgelegt haben, wird die StandardrichtlinieAUTO
angewendet und das Endergebnis ist dasselbe. Weitere Informationen zum Sharding von Datensätzen mitMultiWorkerMirroredStrategy
- In der Funktion
main()
wird dasMultiWorkerMirroredStrategy
-Objekt erstellt. Als Nächstes schließen Sie die Erstellung Ihrer Modellvariablen in den Bereich der Strategie ein. Bei diesem wichtigen Schritt wird TensorFlow mitgeteilt, welche Variablen über die Replikate hinweg gespiegelt werden sollen. - Die Batchgröße wird um den Wert von
num_replicas_in_sync
skaliert. So wird sichergestellt, dass jedes Replik bei jedem Schritt dieselbe Anzahl von Beispielen verarbeitet. Die Batchgröße zu skalieren, ist eine Best Practice bei der Verwendung von Strategien für die synchrone Datenparallelität in TensorFlow. - Bei mehreren Workern ist das Speichern des Modells etwas komplizierter, da das Ziel für jeden Worker unterschiedlich sein muss. Der Chief Worker speichert das Modell im gewünschten Modellverzeichnis, während die anderen Worker das Modell in temporären Verzeichnissen speichern. Es ist wichtig, dass diese temporären Verzeichnisse eindeutig sind, um zu verhindern, dass mehrere Worker in denselben Speicherort schreiben. Das Speichern kann kollektive Vorgänge umfassen, d. h., alle Worker müssen speichern, nicht nur der Haupt-Worker. Die Funktionen
_is_chief()
,_get_temp_dir()
,write_filepath()
undmain()
enthalten Boilerplate-Code, mit dem das Modell gespeichert werden kann.
Wenn Sie MultiWorkerMirroredStrategy
bereits in einer anderen Umgebung verwendet haben, haben Sie möglicherweise die Umgebungsvariable TF_CONFIG
eingerichtet. Vertex AI legt TF_CONFIG
automatisch für Sie fest, sodass Sie diese Variable nicht auf jeder Maschine im Cluster definieren müssen.
Schritt 4: Container erstellen
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'
Definieren Sie in Google Container Registry eine Variable mit dem URI Ihres Container-Images:
IMAGE_URI="gcr.io/$PROJECT_ID/multiworker:cassava"
Docker konfigurieren
gcloud auth configure-docker
Erstellen Sie dann den Container, indem Sie im Stammverzeichnis von cassava
Folgendes ausführen:
docker build ./ -t $IMAGE_URI
Übertragen Sie die Datei anschließend per Push in Google Container Registry:
docker push $IMAGE_URI
Nachdem der Container in Container Registry hochgeladen wurde, können Sie den Trainingsjob starten.
6. Mehrere Jobs für die verteilte Modellerstellung in Vertex AI ausführen
In diesem Lab wird ein benutzerdefiniertes Training über einen benutzerdefinierten Container in der Google Container Registry verwendet. Sie können aber auch einen Trainingsjob mit den vordefinierten Containern ausführen.
Rufen Sie zuerst in der Cloud Console im Bereich „Vertex“ den Bereich Training auf:
Schritt 1: Trainingsjob konfigurieren
Klicken Sie auf Erstellen, um die Parameter für den Trainingsjob einzugeben.
- Wählen Sie unter Dataset die Option Kein verwaltetes Dataset aus.
- Wählen Sie dann Benutzerdefiniertes Training (erweitert) als Trainingsmethode aus und klicken Sie auf Weiter.
- Geben Sie
multiworker-cassava
(oder einen beliebigen Namen) für Modellname ein. - Klicken Sie auf Weiter.
Wählen Sie im Schritt „Containereinstellungen“ die Option Benutzerdefinierter Container aus:
Geben Sie im ersten Feld (Container-Image) den Wert der Variablen IMAGE_URI
aus dem vorherigen Abschnitt ein. Es sollte gcr.io/your-cloud-project/multiworker:cassava
mit Ihrer eigenen Projekt-ID sein. Lassen Sie die anderen Felder leer und klicken Sie auf Continue (Weiter).
Überspringen Sie den Schritt „Hyperparameter“ und klicken Sie noch einmal auf Weiter.
Schritt 2: Rechencluster konfigurieren
Vertex AI bietet 4 Worker-Pools, um die verschiedenen Arten von Maschinenaufgaben abzudecken.
Worker-Pool 0 konfiguriert den Primär-, Chief-, Planer- oder „Master“. In MultiWorkerMirroredStrategy
werden alle Maschinen als Worker bezeichnet. Das sind die physischen Maschinen, auf denen die replizierte Berechnung ausgeführt wird. Zusätzlich dazu, dass jeder Rechner ein Worker ist, muss es einen Worker geben, der zusätzliche Arbeit übernimmt, z. B. das Speichern von Prüfpunkten und das Schreiben von Zusammenfassungsdateien in TensorBoard. Diese Maschine wird als „Chief“ bezeichnet. Es gibt immer nur einen Haupt-Worker. Die Anzahl der Worker für Worker-Pool 0 ist daher immer 1.
Lassen Sie unter Computing und Preise die ausgewählte Region unverändert und konfigurieren Sie Worker-Pool 0 so:
Unter „Worker-Pool 1“ konfigurieren Sie die Worker für Ihren Cluster.
Konfigurieren Sie Worker-Pool 1 so:
Der Cluster ist jetzt so konfiguriert, dass er zwei reine CPU-Maschinen hat. Wenn der Code der Trainingsanwendung ausgeführt wird, verteilt MultiWorkerMirroredStrategy
das Training auf beide Maschinen.
MultiWorkerMirroredStrategy
hat nur die Aufgabentypen „Leiter“ und „Arbeiter“. Daher müssen keine zusätzlichen Worker-Pools konfiguriert werden. Wenn Sie jedoch ParameterServerStrategy
von TensorFlow verwenden, würden Sie Ihre Parameterserver in Worker-Pool 2 konfigurieren. Wenn Sie Ihrem Cluster einen Evaluator hinzufügen möchten, konfigurieren Sie diese Maschine in Worker-Pool 3.
Klicken Sie auf Training starten, um den Hyperparameter-Abstimmungsjob zu starten. Im Bereich „Training“ der Console wird auf dem Tab TRAININGSPIPELINES der neu gestartete Job angezeigt:
🎉 Glückwunsch! 🎉
Sie haben gelernt, wie Sie Vertex AI für Folgendes verwenden:
- Einen Trainingsjob für mehrere Worker für Trainingscode starten, der in einem benutzerdefinierten Container bereitgestellt wird. In diesem Beispiel wurde ein TensorFlow-Modell verwendet. Sie können aber auch ein mit einem beliebigen Framework erstelltes Modell mit benutzerdefinierten oder integrierten Containern trainieren.
Weitere Informationen zu den verschiedenen Bereichen von Vertex finden Sie in der Dokumentation.
7. [Optional] Vertex SDK verwenden
Im vorherigen Abschnitt wurde gezeigt, wie Sie den Trainingsjob über die Benutzeroberfläche starten. In diesem Abschnitt erfahren Sie, wie Sie den Trainingsjob mithilfe der Vertex Python API einreichen können.
Kehren Sie zu Ihrer Notebook-Instanz zurück und erstellen Sie über den Launcher ein TensorFlow 2-Notebook:
Importieren Sie das Vertex AI SDK.
from google.cloud import aiplatform
Um den Trainingsjob mit mehreren Workern zu starten, müssen Sie zuerst die Worker-Pool-Spezifikation definieren. Die Verwendung von GPUs in der Spezifikation ist völlig optional. Sie können accelerator_type
und accelerator_count
entfernen, wenn Sie einen reinen CPU-Cluster wie im vorherigen Abschnitt gezeigt benötigen.
# The spec of the worker pools including machine type and Docker image
# Be sure to replace {YOUR-PROJECT-ID} with your project ID.
worker_pool_specs=[
{
"replica_count": 1,
"machine_spec": {
"machine_type": "n1-standard-8", "accelerator_type": "NVIDIA_TESLA_V100", "accelerator_count": 1
},
"container_spec": {"image_uri": "gcr.io/{YOUR-PROJECT-ID}/multiworker:cassava"}
},
{
"replica_count": 1,
"machine_spec": {
"machine_type": "n1-standard-8", "accelerator_type": "NVIDIA_TESLA_V100", "accelerator_count": 1
},
"container_spec": {"image_uri": "gcr.io/{YOUR-PROJECT-ID}/multiworker:cassava"}
}
]
Erstellen und führen Sie als Nächstes einen CustomJob
aus. Ersetzen Sie {YOUR_BUCKET}
in Ihrem Projekt durch einen Bucket für das Staging. Sie können denselben Bucket verwenden, den Sie zuvor erstellt haben.
# Replace YOUR_BUCKET
my_multiworker_job = aiplatform.CustomJob(display_name='multiworker-cassava-sdk',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
my_multiworker_job.run()
Im Abschnitt "Training" der Konsole auf dem Tab BENUTZERDEFINIERTE JOBS sehen Sie Ihren Trainingsjob:
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 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“.
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“: