

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.

# Schritt 1: Ändern Sie Ihr eigenes Trainingsskript mithilfe SageMaker der Distributed Model Parallel Library
<a name="model-parallel-customize-training-script"></a>

In diesem Abschnitt erfahren Sie, wie Sie Ihr Schulungsskript anpassen können, um die Kernfunktionen der Amazon SageMaker AI-Bibliothek für Modellparallelismus zu nutzen. Um die bibliotheksspezifischen API-Funktionen und -Parameter zu verwenden, empfehlen wir Ihnen, diese Dokumentation zusammen mit der [SageMaker Modellparallel-Bibliothek APIs](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) in der *SageMaker Python SDK-Dokumentation* zu verwenden.

Die in diesen Abschnitten bereitgestellten Beispiele für Trainingsskripte sind vereinfacht und sollen die erforderlichen Änderungen hervorheben, die Sie vornehmen müssen, um die Bibliothek verwenden zu können. Ausführbare Notebook-Beispiele end-to-end, die demonstrieren, wie Sie ein TensorFlow PyTorch OR-Trainingsskript mit der SageMaker Modellparallelismus-Bibliothek verwenden, finden Sie unter. [Beispiele für die Amazon SageMaker AI-Modellparallelismusbibliothek v2](distributed-model-parallel-v2-examples.md)

