Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Verteiltes Training mit TensorFlow

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

Überblick

tf.distribute.Strategy ist eine TensorFlow-API zum Verteilen von Schulungen auf mehrere GPUs, mehrere Computer oder TPUs. Mit dieser API können Sie Ihre vorhandenen Modelle und den Trainingscode mit minimalen Codeänderungen verteilen.

tf.distribute.Strategy wurde unter tf.distribute.Strategy der folgenden Hauptziele entwickelt:

  • Einfach zu bedienen und zu unterstützen, mehrere Benutzersegmente, einschließlich Forscher, ML-Ingenieure usw.
  • Bieten Sie sofort eine gute Leistung.
  • Einfacher Wechsel zwischen Strategien.

tf.distribute.Strategy kann mit einer High-Level-API wie Keras verwendet werden und kann auch zum Verteilen von benutzerdefinierten Trainingsschleifen (und im Allgemeinen für jede Berechnung mit TensorFlow) verwendet werden.

In TensorFlow 2.x können Sie Ihre Programme eifrig oder in einem Diagramm mit tf.function . tf.distribute.Strategy beabsichtigt, beide Ausführungsmodi zu unterstützen, funktioniert jedoch am besten mit tf.function . Der Eager-Modus wird nur zum Debuggen empfohlen und für TPUStrategy nicht unterstützt. Obwohl wir in diesem Handbuch die meiste Zeit über Schulungen sprechen, kann diese API auch zum Verteilen von Bewertungen und Vorhersagen auf verschiedenen Plattformen verwendet werden.

Sie können tf.distribute.Strategy mit sehr wenigen Änderungen an Ihrem Code verwenden, da wir die zugrunde liegenden Komponenten von TensorFlow geändert haben, um strategiebewusst zu werden. Dies umfasst Variablen, Ebenen, Modelle, Optimierer, Metriken, Zusammenfassungen und Prüfpunkte.

In diesem Handbuch erklären wir verschiedene Arten von Strategien und wie Sie sie in verschiedenen Situationen einsetzen können.

 # Import TensorFlow
import tensorflow as tf
 

Arten von Strategien

tf.distribute.Strategy beabsichtigt, eine Reihe von Anwendungsfällen entlang verschiedener Achsen abzudecken. Einige dieser Kombinationen werden derzeit unterstützt, andere werden in Zukunft hinzugefügt. Einige dieser Achsen sind:

  • Synchrones oder asynchrones Training: Dies sind zwei gängige Methoden zum Verteilen von Training mit Datenparallelität. Während des Synchronisierungstrainings trainieren alle Mitarbeiter synchron über verschiedene Teile der Eingabedaten und aggregieren bei jedem Schritt die Gradienten. Bei der asynchronen Schulung trainieren alle Mitarbeiter unabhängig voneinander die Eingabedaten und aktualisieren die Variablen asynchron. In der Regel wird das Synchronisierungstraining über All-Reduce und Async über die Parameterserver-Architektur unterstützt.
  • Hardwareplattform: Möglicherweise möchten Sie Ihr Training auf mehrere GPUs auf einem Computer oder auf mehrere Computer in einem Netzwerk (mit jeweils 0 oder mehr GPUs) oder auf Cloud-TPUs skalieren.

Um diese Anwendungsfälle zu unterstützen, stehen sechs Strategien zur Verfügung. Im nächsten Abschnitt erklären wir, welche davon in welchen Szenarien in TF 2.2 zu diesem Zeitpunkt unterstützt werden. Hier ist eine kurze Übersicht:

Trainings-API MirroredStrategy TPUS-Strategie MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Keras API Unterstützt Unterstützt Experimentelle Unterstützung Experimentelle Unterstützung Unterstützte geplante Post 2.3
Benutzerdefinierte Trainingsschleife Unterstützt Unterstützt Experimentelle Unterstützung Experimentelle Unterstützung Unterstützte geplante Post 2.3
Schätzer-API Eingeschränkter Support Nicht unterstützt Eingeschränkter Support Eingeschränkter Support Eingeschränkter Support

MirroredStrategy

tf.distribute.MirroredStrategy unterstützt synchrones verteiltes Training auf mehreren GPUs auf einem Computer. Es wird ein Replikat pro GPU-Gerät erstellt. Jede Variable im Modell wird über alle Replikate gespiegelt. Zusammen bilden diese Variablen eine einzige konzeptionelle Variable namens MirroredVariable . Diese Variablen werden durch Anwenden identischer Aktualisierungen miteinander synchronisiert.

Effiziente All-Reduce-Algorithmen werden verwendet, um die variablen Aktualisierungen zwischen den Geräten zu kommunizieren. Reduzieren Sie die Aggregattensoren auf allen Geräten, indem Sie sie addieren, und stellen Sie sie auf jedem Gerät zur Verfügung. Es ist ein fusionierter Algorithmus, der sehr effizient ist und den Overhead der Synchronisation erheblich reduzieren kann. Abhängig von der Art der Kommunikation zwischen Geräten stehen viele All-Reduce-Algorithmen und -Implementierungen zur Verfügung. Standardmäßig wird NVIDIA NCCL als All-Reduce-Implementierung verwendet. Sie können aus einigen anderen von uns angebotenen Optionen auswählen oder Ihre eigenen schreiben.

Hier ist die einfachste Möglichkeit, MirroredStrategy erstellen:

 mirrored_strategy = tf.distribute.MirroredStrategy()
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

Dadurch wird eine MirroredStrategy Instanz erstellt, die alle für TensorFlow sichtbaren GPUs verwendet und NCCL als geräteübergreifende Kommunikation verwendet.

