Auf dieser Seite wird beschrieben, wie Sie verteilte Trainingsjobs auf Vertex AI ausführen.
Codeanforderungen
Verwenden Sie ein ML-Framework, das verteiltes Training unterstützt. In Ihrem Trainingscode können Sie die Umgebungsvariablen CLUSTER_SPEC
oder TF_CONFIG
verwenden, um auf bestimmte Teile Ihres Trainingsclusters zu verweisen.
Struktur des Trainingsclusters
Wenn Sie einen verteilten Trainingsjob mit Vertex AI ausführen, legen Sie mehrere Maschinen (Knoten) in einem Trainingscluster fest. Der Trainingsdienst weist die Ressourcen für die von Ihnen angegebenen Maschinentypen zu. Der aktuell auf einem Knoten ausgeführte Job wird als Replikat bezeichnet. Eine Gruppe von Replikaten mit derselben Konfiguration wird als Worker-Pool bezeichnet.
Jedem Replikat im Trainingscluster wird eine einzelne Rolle oder Aufgabe im verteilten Training zugewiesen. Beispiel:
Primäres Replikat: Genau ein Replikat wird als primäres Replikat festgelegt. Es verwaltet die anderen Replikate und meldet den Gesamtstatus des Jobs.
Worker: Es können ein oder mehrere Replikate als Worker festgelegt werden. Diese Replikate übernehmen jeweils einen Teil der Arbeit, wie Sie dies in der Jobkonfiguration festgelegt haben.
Parameterserver: Wenn Ihr ML-Framework unterstützt wird, können ein oder mehrere Replikate als Parameterserver festgelegt werden. Diese Replikate speichern Modellparameter und koordinieren den gemeinsamen Modellstatus unter den Workern.
Evaluator(s):: Wenn Ihr ML-Framework unterstützt wird, können ein oder mehrere Replikate als Evaluators bezeichnet werden. Es ist möglich, diese Replikate zur Bewertung Ihres Modells zu verwenden. Wenn Sie TensorFlow verwenden, wird im Allgemeinen davon ausgegangen, dass Sie nicht mehr als einen Evaluator verwenden.
Verteilten Trainingsjob konfigurieren
Sie können jeden benutzerdefinierten Trainingsjob als verteilten Trainingsjob konfigurieren, indem Sie mehrere Worker-Pools definieren. Sie können verteiltes Training auch in einer Trainingspipeline oder einem Hyperparameter-Abstimmungsjob ausführen.
Zum Konfigurieren eines verteilten Trainingsjobs definieren Sie Ihre Liste der Worker-Pools (workerPoolSpecs[]
) und legen Sie dabei WorkerPoolSpec
für jeden Aufgabentyp fest:
Position in workerPoolSpecs[] |
Im Cluster ausgeführte Aufgabe |
---|---|
Erste (workerPoolSpecs[0] ) |
Primary, chief, scheduler oder "master" |
Zweite (workerPoolSpecs[1] ) |
Secondary, replicas, workers |
Dritte (workerPoolSpecs[2] ) |
Parameterserver, Reduction Server |
Vierte (workerPoolSpecs[3] ) |
Evaluators |
Sie müssen ein primäres Replikat angeben, das die Arbeit aller anderen Replikate koordiniert. Verwenden Sie die erste Worker-Pool-Spezifikation nur für das primäre Replikat und legen Sie deren replicaCount
auf 1
fest:
{
"workerPoolSpecs": [
// `WorkerPoolSpec` for worker pool 0, primary replica, required
{
"machineSpec": {...},
"replicaCount": 1,
"diskSpec": {...},
...
},
// `WorkerPoolSpec` for worker pool 1, optional
{},
// `WorkerPoolSpec` for worker pool 2, optional
{},
// `WorkerPoolSpec` for worker pool 3, optional
{}
]
...
}
Zusätzliche Worker-Pools angeben
Je nach ML-Framework können Sie zusätzliche Worker-Pools für andere Zwecke angeben. Wenn Sie beispielsweise TensorFlow verwenden, können Sie Worker-Pools angeben, um Worker-Replikate, Parameterserver-Replikate und Bewertungsreplikate zu konfigurieren.
Die Reihenfolge der Worker-Pools, die Sie in der Liste workerPoolSpecs[]
angeben, bestimmt den Typ des Worker-Pools. Legen Sie leere Werte für Worker-Pools fest, die Sie nicht verwenden möchten, damit Sie sie in der Liste workerPoolSpecs[]
überspringen können, um Worker-Pools anzugeben, die Sie verwenden möchten. Beispiel:
Wenn Sie einen Job angeben möchten, der nur ein primäres Replikat und einen Parameterserver-Worker-Pool enthält, müssen Sie für den Worker-Pool einen leeren Wert festlegen:
{
"workerPoolSpecs": [
// `WorkerPoolSpec` for worker pool 0, required
{
"machineSpec": {...},
"replicaCount": 1,
"diskSpec": {...},
...
},
// `WorkerPoolSpec` for worker pool 1, optional
{},
// `WorkerPoolSpec` for worker pool 2, optional
{
"machineSpec": {...},
"replicaCount": 1,
"diskSpec": {...},
...
},
// `WorkerPoolSpec` for worker pool 3, optional
{}
]
...
}
Trainingszeit mit Reduction Server reduzieren
Wenn Sie ein großes ML-Modell mit mehreren Knoten trainieren, kann die Kommunikation von Gradienten zwischen Knoten zu einer erheblichen Latenz führen. Reduction Server ist ein All-Reduce-Algorithmus, der den Durchsatz erhöhen und die Latenz für verteiltes Training reduzieren kann. Vertex AI stellt Reduction Server in einem Docker-Container-Image zur Verfügung, das Sie während des verteilten Trainings für einen Ihrer Worker-Pools verwenden können.
Informationen zur Funktionsweise von Reduction Server finden Sie unter Schnelleres verteiltes GPU-Training mit Reduction Server auf Vertex AI.
Vorbereitung
Sie können Reduction Server verwenden, wenn Sie die folgenden Anforderungen erfüllen:
Sie führen verteiltes Training mit GPU-Workern durch.
Der Trainingscode verwendet TensorFlow oder PyTorch und ist für das datenparallele Training mit mehreren Hosts und GPUs konfiguriert. Dabei wird NCCL-All-Reduce verwendet. (Sie können auch andere ML-Frameworks verwenden, die NCCL verwenden.)
Die Container, die auf Ihrem primären Knoten (
workerPoolSpecs[0]
) und Ihren Workern (workerPoolSpecs[1]
) ausgeführt werden, unterstützen Reduction Server. Jeder Container ist einer der folgenden:Ein vordefinierter TensorFlow-Trainingscontainer ab Version 2.3.
Ein vordefinierter Pytorch-Trainingscontainer ab Version 1.4.
Ein benutzerdefinierter Container mit NCCL 2.7 oder höher und installiertem Paket
google-reduction-server
. Sie können dieses Paket auf einem benutzerdefinierten Container-Image installieren. Dazu fügen Sie Ihrem Dockerfile die folgende Zeile hinzu:RUN echo "deb https://packages.cloud.google.com/apt google-fast-socket main" | tee /etc/apt/sources.list.d/google-fast-socket.list && \ curl -s -L https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \ apt update && apt install -y google-reduction-server
Mit Reduction Server trainieren
Wenn Sie Reduction Server verwenden, gehen Sie beim Erstellen einer benutzerdefinierten Trainingsressource so vor:
Geben Sie im Feld
containerSpec.imageUri
des dritten Worker-Pools (workerPoolSpecs[2]
) einen der folgenden URIs an:us-docker.pkg.dev/vertex-ai-restricted/training/reductionserver:latest
europe-docker.pkg.dev/vertex-ai-restricted/training/reductionserver:latest
asia-docker.pkg.dev/vertex-ai-restricted/training/reductionserver:latest
Wenn Sie den multiregionalen Standort auswählen, der dem Ort des benutzerdefinierten Trainings am nächsten ist, kann die Latenz verringert werden.
Achten Sie bei der Auswahl des Maschinentyps und der Anzahl der Knoten für den dritten Worker-Pool darauf, dass die gesamte Netzwerkbandbreite des dritten Worker-Pools mindestens der gesamten Netzwerkbandbreite des ersten und des zweiten Worker-Pools entspricht.
Informationen zur maximal verfügbaren Bandbreite jedes Knotens im zweiten Worker-Pool finden Sie unter Netzwerkbandbreite und GPUs.
Sie verwenden keine GPUs für Reduction Server-Knoten. Informationen zur maximalen verfügbaren Bandbreite jedes Knotens im dritten Worker-Pool finden Sie in der Spalte "Maximale Bandbreite für ausgehenden Traffic (Gbit/s)" unter Maschinenfamilie für allgemeine Zwecke.
Wenn Sie beispielsweise den ersten und zweiten Worker-Pool für die Verwendung von 5
n1-highmem-96
-Knoten mit jeweils 8NVIDIA_TESLA_V100
-GPUs konfigurieren, hat jeder Knoten eine maximale verfügbare Bandbreite von 100 Gbit/s für eine Gesamtbandbreite von 500 Gbit/s. Zum Erreichen dieser Bandbreite im dritten Worker-Pool können Sie 16n1-highcpu-16
-Knoten mit jeweils einer maximalen Bandbreite von 32 Gbit/s und einer Gesamtbandbreite von 512 Gbit/s verwenden.Wir empfehlen die Verwendung des Maschinentyps
n1-highcpu-16
für Reduction Server-Knoten, da dieser Maschinentyp eine relativ hohe Bandbreite für seine Ressourcen bietet.
Der folgende Befehl zeigt ein Beispiel für das Erstellen einer CustomJob
-Ressource, die Reduction Server verwendet:
gcloud ai custom-jobs create \
--region=LOCATION \
--display-name=JOB_NAME \
--worker-pool-spec=machine-type=n1-highmem-96,replica-count=1,accelerator-type=NVIDIA_TESLA_V100,accelerator-count=8,container-image-uri=CUSTOM_CONTAINER_IMAGE_URI \
--worker-pool-spec=machine-type=n1-highmem-96,replica-count=4,accelerator-type=NVIDIA_TESLA_V100,accelerator-count=8,container-image-uri=CUSTOM_CONTAINER_IMAGE_URI \
--worker-pool-spec=machine-type=n1-highcpu-16,replica-count=16,container-image-uri=us-docker.pkg.dev/vertex-ai-restricted/training/reductionserver:latest
Weitere Informationen finden Sie im Leitfaden zum Erstellen eines CustomJob
.
Best Practices für das Training mit Reduction Server
Maschinentyp und Anzahl
Im Training mit Reduction Server muss jeder Worker eine Verbindung zu allen Reducer-Hosts herstellen. Verwenden Sie einen Maschinentyp mit der höchsten Netzwerkbandbreite für Ihren Reducer-Host, um die Anzahl der Verbindungen auf dem Worker-Host zu minimieren.
Eine gute Wahl für Reducer-Hosts ist eine allgemeine N1/N2-VM mit mindestens 16 vCPUs, die eine Bandbreite für ausgehenden Traffic von 32 Gbit/s bietet, beispielsweise n1-highcpu-16
und n2-highcpu-16
. Die Tier 1-VM-Bandbreite für N1/N2-VMs erhöht die maximale Bandbreite für ausgehenden Traffic von 50 Gbit/s bis 100 Gbit/s. Dies ist eine gute Wahl für Reducer-VM-Knoten.
Die Gesamtbandbreite für ausgehenden Traffic von Workern und Reducern sollte identisch sein. Wenn Sie beispielsweise 8 a2-megagpu-16g
-VMs als Worker verwenden, sollten Sie mindestens 25 n1-highcpu-16
-VMs als Reducer verwenden.
`(8 worker VMs * 100 Gbps) / 32 Gbps egress = 25 reducer VMs`.
Kleine Nachrichten im Batch zusammenfassen
Der Reduction Server funktioniert am besten, wenn die zu aggregierenden Nachrichten ausreichend groß sind. Die meisten ML-Frameworks bieten bereits Techniken mit unterschiedlichen Terminologien für das Batching kleiner Gradiententensoren, bevor der All-Reduce-Vorgang durchgeführt wird.
Horovod
Horovod unterstützt Tensor Fusion, um kleine Tensoren für den All-Reduce-Vorgang in Batches aufzuteilen. Tensoren werden in einem Fusionspuffer gefüllt, bis der Puffer vollständig gefüllt ist und der All-Reduce-Vorgang für den Zwischenspeicher ausgeführt wird. Sie können die Größe des Fusionspuffers anpassen, indem Sie die Umgebungsvariable HOROVOD_FUSION_THRESHOLD
festlegen.
Der empfohlene Wert für die Umgebungsvariable HOROVOD_FUSION_THRESHOLD
ist mindestens 128 MB. In diesem Fall setzen Sie die Umgebungsvariable HOROVOD_FUSION_THRESHOLD
auf 134217728 (128 * 1024 * 1024).
PyTorch
PyTorch DistributedDataParallel unterstützt Batchnachrichten als „Gradient Bucketing“. Legen Sie den Parameter bucket_cap_mb
im Konstruktor DistributedDataParallel
fest, um die Größe Ihrer Batch-Buckets zu steuern.
Die Standardgröße ist 25 MB.
BEST PRACTICE: Der empfohlene Wert von „bucket_cap_mb“ ist 64 (64 MB).
Umgebungsvariablen für Ihren Cluster
Vertex AI fügt für jedes Replikat Daten in eine CLUSTER_SPEC
-Umgebungsvariable ein, die beschreibt, wie der allgemeine Cluster eingerichtet ist. Wie TF_CONFIG
von TensorFlow beschreibt CLUSTER_SPEC
jedes Replikat im Cluster, einschließlich Index und Rolle (primäres Replikat, Worker, Parameterserver oder Evaluator).
Wenn Sie ein verteiltes Training mit TensorFlow ausführen, wird TF_CONFIG
für das Erstellen von tf.train.ClusterSpec
geparst.
Ähnliches gilt für die Ausführung des verteilten Trainings mit anderen ML-Frameworks. CLUSTER_SPEC
muss geparst werden, um Umgebungsvariablen oder Einstellungen festzulegen, die für das Framework erforderlich sind.
Format von CLUSTER_SPEC
Die Umgebungsvariable CLUSTER_SPEC
ist ein JSON-String mit dem folgenden Format:
Schlüssel | Beschreibung | |
---|---|---|
"cluster"
|
Die Clusterbeschreibung für den benutzerdefinierten Container. Wie bei Die Clusterbeschreibung enthält eine Liste der Replikatnamen für jeden von Ihnen angegebenen Worker-Pool. |
|
"workerpool0"
|
Alle verteilten Trainingsjobs haben im ersten Worker-Pool ein primäres Replikat. | |
"workerpool1"
|
Dieser Worker-Pool enthält Worker-Replikate, falls Sie diese beim Erstellen des Jobs angegeben haben. | |
"workerpool2"
|
Dieser Worker-Pool enthält Parameterserver, wenn Sie diese beim Erstellen Ihres Jobs angegeben haben. | |
"workerpool3"
|
Dieser Worker-Pool enthält Evaluators, wenn Sie diese beim Erstellen des Jobs angegeben haben. | |
"environment"
|
Der String cloud .
|
|
"task"
|
Beschreibt die Aufgabe des jeweiligen Knotens, auf dem Ihr Code läuft. Sie können diese Informationen verwenden, um Code für bestimmte Worker in einem verteilten Job zu schreiben. Dieser Eintrag ist ein Wörterbuch mit folgenden Schlüsseln: | |
"type"
|
Der Typ des Worker-Pools, in dem diese Aufgabe ausgeführt wird. Beispielsweise bezieht sich "workerpool0" auf das primäre Replikat.
|
|
"index"
|
Der nullbasierte Index der Aufgabe. Wenn Ihr Trainingsjob beispielsweise zwei Worker enthält, wird dieser Wert für den einen auf |
|
"trial"
|
Die Kennzeichnung des gerade ausgeführten Hyperparameter-Abstimmungstests. Wenn Sie die Hyperparameter-Abstimmung für Ihren Job konfigurieren, legen Sie eine Reihe von Tests fest, die trainiert werden sollen. Mit diesem Wert können Sie zwischen den verschiedenen Tests unterscheiden, die in Ihrem Code ausgeführt werden. Die Kennzeichnung ist ein Stringwert, der die Testnummer enthält, beginnend mit Test 1. | |
job |
Der |
Beispiel für CLUSTER_SPEC
Hier ein Beispielwert:
{ "cluster":{ "workerpool0":[ "cmle-training-workerpool0-ab-0:2222" ], "workerpool1":[ "cmle-training-workerpool1-ab-0:2222", "cmle-training-workerpool1-ab-1:2222" ], "workerpool2":[ "cmle-training-workerpool2-ab-0:2222", "cmle-training-workerpool2-ab-1:2222" ], "workerpool3":[ "cmle-training-workerpool3-ab-0:2222", "cmle-training-workerpool3-ab-1:2222", "cmle-training-workerpool3-ab-2:2222" ] }, "environment":"cloud", "task":{ "type":"workerpool0", "index":0, "trial":"TRIAL_ID" }, "job": { ... } }
Format von TF_CONFIG
Zusätzlich zu CLUSTER_SPEC
legt Vertex AI die Umgebungsvariable TF_CONFIG
für jedes Replikat aller verteilten Trainingsjobs fest. Vertex AI legt nicht TF_CONFIG
für Trainingsjobs mit einzelnem Replikat fest.
CLUSTER_SPEC
und TF_CONFIG
haben einige gemeinsame Werte, aber unterschiedliche Formate. Beide Umgebungsvariablen umfassen zusätzliche Felder, die über die Anforderungen von TensorFlow hinausgehen.
Verteiltes Training mit TensorFlow funktioniert genauso, wenn Sie benutzerdefinierte Container und einen vordefinierten Container verwenden.
Die Umgebungsvariable TF_CONFIG
ist ein JSON-String mit dem folgenden Format:
TF_CONFIG -Felder |
|||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
cluster |
Die TensorFlow-Clusterbeschreibung. Ein Wörterbuch, das einen oder mehrere Aufgabennamen ( Dies ist ein gültiges erstes Argument für den |
||||||||||
task |
Die Aufgabenbeschreibung der VM, auf der diese Umgebungsvariable festgelegt ist. Bei einem bestimmten Trainingsjob ist dieses Wörterbuch auf jeder VM unterschiedlich. Anhand dieser Informationen können Sie anpassen, welcher Code auf jeder VM in einem verteilten Trainingsjob ausgeführt wird. Sie können damit auch das Verhalten Ihres Trainingscodes für verschiedene Versuche eines Hyperparameter-Abstimmungsjobs ändern. Dieses Wörterbuch enthält die folgenden Schlüssel/Wert-Paare:
|
||||||||||
job |
Der |
||||||||||
environment |
Der String |
Beispiel für TF_CONFIG
Der folgende Beispielcode gibt die Umgebungsvariable TF_CONFIG
an Ihre Trainingslogs aus:
import json
import os
tf_config_str = os.environ.get('TF_CONFIG')
tf_config_dict = json.loads(tf_config_str)
# Convert back to string just for pretty printing
print(json.dumps(tf_config_dict, indent=2))
Bei einem Hyperparameter-Abstimmungsjob, der in der Laufzeitversion 2.1 oder höher ausgeführt wird und einen Master-Worker, zwei Worker und einen Parameterserver verwendet, erstellt dieser Code während des ersten Hyperparameter-Abstimmungstests für einen der Worker das folgende Log. Die Beispielausgabe blendet das job
-Feld aus Gründen der Übersichtlichkeit aus und ersetzt einige IDs durch generische Werte.
{
"cluster": {
"chief": [
"training-workerpool0-[ID_STRING_1]-0:2222"
],
"ps": [
"training-workerpool2-[ID_STRING_1]-0:2222"
],
"worker": [
"training-workerpool1-[ID_STRING_1]-0:2222",
"training-workerpool1-[ID_STRING_1]-1:2222"
]
},
"environment": "cloud",
"job": {
...
},
"task": {
"cloud": "[ID_STRING_2]",
"index": 0,
"trial": "1",
"type": "worker"
}
}
Verwendung von TF_CONFIG
TF_CONFIG
wird nur für verteilte Trainingsjobs festgelegt.
Wahrscheinlich müssen Sie nicht direkt mit der Umgebungsvariable TF_CONFIG
in Ihrem Trainingscode interagieren. Greifen Sie nur dann auf die Umgebungsvariable TF_CONFIG
zu, wenn die Verteilungsstrategien von TensorFlow und der standardmäßige Hyperparameter-Abstimmungsworkflow von Vertex AI (beides wird in den nächsten Abschnitten beschrieben) nicht für Ihren Job geeignet sind.
Verteiltes Training
Vertex AI legt die Umgebungsvariable TF_CONFIG
fest, um die Spezifikationen zu erweitern, die TensorFlow für verteiltes Training benötigt.
Verwenden Sie die tf.distribute.Strategy
API, um verteiltes Training mit TensorFlow durchzuführen.
Insbesondere empfehlen wir Ihnen, die Keras API zusammen mit der MultiWorkerMirroredStrategy
oder, wenn Sie für den Job Parameterserver angeben, mit der ParameterServerStrategy
zu verwenden.
Beachten Sie jedoch, dass TensorFlow derzeit nur experimentelle Unterstützung für diese Strategien bietet.
Bei diesen Verteilungsstrategien wird die Umgebungsvariable TF_CONFIG
verwendet, um jeder VM in Ihrem Trainingsjob Rollen zuzuweisen und die Kommunikation zwischen den VMs zu erleichtern. Sie müssen nicht direkt im Trainingscode auf die Umgebungsvariable TF_CONFIG
zugreifen, da TensorFlow das für Sie übernimmt.
Parsen Sie die Umgebungsvariable TF_CONFIG
nur dann direkt, wenn Sie anpassen möchten, wie sich die verschiedenen VMs verhalten, die Ihren Trainingsjob ausführen.
Hyperparameter-Feinabstimmung
Wenn Sie einen Hyperparameter-Abstimmungsjob ausführen, stellt Vertex AI für jeden Test verschiedene Argumente bereit. Der Trainingscode muss nicht unbedingt wissen, welcher Test gerade ausgeführt wird. Darüber hinaus können Sie den Fortschritt von Hyperparameter-Abstimmungsjobs in der Google Cloud Console überwachen.
Bei Bedarf kann Ihr Code die aktuelle Testnummer aus dem Feld trial
des Felds task
der Umgebungsvariablen TF_CONFIG
lesen.
Nächste Schritte
- Erstellen Sie eine Trainingspipeline.