**Topics**
+ [Teilen Sie das Modell Ihres Trainingsskripts mithilfe der Modellparallelismus-Bibliothek auf SageMaker](#model-parallel-model-splitting-using-smp-lib)
+ [Ändern Sie ein TensorFlow Trainingsskript](model-parallel-customize-training-script-tf.md)
+ [Ein PyTorch Trainingsskript ändern](model-parallel-customize-training-script-pt.md)

## Teilen Sie das Modell Ihres Trainingsskripts mithilfe der Modellparallelismus-Bibliothek auf SageMaker
<a name="model-parallel-model-splitting-using-smp-lib"></a>

Es gibt zwei Möglichkeiten, Ihr Trainingsskript so zu ändern, dass das Modellsplitting eingerichtet wird: automatisiertes Splitting oder manuelles Splitting.

### Automatisiertes Aufteilen von Modellen
<a name="model-parallel-automated-model-splitting"></a>

*Wenn Sie die Modellparallelitätsbibliothek verwenden SageMaker, können Sie die Vorteile der *automatisierten Modellteilung nutzen, die auch als automatisierte Modellpartitionierung* bezeichnet wird.* Die Bibliothek verwendet einen Partitionierungsalgorithmus, der den Arbeitsspeicher ausgleicht, die Kommunikation zwischen Geräten minimiert und die Leistung optimiert. Sie können den automatisierten Partitionierungsalgorithmus so konfigurieren, dass Geschwindigkeit oder Speicher optimiert werden. 

Alternativ können Sie die manuelle Modell-Splitting verwenden. Wir empfehlen die automatische Modellteilung, sofern Sie mit der Modellarchitektur nicht sehr vertraut sind und eine gute Vorstellung davon haben, wie Sie Ihr Modell effizient partitionieren können.

#### Funktionsweise
<a name="model-parallel-automated-model-splitting-how-it-works"></a>

Die automatische Partitionierung erfolgt während des ersten Trainingsschritts, wenn die mit `smp.step` -dekorierte Funktion zum ersten Mal aufgerufen wird. Während dieses Aufrufs erstellt die Bibliothek zunächst eine Version des Modells im CPU-RAM (um GPU-Speicherbeschränkungen zu vermeiden), analysiert dann das Modelldiagramm und trifft eine Partitionierungsentscheidung. Basierend auf dieser Entscheidung wird jede Modellpartition auf eine GPU geladen, und erst dann wird der erste Schritt ausgeführt. Aufgrund dieser Analyse- und Partitionierungsschritte kann der erste Trainingsschritt länger dauern. 

In beiden Frameworks verwaltet die Bibliothek die Kommunikation zwischen Geräten über ihr eigenes Backend, das für die Infrastruktur optimiert ist. AWS 

Das Design der automatischen Partition passt sich den Eigenschaften des Frameworks an, und die Bibliothek führt die Partitionierung auf der Granularitätsebene durch, die in jedem Framework natürlicher ist. Beispielsweise kann in TensorFlow jede spezifische Operation einem anderen Gerät zugewiesen werden, wohingegen die Zuweisung in PyTorch auf Modulebene erfolgt, wo jedes Modul aus mehreren Operationen besteht. Im folgenden Abschnitt werden die Besonderheiten des Designs in den einzelnen Frameworks beschrieben.

##### Automatisierte Modellteilung mit PyTorch
<a name="model-parallel-auto-model-split-pt"></a>

Während des ersten Trainingsschritts führt die Modellparallelitätsbibliothek intern einen Tracing-Schritt durch, der dazu dient, den Modellgraphen zu konstruieren und die Tensor- und Parameterformen zu bestimmen. Nach diesem Verfolgungsschritt erstellt die Bibliothek einen Baum, der aus den verschachtelten `nn.Module` Objekten im Modell sowie aus zusätzlichen Daten besteht, die bei der Ablaufverfolgung gesammelt wurden, wie z. B. die Menge der gespeicherten `nn.Parameters` und die Ausführungszeit für jedes `nn.Module`. 

Als Nächstes durchläuft die Bibliothek diesen Baum von der Wurzel aus und führt einen Partitionierungsalgorithmus aus, der jedes `nn.Module` Gerät einem Gerät zuweist, wodurch die Rechenlast (gemessen an der Modulausführungszeit) und die Speichernutzung (gemessen an der gesamten gespeicherten `nn.Parameter` Größe und den Aktivierungen) ausgeglichen werden. Wenn mehrere Module `nn.Modules` dasselbe `nn.Parameter` verwenden, werden diese Module auf demselben Gerät platziert, um zu vermeiden, dass mehrere Versionen desselben Parameters beibehalten werden. Sobald die Entscheidung über die Partitionierung getroffen wurde, werden die zugewiesenen Module und Gewichte auf ihre Geräte geladen.

Eine Anleitung, wie Sie den `smp.step` Decorator für Ihr PyTorch Trainingsskript registrieren, finden Sie unter. [Automatisiertes Teilen mit PyTorch](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16)

##### Automatisierte Modellteilung mit TensorFlow
<a name="model-parallel-auto-model-split-tf"></a>

Die Modellparallelitätsbibliothek analysiert die Größen der trainierbaren Variablen und die Graphstruktur und verwendet intern einen Algorithmus zur Graphpartitionierung. Dieser Algorithmus erstellt für jeden Vorgang eine Gerätezuweisung mit dem Ziel, den Kommunikationsaufwand zwischen den Geräten zu minimieren. Dabei gelten zwei Einschränkungen: 
+ Ausbalancierung der Anzahl der in jedem Gerät gespeicherten Variablen
+ Ausgleich der Anzahl der auf jedem Gerät ausgeführten Operationen

Wenn Sie `speed` für `optimize` (in den Modellparallelitätsparametern im Python-SDK) angeben, versucht die Bibliothek, die Anzahl der Operationen und `tf.Variable` Objekte in jedem Gerät auszugleichen. Andernfalls versucht sie, die Gesamtgröße von `tf.Variables` auszugleichen.

Sobald die Entscheidung über die Partitionierung getroffen wurde, erstellt die Bibliothek eine serialisierte Darstellung des Untergraphen, den jedes Gerät ausführen muss, und importiert sie auf jedes Gerät. Bei der Partitionierung platziert die Bibliothek Operationen, die dasselbe `tf.Variable` verbrauchen, und Operationen, die Teil derselben Keras-Schicht sind, auf demselben Gerät. Es berücksichtigt auch die Colocation-Einschränkungen von. TensorFlow Dies bedeutet, dass, wenn es beispielsweise zwei Keras-Ebenen gibt, die sich eine `tf.Variable` teilen, alle Operationen, die Teil dieser Ebenen sind, auf einem einzigen Gerät platziert werden.

Eine Anleitung, wie Sie den `smp.step` Decorator für Ihr PyTorch Trainingsskript registrieren, finden Sie unter. [Automatisiertes Teilen mit TensorFlow](model-parallel-customize-training-script-tf.md#model-parallel-customize-training-script-tf-23)

##### Vergleich der automatisierten Modellaufteilung zwischen Frameworks
<a name="model-parallel-auto-model-split-comparison"></a>

In TensorFlow ist die grundlegende Berechnungseinheit a `tf.Operation` und TensorFlow stellt das Modell als gerichteten azyklischen Graphen (DAG) von `tf.Operation` s dar. Aus diesem Grund partitioniert die Modellparallelitätsbibliothek diesen DAG, sodass jeder Knoten zu einem Gerät gehört. Entscheidend ist, dass `tf.Operation` Objekte ausreichend reich an anpassbaren Attributen sind und dass sie insofern universell sind, als jedes Modell garantiert aus einem Graphen solcher Objekte besteht. 

PyTorch auf der anderen Seite verfügt sie nicht über ein entsprechendes Funktionsverständnis, das umfassend und universell genug wäre. Die Recheneinheit PyTorch , die diesen Eigenschaften am nächsten kommt, ist an`nn.Module`, die sich auf einer viel höheren Granularitätsebene befindet, und aus diesem Grund partitioniert die Bibliothek auf dieser Ebene in. PyTorch

### Manuelles Aufteilen von Modellen
<a name="model-parallel-manual-model-splitting"></a>

Wenn Sie manuell angeben möchten, wie Ihr Modell geräteübergreifend partitioniert werden soll, verwenden Sie den `smp.partition` Kontext-Manager. Anleitungen zum Einrichten des Kontext-Managers für die manuelle Partitionierung finden Sie auf den folgenden Seiten.
+ [Manuelles Teilen mit TensorFlow](model-parallel-customize-training-script-tf.md#model-parallel-customize-training-script-tf-manual)
+ [Manuelles Teilen mit PyTorch](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16-hvd)

Um diese Option zu verwenden, nachdem Sie Änderungen vorgenommen haben, müssen Sie in Schritt 2 `default_partition` in der Framework-Schätzerklasse des SageMaker Python-SDK eine festlegen und diese definieren. `auto_partition` `False` Jede Operation, die nicht explizit über den `smp.partition` Kontext-Manager auf einer Partition platziert wurde, wird auf der `default_partition` ausgeführt. In diesem Fall wird die automatische Aufteilungslogik umgangen und jede Operation wird auf der Grundlage Ihrer Spezifikation platziert. Auf der Grundlage der resultierenden Graphstruktur erstellt die Modellparallelitätsbibliothek automatisch einen Ausführungsplan über die Pipeline.

# Ä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.

# Ein PyTorch Trainingsskript ändern
<a name="model-parallel-customize-training-script-pt"></a>

In diesem Abschnitt erfahren Sie, wie Sie PyTorch Trainingsskripte ändern, um die SageMaker Modellparallelitätsbibliothek für automatische Partitionierung und manuelle Partitionierung zu konfigurieren.

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

**Tipp**  
 end-to-endNotebook-Beispiele, die veranschaulichen, wie ein PyTorch Trainingsskript mit der SageMaker Modellparallelitätsbibliothek verwendet wird, finden Sie unter. [Beispiele für die Amazon SageMaker AI-Modellparallelismusbibliothek v1](distributed-model-parallel-examples.md)

Beachten Sie, dass die automatische Partitionierung standardmäßig aktiviert ist. Sofern nicht anders angegeben, verwenden die folgenden Skripten automatische Partitionierung. 

**Topics**
+ [Automatisiertes Teilen mit PyTorch](#model-parallel-customize-training-script-pt-16)
+ [Manuelles Teilen mit PyTorch](#model-parallel-customize-training-script-pt-16-hvd)
+ [Überlegungen](#model-parallel-pt-considerations)
+ [Nicht unterstützte Framework-Funktionen](#model-parallel-pt-unsupported-features)

## Automatisiertes Teilen mit PyTorch
<a name="model-parallel-customize-training-script-pt-16"></a>

Die folgenden Änderungen am Trainingsskript sind erforderlich, um ein PyTorch Trainingsskript mit SageMaker der Modellparallelismus-Bibliothek 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. Schließen Sie das Modell mit [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedModel](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedModel) um. Beachten Sie, dass alle Tensoren, die von der `forward` Methode des zugrunde liegenden `nn.Module` Objekts zurückgegeben werden, über modellparallele Geräte übertragen werden, was zu Kommunikationsaufwand führt. Daher sollten alle Tensoren, die außerhalb der Aufrufmethode nicht benötigt werden (z. B. Zwischenaktivierungen), nicht zurückgegeben werden.
**Anmerkung**  
Für das FP16 Training müssen Sie den Kontextmanager [smdistributed.modelparallel.torch.model\$1creation](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html) () verwenden, um das Modell zu umschließen. Weitere Informationen finden Sie unter [FP16 Training mit Modellparallelität](model-parallel-extended-features-pytorch-fp16.md).

1. Umschließen Sie den Optimierer mit [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedOptimizer](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedOptimizer).
**Anmerkung**  
Für das Training müssen Sie eine statische oder dynamische Verlustskalierung einrichten FP16 . Weitere Informationen finden Sie unter [FP16 Training mit Modellparallelität](model-parallel-extended-features-pytorch-fp16.md).

1. Verwenden Sie das zurückgegebene `DistributedModel` Objekt anstelle eines Benutzermodells.

1. Fügen Sie die Vorwärts- und Rückwärtslogik in eine Schrittfunktion ein und dekorieren Sie sie 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. Beschränken Sie jeden Prozess auf sein eigenes Gerät durch `torch.cuda.set_device(smp.local_rank())`.

1. Verschieben Sie die Eingangstensoren mithilfe der `.to()` API vor dem `smp.step` Aufruf auf die GPU (siehe Beispiel unten).

1. Ersetzen Sie `torch.Tensor.backward` und `torch.autograd.backward` mit `DistributedModel.backward`.

1. Führen Sie die Nachbearbeitung der Ausgaben für alle Mikrobatches mithilfe von [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) Methoden wie `reduce_mean` durch.

1. Wenn es einen Bewertungsschritt gibt, platzieren Sie die Vorwärtslogik auf ähnliche Weise in einer mit -`smp.step`dekorierten Funktionen und bearbeiten 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.

1. `drop_last=True` in `DataLoader` einstellen. Alternativ können Sie einen Stapel in der Trainingsschleife manuell überspringen, wenn die Batchgröße nicht durch die Anzahl der Mikrobatches teilbar ist.

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 torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchnet.dataset import SplitDataset
from torchvision import datasets

import smdistributed.modelparallel.torch as smp

class GroupedNet(nn.Module):
    def __init__(self):
        super(GroupedNet, self).__init__()
        # define layers

    def forward(self, x):
        # define forward pass and return model outputs


# smdistributed: Define smp.step. Return any tensors needed outside.
@smp.step
def train_step(model, data, target):
    output = model(data)
    loss = F.nll_loss(output, target, reduction="mean")
    model.backward(loss)
    return output, loss


def train(model, device, train_loader, optimizer):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        # smdistributed: Move input tensors to the GPU ID used by the current process,
        # based on the set_device call.
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        # Return value, loss_mb is a StepOutput object
        _, loss_mb = train_step(model, data, target)

        # smdistributed: Average the loss across microbatches.
        loss = loss_mb.reduce_mean()

        optimizer.step()

# smdistributed: initialize the backend
smp.init()

# smdistributed: Set the device to the GPU ID used by the current process.
# Input tensors should be transferred to this device.
torch.cuda.set_device(smp.local_rank())
device = torch.device("cuda")

# smdistributed: Download only on a single process per instance.
# When this is not present, the file is corrupted by multiple processes trying
# to download and extract at the same time
dataset = datasets.MNIST("../data", train=True, download=False)

# smdistributed: Shard the dataset based on data-parallel ranks
if smp.dp_size() > 1:
    partitions_dict = {f"{i}": 1 / smp.dp_size() for i in range(smp.dp_size())}
    dataset = SplitDataset(dataset, partitions=partitions_dict)
    dataset.select(f"{smp.dp_rank()}")

# smdistributed: Set drop_last=True to ensure that batch size is always divisible
# by the number of microbatches
train_loader = torch.utils.data.DataLoader(dataset, batch_size=64, drop_last=True)

model = GroupedNet()
optimizer = optim.Adadelta(model.parameters(), lr=4.0)

# smdistributed: Use the DistributedModel container to provide the model
# to be partitioned across different ranks. For the rest of the script,
# the returned DistributedModel object should be used in place of
# the model provided for DistributedModel class instantiation.
model = smp.DistributedModel(model)
optimizer = smp.DistributedOptimizer(optimizer)

train(model, device, train_loader, optimizer)
```

## Manuelles Teilen mit PyTorch
<a name="model-parallel-customize-training-script-pt-16-hvd"></a>

Verwenden Sie [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedOptimizer](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedOptimizer) Kontextmanager, um Module auf bestimmten Geräten zu platzieren. Jedes Modul, das sich nicht in einem `smp.partition` Kontext befindet, wird in den `default_partition` platziert. Das `default_partition` muss angegeben werden, wenn `auto_partition` auf `False` gesetzt ist. Die Module, die in einem bestimmten `smp.partition` Kontext erstellt werden, werden auf der entsprechenden 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 torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchnet.dataset import SplitDataset
from torchvision import datasets

import smdistributed.modelparallel.torch as smp

class GroupedNet(nn.Module):
    def __init__(self):
        super(GroupedNet, self).__init__()
        with smp.partition(0):
            # define child modules on device 0
        with smp.partition(1):
            # define child modules on device 1

    def forward(self, x):
        # define forward pass and return model outputs


# smdistributed: Define smp.step. Return any tensors needed outside.
@smp.step
def train_step(model, data, target):
    output = model(data)
    loss = F.nll_loss(output, target, reduction="mean")
    model.backward(loss)
    return output, loss


def train(model, device, train_loader, optimizer):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        # smdistributed: Move input tensors to the GPU ID used by the current process,
        # based on the set_device call.
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        # Return value, loss_mb is a StepOutput object
        _, loss_mb = train_step(model, data, target)

        # smdistributed: Average the loss across microbatches.
        loss = loss_mb.reduce_mean()

        optimizer.step()

# smdistributed: initialize the backend
smp.init()

# smdistributed: Set the device to the GPU ID used by the current process.
# Input tensors should be transferred to this device.
torch.cuda.set_device(smp.local_rank())
device = torch.device("cuda")

# smdistributed: Download only on a single process per instance.
# When this is not present, the file is corrupted by multiple processes trying
# to download and extract at the same time
dataset = datasets.MNIST("../data", train=True, download=False)

# smdistributed: Shard the dataset based on data-parallel ranks
if smp.dp_size() > 1:
    partitions_dict = {f"{i}": 1 / smp.dp_size() for i in range(smp.dp_size())}
    dataset = SplitDataset(dataset, partitions=partitions_dict)
    dataset.select(f"{smp.dp_rank()}")

# smdistributed: Set drop_last=True to ensure that batch size is always divisible
# by the number of microbatches
train_loader = torch.utils.data.DataLoader(dataset, batch_size=64, drop_last=True)

model = GroupedNet()
optimizer = optim.Adadelta(model.parameters(), lr=4.0)

# smdistributed: Use the DistributedModel container to provide the model
# to be partitioned across different ranks. For the rest of the script,
# the returned DistributedModel object should be used in place of
# the model provided for DistributedModel class instantiation.
model = smp.DistributedModel(model)
optimizer = smp.DistributedOptimizer(optimizer)

train(model, device, train_loader, optimizer)
```

## Überlegungen
<a name="model-parallel-pt-considerations"></a>

Wenn Sie ein PyTorch Trainingsskript mithilfe SageMaker der Modellparallelismus-Bibliothek konfigurieren, sollten Sie Folgendes beachten:
+ Wenn Sie eine Optimierungstechnik verwenden, die auf globalen Gradientennormen basiert, z. B. der Gradientennorm aus dem gesamten Modell, wie z. B. einige Varianten des LAMB-Optimizers oder des globalen Gradientenclippings, müssen Sie alle Normen aus den Modellpartitionen zusammenstellen, um ihre Richtigkeit zu überprüfen. Zu diesem Zweck können Sie die grundlegenden Kommunikationsdatentypen der Bibliothek verwenden.
+ Alle `torch.Tensor` Argumente für die Vorwärtsmethoden von `nn.Modules` in Ihrem Modell müssen bei der Berechnung der Modulausgabe verwendet werden. Mit anderen Worten, die Bibliothek unterstützt nicht den Fall, dass es ein `torch.Tensor` Argument für ein Modul gibt, von dem die Modulausgabe nicht abhängt.
+ Das Argument für den `smp.DistributedModel.backward()` Aufruf muss von allen Modellausgaben abhängen. Mit anderen Worten, es darf keine Ausgabe des `smp.DistributedModel.forward` Aufrufs geben, die nicht bei der Berechnung des Tensors verwendet wird, der in den `smp.DistributedModel.backward` Aufruf eingespeist wird.
+ Wenn Ihr Code `torch.cuda.synchronize()` Aufrufe enthält, müssen Sie möglicherweise `torch.cuda.set_device(smp.local_rank())` unmittelbar vor dem Synchronisierungsaufruf anrufen. Andernfalls könnten in Gerät 0 unnötige CUDA-Kontexte erstellt werden, die unnötig Speicherplatz verbrauchen.
+ Da sich die Bibliothek `nn.Modules` auf unterschiedlichen Geräten befindet, dürfen die Module im Modell nicht von einem globalen Status abhängen, der im Inneren von `smp.step` geändert wird. Jeder Status, der während des gesamten Trainings unverändert bleibt oder außerhald von `smp.step` so verändert wird, dass er für alle Prozesse sichtbar ist, ist zulässig.
+ Sie müssen das Modell nicht auf die GPU verschieben (z. B. verwenden von `model.to(device)`), wenn Sie die Bibliothek verwenden. Wenn Sie versuchen, das Modell auf die GPU zu verschieben, bevor das Modell partitioniert wurde (vor dem ersten `smp.step` Aufruf), wird der Move-Aufruf ignoriert. Die Bibliothek verschiebt den Teil des Modells, der einem Rang zugewiesen wurde, automatisch auf ihre GPU. Sobald das Training mit der Bibliothek begonnen hat, sollten Sie das Modell nicht auf die CPU verschieben und es verwenden, da es sonst keine korrekten Parameter für Module enthält, die nicht der vom Prozess gespeicherten Partition zugewiesen sind. Wenn Sie ein Modell neu trainieren oder es ohne die Bibliothek für Inferenz verwenden möchten, nachdem es mit der Modellparallelismus-Bibliothek trainiert wurde, empfiehlt es sich, das vollständige Modell mithilfe unserer Checkpoint-API zu speichern und es wieder in ein reguläres Modul zu laden. PyTorch 
+ Wenn Sie eine Liste von Modulen haben, bei denen die Ausgabe eines Moduls in ein anderes einfließen kann, kann das Ersetzen dieser Liste durch die Leistung erheblich verbessern. `nn.Sequential`
+ Das Gewichtsupdate (`optimizer.step()`) muss außerhalb von `smp.step` erfolgen, da dann der gesamte Rückwärtsdurchlauf abgeschlossen ist und die Farbverläufe bereit sind. Wenn Sie ein Hybridmodell mit Modell- und Datenparallelität verwenden, ist zu diesem Zeitpunkt auch garantiert, dass die Gradienten beendet AllReduce sind.
+ Wenn Sie die Bibliothek in Kombination mit Datenparallelität verwenden, stellen Sie sicher, dass die Anzahl der Batches auf allen datenparallelen Rängen gleich ist, damit Sie AllReduce nicht auf einen Rang warten, der nicht am Schritt teilnimmt.
+ Wenn Sie einen Trainingsjob mit einem ml.p4d-Instance-Typ (z. B. ml.p4d.24xlarge) starten, müssen Sie die Dataloader-Variable `num_workers=0` festlegen. Sie können `DataLoader` Ihren beispielsweise wie folgt definieren:

  ```
  dataloader = torch.utils.data.DataLoader(
              data,
              batch_size=batch_size,
              num_workers=0,
              pin_memory=True,
              drop_last=True,
              shuffle=shuffle,
          )
  ```
+ Die Eingaben für `smp.step` müssen die Modelleingaben sein, die von `DataLoader` generiert wurden. Der Grund dafür ist, dass `smp.step` die Eingabetensoren intern entlang der Stapeldimension aufteilt und sie in eine Pipeline einfügt. Dies bedeutet, dass es nicht funktioniert, `DataLoader` sich selbst an die `smp.step` Funktion zur Generierung der darin enthaltenen Modelleingaben zu übergeben. 

  Wenn Sie beispielsweise a `DataLoader` wie folgt definieren:

  ```
  train_loader = torch.utils.data.DataLoader(dataset, batch_size=64, drop_last=True)
  ```

  Sie sollten auf die Modelleingaben zugreifen, die von generiert wurden, `train_loader` und diese an eine `smp.step` dekorierte Funktion übergeben. Übergeben Sie `train_loader` nicht direkt an die `smp.step` Funktion.

  ```
  def train(model, device, train_loader, optimizer):
      model.train()
      for batch_idx, (data, target) in enumerate(train_loader):
          ...
          _, loss_mb = train_step(model, data, target)
          ...
  
  @smp.step
  def train_step(model, data, target):
      ...
      return output, loss
  ```
+ Die Eingangstensoren für `smp.step` müssen mithilfe der `.to()` API auf das aktuelle Gerät verschoben werden, was nach dem `torch.cuda.set_device(local_rank())` Aufruf erfolgen muss.

  Sie können z. B. wie folgt die Funktion `train` definieren. Diese Funktion fügt dem aktuellen Gerät mithilfe der `.to()` API `data` und `target` hinzu, bevor diese Eingangstensoren zum Aufrufen von `train_step` verwendet werden.

  ```
  def train(model, device, train_loader, optimizer):
      model.train()
      for batch_idx, (data, target) in enumerate(train_loader):
          # smdistributed: Move input tensors to the GPU ID used by the current process,
          # based on the set_device call.
          data, target = data.to(device), target.to(device)
          optimizer.zero_grad()
          # Return value, loss_mb is a StepOutput object
          _, loss_mb = train_step(model, data, target)
  
          # smdistributed: Average the loss across microbatches.
          loss = loss_mb.reduce_mean()
  
          optimizer.step()
  ```

  Die Eingangstensoren für diese `smp.set` dekorierte Funktion wurden in der obigen `train` Funktion auf das aktuelle Gerät verschoben. Das Modell muss *nicht* auf das aktuelle Gerät verschoben werden. Die Bibliothek verschiebt den Teil des Modells, der einem Rang zugewiesen ist, automatisch auf ihre GPU.

  ```
  @smp.step
  def train_step(model, data, target):
      output = model(data)
      loss = F.nll_loss(output, target, reduction="mean")
      model.backward(loss)
      return output, loss
  ```

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

Die folgenden PyTorch Funktionen werden von der Modellparallelitätsbibliothek nicht unterstützt SageMaker:
+ Wenn Sie Datenparallelität mit dem nativen [PyTorch DDP](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html) verwenden, wird das [https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html](https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html)Wrapper-Modul von der Bibliothek nicht unterstützt. Die Bibliothek verwaltet intern die Integration mit PyTorch DDP, einschließlich Parameterübertragung und Gradient. AllReduce Bei Verwendung der Bibliothek werden Modulpuffer zu Beginn des Trainings nur einmal übertragen. Wenn Ihr Modell über Modulpuffer verfügt, die bei jedem Schritt über datenparallele Gruppen hinweg synchronisiert werden müssen, können Sie dies über die `torch.distributed` API tun, indem Sie die Prozessgruppe verwenden, die über `smp.get_dp_process_group()` abgerufen werden kann.
+ Für gemischtes Präzisionstraining wird das `apex.amp` Modul nicht unterstützt. Es wird empfohlen, die Bibliothek mit automatischer Mixed-Precision `torch.cuda.amp` zu verwenden, mit der Ausnahme, dass `smp.amp.GradScaler` anstelle der Implementierung in Torch verwendet wird.
+ `torch.jit.ScriptModules` und `ScriptFunctions` werden von `smp.DistributedModel` nicht unterstützt.
+ `apex` : `FusedLayerNorm`, `FusedAdam` `FusedLAMB`, und `FusedNovoGrad` von `apex` werden nicht unterstützt. Sie können stattdessen deren Bibliotheksimplementierungen über `smp.optimizers` und `smp.nn` APIs verwenden.