Wenn Sie nur einige der GPUs auf Ihrem Computer verwenden möchten, können Sie dies folgendermaßen tun:

 mirrored_strategy = tf.distribute.MirroredStrategy(devices=["/gpu:0", "/gpu:1"])
 
WARNING:tensorflow:Some requested devices in `tf.distribute.Strategy` are not visible to TensorFlow: /job:localhost/replica:0/task:0/device:GPU:0,/job:localhost/replica:0/task:0/device:GPU:1
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0', '/job:localhost/replica:0/task:0/device:GPU:1')

Wenn Sie die geräteübergreifende Kommunikation überschreiben möchten, können Sie dies mit dem Argument cross_device_ops tun, indem cross_device_ops eine Instanz von tf.distribute.CrossDeviceOps . Derzeit sind tf.distribute.HierarchicalCopyAllReduce und tf.distribute.ReductionToOneDevice zwei andere Optionen als tf.distribute.NcclAllReduce (Standardeinstellung).

 mirrored_strategy = tf.distribute.MirroredStrategy(
    cross_device_ops=tf.distribute.HierarchicalCopyAllReduce())
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

TPUS-Strategie

tf.distribute.TPUStrategy können Sie Ihr TensorFlow-Training für Tensor Processing Units (TPUs) durchführen. TPUs sind Googles spezialisierte ASICs, die die Arbeitslast beim maschinellen Lernen erheblich beschleunigen sollen. Sie sind in Google Colab, der TensorFlow Research Cloud und der Cloud TPU verfügbar.

In Bezug auf die verteilte Trainingsarchitektur ist TPUStrategy dieselbe MirroredStrategy - sie implementiert synchrones verteiltes Training. TPUs bieten ihre eigene Implementierung effizienter All- TPUStrategy und anderer kollektiver Operationen über mehrere TPU-Kerne hinweg, die in TPUStrategy .

So würden Sie TPUStrategy instanziieren:

 cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver(
    tpu=tpu_address)
tf.config.experimental_connect_to_cluster(cluster_resolver)
tf.tpu.experimental.initialize_tpu_system(cluster_resolver)
tpu_strategy = tf.distribute.TPUStrategy(cluster_resolver)
 

Die TPUClusterResolver Instanz hilft beim Auffinden der TPUs. In Colab müssen Sie keine Argumente dafür angeben.

Wenn Sie dies für Cloud-TPUs verwenden möchten:

  • Sie müssen den Namen Ihrer TPU-Ressource im Argument tpu .
  • Sie müssen das TPU-System explizit zu Beginn des Programms initialisieren. Dies ist erforderlich, bevor TPUs für die Berechnung verwendet werden können. Durch die Initialisierung des TPU-Systems wird auch der TPU-Speicher gelöscht. Daher ist es wichtig, diesen Schritt zuerst auszuführen, um einen Statusverlust zu vermeiden.

MultiWorkerMirroredStrategy

tf.distribute.experimental.MultiWorkerMirroredStrategy ist MirroredStrategy sehr ähnlich. Es implementiert synchrones verteiltes Training für mehrere Mitarbeiter mit jeweils möglicherweise mehreren GPUs. Ähnlich wie bei MirroredStrategy werden Kopien aller Variablen im Modell auf jedem Gerät für alle Worker erstellt.

Es verwendet CollectiveOps als Multi-Worker-All-Reduce-Kommunikationsmethode, mit der Variablen synchron gehalten werden. Eine kollektive Operation ist eine einzelne Operation im TensorFlow-Diagramm, mit der automatisch ein All-Reduction-Algorithmus in der TensorFlow-Laufzeit entsprechend der Hardware, der Netzwerktopologie und den Tensorgrößen ausgewählt werden kann.

Außerdem werden zusätzliche Leistungsoptimierungen implementiert. Zum Beispiel enthält es eine statische Optimierung, die mehrere Allreduktionen bei kleinen Tensoren in weniger Allreduktionen bei größeren Tensoren umwandelt. Darüber hinaus entwerfen wir eine Plugin-Architektur, damit Sie in Zukunft Algorithmen einstecken können, die besser auf Ihre Hardware abgestimmt sind. Beachten Sie, dass kollektive Operationen auch andere kollektive Operationen wie Broadcast und All-Gather implementieren.

Hier ist die einfachste Methode zum Erstellen von MultiWorkerMirroredStrategy :

 multiworker_strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy()
 
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Using MirroredStrategy with devices ('/device:GPU:0',)
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CollectiveCommunication.AUTO

MultiWorkerMirroredStrategy können Sie derzeit zwischen zwei verschiedenen Implementierungen von kollektiven MultiWorkerMirroredStrategy wählen. CollectiveCommunication.RING implementiert ringbasierte Kollektive unter Verwendung von gRPC als Kommunikationsschicht. CollectiveCommunication.NCCL verwendet Nvidias NCCL , um Kollektive zu implementieren. CollectiveCommunication.AUTO die Auswahl auf die Laufzeit. Die beste Wahl für die kollektive Implementierung hängt von der Anzahl und Art der GPUs sowie der Netzwerkverbindung im Cluster ab. Sie können sie folgendermaßen angeben:

 multiworker_strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy(
    tf.distribute.experimental.CollectiveCommunication.NCCL)
 
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Using MirroredStrategy with devices ('/device:GPU:0',)
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CollectiveCommunication.NCCL

