

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Ändern Sie ein TensorFlow Trainingsskript
<a name="model-parallel-customize-training-script-tf"></a>

In diesem Abschnitt erfahren Sie, wie Sie TensorFlow Trainingsskripte ändern, um die SageMaker Modellparallelitätsbibliothek für automatische Partitionierung und manuelle Partitionierung zu konfigurieren. Diese Auswahl an Beispielen umfasst auch ein in Horovod integriertes Beispiel für Hybridmodell und Datenparallelität.

**Anmerkung**  
Informationen darüber, welche TensorFlow Versionen von der Bibliothek unterstützt werden, finden Sie unter. [Unterstützte Frameworks und AWS-Regionen](distributed-model-parallel-support.md)

Die erforderlichen Änderungen, die Sie an Ihrem Trainingsskript vornehmen müssen, um die Bibliothek verwenden zu können, sind unter [Automatisiertes Teilen mit TensorFlow](#model-parallel-customize-training-script-tf-23) aufgeführt.

Informationen zum Ändern Ihres Trainingsskripts zur Verwendung des Hybridmodells und der Datenparallelität mit Horovod finden Sie unter [Automatisiertes Splitten mit TensorFlow und Horovod für Hybridmodell und Datenparallelität](#model-parallel-customize-training-script-tf-2.3).

Wenn Sie die manuelle Partitionierung verwenden möchten, lesen Sie auch [Manuelles Teilen mit TensorFlow](#model-parallel-customize-training-script-tf-manual). 

Die folgenden Themen zeigen Beispiele für Trainingsskripte, mit denen Sie die Modellparallelitätsbibliothek für Modelle mit automatischer Partitionierung und manueller Partitionierung konfigurieren SageMaker können. TensorFlow 

**Anmerkung**  
Die automatische Partitionierung ist standardmäßig aktiviert. Sofern nicht anders angegeben, verwenden die Beispielskripten automatische Partitionierung.

**Topics**
+ [Automatisiertes Teilen mit TensorFlow](#model-parallel-customize-training-script-tf-23)
+ [Automatisiertes Splitten mit TensorFlow und Horovod für Hybridmodell und Datenparallelität](#model-parallel-customize-training-script-tf-2.3)
+ [Manuelles Teilen mit TensorFlow](#model-parallel-customize-training-script-tf-manual)
+ [Nicht unterstützte Framework-Funktionen](#model-parallel-tf-unsupported-features)

## Automatisiertes Teilen mit TensorFlow
<a name="model-parallel-customize-training-script-tf-23"></a>

Die folgenden Änderungen am Trainingsskript sind erforderlich, um ein TensorFlow Modell mit SageMaker der Modellparallelitätsbibliothek auszuführen:

1. Importieren und initialisieren Sie die Bibliothek mit. [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init)

1. Definieren Sie ein Keras-Modell, indem Sie es von der Keras Model-Klasse [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_tensorflow.html](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_tensorflow.html) statt von der Keras-Model-Klasse erben. Gibt die Modellausgaben der Aufrufmethode des `smp.DistributedModel` Objekts zurück. Beachten Sie, dass alle von der Aufrufmethode zurückgegebenen Tensoren über modellparallele Geräte übertragen werden, was zu einem Kommunikationsaufwand führt. Daher sollten alle Tensoren, die außerhalb der Aufrufmethode nicht benötigt werden (z. B. Zwischenaktivierungen), nicht zurückgegeben werden.

1. `drop_remainder=True` in Methode `tf.Dataset.batch()` eingeben. Damit soll sichergestellt werden, dass die Batchgröße immer durch die Anzahl der Mikrobatches teilbar ist.

1. Legen Sie die zufälligen Operationen in der Datenpipeline fest`smp.dp_rank()`, `shuffle(ds, seed=smp.dp_rank())` um z. B. die Konsistenz von Datenproben sicherzustellen GPUs , die unterschiedliche Modellpartitionen enthalten.

1. Fügen Sie die Vorwärts- und Rückwärtslogik in eine Schritt-Funktion ein und dekorieren Sie sie mit `smp.step`.

1. Führen Sie die Nachbearbeitung der Ausgänge in verschiedenen Mikrobatches mit Methoden [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput)wie durch `reduce_mean`. Die [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init)Funktion muss einen Rückgabewert haben, der von der Ausgabe von `smp.DistributedModel` abhängt.

1. [Wenn es einen Bewertungsschritt gibt, platzieren Sie die Vorwärtslogik auf ähnliche Weise in einer mit – `smp.step`dekorierten Funktion und verarbeiten Sie die Ausgaben mithilfe der `StepOutput` API](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput) nach.

Weitere Informationen über die API SageMaker der Modellparallelismus-Bibliothek finden Sie in der [API-Dokumentation](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html). 

Das folgende Python-Skript ist ein Beispiel für ein Trainingsskript, nachdem die Änderungen vorgenommen wurden.

```
import tensorflow as tf

# smdistributed: Import TF2.x API
import smdistributed.modelparallel.tensorflow as smp

# smdistributed: Initialize
smp.init()

# Download and load MNIST dataset.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    "MNIST-data-%d" % smp.rank()
)
x_train, x_test = x_train / 255.0, x_test / 255.0

# Add a channels dimension
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

# smdistributed: If needed, seed the shuffle with smp.dp_rank(), and drop_remainder
# in batching to make sure batch size is always divisible by number of microbatches
train_ds = (
    tf.data.Dataset.from_tensor_slices((x_train, y_train))
    .shuffle(10000, seed=smp.dp_rank())
    .batch(256, drop_remainder=True)
)

# smdistributed: Define smp.DistributedModel the same way as Keras sub-classing API 
class MyModel(smp.DistributedModel):
    def __init__(self):
        super(MyModel, self).__init__()
        # define layers

    def call(self, x, training=None):
        # define forward pass and return the model output

model = MyModel()

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name="train_accuracy")

# smdistributed: Define smp.step. Return any tensors needed outside
@smp.step
def get_grads(images, labels):
    predictions = model(images, training=True)
    loss = loss_object(labels, predictions)

    grads = optimizer.get_gradients(loss, model.trainable_variables)
    return grads, loss, predictions


@tf.function
def train_step(images, labels):
    gradients, loss, predictions = get_grads(images, labels)

    # smdistributed: Accumulate the gradients across microbatches
    gradients = [g.accumulate() for g in gradients]
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    # smdistributed: Merge predictions and average losses across microbatches
    train_accuracy(labels, predictions.merge())
    return loss.reduce_mean()


for epoch in range(5):
    # Reset the metrics at the start of the next epoch
    train_accuracy.reset_states()
    for images, labels in train_ds:
        loss = train_step(images, labels)
    accuracy = train_accuracy.result()
```

Wenn Sie mit der Vorbereitung Ihres Trainingsskripts fertig sind, fahren Sie zu [Schritt 2: Starten Sie einen Trainingsjob mit dem SageMaker Python-SDK](model-parallel-sm-sdk.md) fort. Wenn Sie einen hybriden Modell- und Datenparallel-Trainingsjob ausführen möchten, fahren Sie mit dem nächsten Abschnitt fort.

## Automatisiertes Splitten mit TensorFlow und Horovod für Hybridmodell und Datenparallelität
<a name="model-parallel-customize-training-script-tf-2.3"></a>

Sie können die SageMaker Modellparallelitätsbibliothek mit Horovod für Hybridmodell- und Datenparallelität verwenden. Weitere Informationen darüber, wie die Bibliothek ein Modell für hybride Parallelität aufteilt, finden Sie unter [PyTorch TensorFlowPipeline-Parallelität (verfügbar für und)](model-parallel-intro.md#model-parallel-intro-pp).

In diesem Schritt konzentrieren wir uns darauf, wie Sie Ihr Trainingsskript modifizieren können, um die Modellparallelitätsbibliothek anzupassen. SageMaker

Um Ihr Trainingsskript so einzurichten, dass es die Konfiguration der Hybrid-Parallelität, die Sie in [Schritt 2: Starten Sie einen Trainingsjob mit dem SageMaker Python-SDK](model-parallel-sm-sdk.md) einrichten werden, übernimmt, verwenden Sie die Hilfsfunktionen `smp.dp_rank()` und `smp.mp_rank()` der Bibliothek, die automatisch den parallel Datenrang bzw. den parallel Modellrang erkennen. 

Informationen zu allen MPI-Primitiven, die die Bibliothek unterstützt, finden Sie unter [MPI Basics](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#mpi-basics) in der SageMaker Python SDK-Dokumentation. 

Die erforderlichen Änderungen im Skript sind:
+ Hinzufügen von `hvd.allreduce`
+ Übertragung von Variablen nach dem ersten Batch, wie von Horovod gefordert
+  and/or Sharding-Sharding-Operationen in der Datenpipeline starten mit. `smp.dp_rank()`

**Anmerkung**  
Wenn Sie Horovod verwenden, dürfen Sie Ihr Trainingsskript nicht direkt `hvd.init` aufrufen. Stattdessen müssen Sie `True` in den SageMaker `modelparallel` Python-SDK-Parametern unter auf einstellen[Schritt 2: Starten Sie einen Trainingsjob mit dem SageMaker Python-SDK](model-parallel-sm-sdk.md). `"horovod"` Dadurch kann die Bibliothek Horovod auf der Grundlage der Gerätezuweisungen der Modellpartitionen intern initialisieren. Direktes Aufrufen von `hvd.init()` in Ihrem Trainingsskript kann zu Problemen führen.

**Anmerkung**  
Die Verwendung der `hvd.DistributedOptimizer`-API direkt in Ihrem Trainingsskript kann zu einer schlechten Trainingsleistung und -geschwindigkeit führen, da die API die `AllReduce`-Operation implizit in `smp.step` platziert. Wir empfehlen Ihnen, die Modellparallelismus-Bibliothek mit Horovod zu verwenden, indem Sie direkt `hvd.allreduce` nach dem Aufruf `accumulate()` oder `reduce_mean()` auf den zurückgegebenen Gradienten von `smp.step` aufrufen, wie im folgenden Beispiel gezeigt wird.

Weitere Informationen zur API SageMaker der Modellparallelismus-Bibliothek finden Sie in der [API-Dokumentation](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html).

```
import tensorflow as tf
import horovod.tensorflow as hvd

# smdistributed: Import TF2.x API 
import smdistributed.modelparallel.tensorflow as smp

# smdistributed: Initialize
smp.init()

# Download and load MNIST dataset.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    "MNIST-data-%d" % smp.rank()
)
x_train, x_test = x_train / 255.0, x_test / 255.0

# Add a channels dimension
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

# smdistributed: Seed the shuffle with smp.dp_rank(), and drop_remainder
# in batching to make sure batch size is always divisible by number of microbatches
train_ds = (
    tf.data.Dataset.from_tensor_slices((x_train, y_train))
    .shuffle(10000, seed=smp.dp_rank())
    .batch(256, drop_remainder=True)
)

# smdistributed: Define smp.DistributedModel the same way as Keras sub-classing API 
class MyModel(smp.DistributedModel):
    def __init__(self):
        super(MyModel, self).__init__()
        # define layers

    def call(self, x, training=None):
        # define forward pass and return model outputs


model = MyModel()

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name="train_accuracy")

# smdistributed: Define smp.step. Return any tensors needed outside
@smp.step
def get_grads(images, labels):
    predictions = model(images, training=True)
    loss = loss_object(labels, predictions)

    grads = optimizer.get_gradients(loss, model.trainable_variables)
    return grads, loss, predictions


@tf.function
def train_step(images, labels, first_batch):
    gradients, loss, predictions = get_grads(images, labels)

    # smdistributed: Accumulate the gradients across microbatches
    # Horovod: AllReduce the accumulated gradients
    gradients = [hvd.allreduce(g.accumulate()) for g in gradients]
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    # Horovod: Broadcast the variables after first batch 
    if first_batch:
        hvd.broadcast_variables(model.variables, root_rank=0)
        hvd.broadcast_variables(optimizer.variables(), root_rank=0)

    # smdistributed: Merge predictions across microbatches
    train_accuracy(labels, predictions.merge())
    return loss.reduce_mean()


for epoch in range(5):
    # Reset the metrics at the start of the next epoch
    train_accuracy.reset_states()

    for batch, (images, labels) in enumerate(train_ds):
        loss = train_step(images, labels, tf.constant(batch == 0))
```

## Manuelles Teilen mit TensorFlow
<a name="model-parallel-customize-training-script-tf-manual"></a>

Verwenden Sie `smp.partition` Kontextmanager, um Operationen in einer bestimmten Partition zu platzieren. Jede Operation, die nicht in einem `smp.partition` Kontext steht, wird in der `default_partition` platziert. [Weitere Informationen zur API SageMaker der Modellparallelismus-Bibliothek finden Sie in der API-Dokumentation.](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) 

```
import tensorflow as tf

# smdistributed: Import TF2.x API.
import smdistributed.modelparallel.tensorflow as smp

# smdistributed: Initialize
smp.init()

# Download and load MNIST dataset.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    "MNIST-data-%d" % smp.rank()
)
x_train, x_test = x_train / 255.0, x_test / 255.0

# Add a channels dimension
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

# smdistributed: If needed, seed the shuffle with smp.dp_rank(), and drop_remainder
# in batching to make sure batch size is always divisible by number of microbatches.
train_ds = (
    tf.data.Dataset.from_tensor_slices((x_train, y_train))
    .shuffle(10000, seed=smp.dp_rank())
    .batch(256, drop_remainder=True)
)

# smdistributed: Define smp.DistributedModel the same way as Keras sub-classing API.
class MyModel(smp.DistributedModel):
    def __init__(self):
         # define layers

    def call(self, x):
        with smp.partition(0):
            x = self.layer0(x)
        with smp.partition(1):
            return self.layer1(x)


model = MyModel()

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name="train_accuracy")

# smdistributed: Define smp.step. Return any tensors needed outside
@smp.step
def get_grads(images, labels):
    predictions = model(images, training=True)
    loss = loss_object(labels, predictions)

    grads = optimizer.get_gradients(loss, model.trainable_variables)
    return grads, loss, predictions


@tf.function
def train_step(images, labels):
    gradients, loss, predictions = get_grads(images, labels)

    # smdistributed: Accumulate the gradients across microbatches
    gradients = [g.accumulate() for g in gradients]
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    # smdistributed: Merge predictions and average losses across microbatches
    train_accuracy(labels, predictions.merge())
    return loss.reduce_mean()


for epoch in range(5):
    # Reset the metrics at the start of the next epoch
    train_accuracy.reset_states()
    for images, labels in train_ds:
        loss = train_step(images, labels)
    accuracy = train_accuracy.result()
```

## Nicht unterstützte Framework-Funktionen
<a name="model-parallel-tf-unsupported-features"></a>

Die folgenden TensorFlow Funktionen werden von der Bibliothek nicht unterstützt:
+ `tf.GradientTape()` wird derzeit nicht unterstützt. Sie können stattdessen `Optimizer.get_gradients()` oder `Optimizer.compute_gradients()` verwenden, um Gradienten zu berechnen.
+ Derzeit wird die `tf.train.Checkpoint.restore()`-API nicht unterstützt. Verwenden Sie für Checkpointing `smp.CheckpointManager` stattdessen, das dieselbe API und Funktionalität bietet. Beachten Sie, dass Checkpoint-Wiederherstellungen mit `smp.CheckpointManager` nach dem ersten Schritt erfolgen sollten.