Einer der Hauptunterschiede, um das Multi-Worker-Training im Vergleich zum Multi-GPU-Training in Gang zu bringen, ist das Multi-Worker-Setup. Die Umgebungsvariable TF_CONFIG ist die Standardmethode in TensorFlow, um die Clusterkonfiguration für jeden Worker anzugeben, der Teil des Clusters ist. Weitere Informationen zum Einrichten von TF_CONFIG .

CentralStorageStrategy

tf.distribute.experimental.CentralStorageStrategy führt auch synchrones Training durch. Variablen werden nicht gespiegelt, sondern auf der CPU platziert und Vorgänge werden auf alle lokalen GPUs repliziert. Wenn nur eine GPU vorhanden ist, werden alle Variablen und Operationen auf dieser GPU platziert.

Erstellen Sie eine Instanz von CentralStorageStrategy mit:

 central_storage_strategy = tf.distribute.experimental.CentralStorageStrategy()
 
INFO:tensorflow:ParameterServerStrategy (CentralStorageStrategy if you are using a single machine) with compute_devices = ['/job:localhost/replica:0/task:0/device:GPU:0'], variable_device = '/job:localhost/replica:0/task:0/device:GPU:0'

Dadurch wird eine CentralStorageStrategy Instanz erstellt, die alle sichtbaren GPUs und die CPU verwendet. Aktualisierungen von Variablen in Replikaten werden aggregiert, bevor sie auf Variablen angewendet werden.

ParameterServerStrategy

tf.distribute.experimental.ParameterServerStrategy unterstützt das Training von Parameterservern auf mehreren Computern. In diesem Setup werden einige Computer als Worker und andere als Parameterserver bezeichnet. Jede Variable des Modells wird auf einem Parameterserver platziert. Die Berechnung wird auf alle GPUs aller Worker repliziert.

In Bezug auf Code sieht es ähnlich aus wie bei anderen Strategien:

 ps_strategy = tf.distribute.experimental.ParameterServerStrategy()
 

Für die Multi-Worker-Schulung muss TF_CONFIG die Konfiguration der Parameterserver und Worker in Ihrem Cluster angeben . Weitere Informationen hierzu finden Sie in TF_CONFIG weiter unten .

Andere Strategien

Zusätzlich zu den oben genannten Strategien gibt es zwei weitere Strategien, die für das Prototyping und Debuggen bei Verwendung von tf.distribute APIs tf.distribute .

Standardstrategie

Die Standardstrategie ist eine Verteilungsstrategie, die vorhanden ist, wenn keine explizite Verteilungsstrategie im Geltungsbereich liegt. Es implementiert die Schnittstelle tf.distribute.Strategy , ist jedoch ein Pass-Through und bietet keine tatsächliche Verteilung. Zum Beispiel ruft strategy.run(fn) einfach fn . Mit dieser Strategie geschriebener Code sollte sich genauso verhalten wie Code, der ohne Strategie geschrieben wurde. Sie können sich das als "No-Op" -Strategie vorstellen.

Die Standardstrategie ist ein Singleton - und man kann keine weiteren Instanzen davon erstellen. Es kann mit tf.distribute.get_strategy() außerhalb des Bereichs einer expliziten Strategie abgerufen werden tf.distribute.get_strategy() dieselbe API, mit der die aktuelle Strategie innerhalb des Bereichs einer expliziten Strategie abgerufen werden kann).

 default_strategy = tf.distribute.get_strategy()
 

Diese Strategie dient zwei Hauptzwecken:

  • Es ermöglicht das bedingungslose Schreiben von verteilungsbewusstem Bibliothekscode. Im Optimierer können wir beispielsweise tf.distribute.get_strategy() und diese Strategie zum Reduzieren von Verläufen verwenden. Es wird immer ein Strategieobjekt zurückgegeben, für das wir die Reduktions-API aufrufen können.
 # In optimizer or other library code
# Get currently active strategy
strategy = tf.distribute.get_strategy()
strategy.reduce("SUM", 1., axis=None)  # reduce some values
 
1.0
  • Ähnlich wie Bibliothekscode können damit Endbenutzerprogramme für die Arbeit mit und ohne Verteilungsstrategie geschrieben werden, ohne dass eine bedingte Logik erforderlich ist. Ein Beispielcode-Snippet, das dies veranschaulicht:
 if tf.config.list_physical_devices('gpu'):
  strategy = tf.distribute.MirroredStrategy()
else:  # use default strategy
  strategy = tf.distribute.get_strategy() 

with strategy.scope():
  # do something interesting
  print(tf.Variable(1.))
 
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>

OneDeviceStrategy

tf.distribute.OneDeviceStrategy ist eine Strategie zum Platzieren aller Variablen und Berechnungen auf einem einzelnen angegebenen Gerät.

 strategy = tf.distribute.OneDeviceStrategy(device="/gpu:0")
 

Diese Strategie unterscheidet sich in vielerlei Hinsicht von der Standardstrategie. In der Standardstrategie bleibt die Logik für die variable Platzierung im Vergleich zur Ausführung von TensorFlow ohne Verteilungsstrategie unverändert. Bei Verwendung von OneDeviceStrategy werden jedoch alle in seinem Bereich erstellten Variablen explizit auf dem angegebenen Gerät platziert. Darüber hinaus werden alle über OneDeviceStrategy.run aufgerufenen Funktionen auch auf dem angegebenen Gerät platziert.

Durch diese Strategie verteilte Eingaben werden auf das angegebene Gerät vorab abgerufen. In der Standardstrategie gibt es keine Eingabeverteilung.

Ähnlich wie bei der Standardstrategie kann diese Strategie auch zum Testen Ihres Codes verwendet werden, bevor zu anderen Strategien gewechselt wird, die tatsächlich auf mehrere Geräte / Maschinen verteilt werden. Dadurch wird die Verteilungsstrategie-Maschinerie etwas mehr als die Standardstrategie ausgeführt, jedoch nicht in vollem Umfang wie bei Verwendung von MirroredStrategy oder TPUStrategy usw. Wenn Sie Code möchten, der sich so verhält, als ob keine Strategie vorliegt, verwenden Sie die Standardstrategie.

Bisher haben wir darüber gesprochen, welche verschiedenen Strategien verfügbar sind und wie Sie sie instanziieren können. In den nächsten Abschnitten werden wir über die verschiedenen Möglichkeiten sprechen, wie Sie sie zur Verteilung Ihres Trainings verwenden können. In diesem Handbuch werden kurze Codefragmente angezeigt und Links zu vollständigen Tutorials erstellt, die Sie von Ende zu Ende ausführen können.

Verwenden von tf.distribute.Strategy mit tf.keras.Model.fit

Wir haben tf.distribute.Strategy in tf.keras integriert. tf.distribute.Strategy ist TensorFlows Implementierung der Keras-API-Spezifikation . tf.keras ist eine API auf hoher Ebene zum Erstellen und Trainieren von Modellen. Durch die Integration in das tf.keras Backend haben wir es für Sie nahtlos gemacht, Ihr im Keras-Trainingsframework geschriebenes Training mit model.fit .

Folgendes müssen Sie in Ihrem Code ändern:

  1. Erstellen Sie eine Instanz der entsprechenden tf.distribute.Strategy .
  2. Verschieben Sie die Erstellung von Keras-Modell, Optimierer und Metriken in strategy.scope .

Wir unterstützen alle Arten von Keras-Modellen - sequentiell, funktional und in Unterklassen.

Hier ist ein Codeausschnitt, um dies für ein sehr einfaches Keras-Modell mit einer dichten Ebene zu tun:

 mirrored_strategy = tf.distribute.MirroredStrategy()

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])

model.compile(loss='mse', optimizer='sgd')
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

In diesem Beispiel haben wir MirroredStrategy damit wir dies auf einem Computer mit mehreren GPUs ausführen können. strategy.scope() gibt Keras an, mit welcher Strategie das Training verteilt werden soll. Durch das Erstellen von Modellen / Optimierern / Metriken in diesem Bereich können verteilte Variablen anstelle von regulären Variablen erstellt werden. Sobald dies eingerichtet ist, können Sie Ihr Modell wie gewohnt anpassen. MirroredStrategy kümmert sich darum, das Training des Modells auf den verfügbaren GPUs zu replizieren, Farbverläufe zu aggregieren und vieles mehr.

 dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(10)
model.fit(dataset, epochs=2)
model.evaluate(dataset)
 
Epoch 1/2
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/data/ops/multi_device_iterator_ops.py:601: get_next_as_optional (from tensorflow.python.data.ops.iterator_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.data.Iterator.get_next_as_optional()` instead.
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
10/10 [==============================] - 0s 2ms/step - loss: 1.0035
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
Epoch 2/2
10/10 [==============================] - 0s 1ms/step - loss: 0.4436
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
10/10 [==============================] - 0s 1ms/step - loss: 0.2755

0.27546340227127075

Hier haben wir ein tf.data.Dataset , um das Training und die tf.data.Dataset bereitzustellen. Sie können auch Numpy-Arrays verwenden:

 import numpy as np
inputs, targets = np.ones((100, 1)), np.ones((100, 1))
model.fit(inputs, targets, epochs=2, batch_size=10)
 
Epoch 1/2
10/10 [==============================] - 0s 1ms/step - loss: 0.1961
Epoch 2/2
10/10 [==============================] - 0s 1ms/step - loss: 0.0867

<tensorflow.python.keras.callbacks.History at 0x7fa17808e240>

In beiden Fällen (Datensatz oder Anzahl) wird jeder Stapel der angegebenen Eingabe zu gleichen Teilen auf mehrere Replikate aufgeteilt. Wenn Sie beispielsweise MirroredStrategy mit 2 GPUs verwenden, wird jeder Stapel der Größe 10 auf die 2 GPUs aufgeteilt, wobei jeder in jedem Schritt 5 Eingabebeispiele erhält. Jede Epoche wird dann schneller trainiert, wenn Sie weitere GPUs hinzufügen. In der Regel möchten Sie Ihre Stapelgröße erhöhen, wenn Sie mehr Beschleuniger hinzufügen, um die zusätzliche Rechenleistung effektiv zu nutzen. Sie müssen auch Ihre Lernrate je nach Modell neu einstellen. Sie können strategy.num_replicas_in_sync , um die Anzahl der Replikate abzurufen.

 # Compute global batch size using number of replicas.
BATCH_SIZE_PER_REPLICA = 5
global_batch_size = (BATCH_SIZE_PER_REPLICA *
                     mirrored_strategy.num_replicas_in_sync)
dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100)
dataset = dataset.batch(global_batch_size)

LEARNING_RATES_BY_BATCH_SIZE = {5: 0.1, 10: 0.15}
learning_rate = LEARNING_RATES_BY_BATCH_SIZE[global_batch_size]
 

Was wird jetzt unterstützt?

Trainings-API MirroredStrategy TPUS-Strategie MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Keras-APIs Unterstützt Unterstützt Experimentelle Unterstützung Experimentelle Unterstützung Support geplant nach 2.3

Beispiele und Tutorials

Hier ist eine Liste von Tutorials und Beispielen, die die obige Integration von Keras zu Ende veranschaulichen:

  1. Tutorial zum Trainieren von MNIST mit MirroredStrategy .
  2. Tutorial zum Trainieren von MNIST mit MultiWorkerMirroredStrategy .
  3. Leitfaden zum Training von MNIST mit TPUStrategy .
  4. Das TensorFlow Model Garden- Repository enthält Sammlungen modernster Modelle, die mit verschiedenen Strategien implementiert wurden.

Verwenden von tf.distribute.Strategy mit benutzerdefinierten Trainingsschleifen

Wie Sie gesehen haben, müssen für die Verwendung von tf.distribute.Strategy mit Keras model.fit nur einige Zeilen Ihres Codes model.fit werden. Mit etwas mehr Aufwand können Sie auch tf.distribute.Strategy mit benutzerdefinierten Trainingsschleifen verwenden.

Wenn Sie mehr Flexibilität und Kontrolle über Ihre Trainingsschleifen benötigen, als dies mit Estimator oder Keras möglich ist, können Sie benutzerdefinierte Trainingsschleifen schreiben. Wenn Sie beispielsweise ein GAN verwenden, möchten Sie möglicherweise in jeder Runde eine andere Anzahl von Generator- oder Diskriminatorschritten ausführen. In ähnlicher Weise eignen sich die übergeordneten Frameworks nicht sehr gut für das Reinforcement Learning-Training.

Zur Unterstützung benutzerdefinierter Trainingsschleifen stellen wir über die Klassen tf.distribute.Strategy einen Kernsatz von Methoden tf.distribute.Strategy . Die Verwendung dieser Codes erfordert möglicherweise zunächst eine geringfügige Umstrukturierung des Codes. Sobald dies erledigt ist, sollten Sie in der Lage sein, zwischen GPUs, TPUs und mehreren Computern zu wechseln, indem Sie einfach die Strategieinstanz ändern.

Hier zeigen wir einen kurzen Ausschnitt, der diesen Anwendungsfall für ein einfaches Trainingsbeispiel mit demselben Keras-Modell wie zuvor veranschaulicht.

Zunächst erstellen wir das Modell und den Optimierer im Rahmen der Strategie. Dadurch wird sichergestellt, dass alle mit dem Modell und dem Optimierer erstellten Variablen gespiegelte Variablen sind.

 with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
  optimizer = tf.keras.optimizers.SGD()
 

Als Nächstes erstellen wir den Eingabedatensatz und rufen tf.distribute.Strategy.experimental_distribute_dataset auf, um den Datensatz basierend auf der Strategie zu verteilen.

 dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(
    global_batch_size)
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)
 

Dann definieren wir einen Schritt des Trainings. Wir werden tf.GradientTape , um Verläufe zu berechnen, und Optimierer, um diese Verläufe anzuwenden, um die Variablen unseres Modells zu aktualisieren. Um diesen Trainingsschritt zu verteilen, haben wir in einer Funktion train_step und übergeben es an tf.distrbute.Strategy.run zusammen mit den Daten - Set - Eingängen , die wir von bekommen dist_dataset erstellt vor:

 loss_object = tf.keras.losses.BinaryCrossentropy(
  from_logits=True,
  reduction=tf.keras.losses.Reduction.NONE)

def compute_loss(labels, predictions):
  per_example_loss = loss_object(labels, predictions)
  return tf.nn.compute_average_loss(per_example_loss, global_batch_size=global_batch_size)

def train_step(inputs):
  features, labels = inputs

  with tf.GradientTape() as tape:
    predictions = model(features, training=True)
    loss = compute_loss(labels, predictions)

  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  return loss

@tf.function
def distributed_train_step(dist_inputs):
  per_replica_losses = mirrored_strategy.run(train_step, args=(dist_inputs,))
  return mirrored_strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,
                         axis=None)
 

Ein paar andere Dinge, die im obigen Code zu beachten sind:

  1. Wir haben tf.nn.compute_average_loss , um den Verlust zu berechnen. tf.nn.compute_average_loss summiert den Verlust pro Beispiel und dividiert die Summe durch die global_batch_size. Dies ist wichtig, da die Gradienten später, nachdem sie für jedes Replikat berechnet wurden, durch Summieren über die Replikate hinweg aggregiert werden.
  2. Wir nutzten die tf.distribute.Strategy.reduce API die Ergebnisse von zurück aggregieren tf.distribute.Strategy.run . tf.distribute.Strategy.run gibt Ergebnisse von jedem lokalen Replikat in der Strategie zurück, und es gibt mehrere Möglichkeiten, dieses Ergebnis zu verwenden. Sie können sie reduce , um einen aggregierten Wert zu erhalten. Sie können auch tf.distribute.Strategy.experimental_local_results , um die Liste der im Ergebnis enthaltenen Werte tf.distribute.Strategy.experimental_local_results , einen pro lokalem Replikat.
  3. Wenn apply_gradients innerhalb eines Verteilungsstrategiebereichs apply_gradients wird, wird sein Verhalten geändert. Insbesondere wird vor dem Anwenden von Verläufen auf jede parallele Instanz während des synchronen Trainings eine Summe aller Replikate der Verläufe durchgeführt.

dist_dataset wir den Trainingsschritt definiert haben, können wir dist_dataset und das Training in einer Schleife ausführen:

 for dist_inputs in dist_dataset:
  print(distributed_train_step(dist_inputs))
 
tf.Tensor(0.4155251, shape=(), dtype=float32)
tf.Tensor(0.41321823, shape=(), dtype=float32)
tf.Tensor(0.4109319, shape=(), dtype=float32)
tf.Tensor(0.40866604, shape=(), dtype=float32)
tf.Tensor(0.40642032, shape=(), dtype=float32)
tf.Tensor(0.40419456, shape=(), dtype=float32)
tf.Tensor(0.4019885, shape=(), dtype=float32)
tf.Tensor(0.399802, shape=(), dtype=float32)
tf.Tensor(0.39763477, shape=(), dtype=float32)
tf.Tensor(0.3954866, shape=(), dtype=float32)
tf.Tensor(0.39335734, shape=(), dtype=float32)
tf.Tensor(0.3912467, shape=(), dtype=float32)
tf.Tensor(0.38915452, shape=(), dtype=float32)
tf.Tensor(0.38708064, shape=(), dtype=float32)
tf.Tensor(0.38502476, shape=(), dtype=float32)
tf.Tensor(0.38298675, shape=(), dtype=float32)
tf.Tensor(0.38096642, shape=(), dtype=float32)
tf.Tensor(0.3789635, shape=(), dtype=float32)
tf.Tensor(0.3769779, shape=(), dtype=float32)
tf.Tensor(0.37500936, shape=(), dtype=float32)

Im obigen Beispiel haben wir das dist_dataset , um Eingaben für Ihr Training zu liefern. Wir stellen auch das tf.distribute.Strategy.make_experimental_numpy_dataset zur Verfügung, um numpy-Eingaben zu unterstützen. Mit dieser API können Sie ein Dataset erstellen, bevor Sie tf.distribute.Strategy.experimental_distribute_dataset aufrufen.

Eine andere Möglichkeit, Ihre Daten zu durchlaufen, besteht darin, explizit Iteratoren zu verwenden. Möglicherweise möchten Sie dies tun, wenn Sie für eine bestimmte Anzahl von Schritten ausgeführt werden möchten, anstatt über das gesamte Dataset zu iterieren. Die obige Iteration würde jetzt modifiziert werden , um zunächst einen Iterator zu erstellen und dann explizit aufrufen next sie auf, die Eingangsdaten zu erhalten.

 iterator = iter(dist_dataset)
for _ in range(10):
  print(distributed_train_step(next(iterator)))
 
tf.Tensor(0.37305772, shape=(), dtype=float32)
tf.Tensor(0.3711228, shape=(), dtype=float32)
tf.Tensor(0.3692044, shape=(), dtype=float32)
tf.Tensor(0.36730233, shape=(), dtype=float32)
tf.Tensor(0.3654165, shape=(), dtype=float32)
tf.Tensor(0.36354658, shape=(), dtype=float32)
tf.Tensor(0.36169255, shape=(), dtype=float32)
tf.Tensor(0.3598542, shape=(), dtype=float32)
tf.Tensor(0.35803124, shape=(), dtype=float32)
tf.Tensor(0.3562236, shape=(), dtype=float32)

Dies deckt den einfachsten Fall der Verwendung der API tf.distribute.Strategy zum Verteilen benutzerdefinierter Trainingsschleifen ab. Wir sind dabei, diese APIs zu verbessern. Da dieser Anwendungsfall mehr Arbeit erfordert, um Ihren Code anzupassen, werden wir in Zukunft einen separaten detaillierten Leitfaden veröffentlichen.

Was wird jetzt unterstützt?

Trainings-API MirroredStrategy TPUS-Strategie MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Benutzerdefinierte Trainingsschleife Unterstützt Unterstützt Experimentelle Unterstützung Experimentelle Unterstützung Support geplant nach 2.3

Beispiele und Tutorials

Hier einige Beispiele für die Verwendung der Verteilungsstrategie mit benutzerdefinierten Trainingsschleifen:

  1. Tutorial zum Trainieren von MNIST mit MirroredStrategy .
  2. Leitfaden zum Training von MNIST mit TPUStrategy .
  3. Das TensorFlow Model Garden- Repository enthält Sammlungen modernster Modelle, die mit verschiedenen Strategien implementiert wurden.

Verwenden von tf.distribute.Strategy mit Estimator (eingeschränkte Unterstützung)

tf.estimator ist eine verteilte TensorFlow-Trainings-API, die ursprünglich den Ansatz des asynchronen Parameterservers unterstützte. Wie bei Keras haben wir tf.distribute.Strategy in tf.Estimator . Wenn Sie Estimator für Ihr Training verwenden, können Sie mit nur wenigen Änderungen an Ihrem Code problemlos zu verteiltem Training wechseln. Damit können Estimator-Benutzer jetzt synchron verteilte Schulungen für mehrere GPUs und mehrere Worker durchführen sowie TPUs verwenden. Diese Unterstützung in Estimator ist jedoch begrenzt. Weitere Informationen finden Sie im Abschnitt Was wird jetzt unterstützt?

Die Verwendung von tf.distribute.Strategy mit Estimator unterscheidet sich geringfügig vom Keras-Fall. Anstatt strategy.scope , übergeben wir jetzt das Strategieobjekt an die RunConfig für den Estimator.

Hier ist ein Codeausschnitt, der dies mit einem vorgefertigten Estimator LinearRegressor und MirroredStrategy :

 mirrored_strategy = tf.distribute.MirroredStrategy()
config = tf.estimator.RunConfig(
    train_distribute=mirrored_strategy, eval_distribute=mirrored_strategy)
regressor = tf.estimator.LinearRegressor(
    feature_columns=[tf.feature_column.numeric_column('feats')],
    optimizer='SGD',
    config=config)
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
INFO:tensorflow:Initializing RunConfig with distribution strategies.
INFO:tensorflow:Not using Distribute Coordinator.
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp2ack9oru
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp2ack9oru', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': <tensorflow.python.distribute.mirrored_strategy.MirroredStrategy object at 0x7fa124522b38>, '_device_fn': None, '_protocol': None, '_eval_distribute': <tensorflow.python.distribute.mirrored_strategy.MirroredStrategy object at 0x7fa124522b38>, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1, '_distribute_coordinator_mode': None}

Wir verwenden hier einen vorgefertigten Schätzer, aber der gleiche Code funktioniert auch mit einem benutzerdefinierten Schätzer. train_distribute bestimmt, wie das Training verteilt wird, und eval_distribute bestimmt, wie die Bewertung verteilt wird. Dies ist ein weiterer Unterschied zu Keras, wo wir sowohl für das Training als auch für die Bewertung dieselbe Strategie verwenden.

Jetzt können wir diesen Schätzer mit einer Eingabefunktion trainieren und auswerten:

 def input_fn():
  dataset = tf.data.Dataset.from_tensors(({"feats":[1.]}, [1.]))
  return dataset.repeat(1000).batch(10)
regressor.train(input_fn=input_fn, steps=10)
regressor.evaluate(input_fn=input_fn, steps=10)
 
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_estimator/python/estimator/canned/linear.py:1481: Layer.add_variable (from tensorflow.python.keras.engine.base_layer_v1) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `layer.add_weight` method instead.
INFO:tensorflow:Done calling model_fn.
WARNING:tensorflow:AutoGraph could not transform <function _combine_distributed_scaffold.<locals>.<lambda> at 0x7fa12452cb70> and will run it as-is.
Cause: could not parse the source code:

      lambda scaffold: scaffold.ready_op, args=(grouped_scaffold,))

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function _combine_distributed_scaffold.<locals>.<lambda> at 0x7fa12452cb70> and will run it as-is.
Cause: could not parse the source code:

      lambda scaffold: scaffold.ready_op, args=(grouped_scaffold,))

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
INFO:tensorflow:Create CheckpointSaverHook.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_estimator/python/estimator/util.py:96: DistributedIteratorV1.initialize (from tensorflow.python.distribute.input_lib) is deprecated and will be removed in a future version.
Instructions for updating:
Use the iterator's `initializer` property instead.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp2ack9oru/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 1.0, step = 0
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 10...
INFO:tensorflow:Saving checkpoints for 10 into /tmp/tmp2ack9oru/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 10...
INFO:tensorflow:Loss for final step: 2.877698e-13.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
WARNING:tensorflow:AutoGraph could not transform <function _combine_distributed_scaffold.<locals>.<lambda> at 0x7fa1e9768d08> and will run it as-is.
Cause: could not parse the source code:

      lambda scaffold: scaffold.ready_op, args=(grouped_scaffold,))

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function _combine_distributed_scaffold.<locals>.<lambda> at 0x7fa1e9768d08> and will run it as-is.
Cause: could not parse the source code:

      lambda scaffold: scaffold.ready_op, args=(grouped_scaffold,))

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
INFO:tensorflow:Starting evaluation at 2020-08-04T20:28:12Z
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmp2ack9oru/model.ckpt-10
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [1/10]
INFO:tensorflow:Evaluation [2/10]
INFO:tensorflow:Evaluation [3/10]
INFO:tensorflow:Evaluation [4/10]
INFO:tensorflow:Evaluation [5/10]
INFO:tensorflow:Evaluation [6/10]
INFO:tensorflow:Evaluation [7/10]
INFO:tensorflow:Evaluation [8/10]
INFO:tensorflow:Evaluation [9/10]
INFO:tensorflow:Evaluation [10/10]
INFO:tensorflow:Inference Time : 0.20350s
INFO:tensorflow:Finished evaluation at 2020-08-04-20:28:12
INFO:tensorflow:Saving dict for global step 10: average_loss = 1.4210855e-14, global_step = 10, label/mean = 1.0, loss = 1.4210855e-14, prediction/mean = 0.99999994
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 10: /tmp/tmp2ack9oru/model.ckpt-10

{'average_loss': 1.4210855e-14,
 'label/mean': 1.0,
 'loss': 1.4210855e-14,
 'prediction/mean': 0.99999994,
 'global_step': 10}

Ein weiterer Unterschied zwischen Estimator und Keras ist die Eingabebehandlung. In Keras haben wir erwähnt, dass jeder Stapel des Datasets automatisch auf mehrere Replikate aufgeteilt wird. In Estimator führen wir jedoch weder eine automatische Aufteilung des Stapels durch, noch teilen wir die Daten automatisch auf verschiedene Mitarbeiter auf. Sie haben die volle Kontrolle darüber, wie Ihre Daten auf Mitarbeiter und Geräte verteilt werden sollen, und Sie müssen ein input_fn angeben, um anzugeben, wie Ihre Daten verteilt werden sollen.

Ihre input_fn wird einmal pro Worker aufgerufen, sodass ein Datensatz pro Worker angegeben wird. Dann wird ein Stapel aus diesem Datensatz einem Replikat auf diesem Worker zugeführt, wodurch N Stapel für N Replikate auf einem Worker verbraucht werden. Mit anderen Worten, der von input_fn zurückgegebene input_fn sollte input_fn der Größe PER_REPLICA_BATCH_SIZE . Die globale PER_REPLICA_BATCH_SIZE * strategy.num_replicas_in_sync für einen Schritt kann als PER_REPLICA_BATCH_SIZE * strategy.num_replicas_in_sync abgerufen werden.

Wenn Sie eine Schulung für mehrere Mitarbeiter durchführen, sollten Sie entweder Ihre Daten auf die Mitarbeiter aufteilen oder jeweils einen zufälligen Startwert verwenden. Ein Beispiel dafür finden Sie im Multi-Worker-Training mit Estimator .

In ähnlicher Weise können Sie auch Multi-Worker- und Parameterserver-Strategien verwenden. Der Code bleibt derselbe, Sie müssen jedoch tf.estimator.train_and_evaluate und die Umgebungsvariablen TF_CONFIG für jede in Ihrem Cluster ausgeführte Binärdatei TF_CONFIG .

Was wird jetzt unterstützt?

Das Training mit Estimator mit allen Strategien außer TPUStrategy wird nur begrenzt unterstützt. Grundlegende Schulungen und Bewertungen sollten funktionieren, aber einige erweiterte Funktionen wie das Gerüst funktionieren noch nicht. Es kann auch eine Reihe von Fehlern in dieser Integration geben. Derzeit planen wir nicht, diese Unterstützung aktiv zu verbessern, sondern konzentrieren uns auf die Unterstützung von Keras und benutzerdefinierten Trainingsschleifen. Wenn möglich, sollten Sie lieber tf.distribute mit diesen APIs verwenden.

Trainings-API MirroredStrategy TPUS-Strategie MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Schätzer-API Eingeschränkter Support Nicht unterstützt Eingeschränkter Support Eingeschränkter Support Eingeschränkter Support

Beispiele und Tutorials

Hier sind einige Beispiele, die die End-to-End-Verwendung verschiedener Strategien mit Estimator zeigen:

  1. Multi-Worker-Training mit Estimator zum Trainieren von MNIST mit mehreren MultiWorkerMirroredStrategy mithilfe von MultiWorkerMirroredStrategy .
  2. End-to-End-Beispiel für die Schulung mehrerer Mitarbeiter in Tensorflow / Ökosystem mithilfe von Kubernetes-Vorlagen. Dieses Beispiel beginnt mit einem Keras-Modell und konvertiert es mithilfe der API tf.keras.estimator.model_to_estimator in einen Schätzer.
  3. Offizielles ResNet50- Modell, das entweder mit MirroredStrategy oder MultiWorkerMirroredStrategy trainiert werden MultiWorkerMirroredStrategy .

Andere Themen

In diesem Abschnitt werden einige Themen behandelt, die für mehrere Anwendungsfälle relevant sind.

Einrichten der Umgebungsvariablen TF_CONFIG

Wie bereits erwähnt, müssen Sie für die TF_CONFIG mehreren Mitarbeitern die Umgebungsvariable TF_CONFIG für jede in Ihrem Cluster ausgeführte Binärdatei TF_CONFIG . Die Umgebungsvariable TF_CONFIG ist eine JSON-Zeichenfolge, die angibt, welche Aufgaben einen Cluster bilden, welche Adressen sie haben und welche Rolle die einzelnen Aufgaben im Cluster spielen. Wir stellen eine Kubernetes-Vorlage im Tensorflow / Ökosystem- Repo zur Verfügung, die TF_CONFIG für Ihre Trainingsaufgaben TF_CONFIG .

TF_CONFIG besteht aus zwei Komponenten: Cluster und Task. Der Cluster bietet Informationen zum Schulungscluster, bei dem es sich um ein Diktat handelt, das aus verschiedenen Arten von Jobs besteht, z. B. Arbeiter. In der Schulung für mehrere Mitarbeiter übernimmt normalerweise ein Mitarbeiter etwas mehr Verantwortung wie das Speichern des Prüfpunkts und das Schreiben einer Zusammenfassungsdatei für TensorBoard, zusätzlich zu dem, was ein regulärer Mitarbeiter tut. Ein solcher Arbeiter wird als "Chefarbeiter" bezeichnet, und es ist üblich, dass der Arbeiter mit dem Index 0 zum Chefarbeiter ernannt wird (tatsächlich wird auf diese Weise tf.distribute.Strategy implementiert). Aufgabe hingegen liefert Informationen über die aktuelle Aufgabe. Der erste Komponentencluster ist für alle Worker gleich, und die zweite Komponentenaufgabe ist für jeden Worker unterschiedlich und gibt den Typ und den Index dieses Workers an.

Ein Beispiel für TF_CONFIG ist:

 os.environ["TF_CONFIG"] = json.dumps({
    "cluster": {
        "worker": ["host1:port", "host2:port", "host3:port"],
        "ps": ["host4:port", "host5:port"]
    },
   "task": {"type": "worker", "index": 1}
})
 

Diese TF_CONFIG gibt an, dass der Cluster drei Worker und zwei ps-Tasks zusammen mit ihren Hosts und Ports enthält. Der Teil "Aufgabe" gibt an, dass die Rolle der aktuellen Aufgabe im Cluster Arbeiter 1 (der zweite Arbeiter) ist. Gültige Rollen in einem Cluster sind "Chef", "Arbeiter", "PS" und "Bewerter". Es sollte keinen "ps" tf.distribute.experimental.ParameterServerStrategy außer wenn tf.distribute.experimental.ParameterServerStrategy .

Was kommt als nächstes?

tf.distribute.Strategy befindet sich in der Entwicklung. Wir heißen Sie herzlich willkommen, es auszuprobieren und Ihr Feedback zu GitHub-Problemen zu geben .