

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# (Archivé) Bibliothèque SageMaker de parallélisme des modèles v1.x
<a name="model-parallel"></a>

**Important**  
La bibliothèque SageMaker de parallélisme des modèles (SMP) v2 est publiée depuis le 19 décembre 2023. Au profit de la bibliothèque SMP v2, les capacité de SMP v1 ne seront plus prises en charge dans les prochaines versions. La section et les rubriques suivantes sont archivées et spécifiques à l’utilisation de la bibliothèque SMP v1. Pour plus d’informations sur l’utilisation de la bibliothèque SMP v2, consultez [Bibliothèque SageMaker de parallélisme des modèles v2](model-parallel-v2.md).

Utilisez la bibliothèque Amazon SageMaker AI de parallélisme des modèles pour entraîner de grands modèles de deep learning (DL) difficiles à entraîner en raison de limitations de la mémoire GPU. La bibliothèque divise un modèle automatiquement et efficacement sur plusieurs GPU et instances. À l'aide de la bibliothèque, vous pouvez obtenir une précision de prédiction cible plus rapidement en entraînant efficacement des modèles DL plus volumineux avec des milliards ou des trillions de paramètres.

Vous pouvez utiliser la bibliothèque pour partitionner automatiquement vos propres modèles TensorFlow et PyTorch sur plusieurs GPU et plusieurs nœuds avec des modifications de code minimales. Vous pouvez accéder à l'API de la bibliothèque via le kit SDK Python SageMaker.

Consultez les sections suivantes pour en savoir plus sur le parallélisme des modèles et la bibliothèque de modèles parallèles SageMaker. La documentation concernant l’API de cette bibliothèque se trouve sous [Distributed Training APIs](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) dans la *documentation relative au kit SageMaker Python SDK v2.199.0*. 

**Topics**
+ [Présentation du parallélisme des modèles](model-parallel-intro.md)
+ [Frameworks pris en charge et Régions AWS](distributed-model-parallel-support.md)
+ [Principales fonctionnalités de la bibliothèque de parallélisme des SageMaker modèles](model-parallel-core-features.md)
+ [Exécutez un travail de formation SageMaker distribué avec Model Parallelism](model-parallel-use-api.md)
+ [Point de contrôle et optimisation d'un modèle grâce au parallélisme de modèles](distributed-model-parallel-checkpointing-and-finetuning.md)
+ [Exemples de bibliothèque de parallélisme de modèles Amazon SageMaker AI v1](distributed-model-parallel-examples.md)
+ [SageMaker Meilleures pratiques en matière de parallélisme des modèles distribués](model-parallel-best-practices.md)
+ [Conseils et pièges de configuration de la bibliothèque de parallélisme des modèles SageMaker distribués](model-parallel-customize-tips-pitfalls.md)
+ [Dépannage pour les modèles parallèles](distributed-troubleshooting-model-parallel.md)

# Présentation du parallélisme des modèles
<a name="model-parallel-intro"></a>

Le parallélisme de modèle est une méthode d'entraînement distribué dans laquelle le modèle de deep learning est partitionné sur plusieurs appareils, au sein des instances ou entre celles-ci. Cette page d'introduction fournit une présentation générale du parallélisme des modèles, une description de la manière dont il peut aider à résoudre les problèmes qui surviennent lors de l'entraînement de modèles DL généralement de très grande taille, et des exemples de ce que propose la bibliothèque de modèles SageMaker parallèles pour aider à gérer les stratégies de modélisation parallèle ainsi que la consommation de mémoire.

## Qu'est-ce que le parallélisme des modèles ?
<a name="model-parallel-what-is"></a>

L'augmentation de la taille des modèles de deep learning (couches et paramètres) permet une meilleure précision pour des tâches complexes telles que la reconnaissance d'image et le traitement du langage naturel. Toutefois, il y a une limite à la taille maximale de modèle que vous pouvez faire tenir dans la mémoire d'un GPU individuel. Lors de l'entraînement de modèles DL, les limites de mémoire du GPU peuvent constituer un goulet d'étranglement :
+ Elles limitent la taille du modèle que vous pouvez entraîner, car l'empreinte mémoire d'un modèle évolue proportionnellement au nombre de paramètres.
+ Elles limitent la taille de lot par GPU pendant l'entraînement, ce qui réduit l'utilisation du GPU et l'efficacité de l'entraînement.

Pour surmonter les limites associées à l'entraînement d'un modèle sur un seul GPU, SageMaker fournit la bibliothèque model parallel qui permet de distribuer et d'entraîner efficacement les modèles DL sur plusieurs nœuds de calcul. En outre, cette bibliothèque vous permet de profiter d'un entraînement distribué optimisé à l'aide d'appareils intégrant EFA, qui améliorent les performances de la communication entre les nœuds avec une faible latence, un débit élevé et le contournement du système d'exploitation.

## Estimation des besoins en mémoire avant d’utiliser le parallélisme des modèles
<a name="model-parallel-intro-estimate-memory-requirements"></a>

Avant d'utiliser la bibliothèque SageMaker model parallel, considérez les points suivants pour vous faire une idée des besoins en mémoire liés à l'entraînement de grands modèles DL.

Pour une tâche d'entraînement utilisant les optimiseurs AMP (FP16) et Adam, la mémoire GPU requise par paramètre est d'environ 20 octets, que nous pouvons décomposer comme suit :
+ Un FP16 paramètre d'environ 2 octets
+ Un FP16 gradient d'environ 2 octets
+ Un état d' FP32 optimisation d'environ 8 octets basé sur les optimiseurs Adam
+ Une FP32 copie du paramètre d'environ 4 octets (nécessaire pour l'opération `optimizer apply` (OA))
+ Une FP32 copie du gradient d'environ 4 octets (nécessaire pour l'opération OA)

Même un modèle DL relativement petit, avec 10 milliards de paramètres, peut nécessiter au moins 200 Go de mémoire, ce qui dépasse nettement la mémoire GPU standard (par exemple, NVIDIA A100 avec 40/80 Go de mémoire et V100 avec 16/32 Go) disponible sur un GPU individuel. Notez qu'en plus des besoins en mémoire pour les états de modèle et d'optimiseur, il existe d'autres consommateurs de mémoire tels que les activations générées dans la transmission vers l'avant. La mémoire requise peut être largement supérieure à 200 Go.

Pour les formations distribuées, nous vous recommandons d'utiliser des instances Amazon EC2 P3 et P4 dotées respectivement de NVIDIA V100 et A100 Tensor Core. GPUs Pour plus de détails sur les spécifications telles que les cœurs de processeur, la RAM, le volume de stockage attaché et la bande passante du réseau, consultez la section *Calcul accéléré* de la page [Types d'instances Amazon EC2](https://aws.amazon.com/ec2/instance-types/).

Même avec les instances de calcul accéléré, il est évident que des modèles avec environ 10 milliards de paramètres, tels que Megatron-LM et T5, et des modèles encore plus grands avec des centaines de milliards de paramètres, tels que GPT-3, ne peuvent pas faire tenir les réplicas de modèles dans chaque périphérique GPU. 

## Utilisation par la bibliothèque des techniques d’économie de mémoire et de parallélisme des modèles
<a name="model-parallel-intro-features"></a>

La bibliothèque comprend différents types de fonctionnalités de parallélisme de modèle et de fonctionnalités d'économie de mémoire, telles que le partitionnement de l'état de l'optimiseur, les points de contrôle d'activation et le déchargement d'activation. Toutes ces techniques peuvent être combinées pour entraîner efficacement des modèles de grande taille composés de centaines de milliards de paramètres.

**Topics**
+ [Parallélisme de données fragmenté (disponible pour) PyTorch](#model-parallel-intro-sdp)
+ [Parallélisme du pipeline (disponible pour PyTorch et) TensorFlow](#model-parallel-intro-pp)
+ [Parallélisme tensoriel (disponible pour) PyTorch](#model-parallel-intro-tp)
+ [Sharding de l'état de l'optimiseur (disponible pour) PyTorch](#model-parallel-intro-oss)
+ [Activation, déchargement et point de contrôle (disponible pour) PyTorch](#model-parallel-intro-activation-offloading-checkpointing)
+ [Choix des techniques appropriées pour votre modèle](#model-parallel-intro-choosing-techniques)

### Parallélisme de données fragmenté (disponible pour) PyTorch
<a name="model-parallel-intro-sdp"></a>

*Le parallélisme des données partitionnées* est une technique d'entraînement distribuée économisant de la mémoire qui divise l'état d'un modèle (paramètres du modèle, dégradés et états de l'optimiseur) au sein d'un groupe parallèle de données. GPUs 

SageMaker ****[L'IA met en œuvre le parallélisme des données fragmentées grâce à la mise en œuvre de MICS, une bibliothèque qui minimise l'échelle de la communication et dont il est question dans le billet de blog **Scaling** near linear scaling of gigantic-model training on. AWS](https://www.amazon.science/blog/near-linear-scaling-of-gigantic-model-training-on-aws)****

Vous pouvez appliquer le parallélisme de données partitionnées à votre modèle en tant que stratégie autonome. De plus, si vous utilisez les instances GPU les plus performantes équipées du NVIDIA A100 Tensor Core GPUs`ml.p4d.24xlarge`, vous pouvez profiter de la vitesse d'entraînement améliorée grâce au `AllGather` fonctionnement proposé par SMDDP Collectives.

Pour approfondir le parallélisme des données fragmentées et apprendre à le configurer ou à utiliser une combinaison du parallélisme de données fragmenté avec d'autres techniques telles que le parallélisme tensoriel et l'entraînement, voir. FP16 [Parallélisme des données partitionnées](model-parallel-extended-features-pytorch-sharded-data-parallelism.md)

### Parallélisme du pipeline (disponible pour PyTorch et) TensorFlow
<a name="model-parallel-intro-pp"></a>

Le *parallélisme de pipeline* partitionne l'ensemble de couches ou d'opérations sur l'ensemble de dispositifs, laissant chaque opération intacte. Lorsque vous spécifiez une valeur pour le nombre de partitions de modèle (`pipeline_parallel_degree`), le nombre total de GPUs (`processes_per_host`) doit être divisible par le nombre de partitions de modèle. Pour configurer cela correctement, vous devez spécifier les bonnes valeurs pour les paramètres `pipeline_parallel_degree` et `processes_per_host`. Le calcul simple est le suivant :

```
(pipeline_parallel_degree) x (data_parallel_degree) = processes_per_host
```

La bibliothèque se charge de calculer le nombre de réplicas du modèle (également appelé `data_parallel_degree`) en fonction des deux paramètres d'entrée que vous fournissez. 

Par exemple, si vous définissez `"pipeline_parallel_degree": 2` et `"processes_per_host": 8` utilisez une instance ML avec huit processeurs graphiques, par exemple`ml.p3.16xlarge`, la bibliothèque configure automatiquement le modèle distribué sur le parallélisme des données GPUs et le parallélisme quadridirectionnel. L'image suivante montre comment un modèle est distribué sur les huit, ce qui permet d' GPUs obtenir un parallélisme des données quadridirectionnel et un parallélisme des pipelines bidirectionnel. Chaque réplique de modèle, dans laquelle nous la définissons comme un *groupe parallèle de pipelines* et l'étiquetons comme suit`PP_GROUP`, est partitionnée en deux GPUs. Chaque partition du modèle est affectée à quatre GPUs, les quatre répliques de partitions se trouvant dans un *groupe data parallel* et étiquetées comme`DP_GROUP`. Sans parallélisme de tenseur, le groupe de parallélisme de pipeline est essentiellement le groupe de parallélisme de modèle.

![\[Comment un modèle est distribué entre les huit pour GPUs obtenir un parallélisme des données quadridirectionnel et un parallélisme bidirectionnel des pipelines.\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/smdmp-pipeline-parallel-only.png)


Pour explorer le parallélisme de pipeline, consultez [Principales fonctionnalités de la bibliothèque de parallélisme des SageMaker modèles](model-parallel-core-features.md). 

Pour commencer à exécuter votre modèle à l'aide du parallélisme de pipeline, voir [Run a SageMaker Distributed Training Job with the SageMaker Model Parallel Library](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-use-api.html).

### Parallélisme tensoriel (disponible pour) PyTorch
<a name="model-parallel-intro-tp"></a>

Le *parallélisme de tenseurs* divise les couches individuelles, ou `nn.Modules`, entre les dispositifs, pour qu'elles soient exécutées en parallèle. La figure suivante illustre l'exemple le plus simple de la façon dont la bibliothèque divise un modèle à quatre couches pour obtenir un parallélisme de tenseur bidirectionnel (`"tensor_parallel_degree": 2`). Les couches de chaque réplique du modèle sont coupées en deux et réparties en deux GPUs. Dans ce cas d'exemple, la configuration parallèle du modèle inclut également `"pipeline_parallel_degree": 1` et `"ddp": True` (utilise le PyTorch DistributedDataParallel package en arrière-plan), de sorte que le degré de parallélisme des données passe à huit. La bibliothèque gère la communication entre les réplicas de modèles distribués par tenseur.

![\[Exemple le plus simple de la façon dont la bibliothèque divise un modèle à quatre couches pour obtenir un parallélisme de tenseur bidirectionnel ("tensor_parallel_degree": 2).\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/smdmp-tensor-parallel-only.png)


L'utilité de cette fonctionnalité réside dans le fait que vous pouvez sélectionner des couches spécifiques ou un sous-ensemble de couches pour appliquer le parallélisme de tenseur. Pour en savoir plus sur le parallélisme des tenseurs et d'autres fonctionnalités permettant d'économiser de la mémoire PyTorch, et pour apprendre à définir une combinaison de parallélisme de pipeline et de tenseur, voir. [Parallélisme de tenseur](model-parallel-extended-features-pytorch-tensor-parallelism.md)

### Sharding de l'état de l'optimiseur (disponible pour) PyTorch
<a name="model-parallel-intro-oss"></a>

Pour comprendre comment la bibliothèque effectue le *partitionnement de l'état de l'optimiseur*, envisagez un exemple de modèle simple à quatre couches. L'idée clé pour optimiser le partitionnement des états est que vous n'avez pas besoin de reproduire l'état de votre optimiseur dans tous vos. GPUs Au lieu de cela, un seul réplica de l'état de l'optimiseur est partitionné entre les rangs parallèles de données, sans redondance entre les appareils. Par exemple, le GPU 0 conserve l'état de l'optimiseur pour la couche 1, le GPU 1 suivant contient l'état de l'optimiseur pour la couche 2 (L2), etc. La figure animée suivante montre une propagation vers l'arrière avec la technique de partitionnement de l'état de l'optimiseur. À la fin de la propagation vers l'arrière, il y a le temps de calcul et de réseau pour l'opération `optimizer apply` (OA) pour mettre à jour les états de l'optimiseur et l'opération `all-gather` (AG) pour mettre à jour les paramètres du modèle pour la prochaine itération. Surtout, l'opération `reduce` peut chevaucher le calcul sur GPU 0, ce qui entraîne une propagation vers l'arrière plus rapide et plus efficace en termes de mémoire. Dans l'implémentation actuelle, les opérations AG et OA ne chevauchent pas `compute`. Cela peut entraîner un calcul étendu pendant l'opération AG, pouvant donner lieu à un compromis. 

![\[Propagation vers l’arrière avec la technique de partitionnement de l’état de l’optimiseur.\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/smdmp-optimizer-state-sharding.gif)


Pour plus d'informations sur l'utilisation de cette fonctionnalité, consultez [Partitionnement de l'état de l'optimiseur](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-optimizer-state-sharding.html).

### Activation, déchargement et point de contrôle (disponible pour) PyTorch
<a name="model-parallel-intro-activation-offloading-checkpointing"></a>

Pour enregistrer la mémoire GPU, la bibliothèque prend en charge les points de contrôle d'activation afin d'éviter de stocker des activations internes dans la mémoire GPU pour les modules spécifiés par l'utilisateur pendant la transmission vers l'avant. La bibliothèque recalcule ces activations pendant la transmission vers l'arrière. En outre, la fonctionnalité de déchargement d'activation décharge les activations stockées dans la mémoire CPU et les récupère dans le GPU pendant la transmission vers l'arrière, afin de réduire encore l'empreinte mémoire d'activation. Pour plus d'informations sur l'utilisation de ces fonctionnalités, consultez [Points de contrôle d'activation](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-activation-checkpointing.html) et [Déchargement de l'activation](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-activation-offloading.html).

### Choix des techniques appropriées pour votre modèle
<a name="model-parallel-intro-choosing-techniques"></a>

Pour plus d'informations sur le choix des techniques et des configurations appropriées, consultez les [meilleures pratiques parallèles en matière de modèles SageMaker distribués](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-best-practices.html) et les [conseils et pièges en matière de configuration](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-customize-tips-pitfalls.html).

# Frameworks pris en charge et Régions AWS
<a name="distributed-model-parallel-support"></a>

Avant d'utiliser la bibliothèque de SageMaker modèles de parallélisme, vérifiez les frameworks et les types d'instances pris en charge, et déterminez s'il y a suffisamment de quotas dans votre AWS compte et. Région AWS

**Note**  
Pour consulter les dernières mises à jour et notes de publication de la bibliothèque, consultez les [notes de version de SageMaker Model Parallel](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_release_notes/smd_model_parallel_change_log.html) dans la *documentation du SDK SageMaker Python*.

## Cadres pris en charge
<a name="distributed-model-parallel-supported-frameworks"></a>

La bibliothèque de SageMaker modèles de parallélisme prend en charge les frameworks d'apprentissage profond suivants et est disponible dans AWS Deep Learning Containers (DLC) ou téléchargeable sous forme de fichier binaire.

PyTorch versions prises en charge par l' SageMaker IA et la bibliothèque de parallélisme des SageMaker modèles


| PyTorch version | SageMaker version de la bibliothèque de parallélisme des modèles | URI de l'image intégrée `smdistributed-modelparallel` | URL du fichier binaire\$1\$1 | 
| --- | --- | --- | --- | 
| v2.0.0 | smdistributed-modelparallel==v1.15.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:2.0.0-gpu-py310-cu118-ubuntu20.04-sagemaker`  | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-2.0.0/build-artifacts/2023-04-14-20-14/smdistributed\$1modelparallel-1.15.0-cp310-cp310-linux\$1x86\$164.whl | 
| v1.13.1 | smdistributed-modelparallel==v1.15.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.13.1-gpu-py39-cu117-ubuntu20.04-sagemaker`  | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-1.13.1/build-artifacts/2023-04-17-15-49/smdistributed\$1modelparallel-1.15.0-cp39-cp39-linux\$1x86\$164.whl | 
| v1.12.1 | smdistributed-modelparallel==v1.13.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.12.1-gpu-py38-cu113-ubuntu20.04-sagemaker`  | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-1.12.1/build-artifacts/2\$112-08-21-34/smdistributed\$1modelparallel-1.13.0-cp38-cp38-linux\$1x86\$164.whl | 
| v1.12.0 | smdistributed-modelparallel==v1.11.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.12.0-gpu-py38-cu113-ubuntu20.04-sagemaker`   | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-1.12.0/build-artifacts/▲ 08-12-16-58/smdistributed\$1modelparallel-1.11.0-cp38-cp38-linux\$1x86\$164.whl | 
| v1.11.0 | smdistributed-modelparallel==v1.10.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.11.0-gpu-py38-cu113-ubuntu20.04-sagemaker`  | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-1.11.0/build-artifacts/▲ 07-11-19-23/smdistributed\$1modelparallel-1.10.0-cp38-cp38-linux\$1x86\$164.whl | 
| v1.10.2 |  smdistributed-modelparallel==v1.7.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.10.2-gpu-py38-cu113-ubuntu20.04-sagemaker`  | - | 
| v1.10.0 |  smdistributed-modelparallel==v1.5.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.10.0-gpu-py38-cu113-ubuntu20.04-sagemaker`  | - | 
| v1.9.1 |  smdistributed-modelparallel==v1.4.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.9.1-gpu-py38-cu111-ubuntu20.04`  | - | 
| v1.8.1\$1 |  smdistributed-modelparallel==v1.6.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.8.1-gpu-py36-cu111-ubuntu18.04`  | - | 

**Note**  
La bibliothèque de parallélisme des SageMaker modèles v1.6.0 et versions ultérieures fournit des fonctionnalités étendues pour. PyTorch Pour de plus amples informations, veuillez consulter [Principales fonctionnalités de la bibliothèque de parallélisme des SageMaker modèles](model-parallel-core-features.md).

\$1\$1 Les URLs fichiers binaires sont destinés à installer la bibliothèque de parallélisme du SageMaker modèle dans des conteneurs personnalisés. Pour de plus amples informations, veuillez consulter [Créez votre propre conteneur Docker avec la bibliothèque parallèle de modèles SageMaker distribués](model-parallel-sm-sdk.md#model-parallel-bring-your-own-container).

TensorFlow versions prises en charge par l' SageMaker IA et la bibliothèque de parallélisme des SageMaker modèles


| TensorFlow version | SageMaker version de la bibliothèque de parallélisme des modèles | URI de l'image DLC intégrée `smdistributed-modelparallel` | 
| --- | --- | --- | 
| v2.6.0 | smdistributed-modelparallel==v1.4.0 | 763104351884.dkr.ecr.<region>.amazonaws.com/tensorflow-training:2.6.0-gpu-py38-cu112-ubuntu20.04 | 
| v2.5.1 | smdistributed-modelparallel==v1.4.0  | 763104351884.dkr.ecr.<region>.amazonaws.com/tensorflow-training:2.5.1-gpu-py37-cu112-ubuntu18.04  | 

**Versions de Hugging Face Transformers prises en charge SageMaker par l'IA et SageMaker la bibliothèque parallèle de données distribuées**

Les AWS Deep Learning Containers for Hugging Face utilisent SageMaker les Training Containers PyTorch pour TensorFlow et comme images de base. Pour consulter les versions et les versions PyTorch associées de la bibliothèque Hugging Face Transformers, consultez les dernières versions de [Hugging Face Containers TensorFlow et les versions précédentes de Hugging](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#huggingface-training-containers) [Face Container](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#prior-hugging-face-container-versions).

## Régions AWS
<a name="distributed-model-parallel-availablity-zone"></a>

La bibliothèque SageMaker Data Parallel est disponible partout Régions AWS où les [AWS Deep Learning Containers for SageMaker](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only) sont en service. Pour plus d’informations, consultez [Images Deep Learning Containers disponibles](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#available-deep-learning-containers-images).

## Types d’instance pris en charge
<a name="distributed-model-parallel-supported-instance-types"></a>

La bibliothèque de parallélisme de SageMaker modèles nécessite l'un des types d'instances ML suivants.


| Type d’instance | 
| --- | 
| ml.g4dn.12xlarge | 
| ml.p3.16xlarge | 
| ml.p3dn.24xlarge  | 
| ml.p4d.24xlarge | 
| ml.p4de.24xlarge | 

Pour les spécifications des types d’instances, consultez la section **Calcul accéléré** sur la page [Types d’instances Amazon EC2](https://aws.amazon.com/ec2/instance-types/). Pour plus d'informations sur la tarification des instances, consultez [Amazon SageMaker AI Pricing](https://aws.amazon.com/sagemaker/pricing/).

Si vous avez rencontré un message d'erreur similaire au suivant, suivez les instructions de la section [Demander une augmentation du quota de service pour les ressources d' SageMaker IA](https://docs.aws.amazon.com/sagemaker/latest/dg/regions-quotas.html#service-limit-increase-request-procedure).

```
ResourceLimitExceeded: An error occurred (ResourceLimitExceeded) when calling
    the CreateTrainingJob operation: The account-level service limit 'ml.p3dn.24xlarge
    for training job usage' is 0 Instances, with current utilization of 0 Instances
    and a request delta of 1 Instances.
    Please contact AWS support to request an increase for this limit.
```

# Principales fonctionnalités de la bibliothèque de parallélisme des SageMaker modèles
<a name="model-parallel-core-features"></a>

La bibliothèque de parallélisme des modèles d'Amazon SageMaker AI propose des stratégies de distribution et des techniques d'économie de mémoire, telles que le parallélisme des données fragmentées, le parallélisme des tenseurs, le partitionnement des modèles par couches pour la planification des pipelines et le point de contrôle. Les stratégies et techniques de parallélisme de modèles permettent de distribuer de grands modèles sur plusieurs appareils tout en optimisant la vitesse d'entraînement et la consommation de mémoire. La bibliothèque fournit également des fonctions d'assistance, des gestionnaires de contexte et des fonctions d'encapsulation de Python pour adapter votre script d'entraînement au partitionnement automatique ou manuel de votre modèle.

Lorsque vous implémentez le parallélisme des modèles dans votre tâche de formation, vous conservez le même flux de travail en deux étapes que celui indiqué dans la section [Exécuter un travail de SageMaker formation distribué avec le parallélisme des modèles](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-use-api.html). Pour adapter votre script d'entraînement, vous n'ajouterez aucune ligne de code ou quelques lignes de code supplémentaires à votre script d'entraînement. Pour lancer une tâche d'entraînement du script d'entraînement adapté, vous devez définir les paramètres de configuration de distribution afin d'activer les fonctionnalités d'économie de mémoire ou de transmettre des valeurs pour le degré de parallélisme.

Pour commencer avec des exemples, consultez les blocs-notes Jupyter suivants qui montrent comment utiliser la bibliothèque de parallélisme des SageMaker modèles.
+ [PyTorch exemples de carnets](https://github.com/aws/amazon-sagemaker-examples/tree/main/training/distributed_training/pytorch/model_parallel)
+ [TensorFlow exemples de carnets](https://github.com/aws/amazon-sagemaker-examples/tree/main/training/distributed_training/tensorflow/model_parallel/mnist)

Pour en savoir plus sur les fonctionnalités de base de la bibliothèque, consultez les rubriques suivantes.

**Note**  
Les bibliothèques de formation SageMaker distribuées sont disponibles via les conteneurs d'apprentissage AWS profond de PyTorch Hugging Face TensorFlow et au sein de SageMaker la plateforme de formation. Pour utiliser les fonctionnalités des bibliothèques de formation distribuées, nous vous recommandons d'utiliser le SDK SageMaker Python. Vous pouvez également configurer manuellement dans la syntaxe des requêtes JSON si vous l'utilisez SageMaker APIs via SDK for Python (Boto3) ou. AWS Command Line Interface Tout au long de la documentation, les instructions et les exemples se concentrent sur l'utilisation des bibliothèques de formation distribuées avec le SDK SageMaker Python.

**Important**  
La bibliothèque de parallélisme des SageMaker modèles prend en charge toutes les fonctionnalités de base et prend en charge le parallélisme des pipelines pour PyTorch. TensorFlow

**Topics**
+ [Parallélisme des données partitionnées](model-parallel-extended-features-pytorch-sharded-data-parallelism.md)
+ [Mise en pipeline d'un modèle](model-parallel-core-features-pipieline-parallelism.md)
+ [Parallélisme de tenseur](model-parallel-extended-features-pytorch-tensor-parallelism.md)
+ [Partitionnement de l'état de l'optimiseur](model-parallel-extended-features-pytorch-optimizer-state-sharding.md)
+ [Points de contrôle d'activation](model-parallel-extended-features-pytorch-activation-checkpointing.md)
+ [Déchargement de l'activation](model-parallel-extended-features-pytorch-activation-offloading.md)
+ [FP16 Entraînement avec le parallélisme des modèles](model-parallel-extended-features-pytorch-fp16.md)
+ [Support pour FlashAttention](model-parallel-attention-head-size-for-flash-attention.md)

# Parallélisme des données partitionnées
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism"></a>

*Le parallélisme des données partitionnées* est une technique d'entraînement distribuée économisant de la mémoire qui divise l'état d'un modèle (paramètres du modèle, gradients et états de l'optimiseur) au sein d'un groupe de données parallèles. GPUs 

**Note**  
Le parallélisme des données partitionnées est disponible PyTorch dans la bibliothèque de parallélisme des SageMaker modèles v1.11.0 et versions ultérieures.

Lorsque vous étendez votre tâche d'entraînement à un grand cluster de processeurs graphiques, vous pouvez réduire l'empreinte mémoire par GPU du modèle en répartissant l'état d'entraînement du modèle sur plusieurs. GPUs Cela présente deux avantages : vous pouvez adapter des modèles plus grands, qui risqueraient sinon de manquer de mémoire avec un parallélisme des données standard, ou vous pouvez augmenter la taille du lot en utilisant la mémoire GPU libérée.

La technique standard de parallélisme des données reproduit les états d'apprentissage dans le groupe GPUs in the data parallel et effectue une agrégation de gradient en fonction de l'opération. `AllReduce` Le parallélisme des données partitionnées modifie la procédure d'entraînement distribué à données parallèles standard pour tenir compte de la nature partitionnée des états de l'optimiseur. Un groupe de rangs sur lequel les états du modèle et de l'optimiseur sont partitionnés est appelé *groupe de partitionnement*. *La technique de parallélisme des données fragmentées partage les paramètres pouvant être entraînés d'un modèle ainsi que les dégradés correspondants et les états de l'optimiseur dans le groupe de partitionnement. GPUs *

SageMaker L'IA parvient à un parallélisme des données fragmenté grâce à la mise en œuvre de MIC, dont il est question dans le billet de AWS blog [Near linear scaling of gigantic-model training](https://www.amazon.science/blog/near-linear-scaling-of-gigantic-model-training-on-aws) on. AWS Dans cette implémentation, vous pouvez définir le degré de partitionnement en tant que paramètre configurable, qui doit être inférieur au degré de parallélisme des données. À chaque passage en avant et en arrière, le MICS recombine temporairement les paramètres du modèle tout au GPUs long de l'`AllGather`opération. Après la transmission vers l'avant ou l'arrière de chaque couche, la méthode MiCS partitionne à nouveau les paramètres pour économiser de la mémoire GPU. Pendant le passage en arrière, les MICS réduisent les dégradés et les répartissent simultanément tout au long GPUs de l'opération. `ReduceScatter` Enfin, la méthode MiCS applique les gradients partitionnés et réduits locaux à leurs partitions de paramètres locales correspondantes, en utilisant les partitions locales des états de l'optimiseur. Pour réduire la surcharge de communication, la bibliothèque de parallélisme du SageMaker modèle préextrait les couches à venir lors de la passe avant ou arrière, et superpose les communications réseau aux calculs.

L'état d'entraînement du modèle est répliqué dans l'ensemble des groupes de partitionnement. Cela signifie qu'avant d'appliquer les gradients aux paramètres, l'opération `AllReduce` doit avoir lieu dans tous les groupes de partitionnement, en plus de l'opération `ReduceScatter` qui a lieu au sein du groupe de partitionnement.

En effet, le parallélisme des données partitionnées introduit un compromis entre la surcharge de communication et l'efficacité de la mémoire GPU. L'utilisation du parallélisme des données partitionnées augmente les coûts de communication, mais l'empreinte mémoire par GPU (à l'exclusion de l'utilisation de la mémoire due aux activations) est divisée par le degré de parallélisme des données partitionnées, ce qui permet d'intégrer des modèles plus grands dans le cluster de GPU.

**Sélection du degré de parallélisme de données partitionnées**

Lorsque vous sélectionnez une valeur pour le degré de parallélisme de données partitionnées, cette valeur doit diviser le degré de parallélisme de données de manière égale. Par exemple, pour une tâche de parallélisme des données à 8 voies, choisissez 2, 4 ou 8 comme degré de parallélisme des données partitionnées. Lorsque vous choisissez le degré de parallélisme des données partitionnées, nous vous recommandons de commencer par un petit nombre, puis de l'augmenter progressivement jusqu'à ce que le modèle tienne dans la mémoire avec la taille de lot souhaitée.

**Sélection de la taille du lot**

Après avoir configuré le parallélisme de données partitionnées, assurez-vous de trouver la configuration d'entraînement la plus optimale pouvant s'exécuter avec succès sur le cluster de GPU. Pour la formation de grands modèles linguistiques (LLM), commencez par la taille du lot 1, puis augmentez-la progressivement jusqu'à ce que vous atteigniez le point de réception de l'erreur out-of-memory (OOM). Si vous rencontrez l'erreur OOM même avec la plus petite taille de lot, appliquez un degré plus élevé de parallélisme de données partitionnées ou une combinaison de parallélisme de données partitionnées et de parallélisme de tenseurs.

**Topics**
+ [Comment appliquer le parallélisme de données partitionnées à votre tâche d'entraînement](#model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use)
+ [Référence de configurations](#model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use-config-sample)
+ [Parallélisme des données partitionnées avec les collectifs SMDDP](#model-parallel-extended-features-pytorch-sharded-data-parallelism-smddp-collectives)
+ [Entraînement à précision mixte avec parallélisme de données partitionnées](#model-parallel-extended-features-pytorch-sharded-data-parallelism-16bits-training)
+ [Parallélisme de données partitionnées avec parallélisme de tenseurs](#model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism)
+ [Conseils et considérations concernant l'utilisation du parallélisme de données partitionnées](#model-parallel-extended-features-pytorch-sharded-data-parallelism-considerations)

## Comment appliquer le parallélisme de données partitionnées à votre tâche d'entraînement
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use"></a>

Pour commencer à utiliser le parallélisme des données partitionnées, appliquez les modifications requises à votre script d'apprentissage et configurez l' SageMaker PyTorch estimateur avec les paramètres. sharded-data-parallelism-specific Pensez également à prendre des valeurs de référence et des exemples de blocs-notes comme point de départ.

### Adaptez votre script PyTorch d'entraînement
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use-modify-script"></a>

Suivez les instructions de l'[étape 1 : Modifiez un script d' PyTorch entraînement](model-parallel-customize-training-script-pt.md) pour encapsuler les objets du modèle et de l'optimiseur avec les `smdistributed.modelparallel.torch` enveloppes des modules `torch.nn.parallel` et`torch.distributed`.

**(Facultatif) Modification supplémentaire pour enregistrer les paramètres externes du modèle**

Si votre modèle est construit avec `torch.nn.Module` et qu'il utilise des paramètres qui ne sont pas définis dans la classe de module, vous devez les enregistrer manuellement dans le module pour que SMP collecte les paramètres complets pendant ce temps. Pour enregistrer les paramètres d'un module, utilisez `smp.register_parameter(module, parameter)`.

```
class Module(torch.nn.Module):
    def __init__(self, *args):
        super().__init__(self, *args)
        self.layer1 = Layer1()
        self.layer2 = Layer2()
        smp.register_parameter(self, self.layer1.weight)

    def forward(self, input):
        x = self.layer1(input)
        # self.layer1.weight is required by self.layer2.forward
        y = self.layer2(x, self.layer1.weight)
        return y
```

### Configuration de l' SageMaker PyTorch estimateur
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use-set-estimator"></a>

Lorsque vous configurez un SageMaker PyTorch estimateur dans[Étape 2 : Lancer un job de formation à l'aide du SDK SageMaker Python](model-parallel-sm-sdk.md), ajoutez les paramètres du parallélisme des données fragmentées. 

Pour activer le parallélisme des données partitionnées, ajoutez le `sharded_data_parallel_degree` paramètre à l'estimateur. SageMaker PyTorch Ce paramètre indique le nombre de points GPUs sur lesquels l'état d'apprentissage est fragmenté. La valeur pour `sharded_data_parallel_degree` doit être un entier compris entre 1 et le degré de parallélisme des données, et elle doit diviser de manière égale le degré de parallélisme des données. Notez que la bibliothèque détecte automatiquement le nombre de GPUs donc le degré de parallélisme des données. Les paramètres supplémentaires suivants sont disponibles pour configurer le parallélisme des données partitionnées.
+ `"sdp_reduce_bucket_size"`*(int, default : 5e8)* — Spécifie la taille des [compartiments de dégradé PyTorch DDP](https://pytorch.org/docs/stable/notes/ddp.html#internal-design) en nombre d'éléments du dtype par défaut.
+ `"sdp_param_persistence_threshold"` *(entier, par défaut : 1e6)* : spécifie la taille d'un tenseur de paramètres en nombre d'éléments qui peuvent persister sur chaque GPU. Le parallélisme de données fractionné divise chaque tenseur de paramètres au sein d' GPUs un groupe de données parallèles. Si le nombre d'éléments dans le tenseur de paramètres est inférieur à ce seuil, le tenseur de paramètres n'est pas divisé ; cela permet de réduire la surcharge de communication car le tenseur de paramètres est répliqué entre données parallèles. GPUs
+ `"sdp_max_live_parameters"` *(entier, par défaut : 1e9)* : spécifie le nombre maximal de paramètres pouvant être simultanément dans un état d'entraînement recombiné pendant la transmission vers l'avant ou vers l'arrière. La récupération de paramètres avec l'opération `AllGather` s'interrompt lorsque le nombre de paramètres actifs atteint le seuil donné. Notez que l'augmentation de ce paramètre augmente l'empreinte mémoire.
+ `"sdp_hierarchical_allgather"` *(booléen, par défaut : True)* : si ce paramètre a pour valeur `True`, l'opération `AllGather` s'exécute de manière hiérarchique : elle s'exécute d'abord dans chaque nœud, puis sur tous les nœuds. Pour les tâches d'entraînement distribué à plusieurs nœuds, l'opération `AllGather` hiérarchique est automatiquement activée.
+ `"sdp_gradient_clipping"` *(valeur à virgule flottante, par défaut : 1,0)* : spécifie un seuil pour l'écrêtage de gradient de la norme L2 des gradients avant leur propagation vers l'arrière via les paramètres du modèle. Lorsque le parallélisme des données partitionnées est activé, l'écrêtage de gradient est également activé. Le seuil par défaut est `1.0`. Réglez ce paramètre si vous rencontrez le problème d'explosion de gradient.

Le code suivant montre un exemple de configuration du parallélisme des données partitionnées.

```
import sagemaker
from sagemaker.pytorch import PyTorch

smp_options = {
    "enabled": True,
    "parameters": {
        # "pipeline_parallel_degree": 1,    # Optional, default is 1
        # "tensor_parallel_degree": 1,      # Optional, default is 1
        "ddp": True,
        # parameters for sharded data parallelism
        "sharded_data_parallel_degree": 2,              # Add this to activate sharded data parallelism
        "sdp_reduce_bucket_size": int(5e8),             # Optional
        "sdp_param_persistence_threshold": int(1e6),    # Optional
        "sdp_max_live_parameters": int(1e9),            # Optional
        "sdp_hierarchical_allgather": True,             # Optional
        "sdp_gradient_clipping": 1.0                    # Optional
    }
}

mpi_options = {
    "enabled" : True,                      # Required
    "processes_per_host" : 8               # Required
}

smp_estimator = PyTorch(
    entry_point="your_training_script.py", # Specify your train script
    role=sagemaker.get_execution_role(),
    instance_count=1,
    instance_type='ml.p3.16xlarge',
    framework_version='1.13.1',
    py_version='py3',
    distribution={
        "smdistributed": {"modelparallel": smp_options},
        "mpi": mpi_options
    },
    base_job_name="sharded-data-parallel-job"
)

smp_estimator.fit('s3://my_bucket/my_training_data/')
```

## Référence de configurations
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use-config-sample"></a>

L'équipe de formation SageMaker distribuée fournit les configurations de référence suivantes que vous pouvez utiliser comme point de départ. Vous pouvez extrapoler à partir des configurations précédentes pour expérimenter et estimer l'utilisation de la mémoire GPU pour la configuration de votre modèle. 

Parallélisme des données partitionnées avec les collectifs SMDDP


| Modèle/le nombre de paramètres | Nombre d'instances | Type d’instance | Durée de la séquence | Taille globale de lot | Taille du mini-lot | Degré de parallélisation des données partitionnées | 
| --- | --- | --- | --- | --- | --- | --- | 
| GPT-NEOX-20B | 2 | ml.p4d.24xlarge | 2048 | 64 | 4 | 16 | 
| GPT-NEOX-20B | 8 | ml.p4d.24xlarge | 2048 | 768 | 12 | 32 | 

Par exemple, si vous augmentez la longueur de séquence d'un modèle de 20 milliards de paramètres ou si vous augmentez la taille du modèle à 65 milliards de paramètres, vous devez d'abord essayer de réduire la taille du lot. Si le modèle ne correspond toujours pas à la plus petite taille de lot (la taille de lot de 1), essayez d'augmenter le degré de parallélisme du modèle.

Parallélisme de données partitionnées avec parallélisme de tenseurs et NCCL Collectives


| Modèle/le nombre de paramètres | Nombre d'instances | Type d’instance | Durée de la séquence | Taille globale de lot | Taille du mini-lot | Degré de parallélisation des données partitionnées | Degré de parallélisation du tenseur | Déchargement de l'activation | 
| --- | --- | --- | --- | --- | --- | --- | --- | --- | 
| GPT-NEOX-65B | 64 | ml.p4d.24xlarge | 2048 | 512 | 8 | 16 | 8 | Y | 
| GPT-NEOX-65B | 64 | ml.p4d.24xlarge | 4096 | 512 | 2 | 64 | 2 | Y | 

L'utilisation combinée du parallélisme des données fragmentées et du parallélisme des tenseurs est utile lorsque vous souhaitez adapter un modèle de langage étendu (LLM) à un cluster à grande échelle tout en utilisant des données texte dont la longueur de séquence est plus longue, ce qui permet d'utiliser une taille de lot plus petite, et donc de gérer l'utilisation de la mémoire du GPU pour vous entraîner sur des séquences de texte plus longues. LLMs Pour en savoir plus, veuillez consulter la section [Parallélisme de données partitionnées avec parallélisme de tenseurs](#model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism).

Pour des études de cas, des benchmarks et d'autres exemples de configuration, consultez le billet de blog [New performance improvements in Amazon SageMaker AI model parallel library](https://aws.amazon.com/blogs/machine-learning/new-performance-improvements-in-amazon-sagemaker-model-parallel-library/).

## Parallélisme des données partitionnées avec les collectifs SMDDP
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-smddp-collectives"></a>

La bibliothèque de parallélisme des SageMaker données propose des primitives de communication collective (collectifs SMDDP) optimisées pour l'infrastructure. AWS Il parvient à l'optimisation en adoptant un modèle de all-to-all-type communication utilisant [Elastic Fabric Adapter (EFA), ce qui permet de créer des collectifs à haut débit et moins sensibles à la latence, de décharger le traitement lié à la communication vers le processeur et de libérer](https://aws.amazon.com/hpc/efa/) des cycles GPU pour les calculs. Sur les grands clusters, les collectifs SMDDP peuvent améliorer les performances d'entraînement distribué jusqu'à 40 % par rapport au NCCL. Pour des études de cas et des résultats de référence, consultez le blog [Nouvelles améliorations des performances dans la bibliothèque de parallélisme de modèles Amazon SageMaker AI](https://aws.amazon.com/blogs/machine-learning/new-performance-improvements-in-amazon-sagemaker-model-parallel-library/).

**Note**  
Le parallélisme de données partitionné avec SMDDP Collectives est disponible dans la bibliothèque de parallélisme de SageMaker modèles v1.13.0 et versions ultérieures, et dans la bibliothèque de parallélisme de données v1.6.0 et versions ultérieures. SageMaker Consultez également [Supported configurations](#sharded-data-parallelism-smddp-collectives-supported-config) pour utiliser le parallélisme des données partitionnées avec les collectifs SMDDP.

Dans le cas du parallélisme des données partitionnées, qui est une technique couramment utilisée dans l'entraînement distribué à grande échelle, le collectif `AllGather` est utilisé pour reconstituer les paramètres de la couche partitionnée pour les calculs de passes en avant et en arrière, en parallèle avec le calcul GPU. Pour les modèles de grande taille, réaliser l'opération `AllGather` est essentiel pour éviter les problèmes d'engorgement du GPU et ralentir la vitesse d'entraînement. Lorsque le parallélisme des données partitionnées est activé, les collectifs SMDDP entrent dans ces collectifs `AllGather` critiques en termes de performances, améliorant ainsi le débit d'entraînement.

**S'entraîner avec les collectifs SMDDP**

Lorsque le parallélisme des données partitionnées est activé pour votre tâche d'entraînement et qu'il répond aux exigences [Supported configurations](#sharded-data-parallelism-smddp-collectives-supported-config), les collectifs SMDDP sont automatiquement activés. En interne, les collectifs SMDDP optimisent le `AllGather` collectif pour qu'il soit performant sur l' AWS infrastructure et s'en remettent au NCCL pour tous les autres collectifs. De plus, dans les configurations non prises en charge, tous les collectifs, y compris `AllGather`, utilisent automatiquement le backend NCCL.

Depuis la version 1.13.0 de la bibliothèque de parallélisme des SageMaker modèles, le `"ddp_dist_backend"` paramètre est ajouté aux options. `modelparallel` La valeur par défaut de ce paramètre de configuration est `"auto"`, qui utilise les collectifs SMDDP chaque fois que possible et revient à NCCL dans le cas contraire. Pour forcer la bibliothèque à toujours utiliser NCCL, spécifiez `"nccl"` sur le paramètre de configuration `"ddp_dist_backend"`. 

L'exemple de code suivant montre comment configurer un PyTorch estimateur à l'aide du parallélisme de données fragmenté avec le `"ddp_dist_backend"` paramètre, qui est défini `"auto"` par défaut et dont l'ajout est donc facultatif. 

```
import sagemaker
from sagemaker.pytorch import PyTorch

smp_options = {
    "enabled":True,
    "parameters": {                        
        "partitions": 1,
        "ddp": True,
        "sharded_data_parallel_degree": 64
        "bf16": True,
        "ddp_dist_backend": "auto"  # Specify "nccl" to force to use NCCL.
    }
}

mpi_options = {
    "enabled" : True,                      # Required
    "processes_per_host" : 8               # Required
}

smd_mp_estimator = PyTorch(
    entry_point="your_training_script.py", # Specify your train script
    source_dir="location_to_your_script",
    role=sagemaker.get_execution_role(),
    instance_count=8,
    instance_type='ml.p4d.24xlarge',
    framework_version='1.13.1',
    py_version='py3',
    distribution={
        "smdistributed": {"modelparallel": smp_options},
        "mpi": mpi_options
    },
    base_job_name="sharded-data-parallel-demo",
)

smd_mp_estimator.fit('s3://my_bucket/my_training_data/')
```

**Configurations prises en charge**

L'opération `AllGather` avec les collectifs SMDDP est activée dans les tâches d'entraînement lorsque toutes les exigences de configuration suivantes sont remplies.
+ Le degré de parallélisme des données partitionnées est supérieur à 1
+ `Instance_count` supérieur à 1 
+ `Instance_type` égal à `ml.p4d.24xlarge` 
+ SageMaker conteneur d'entraînement pour PyTorch v1.12.1 ou version ultérieure
+ La bibliothèque de parallélisme des SageMaker données v1.6.0 ou version ultérieure
+ La bibliothèque de parallélisme des SageMaker modèles v1.13.0 ou version ultérieure

**Réglage des performances et de la mémoire**

Les collectifs SMDDP utilisent une mémoire GPU supplémentaire. Deux variables d'environnement permettent de configurer l'utilisation de la mémoire GPU en fonction des différents cas d'utilisation des modèles d'entraînement.
+ `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES` : pendant l'opération `AllGather` SMDDP, la mémoire tampon d'entrée `AllGather` est copiée dans une mémoire tampon temporaire pour la communication entre nœuds. La variable `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES` contrôle la taille (en octets) de cette mémoire tampon temporaire. Si la taille de la mémoire tampon temporaire est inférieure à la taille de la mémoire tampon d'entrée `AllGather`, le collectif `AllGather` revient à utiliser NCCL.
  + Valeur par défaut : 16 \$1 1024 \$1 1024 (16 Mo)
  + Valeurs acceptables : tout multiple de 8 192
+  `SMDDP_AG_SORT_BUFFER_SIZE_BYTES` : la variable `SMDDP_AG_SORT_BUFFER_SIZE_BYTES` permet de dimensionner la mémoire tampon temporaire (en octets) pour contenir les données collectées lors de la communication entre nœuds. Si la taille de la mémoire tampon temporaire est inférieure à `1/8 * sharded_data_parallel_degree * AllGather input size`, le collectif `AllGather` revient à utiliser NCCL.
  + Valeur par défaut : 128 \$1 1024 \$1 1024 (128 Mo)
  + Valeurs acceptables : tout multiple de 8 192

**Conseils de réglage sur les variables de taille de la mémoire tampon**

Les valeurs par défaut des variables d'environnement devraient fonctionner correctement dans la plupart des cas d'utilisation. Nous recommandons de régler ces variables uniquement si l'entraînement se heurte à l'erreur out-of-memory (OOM). 

La liste suivante présente quelques conseils de réglage visant à réduire l'empreinte de la mémoire GPU des collectifs SMDDP tout en préservant les gains de performances qui en découlent.
+ Réglage de `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES`
  + La taille de la mémoire tampon d'entrée `AllGather` est plus petite pour les modèles plus petits. Par conséquent, la taille requise pour `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES` peut être plus petite pour les modèles comportant moins de paramètres.
  + La taille de la mémoire tampon `AllGather` d'entrée diminue au fur et à mesure que l'on `sharded_data_parallel_degree` augmente, car le modèle est davantage GPUs segmenté. Par conséquent, la taille requise pour `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES` peut être plus petite pour les tâches d'entraînement avec des valeurs élevées pour `sharded_data_parallel_degree`.
+ Réglage de `SMDDP_AG_SORT_BUFFER_SIZE_BYTES`
  + La quantité de données collectées à partir de la communication entre nœuds est moins importante pour les modèles comportant moins de paramètres. Par conséquent, la taille requise pour `SMDDP_AG_SORT_BUFFER_SIZE_BYTES` peut être plus petite pour de tels modèles avec moins de paramètres.

Certains collectifs peuvent revenir à l'utilisation de NCCL ; par conséquent, vous risquez de ne pas bénéficier du gain de performances des collectifs SMDDP optimisés. Si de la mémoire GPU supplémentaire est disponible, vous pouvez envisager d'augmenter les valeurs de `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES` et `SMDDP_AG_SORT_BUFFER_SIZE_BYTES` pour tirer parti du gain de performances.

Le code suivant montre comment configurer les variables d'environnement en les ajoutant `mpi_options` au paramètre de distribution de l' PyTorch estimateur.

```
import sagemaker
from sagemaker.pytorch import PyTorch

smp_options = {
    .... # All modelparallel configuration options go here
}

mpi_options = {
    "enabled" : True,                      # Required
    "processes_per_host" : 8               # Required
}

# Use the following two lines to tune values of the environment variables for buffer
mpioptions += " -x SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES=8192" 
mpioptions += " -x SMDDP_AG_SORT_BUFFER_SIZE_BYTES=8192"

smd_mp_estimator = PyTorch(
    entry_point="your_training_script.py", # Specify your train script
    source_dir="location_to_your_script",
    role=sagemaker.get_execution_role(),
    instance_count=8,
    instance_type='ml.p4d.24xlarge',
    framework_version='1.13.1',
    py_version='py3',
    distribution={
        "smdistributed": {"modelparallel": smp_options},
        "mpi": mpi_options
    },
    base_job_name="sharded-data-parallel-demo-with-tuning",
)

smd_mp_estimator.fit('s3://my_bucket/my_training_data/')
```

## Entraînement à précision mixte avec parallélisme de données partitionnées
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-16bits-training"></a>

Pour économiser davantage de mémoire sur le GPU grâce à des nombres à virgule flottante à demi-précision et à un parallélisme de données fragmenté, vous pouvez activer le format à virgule flottante 16 bits (FP16) ou le format à [virgule flottante Brain](https://en.wikichip.org/wiki/brain_floating-point_format) (BF16) en ajoutant un paramètre supplémentaire à la configuration d'entraînement distribuée.

**Note**  
Un entraînement de précision mixte avec parallélisme de données fragmenté est disponible dans la bibliothèque de parallélisme des SageMaker modèles v1.11.0 et versions ultérieures.

**Pour la FP16 formation avec le parallélisme des données fragmentées**

Pour exécuter un FP16 entraînement avec un parallélisme de données fragmenté, ajoutez-le `"fp16": True"` au dictionnaire de `smp_options` configuration. Dans votre script d'entraînement, vous pouvez choisir entre les options de mise à l'échelle statique et dynamique des pertes via le module `smp.DistributedOptimizer`. Pour de plus amples informations, veuillez consulter [FP16 Entraînement avec le parallélisme des modèles](model-parallel-extended-features-pytorch-fp16.md).

```
smp_options = {
    "enabled": True,
    "parameters": {
        "ddp": True,
        "sharded_data_parallel_degree": 2,
        "fp16": True
    }
}
```

**Pour la BF16 formation avec le parallélisme des données fragmentées**

La fonctionnalité de parallélisme des données fragmentée de l' SageMaker IA permet de s'entraîner au BF16 type de données. Le type de BF16 données utilise 8 bits pour représenter l'exposant d'un nombre à virgule flottante, tandis que le type de FP16 données utilise 5 bits. La préservation des 8 bits pour l'exposant permet de conserver la même représentation de l'exposant d'un nombre à virgule flottante à précision unique () FP32 de 32 bits. Cela simplifie la conversion entre FP32 et et BF16 est nettement moins susceptible de provoquer des problèmes de débordement et de sous-débit qui surviennent souvent lors de l' FP16 entraînement, en particulier lors de l'entraînement de modèles plus grands. Bien que les deux types de données utilisent 16 bits au total, cette plage de représentation accrue de l'exposant dans le BF16 format se fait au détriment de la précision. Dans le cadre de l'entraînement de grands modèles, cette baisse de précision est souvent considérée comme un compromis acceptable pour la plage et la stabilité de l'entraînement.

**Note**  
Actuellement, la BF16 formation ne fonctionne que lorsque le parallélisme des données partitionnées est activé.

Pour exécuter un BF16 entraînement avec un parallélisme de données fragmenté, ajoutez-le `"bf16": True` au dictionnaire de `smp_options` configuration.

```
smp_options = {
    "enabled": True,
    "parameters": {
        "ddp": True,
        "sharded_data_parallel_degree": 2,
        "bf16": True
    }
}
```

## Parallélisme de données partitionnées avec parallélisme de tenseurs
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism"></a>

Si vous utilisez le parallélisme de données partitionnées et que vous devez également réduire la taille globale du lot, envisagez d'utiliser le [parallélisme de tenseurs](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-tensor-parallelism.html) avec le parallélisme de données partitionnées. Lorsque vous entraînez un modèle de grande taille avec un parallélisme de données partitionnées sur un très grand cluster de calcul (généralement 128 nœuds ou plus), même une petite taille de lot par GPU se traduit par une taille de lot globale très importante. Cela peut entraîner des problèmes de convergence ou de faibles performances de calcul. La réduction de la taille des lots par GPU n'est parfois pas possible avec le seul parallélisme de données partitionnées lorsqu'un seul lot est déjà volumineux et ne peut pas être réduit davantage. Dans de tels cas, l'utilisation du parallélisme de données partitionnées en combinaison avec le parallélisme de tenseurs permet de réduire la taille globale du lot.

Le choix des degrés de parallélisme de données partitionnées et de parallélisme de tenseurs optimaux dépend de l'échelle du modèle, du type d'instance et de la taille de lot globale qui est raisonnable pour que le modèle à converger. Nous vous recommandons de partir d'un faible degré de parallélisme tenseur pour adapter la taille du lot global au cluster de calcul afin de résoudre les out-of-memory erreurs CUDA et d'obtenir les meilleures performances. Consultez les deux exemples de cas suivants pour découvrir comment la combinaison du parallélisme des tenseurs et du parallélisme des données fragmentées vous aide à ajuster la taille globale du lot en le regroupant GPUs pour le parallélisme du modèle, ce qui se traduit par une diminution du nombre de répliques de modèles et une réduction de la taille globale du lot.

**Note**  
Cette fonctionnalité est disponible dans la bibliothèque de parallélisme des SageMaker modèles v1.15 et prend en charge la version 1.13.1. PyTorch 

**Note**  
Cette fonctionnalité est disponible pour les modèles pris en charge par la fonctionnalité de parallélisme de tenseurs de la bibliothèque. Pour trouver la liste des modèles pris en charge, consultez [Prise en charge des modèles Transformer Hugging Face](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-hugging-face.html). Notez également que vous devez transférer `tensor_parallelism=True` à l'argument `smp.model_creation` lorsque vous modifiez votre script d'entraînement. Pour en savoir plus, consultez le script de formation [https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/train_gpt_simple.py#L793](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/train_gpt_simple.py#L793)dans le * GitHub référentiel SageMaker AI Examples*.

### Exemple 1
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism-ex1"></a>

Supposons que nous voulions entraîner un modèle sur un cluster de 1 536 GPUs (192 nœuds de 8 nœuds chacun), GPUs en définissant le degré de parallélisme des données partitionnées sur 32 (`sharded_data_parallel_degree=32`) et la taille du lot par GPU sur 1, chaque lot ayant une longueur de séquence de 4 096 jetons. Dans ce cas, il existe 1 536 réplicas de modèles, la taille globale du lot devient 1 536 et chaque lot global contient environ 6 millions de jetons. 

```
(1536 GPUs) * (1 batch per GPU) = (1536 global batches)
(1536 batches) * (4096 tokens per batch) = (6,291,456 tokens)
```

L'ajout d'un parallélisme de tenseurs peut réduire la taille globale du lot. Un exemple de configuration peut consister à définir le degré de parallélisme du tenseur sur 8 et la taille du lot par GPU sur 4. Cela forme 192 groupes de tenseurs parallèles ou 192 répliques de modèles, où chaque réplique de modèle est répartie sur 8. GPUs La taille de lot de 4 correspond à la quantité de données d'entraînement par itération et par groupe de parallélisme de tenseurs ; en d'autres termes, chaque réplica de modèle consomme 4 lots par itération. Dans ce cas, la taille globale du lot devient 768 et chaque lot global contient environ 3 millions de jetons. Par conséquent, la taille globale du lot est réduite de moitié par rapport au cas précédent avec un parallélisme de données partitionnées uniquement.

```
(1536 GPUs) / (8 tensor parallel degree) = (192 tensor parallelism groups)
(192 tensor parallelism groups) * (4 batches per tensor parallelism group) = (768 global batches)
(768 batches) * (4096 tokens per batch) = (3,145,728 tokens)
```

### Exemple 2
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism-ex2"></a>

Lorsque le parallélisme de données partitionnées et le parallélisme de tenseurs sont activés, la bibliothèque applique d'abord le parallélisme de tenseur et partitionne le modèle sur cette dimension. Pour chaque rang de parallélisme de tenseurs, le parallélisme de données est appliqué conformément au `sharded_data_parallel_degree`.

Par exemple, supposons que nous voulions définir 32 GPUs avec un degré de parallélisme du tenseur de 4 (formant des groupes de 4 GPUs), un degré de parallélisme des données partitionnées de 4, pour aboutir à un degré de réplication de 2. L'affectation crée huit groupes de GPU basés sur le degré de parallélisme de tenseurs, comme suit : `(0,1,2,3)`, `(4,5,6,7)`, `(8,9,10,11)`, `(12,13,14,15)`, `(16,17,18,19)`, `(20,21,22,23)`, `(24,25,26,27)`, `(28,29,30,31)`. C'est-à-dire que quatre GPUs forment un groupe parallèle de tenseurs. Dans ce cas, le groupe de parallèles de données réduit pour le 0e rang GPUs des groupes de tenseurs parallèles serait. `(0,4,8,12,16,20,24,28)` Le groupe de parallélisme de données réduit est segmenté en fonction du degré de parallélisme des données fragmenté de 4, ce qui donne lieu à deux groupes de réplication pour le parallélisme des données. GPUs`(0,4,8,12)`formez un groupe de partitionnement, qui détient collectivement une copie complète de tous les paramètres du 0e rang parallèle du tenseur, GPUs `(16,20,24,28)` et formez un autre groupe de ce type. D'autres rangs de parallélisme de tenseurs possèdent également des groupes de partitionnement et de réplication similaires.

![\[Figure 1 : Groupes de parallélisme de tenseur.\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/sdp_tp_group_tp.jpg)


Figure 1 : Groupes de parallélisme de tenseur pour (nœuds, degré de parallélisme partitionné des données, degré de parallélisme de tenseur) = (4, 4, 4), où chaque rectangle représente un GPU avec des indices compris entre 0 et 31. Les groupes de parallélisme des tenseurs de GPUs forme TPG en 0 TPG. 7 Les groupes de réplication sont les suivants : (\$1TPG0, TPG4\$1, \$1TPG1, TPG5\$1 \$1TPG2, TPG6\$1 et \$1TPG3, TPG7\$1) ; chaque paire de groupes de réplication partage la même couleur, mais est remplie différemment.

![\[Figure 2 : Groupes de parallélisme partitionné des données.\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/sdp_tp_group_sdp.jpg)


Figure 2 : Groupes de parallélisme partitionné des données pour (nœuds, degré de parallélisme partitionné des données, degré de parallélisme de tenseur) = (4, 4, 4), où chaque rectangle représente un GPU avec des indices compris entre 0 et 31. Le GPUs formulaire fragmenté regroupe des groupes de parallélisme de données de SDPG à 0 SDPG. 7 Les groupes de réplication sont (\$1SDPG0, SDPG4\$1, \$1SDPG1, SDPG5\$1, \$1SDPG2, SDPG6\$1 et \$1SDPG3, SDPG7\$1) ; chaque paire de groupes de réplication partage la même couleur, mais est remplie différemment.

### Comment activer le parallélisme de données partitionnées avec le parallélisme de tenseurs
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism-activate"></a>

Pour utiliser le parallélisme de données fragmenté avec le parallélisme tensoriel, vous devez définir les deux paramètres `sharded_data_parallel_degree` et, `tensor_parallel_degree` dans la configuration, `distribution` lors de la création d'un objet de la classe d'estimateur. SageMaker PyTorch 

Vous devez également activer `prescaled_batch`. Cela signifie qu'au lieu que chaque GPU lise son propre lot de données, chaque groupe de parallélisme de tenseurs lit collectivement un lot combiné de la taille de lot choisie. En fait, au lieu de diviser le jeu de données en parties égales au nombre de GPUs (ou taille parallèle des données`smp.dp_size()`), il le divise en parties égales au nombre de parties GPUs divisées par `tensor_parallel_degree` (également appelé taille réduite des données parallèles,`smp.rdp_size()`). Pour plus de détails sur le traitement par lots prédimensionnés, consultez [Prescaled Batch](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#prescaled-batch) dans la documentation du SDK *SageMaker Python*. Consultez également l'exemple de script d'entraînement [https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/train_gpt_simple.py#L164](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/train_gpt_simple.py#L164)pour GPT-2 dans le référentiel *SageMaker AI Examples GitHub *.

L'extrait de code suivant montre un exemple de création d'un objet PyTorch estimateur basé sur le scénario susmentionné dans. [Exemple 2](#model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism-ex2)

```
mpi_options = "-verbose --mca orte_base_help_aggregate 0 "
smp_parameters = {
    "ddp": True,
    "fp16": True,
    "prescaled_batch": True,
    "sharded_data_parallel_degree": 4,
    "tensor_parallel_degree": 4
}

pytorch_estimator = PyTorch(
    entry_point="your_training_script.py",
    role=role,
    instance_type="ml.p4d.24xlarge",
    volume_size=200,
    instance_count=4,
    sagemaker_session=sagemaker_session,
    py_version="py3",
    framework_version="1.13.1",
    distribution={
        "smdistributed": {
            "modelparallel": {
                "enabled": True, 
                "parameters": smp_parameters,
            }
        },
        "mpi": {
            "enabled": True,
            "processes_per_host": 8,
            "custom_mpi_options": mpi_options,
        },
    },
    source_dir="source_directory_of_your_code",
    output_path=s3_output_location
)
```

## Conseils et considérations concernant l'utilisation du parallélisme de données partitionnées
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-considerations"></a>

Tenez compte des points suivants lorsque vous utilisez le parallélisme de données fragmenté de la bibliothèque de parallélisme du SageMaker modèle.
+ Le parallélisme des données fragmentées est compatible avec l'entraînement. FP16 Pour organiser un FP16 entraînement, consultez la [FP16 Entraînement avec le parallélisme des modèles](model-parallel-extended-features-pytorch-fp16.md) section.
+ Le parallélisme de données partitionnées est compatible avec le parallélisme de tenseurs. Les éléments suivants sont ceux que vous devrez peut-être prendre en compte pour utiliser le parallélisme de données partitionnées avec le parallélisme de tenseurs.
  + Lorsque vous utilisez le parallélisme de données partitionnées avec le parallélisme de tenseur, les couches d'intégration sont également automatiquement réparties dans le groupe de parallélisme de tenseurs. En d'autres termes, le paramètre `distribute_embedding` est automatiquement défini sur `True`. Pour plus d'informations sur le parallélisme de tenseurs, consultez [Parallélisme de tenseur](model-parallel-extended-features-pytorch-tensor-parallelism.md).
  + Notez que le parallélisme de données partitionnées associé au parallélisme de tenseurs utilise actuellement les collectifs NCCL comme backend de la stratégie d'entraînement distribuée.

  Pour plus d'informations, consultez la section [Parallélisme de données partitionnées avec parallélisme de tenseurs](#model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism).
+ Le parallélisme de données partitionnées n'est actuellement pas compatible avec le [parallélisme de pipelines](model-parallel-intro.md#model-parallel-intro-pp), ni le [partitionnement de l'état de l'optimiseur](model-parallel-extended-features-pytorch-optimizer-state-sharding.md). Pour activer le parallélisme de données partitionnées, désactivez le partitionnement de l'état de l'optimiseur et définissez le degré de parallélisme de pipelines sur 1.
+ Les fonctionnalités des [points de contrôle d'activation](model-parallel-extended-features-pytorch-activation-checkpointing.md) et du [déchargement de l'activation](model-parallel-extended-features-pytorch-activation-offloading.md) sont compatibles avec le parallélisme des données partitionnées.
+ Pour utiliser le parallélisme des données partitionnées avec cumul de gradient, définissez l'argument `backward_passes_per_step` sur le nombre d'étapes de cumul lors de l'enveloppement de votre modèle avec le module [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.DistributedModel](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.DistributedModel). Cela garantit que l'opération `AllReduce` de gradient entre les groupes de réplication du modèle (groupes de partitionnement) a lieu à la limite du cumul de gradient.
+ Vous pouvez vérifier vos modèles entraînés avec le parallélisme de données fragmenté à l'aide du point de contrôle de la bibliothèque, et. APIs `smp.save_checkpoint` `smp.resume_from_checkpoint` Pour de plus amples informations, veuillez consulter [Vérification d'un PyTorch modèle distribué (pour la bibliothèque de parallélisme des SageMaker modèles v1.10.0 et versions ultérieures)](distributed-model-parallel-checkpointing-and-finetuning.md#model-parallel-extended-features-pytorch-checkpoint).
+ Le comportement du paramètre de configuration [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.delay_param_initialization](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.delay_param_initialization) change dans le cadre du parallélisme des données partitionnées. Lorsque ces deux fonctionnalités sont activées simultanément, les paramètres sont immédiatement initialisés lors de la création du modèle d'une manière partitionnée au lieu de retarder l'initialisation des paramètres, de sorte que chaque rang initialise et stocke sa propre partition de paramètres.
+ Lorsque le parallélisme des données partitionnées est activé, la bibliothèque effectue un écrêtage de gradient en interne lorsque l'appel `optimizer.step()` s'exécute. Vous n'avez pas besoin d'utiliser un utilitaire APIs pour le découpage en dégradé, tel que [https://pytorch.org/docs/stable/generated/torch.nn.utils.clip_grad_norm_.html](https://pytorch.org/docs/stable/generated/torch.nn.utils.clip_grad_norm_.html). Pour ajuster la valeur de seuil pour le découpage en dégradé, vous pouvez la définir via le `sdp_gradient_clipping` paramètre de configuration des paramètres de distribution lorsque vous créez l' SageMaker PyTorch estimateur, comme indiqué dans la section. [Comment appliquer le parallélisme de données partitionnées à votre tâche d'entraînement](#model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use)

# Mise en pipeline d'un modèle
<a name="model-parallel-core-features-pipieline-parallelism"></a>

L'une des principales fonctionnalités de la bibliothèque SageMaker de parallélisme des modèles est le *parallélisme des pipelines*, qui détermine l'ordre dans lequel les calculs sont effectués et les données sont traitées sur les appareils pendant l'entraînement du modèle. Le pipeline est une technique permettant d'obtenir une véritable parallélisation dans le parallélisme des modèles, en effectuant le GPUs calcul simultanément sur différents échantillons de données, et en surmontant la perte de performance due au calcul séquentiel. Lorsque vous utilisez le parallélisme de pipelines, la tâche d'entraînement est exécutée en pipeline sur des micro-lots afin d'optimiser l'utilisation de GPU.

**Note**  
Le parallélisme des pipelines, également appelé partitionnement des modèles, est disponible pour les deux. PyTorch TensorFlow Pour les versions de frameworks prises en charge, consultez [Frameworks pris en charge et Régions AWS](distributed-model-parallel-support.md).

## Calendrier d'exécution de pipeline
<a name="model-parallel-pipeline-execution"></a>

Le pipeline est basé sur la division d'un mini-lot en microlots, qui sont introduits dans le pipeline de formation one-by-one et suivent un calendrier d'exécution défini par le moteur d'exécution de la bibliothèque. Un *micro-lot* est un sous-ensemble plus petit d'un mini-lot d'entraînement donné. Le calendrier du pipeline détermine quel micro-lot est exécuté par quel périphérique pour chaque créneau horaire. 

Par exemple, selon le calendrier du pipeline et la partition du modèle, le GPU `i` peut effectuer des calculs (en avant ou en arrière) sur microbatch `b` tandis que le GPU `i+1` effectue des calculs sur microbatch`b+1`, gardant ainsi les deux GPUs actifs en même temps. Durant une seule transmission vers l'avant et vers l'arrière, le flux d'exécution d'un seul micro-lot peut visiter le même périphérique plusieurs fois, en fonction de la décision de partitionnement. Par exemple, une opération située au début du modèle peut être placée sur le même périphérique qu'une opération située à la fin du modèle, tandis que les opérations situées entre les deux sont placées sur différents périphériques, de sorte que ce périphérique est visité deux fois.

La bibliothèque propose deux plannings de pipeline différents, *simples* et *entrelacés*, qui peuvent être configurés à l'aide du `pipeline` paramètre du SDK SageMaker Python. Dans la plupart des cas, les pipelines entrelacés peuvent atteindre de meilleures performances en les utilisant GPUs plus efficacement.

### Pipeline entrelacé
<a name="model-parallel-pipeline-execution-interleaved"></a>

Dans un pipeline entrelacé, la priorité est donnée, dans la mesure du possible, à l'exécution vers l'arrière des micro-lots. Cela permet de libérer plus rapidement la mémoire utilisée pour les activations et donc d'utiliser la mémoire plus efficacement. Cela permet également d'augmenter le nombre de microlots, réduisant ainsi le temps d'inactivité du. GPUs À l'état d'équilibre, chaque périphérique alterne entre les transmissions vers l'avant et vers l'arrière. Cela signifie que la transmission vers l'arrière d'un micro-lot peut s'exécuter avant la fin de la transmission vers l'avant d'un autre micro-lot.

![\[Exemple de calendrier d'exécution pour le pipeline entrelacé sur 2. GPUs\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/interleaved-pipeline-execution.png)


La figure précédente illustre un exemple de calendrier d'exécution pour le pipeline entrelacé sur 2. GPUs Sur la figure, F0 représente la transmission vers l'avant pour le micro-lot 0, et B1 la transmission vers l'arrière pour le micro-lot 1. La **mise à jour** représente la mise à jour des paramètres par l'optimiseur. GPU0 donne toujours la priorité aux passes en arrière dans la mesure du possible (par exemple, exécute B0 avant F2), ce qui permet d'effacer la mémoire utilisée pour les activations antérieures.

### Pipeline simple
<a name="model-parallel-pipeline-execution-simple"></a>

À contrario, un pipeline simple termine d'exécuter la transmission vers l'avant pour chaque micro-lot avant de démarrer la transmission vers l'arrière. En d'autres termes, le pipeline exécute les étapes de transmission vers l'avant et vers l'arrière en interne. La figure suivante illustre un exemple de fonctionnement, sur 2 GPUs.

![\[Exemple de pipeline exécutant la transmission vers l’avant pour chaque micro-lot avant de démarrer la transmission vers l’arrière.\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/simple-pipeline-execution.png)


### Exécution de pipeline dans des cadres spécifiques
<a name="model-parallel-pipeline-frameworks"></a>

Utilisez les sections suivantes pour en savoir plus sur les décisions de planification de pipeline spécifiques au framework que la bibliothèque SageMaker de parallélisme des modèles permet et. TensorFlow PyTorch 

#### Exécution du pipeline avec TensorFlow
<a name="model-parallel-pipeline-execution-interleaved-tf"></a>

L'image suivante est un exemple de TensorFlow graphe partitionné par la bibliothèque de parallélisme du modèle, à l'aide du découpage automatique du modèle. Lorsqu'un graphe est divisé, chaque sous-graphe obtenu est répliqué B fois (sauf pour les variables), B désignant le nombre de micro-lots. Sur cette figure, chaque sous-graphe est répliqué 2 fois (B=2). Une opération `SMPInput` est insérée à chaque entrée d'un sous-graphe, et une opération `SMPOutput` est insérée à chaque sortie. Ces opérations communiquent avec le backend de la bibliothèque pour transférer les tenseurs entre eux de façon bidirectionnelle.

![\[Exemple de TensorFlow graphe partitionné par la bibliothèque de parallélisme du modèle, à l'aide du découpage automatique du modèle.\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/interleaved-pipeline-tf.png)


L'image suivante illustre un exemple de 2 sous-graphes divisés avec B=2, avec ajout d'opérations de gradient. Le gradient d'une opération `SMPInput` est une opération `SMPOutput`, et vice versa. Les gradients peuvent ainsi circuler vers l'arrière pendant la rétro-propagation.

![\[Exemple de deux sous-graphes fractionnés avec B=2, avec ajout d’opérations de gradient.\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/interleaved-pipeline-tf.gif)


Ce GIF illustre un exemple de calendrier d'exécution de pipeline entrelacé avec B=2 micro-lots et 2 sous-graphes. Chaque périphérique exécute l'un des réplicas de sous-graphe séquentiellement afin d'améliorer l'utilisation du GPU. À mesure que B augmente, la fraction d'intervalles de temps d'inactivité tend vers zéro. Chaque fois qu'un calcul (vers l'avant ou vers l'arrière) doit être fait sur un réplica de sous-graphe spécifique, la couche de pipeline signale aux opérations `SMPInput` bleues correspondantes qu'il est temps de démarrer l'exécution.

Une fois que les gradients de tous les micro-lots d'un seul mini-lot sont calculés, la bibliothèque combine les gradients entre les micro-lots, qui peuvent ensuite être appliqués aux paramètres. 

#### Exécution du pipeline avec PyTorch
<a name="model-parallel-pipeline-execution-interleaved-pt"></a>

Conceptuellement, le pipeline suit une idée similaire dans. PyTorch Cependant, comme il PyTorch n'implique pas de graphes statiques, la PyTorch fonctionnalité de la bibliothèque de parallélisme du modèle utilise un paradigme de pipeline plus dynamique. 

Par exemple TensorFlow, chaque lot est divisé en plusieurs microlots, qui sont exécutés un par un sur chaque appareil. Toutefois, le calendrier d'exécution est géré via des serveurs d'exécution lancés sur chaque périphérique. Chaque fois que le périphérique actuel a besoin de la sortie d'un sous-module placé sur un autre périphérique, une demande d'exécution est envoyée au serveur d'exécution du périphérique distant et les tenseurs d'entrée au sous-module. Le serveur exécute alors ce module avec les entrées données et renvoie la réponse au périphérique actuel.

Comme le périphérique actuel est inactif pendant l'exécution du sous-module distant, l'exécution locale du micro-lot actuel s'interrompt et le moteur d'exécution de la bibliothèque bascule l'exécution vers un autre micro-lot sur lequel le périphérique actuel peut travailler activement. La priorité donnée aux micro-lots est déterminée par le calendrier de pipeline choisi. Dans le cas d'un calendrier de pipeline entrelacé, les micro-lots qui se trouvent dans l'étape de transmission vers l'arrière du calcul sont prioritaires dans la mesure du possible.

# Parallélisme de tenseur
<a name="model-parallel-extended-features-pytorch-tensor-parallelism"></a>

Le *parallélisme de tenseur* est un type de parallélisme de modèle dans lequel des poids, des gradients et des états d'optimiseur spécifiques sont répartis entre les appareils. Contrairement au parallélisme de pipeline, qui maintient les poids individuels intacts mais partitionne l'*ensemble* de poids, le parallélisme de tenseur répartit les poids individuels. Cela implique généralement un calcul distribué d'opérations, de modules ou de couches spécifiques du modèle.

Le parallélisme de tenseur est nécessaire dans les cas où un seul paramètre consomme la plus grande partie de la mémoire GPU (par exemple, de grandes tables d'incorporation avec une grande taille de vocabulaire ou une couche softmax volumineuse avec un grand nombre de classes). Dans ce cas, le traitement de ce tenseur ou de cette opération de grande taille comme une unité atomique est inefficace et nuit à l'équilibre de la charge mémoire. 

Le parallélisme de tenseur est également utile pour les modèles extrêmement volumineux dans lesquels un traitement en pipeline pur ne suffit tout simplement pas. Par exemple, avec les modèles à l'échelle GPT-3 qui nécessitent un partitionnement sur des dizaines d'instances, un traitement en pipeline de microlots pur est inefficace, car la profondeur du pipeline devient trop élevée et les frais généraux deviennent excessifs.

**Note**  
Le parallélisme tensoriel est disponible PyTorch dans la bibliothèque de parallélisme des SageMaker modèles v1.6.0 et versions ultérieures.

**Topics**
+ [Fonctionnement du parallélisme de tenseur](model-parallel-extended-features-pytorch-tensor-parallelism-how-it-works.md)
+ [Exécutez un job de formation parallèle sur un modèle SageMaker distribué avec Tensor Parallelism](model-parallel-extended-features-pytorch-tensor-parallelism-examples.md)
+ [Prise en charge des modèles Transformer Hugging Face](model-parallel-extended-features-pytorch-hugging-face.md)
+ [Mécanisme de classement lors de l'utilisation d'une combinaison de parallélisme de pipelines et de parallélisme de tenseurs](model-parallel-extended-features-pytorch-ranking-mechanism.md)

# Fonctionnement du parallélisme de tenseur
<a name="model-parallel-extended-features-pytorch-tensor-parallelism-how-it-works"></a>

Le parallélisme de tenseur a lieu au niveau des `nn.Modules` ; il partitionne des modules spécifiques du modèle sur des rangs parallèles au tenseur. Cela se produit en plus de la partition existante de l'*ensemble de modules* utilisé dans le parallélisme de pipeline.

Lorsqu'un module est partitionné au moyen d'un parallélisme de tenseur, sa propagation vers l'avant et l'arrière est distribuée. La bibliothèque gère la communication nécessaire entre les appareils pour implémenter l'exécution distribuée de ces modules. Les modules sont partitionnés sur plusieurs rangs parallèles de données. Contrairement à la distribution classique des charges de travail, les rangs parallèles aux données ne possèdent **pas** le réplica complet du modèle lorsque le parallélisme de tenseur de la bibliothèque est utilisé. Au lieu de cela, chaque rang parallèle aux données peut comporter uniquement une partition des modules distribués, en plus de l'intégralité des modules qui ne sont pas distribués.

**Exemple :** imaginez un parallélisme de tenseur entre des rangs parallèles aux données, où le degré de parallélisme de données est de 4 et le degré de parallélisme de tenseur est de 2. Supposons que vous disposez d'un groupe parallèle aux données qui contient l'arborescence de modules suivante, après avoir partitionné l'ensemble de modules.

```
A
├── B
|   ├── E
|   ├── F
├── C
└── D
    ├── G
    └── H
```

Supposons que le parallélisme de tenseur soit pris en charge pour les modules B, G et H. L'un des résultats possibles de la partition parallèle au tenseur de ce modèle pourrait être :

```
dp_rank 0 (tensor parallel rank 0): A, B:0, C, D, G:0, H
dp_rank 1 (tensor parallel rank 1): A, B:1, C, D, G:1, H
dp_rank 2 (tensor parallel rank 0): A, B:0, C, D, G:0, H
dp_rank 3 (tensor parallel rank 1): A, B:1, C, D, G:1, H
```

Chaque ligne représente l'ensemble des modules stockés dans ce `dp_rank` et la notation `X:y` représente la `y`-ième fraction du module `X`. Notez ce qui suit :

1. Le partitionnement a lieu entre des sous-ensembles de rangs parallèles aux données, que nous appelons `TP_GROUP`, et non pas dans l'intégralité du `DP_GROUP`. Dès lors, la partition du modèle exacte est répliquée sur `dp_rank` 0 et `dp_rank` 2, et de la même manière sur `dp_rank` 1 et `dp_rank` 3.

1. Les modules `E` et `F` ne font plus partie du modèle, car leur module parent `B` est partitionné et toute exécution qui fait normalement partie des modules `E` et `F` se déroule au sein du module `B` (partitionné).

1. Même si le module `H` est pris en charge pour le parallélisme de tenseur, dans cet exemple, il n'est pas partitionné, ce qui souligne que le partitionnement d'un module dépend de l'entrée utilisateur. Le fait qu'un module soit pris en charge pour le parallélisme de tenseur ne signifie pas nécessairement qu'il est partitionné.

## Comment la bibliothèque adapte le parallélisme des tenseurs au module PyTorch `nn.Linear`
<a name="model-parallel-extended-for-pytorch-adapt-to-module"></a>

Lorsque le parallélisme de tenseur est effectué sur des rangs parallèles aux données, un sous-ensemble des paramètres, des gradients et des états de l'optimiseur est partitionné entre les dispositifs parallèles au tenseur *pour les modules partitionnés*. Pour le reste des modules, les dispositifs parallèles au tenseur fonctionnent de manière parallèle aux données classique. Pour exécuter le module partitionné, un appareil collecte d'abord les parties nécessaires de *tous les échantillons de données* sur des appareils homologues dans le même groupe de parallélisme de tenseur. L'appareil exécute ensuite la fraction locale du module sur tous ces échantillons de données, suivie d'un autre cycle de synchronisation qui combine les parties de la sortie pour chaque échantillon de données et renvoie les échantillons de données combinés à l'origine GPUs de l'échantillon de données. La figure suivante montre un exemple de ce processus sur un module `nn.Linear` partitionné. 

![\[Deux figures illustrant deux concepts de parallélisme de tenseur.\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/tensor-parallel-concept.png)


La première figure montre un petit modèle présentant un grand module `nn.Linear` avec parallélisme de données sur les deux rangs de parallélisme de tenseur. Le module `nn.Linear` est répliqué dans les deux rangs parallèles. 

La deuxième figure montre le parallélisme de tenseurs appliqué sur un modèle plus grand lors du fractionnement du module `nn.Linear`. Chaque `tp_rank` contient la moitié du module linéaire et la totalité du reste des opérations. Pendant l'exécution du module linéaire, chaque `tp_rank` collecte la moitié pertinente de tous les échantillons de données et la transmet par leur moitié du module `nn.Linear`. Le résultat doit être réduit et dispersé (avec sommation comme opération de réduction) afin que chaque rang ait la sortie linéaire finale de ses propres échantillons de données. Le reste du modèle s'exécute de manière parallèle aux données classique.

# Exécutez un job de formation parallèle sur un modèle SageMaker distribué avec Tensor Parallelism
<a name="model-parallel-extended-features-pytorch-tensor-parallelism-examples"></a>

Dans cette section, vous allez apprendre :
+ Comment configurer un SageMaker PyTorch estimateur et l'option de parallélisme du SageMaker modèle pour utiliser le parallélisme des tenseurs.
+ à adapter le script d'entraînement à l'aide des modules `smdistributed.modelparallel` étendus de parallélisme de tenseur.

Pour en savoir plus sur les `smdistributed.modelparallel` modules, consultez le [SageMaker model parallel APIs](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) dans la *documentation du SDK SageMaker Python*.

**Topics**
+ [Parallélisme de tenseur seul](#model-parallel-extended-features-pytorch-tensor-parallelism-alone)
+ [Parallélisme de tenseur associé au parallélisme de pipeline](#model-parallel-extended-features-pytorch-tensor-and-pipeline-parallelism)

## Parallélisme de tenseur seul
<a name="model-parallel-extended-features-pytorch-tensor-parallelism-alone"></a>

Voici un exemple d'option d'entraînement distribué permettant d'activer uniquement le parallélisme de tenseur, sans parallélisme de pipeline. Configurez les `smp_options` dictionnaires `mpi_options` et pour spécifier les options d'apprentissage distribuées à l' SageMaker `PyTorch`estimateur.

**Note**  
Des fonctionnalités étendues d'économie de mémoire sont disponibles via Deep Learning Containers for PyTorch, qui implémente la bibliothèque de parallélisme de SageMaker modèles v1.6.0 ou version ultérieure.

**Configuration d'un SageMaker PyTorch estimateur**

```
mpi_options = {
    "enabled" : True,
    "processes_per_host" : 8,               # 8 processes
    "custom_mpi_options" : "--mca btl_vader_single_copy_mechanism none "
}
               
smp_options = {
    "enabled":True,
    "parameters": {
        "pipeline_parallel_degree": 1,    # alias for "partitions"
        "placement_strategy": "cluster",
        "tensor_parallel_degree": 4,      # tp over 4 devices
        "ddp": True
    }
}
              
smp_estimator = PyTorch(
    entry_point='your_training_script.py', # Specify
    role=role,
    instance_type='ml.p3.16xlarge',
    sagemaker_session=sagemaker_session,
    framework_version='1.13.1',
    py_version='py36',
    instance_count=1,
    distribution={
        "smdistributed": {"modelparallel": smp_options},
        "mpi": mpi_options
    },
    base_job_name="SMD-MP-demo",
)

smp_estimator.fit('s3://my_bucket/my_training_data/')
```

**Astuce**  
Pour obtenir la liste complète des paramètres pour`distribution`, consultez la section [Paramètres de configuration pour le parallélisme des modèles dans la documentation du](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html) SDK SageMaker Python.

**Adaptez votre script PyTorch d'entraînement**

L'exemple de script d'entraînement suivant montre comment adapter la bibliothèque de parallélisme du SageMaker modèle à un script d'entraînement. Dans cet exemple, on suppose que le script est nommé `your_training_script.py`. 

```
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 Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)
        x = torch.flatten(x, 1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        return F.log_softmax(x, 1)

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()
        output = model(data)
        loss = F.nll_loss(output, target, reduction="mean")
        loss.backward()
        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
if smp.local_rank() == 0:
    dataset = datasets.MNIST("../data", train=True, download=False)
smp.barrier()

# 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()}")

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

# smdistributed: Enable tensor parallelism for all supported modules in the model
# i.e., nn.Linear in this case. Alternatively, we can use
# smp.set_tensor_parallelism(model.fc1, True)
# to enable it only for model.fc1
with smp.tensor_parallelism():
    model = Net()

# smdistributed: Use the DistributedModel wrapper to distribute the
# modules for which tensor parallelism is enabled
model = smp.DistributedModel(model)

optimizer = optim.AdaDelta(model.parameters(), lr=4.0)
optimizer = smp.DistributedOptimizer(optimizer)

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

## Parallélisme de tenseur associé au parallélisme de pipeline
<a name="model-parallel-extended-features-pytorch-tensor-and-pipeline-parallelism"></a>

Voici un exemple d'option d'apprentissage distribué qui permet le parallélisme des tenseurs combiné au parallélisme des pipelines. Configurez les `smp_options` paramètres `mpi_options` et pour spécifier les options de parallélisme du modèle avec le parallélisme des tenseurs lorsque vous configurez un estimateur. SageMaker `PyTorch`

**Note**  
Des fonctionnalités étendues d'économie de mémoire sont disponibles via Deep Learning Containers for PyTorch, qui implémente la bibliothèque de parallélisme de SageMaker modèles v1.6.0 ou version ultérieure.

**Configuration d'un SageMaker PyTorch estimateur**

```
mpi_options = {
    "enabled" : True,
    "processes_per_host" : 8,               # 8 processes
    "custom_mpi_options" : "--mca btl_vader_single_copy_mechanism none "
}
               
smp_options = {
    "enabled":True,
    "parameters": {
    "microbatches": 4,
        "pipeline_parallel_degree": 2,    # alias for "partitions"
        "placement_strategy": "cluster",
        "tensor_parallel_degree": 2,      # tp over 2 devices
        "ddp": True
    }
}
              
smp_estimator = PyTorch(
    entry_point='your_training_script.py', # Specify
    role=role,
    instance_type='ml.p3.16xlarge',
    sagemaker_session=sagemaker_session,
    framework_version='1.13.1',
    py_version='py36',
    instance_count=1,
    distribution={
        "smdistributed": {"modelparallel": smp_options},
        "mpi": mpi_options
    },
    base_job_name="SMD-MP-demo",
)

smp_estimator.fit('s3://my_bucket/my_training_data/')  
```

<a name="model-parallel-extended-features-pytorch-tensor-and-pipeline-parallelism-script"></a>**Adaptez votre script PyTorch d'entraînement**

L'exemple de script d'entraînement suivant montre comment adapter la bibliothèque de parallélisme du SageMaker modèle à un script d'entraînement. Notez que le script d'entraînement inclut désormais le décorateur `smp.step` : 

```
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 Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)
        x = torch.flatten(x, 1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        return F.log_softmax(x, 1)


# 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
if smp.local_rank() == 0:
    dataset = datasets.MNIST("../data", train=True, download=False)
smp.barrier()

# 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 = Net()

# smdistributed: enable tensor parallelism only for model.fc1
smp.set_tensor_parallelism(model.fc1, True)

# 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 = optim.AdaDelta(model.parameters(), lr=4.0)
optimizer = smp.DistributedOptimizer(optimizer)

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

# Prise en charge des modèles Transformer Hugging Face
<a name="model-parallel-extended-features-pytorch-hugging-face"></a>

Le parallélisme des tenseurs de la bibliothèque de parallélisme des SageMaker modèles prend en out-of-the-box charge les modèles Hugging Face Transformer suivants :
+ GPT-2, BERT et Ro BERTa (disponibles dans la bibliothèque de parallélisme des SageMaker modèles v1.7.0 et versions ultérieures)
+ GPT-J (disponible dans la bibliothèque de parallélisme des SageMaker modèles v1.8.0 et versions ultérieures)
+ GPT-Neo (disponible dans la bibliothèque de parallélisme des SageMaker modèles v1.10.0 et versions ultérieures)

**Note**  
Pour tous les autres modèles de transformateurs, vous devez utiliser l'API [smdistributed.modelparallel.torch.tp\$1register\$1with\$1module()](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch_tensor_parallel.html#smdistributed.modelparallel.torch.tp_register_with_module) pour appliquer le parallélisme de tenseur.

**Note**  
Pour utiliser le parallélisme tensoriel pour entraîner les modèles Hugging Face Transformer, assurez-vous d'utiliser Hugging Face Deep Learning Containers car ils disposent de la bibliothèque de parallélisme PyTorch des modèles v1.7.0 et SageMaker versions ultérieures. Pour plus d'informations, consultez les notes de mise à [jour de la bibliothèque de parallélisme de SageMaker modèles](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_release_notes/smd_model_parallel_change_log.html).

## Modèles pris en charge prêts à l'emploi
<a name="model-parallel-extended-features-pytorch-hugging-face-out-of-the-box"></a>

Pour les modèles de transformateurs Hugging Face pris en charge par la bibliothèque prêts à l'emploi, il n'est pas nécessaire d'implémenter manuellement des crochets pour traduire le transformateur en APIs couches `smdistributed` de transformateur. [Vous pouvez activer le parallélisme tensoriel en utilisant le gestionnaire de contexte smdistributed.modelparallel.torch.tensor\$1parallelism () et en encapsulant le modèle par [smdistributed.modelparallel.torch](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch_tensor_parallel.html#smdistributed.modelparallel.torch.tensor_parallelism). DistributedModel()](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.DistributedModel). Vous n'avez pas non plus besoin d'enregistrer manuellement les crochets pour le parallélisme de tenseur à l'aide de l'API `smp.tp_register`.

Il est possible d'accéder aux fonctions de traduction `state_dict` entre les transformateurs Hugging Face et `smdistributed.modelparallel` comme suit.
+  `smdistributed.modelparallel.torch.nn.huggingface.gpt2.translate_state_dict_to_hf_gpt2(state_dict, max_seq_len=None)`
+  `smdistributed.modelparallel.torch.nn.huggingface.gpt2.translate_hf_state_dict_to_smdistributed_gpt2(state_dict)` 
+  `smdistributed.modelparallel.torch.nn.huggingface.bert.translate_state_dict_to_hf_bert(state_dict, max_seq_len=None)` 
+  `smdistributed.modelparallel.torch.nn.huggingface.bert.translate_hf_state_dict_to_smdistributed_bert(state_dict)` 
+  `smdistributed.modelparallel.torch.nn.huggingface.roberta.translate_state_dict_to_hf_roberta(state_dict, max_seq_len=None)` 
+  `smdistributed.modelparallel.torch.nn.huggingface.roberta.translate_hf_state_dict_to_smdistributed_roberta(state_dict)` 
+ `smdistributed.modelparallel.torch.nn.huggingface.gptj.translate_state_dict_to_hf_gptj(state_dict, max_seq_len=None)`(Disponible dans la bibliothèque de parallélisme des SageMaker modèles v1.8.0 et versions ultérieures)
+ `smdistributed.modelparallel.torch.nn.huggingface.gptj.translate_hf_gptj_state_dict_to_smdistributed_gptj`(Disponible dans la bibliothèque de parallélisme des SageMaker modèles v1.8.0 et versions ultérieures)
+ `smdistributed.modelparallel.torch.nn.huggingface.gptneo.translate_state_dict_to_hf_gptneo(state_dict, max_seq_len=None)`(Disponible dans la bibliothèque de parallélisme des SageMaker modèles v1.10.0 et versions ultérieures)
+ `smdistributed.modelparallel.torch.nn.huggingface.gptneo.translate_hf_state_dict_to_smdistributed_gptneo(state_dict)`(Disponible dans la bibliothèque de parallélisme des SageMaker modèles v1.10.0 et versions ultérieures)

**Exemple d'utilisation de la fonction de traduction GPT-2**

Commencez par envelopper le modèle, comme indiqué dans le code suivant.

```
from transformers import AutoModelForCausalLM

with smp.tensor_parallelism():
    model = AutoModelForCausalLM.from_config(hf_gpt2_config)

model = smp.DistributedModel(model)
```

De plus, avec un `state_dict` de l'objet `DistributedModel`, vous pouvez charger les poids dans le modèle HuggingFace GPT-2 d'origine à l'aide de la fonction `translate_state_dict_to_hf_gpt2` du code suivant :

```
from smdistributed.modelparallel.torch.nn.huggingface.gpt2 \
                                      import translate_state_dict_to_hf_gpt2
max_seq_len = 1024

# [... code block for training ...]

if smp.rdp_rank() == 0:
    state_dict = dist_model.state_dict()
    hf_state_dict = translate_state_dict_to_hf_gpt2(state_dict, max_seq_len)

    # can now call model.load_state_dict(hf_state_dict) to the original HF model
```

**Exemple d'utilisation de la fonction de BERTa traduction Ro**

De même, étant donné qu'un HuggingFace modèle est pris en charge`state_dict`, vous pouvez utiliser la `translate_hf_state_dict_to_smdistributed` fonction pour le convertir en un format lisible par`smp.DistributedModel`. Cela peut être utile dans les cas d'utilisation d'apprentissage par transfert, où un modèle préentraîné est chargé dans un `smp.DistributedModel` pour le réglage fin du parallélisme de modèles :

```
from smdistributed.modelparallel.torch.nn.huggingface.roberta \
                                      import translate_state_dict_to_smdistributed

model = AutoModelForMaskedLM.from_config(roberta_config)
model = smp.DistributedModel(model)

pretrained_model = AutoModelForMaskedLM.from_pretrained("roberta-large")
translated_state_dict =
        translate_state_dict_to_smdistributed(pretrained_model.state_dict())

# load the translated pretrained weights into the smp.DistributedModel
model.load_state_dict(translated_state_dict)

# start fine-tuning...
```

# Mécanisme de classement lors de l'utilisation d'une combinaison de parallélisme de pipelines et de parallélisme de tenseurs
<a name="model-parallel-extended-features-pytorch-ranking-mechanism"></a>

Cette section explique comment le mécanisme de classement du parallélisme de modèles fonctionne avec le parallélisme de tenseurs. C'est une extension des [notions de base du classement](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#ranking-basics) pour [Principales fonctionnalités de la bibliothèque de parallélisme des SageMaker modèles](model-parallel-core-features.md). Avec le parallélisme des tenseurs, la bibliothèque introduit trois types de classement et de groupe de processus APIs : pour le rang parallèle des `smp.tp_rank()` tenseurs, pour le rang parallèle du `smp.pp_rank()` pipeline et pour le rang parallèle des données `smp.rdp_rank()` réduites. Les groupes de processus de communication correspondants sont le groupe de tenseurs parallèles (`TP_GROUP`), le groupe de pipelines parallèles (`PP_GROUP`) et le groupe de données réduites parallèles (`RDP_GROUP`). Ces groupes sont définis comme suit :
+ Un *groupe de tenseurs parallèles* (`TP_GROUP`) est un sous-ensemble divisible de manière égale du groupe de données parallèles, sur lequel s'exerce la distribution en tenseurs parallèles des modules. Lorsque le degré de parallélisme de pipelines est de 1, `TP_GROUP` est identique au *groupe parallèle au modèle* (`MP_GROUP`). 
+ Un *groupe de pipelines parallèles* (`PP_GROUP`) est le groupe de processus sur lequel s'exerce le parallélisme des pipelines. Lorsque le degré de parallélisme de tenseur est de 1, `PP_GROUP` est identique à `MP_GROUP`. 
+ Un *groupe de données réduites parallèles* (`RDP_GROUP`) est un ensemble de processus qui contiennent les mêmes partitions de parallélisme des pipelines et les mêmes partitions de parallélisme des tenseurs, et qui réalisent un parallélisme des données entre eux. C'est ce que l'on appelle le groupe parallèle aux données réduites, car il s'agit d'un sous-ensemble de l'ensemble du groupe de parallélisme de données, `DP_GROUP`. Pour les paramètres du modèle distribués dans le `TP_GROUP`, l'opération `allreduce` de gradient est effectuée uniquement pour le groupe parallèle aux données réduites, tandis que pour les paramètres non distribués, l'opération `allreduce` de gradient a lieu sur l'ensemble du `DP_GROUP`. 
+ Un groupe parallèle au modèle (`MP_GROUP`) désigne un groupe de processus qui stockent collectivement l'ensemble du modèle. Il s'agit de l'union des `PP_GROUP` de tous les rangs qui se trouvent dans le `TP_GROUP` du processus actuel. Lorsque le degré de parallélisme de tenseur est de 1, `MP_GROUP` est équivalent à `PP_GROUP`. Il est également cohérent avec la définition existante du `MP_GROUP` des versions `smdistributed` précédentes. Veuillez noter que le `TP_GROUP` actuel est un sous-ensemble du `DP_GROUP` et du `MP_GROUP` actuels. 

Pour en savoir plus sur le processus de communication APIs dans la bibliothèque de parallélisme des SageMaker modèles, consultez l'[API commune et l'API PyTorch](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_common_api.html#) [spécifique dans la documentation APIs](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html) du SDK *SageMaker Python*.

![\[Mécanisme de classement, distribution des paramètres et AllReduce opérations associées du parallélisme tensoriel.\]](http://docs.aws.amazon.com/fr_fr/sagemaker/latest/dg/images/distributed/model-parallel/tensor-parallel-ranking-mechanism.png)


Par exemple, considérez les groupes de processus pour un seul nœud avec 8 GPUs, où le degré de parallélisme des tenseurs est de 2, le degré de parallélisme du pipeline est de 2 et le degré de parallélisme des données est de 4. La partie centrale supérieure de la figure précédente montre un exemple de modèle à 4 couches. Les parties inférieure gauche et inférieure droite de la figure illustrent le modèle à 4 couches réparti sur 4 GPUs utilisant à la fois le parallélisme des pipelines et le parallélisme des tenseurs, le parallélisme des tenseurs étant utilisé pour les deux couches du milieu. Les deux figures du bas sont de simples copies permettant d'illustrer des lignes de limites de groupe différentes. Le modèle partitionné est répliqué pour le parallélisme des données entre 0-3 et 4-7. GPUs La figure en bas à gauche montre les définitions de `MP_GROUP`, de `PP_GROUP` et de `TP_GROUP`. La figure en bas à droite montre `RDP_GROUP``DP_GROUP`, et `WORLD` sur le même ensemble de GPUs. Les opérations `allreduce` sont effectuées pour tous les gradients des couches et des tranches de couche de la même couleur dans le cadre du parallélisme des données. Par exemple, les opérations `allreduce` sont effectuées sur la première couche (bleu clair) dans `DP_GROUP`, alors que ces opérations `allreduce` ne sont effectuées sur la tranche orange foncé de la deuxième couche qu'au sein du `RDP_GROUP` de son processus. Les flèches rouge foncé en gras représentent des tenseurs avec le lot de tout le `TP_GROUP`.

```
GPU0: pp_rank 0, tp_rank 0, rdp_rank 0, dp_rank 0, mp_rank 0
GPU1: pp_rank 1, tp_rank 0, rdp_rank 0, dp_rank 0, mp_rank 1
GPU2: pp_rank 0, tp_rank 1, rdp_rank 0, dp_rank 1, mp_rank 2
GPU3: pp_rank 1, tp_rank 1, rdp_rank 0, dp_rank 1, mp_rank 3
GPU4: pp_rank 0, tp_rank 0, rdp_rank 1, dp_rank 2, mp_rank 0
GPU5: pp_rank 1, tp_rank 0, rdp_rank 1, dp_rank 2, mp_rank 1
GPU6: pp_rank 0, tp_rank 1, rdp_rank 1, dp_rank 3, mp_rank 2
GPU7: pp_rank 1, tp_rank 1, rdp_rank 1, dp_rank 3, mp_rank 3
```

Dans cet exemple, le parallélisme de pipeline se produit entre les paires de GPU (0,1) ; (2,3) ; (4,5) et (6,7). En outre, le parallélisme des données (`allreduce`) s'effectue sur GPUs 0, 2, 4, 6 et indépendamment sur GPUs 1, 3, 5, 7. Le parallélisme de tenseur se produit sur des sous-ensembles de `DP_GROUP`, sur les paires de GPU (0,2) ; (1,3) ; (4,6) et (5,7).

  Pour ce type de parallélisme hybride de pipeline et de tenseur, le calcul de `data_parallel_degree` reste `data_parallel_degree = number_of_GPUs / pipeline_parallel_degree`. La bibliothèque calcule encore le degré de parallélisme de données réduit à partir de la relation `reduced_data_parallel_degree * tensor_parallel_degree = data_parallel_degree`.  

# Partitionnement de l'état de l'optimiseur
<a name="model-parallel-extended-features-pytorch-optimizer-state-sharding"></a>

Le *partitionnement de l'état de l'optimiseur* est une technique d'économie de mémoire utile qui partitionne l'état de l'optimiseur (l'ensemble de poids qui décrit l'état de l'optimiseur) entre des groupes d'appareils parallèles aux données. Vous pouvez utiliser le sharding de l'état de l'optimiseur chaque fois que vous utilisez un optimiseur dynamique (tel qu'Adam) ou un FP16 optimiseur (qui stocke les deux FP16 et des FP32 copies des paramètres).

**Note**  
Le sharding d'état de l'optimiseur est disponible PyTorch dans la bibliothèque de parallélisme des SageMaker modèles v1.6.0 et versions ultérieures.

## Utilisation du partitionnement de l'état de l'optimiseur
<a name="model-parallel-extended-features-pytorch-optimizer-state-sharding-how-to-use"></a>

Vous pouvez activer le *partitionnement de l'état de l'optimiseur* en définissant `"shard_optimizer_state": True` dans la configuration `modelparallel`. 

Lorsque cette fonction est activée, la bibliothèque partitionne l'ensemble des paramètres du modèle en fonction du degré de parallélisme de données. Les gradients correspondant à la `i`-ième partition ne sont réduits qu'au `i`-ième rang parallèle de données. À la fin du premier appel à une fonction de décorateur `smp.step`, l'optimiseur enveloppé par `smp.DistributedOptimizer` redéfinit ses paramètres pour qu'ils ne soient limités qu'aux paramètres correspondant à la partition du rang parallèle aux données actuel. Les paramètres redéfinis sont appelés *paramètres virtuels* et partagent le stockage sous-jacent avec les paramètres d'origine. Lors du premier appel à `optimizer.step`, les états de l'optimiseur sont créés en fonction de ces paramètres redéfinis, qui sont partitionnés en raison de la partition d'origine. Après la mise à jour de l'optimiseur, l' AllGatheropération (dans le cadre de l'`optimizer.step`appel) s'exécute sur les rangs parallèles des données pour obtenir des états de paramètres cohérents.

**Astuce**  
Le partitionnement de l'état de l'optimiseur peut être utile lorsque le degré de parallélisme de données est supérieur à 1 et que le modèle comporte plus d'un milliard de paramètres.   
Le degré de parallélisme de données est calculé par `(processes_per_host * instance_count / pipeline_parallel_degree)` et la fonction `smp.dp_size()` gère le dimensionnement en arrière-plan.

**Configuration d'un SageMaker PyTorch estimateur**

```
mpi_options = {
    "enabled" : True,
    "processes_per_host" : 8,               # 8 processes
    "custom_mpi_options" : "--mca btl_vader_single_copy_mechanism none "
}

smp_options = {
    "enabled":True,
    "parameters": {
        "microbatches": 4,
        "pipeline_parallel_degree": 2,    # alias for "partitions"
        "placement_strategy": "cluster",
        "tensor_parallel_degree": 2,      # tp over 2 devices
        "ddp": True,
        "shard_optimizer_state": True
    }
}
```

**Adaptez votre script PyTorch d'entraînement**

Voir [Adapter votre script PyTorch d'entraînement](model-parallel-extended-features-pytorch-tensor-parallelism-examples.md#model-parallel-extended-features-pytorch-tensor-and-pipeline-parallelism-script) dans la section Parallélisme de *Tensor combiné au parallélisme de pipeline*. Aucune modification supplémentaire n'est requise pour le script.

# Points de contrôle d'activation
<a name="model-parallel-extended-features-pytorch-activation-checkpointing"></a>

Les *points de contrôle d'activation* (ou *points de contrôle de gradient*) sont une technique permettant de réduire l'utilisation de la mémoire en effaçant les activations de certaines couches et en les recalculant lors d'une transmission vers l'arrière. Concrètement, cela augmente le temps de calcul pour réduire l'utilisation de la mémoire. Si un module dispose de points de contrôle, à la fin d'une transmission vers l'avant, les entrées et les sorties du module restent en mémoire. Tous les tenseurs intermédiaires qui auraient fait partie du calcul à l'intérieur de ce module sont libérés pendant la transmission vers l'avant. Au cours de la transmission vers l'arrière des modules avec points de contrôle, ces tenseurs sont recalculés. À ce stade, les couches situées au-delà de ce module avec points de contrôle ont terminé leur transmission vers l'arrière. Ainsi, grâce aux points de contrôle, l'utilisation maximale de la mémoire peut être plus faible.

**Note**  
Cette fonctionnalité est disponible PyTorch dans la bibliothèque de parallélisme des SageMaker modèles v1.6.0 et versions ultérieures.

## Utilisation des points de contrôle d'activation
<a name="model-parallel-extended-for-pytorch-activation-checkpointing-how-to-use"></a>

Avec `smdistributed.modelparallel`, vous pouvez utiliser les points de contrôle d'activation au niveau de détails d'un module. Pour tous les modules `torch.nn` à l'exception de `torch.nn.Sequential`, vous ne pouvez créer des points de contrôle pour une arborescence de modules que si celle-ci se trouve dans une seule partition du point de vue du parallélisme de pipeline. Dans le cas du module `torch.nn.Sequential`, chaque arborescence de modules à l'intérieur du module séquentiel doit se trouver complètement dans une partition pour que les points de contrôle d'activation fonctionnent. Lorsque vous utilisez le partitionnement manuel, soyez conscient de ces restrictions.

Lorsque vous utilisez le [partitionnement automatisé des modèles](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-core-features.html#model-parallel-automated-model-splitting), vous pouvez trouver les journaux d'affectation de partitionnement commençant par`Partition assignments:` dans les journaux de tâches d'entraînement. Si un module est partitionné sur plusieurs rangs (par exemple, avec un descendant sur un rang et un autre descendant sur un autre rang), la bibliothèque ignore la tentative de création de points de contrôles pour le module et génère un message d'avertissement indiquant qu'aucun point de contrôle ne sera créé pour le module.

**Note**  
La bibliothèque de parallélisme du SageMaker modèle prend en charge les `allreduce` opérations avec ou sans chevauchement en combinaison avec le point de contrôle. 

**Note**  
PyTorchl'API de point de contrôle native n'est pas compatible avec`smdistributed.modelparallel`.

**Exemple 1 :** l'exemple de code suivant montre comment utiliser les points de contrôle d'activation lorsque le script contient une définition de modèle.

```
import torch.nn as nn
import torch.nn.functional as F

from smdistributed.modelparallel.torch.patches.checkpoint import checkpoint

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = F.max_pool2d(x, 2)
        x = torch.flatten(x, 1)
        # This call of fc1 will be checkpointed
        x = checkpoint(self.fc1, x)
        x = self.fc2(x)
        return F.log_softmax(x, 1)
```

**Exemple 2 :** l'exemple de code suivant montre comment utiliser les points de contrôle d'activation lorsque le script contient un modèle séquentiel.

```
import torch.nn as nn
from smdistributed.modelparallel.torch.patches.checkpoint import checkpoint_sequential

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.seq = nn.Sequential(
            nn.Conv2d(1,20,5),
            nn.ReLU(),
            nn.Conv2d(20,64,5),
            nn.ReLU()
        )

    def forward(self, x):
        # This call of self.seq will be checkpointed
        x = checkpoint_sequential(self.seq, x)
        return F.log_softmax(x, 1)
```

**Exemple 3 :** L'exemple de code suivant montre comment utiliser le point de contrôle d'activation lorsque vous importez un modèle prédéfini à partir d'une bibliothèque, telle que Hugging Face PyTorch Transformers. Que vous créiez ou non des points de contrôle pour des modules séquentiels, procédez comme suit : 

1. Enveloppez le modèle par `smp.DistributedModel()`.

1. Définissez un objet pour les couches séquentielles.

1. Encapsulez l'objet de couche séquentielle par `smp.set_activation_checkpointig()`.

```
import smdistributed.modelparallel.torch as smp
from transformers import AutoModelForCausalLM

smp.init()
model = AutoModelForCausalLM(*args, **kwargs)
model = smp.DistributedModel(model)

# Call set_activation_checkpointing API
transformer_layers = model.module.module.module.transformer.seq_layers
smp.set_activation_checkpointing(
    transformer_layers, pack_args_as_tuple=True, strategy='each')
```

# Déchargement de l'activation
<a name="model-parallel-extended-features-pytorch-activation-offloading"></a>

Lorsque les points de contrôle d'activation et le parallélisme de pipeline sont activés et que le nombre de microlots est supérieur à un, le *déchargement de l'activation* est une fonction supplémentaire qui peut réduire davantage l'utilisation de la mémoire. Le déchargement de l'activation déplace de manière asynchrone les activations avec points de contrôle correspondant à leurs microlots qui ne sont pas en cours d'exécution dans le CPU. Juste avant que le GPU n'ait besoin des activations pour le transfert vers l'arrière du microlot, cette fonctionnalité récupère au préalable les activations déchargées du CPU.

**Note**  
Cette fonctionnalité est disponible PyTorch dans la bibliothèque de parallélisme des SageMaker modèles v1.6.0 et versions ultérieures.

## Utilisation du déchargement de l'activation
<a name="model-parallel-extended-for-pytorch-activation-offloading"></a>

Utilisez le déchargement de l'activation pour réduire l'utilisation de la mémoire lorsque **le nombre de microlots est supérieur à 1 et que les points de contrôle d'activation sont activés** (consultez [Points de contrôle d'activation](model-parallel-extended-features-pytorch-activation-checkpointing.md)). Si les points de contrôle d'activation ne sont pas utilisés, le déchargement de l'activation n'a aucun effet. Si cette fonctionnalité est utilisée avec un seul microlot, elle ne permet pas d'économiser de la mémoire.

Pour utiliser le déchargement de l'activation, définissez `"offload_activations": True` dans la configuration `modelparallel`.

Le déchargement de l'activation déplace les activations avec points de contrôle dans des modules `nn.Sequential` vers le CPU de manière asynchrone. Le transfert de données via le PCIe lien chevauche le calcul du GPU. Le déchargement se produit immédiatement, dès que la transmission vers l'avant d'une couche avec points de contrôle donnée est calculée. Les activations sont rechargées sur le GPU peu de temps avant qu'elles ne soient nécessaires pour la transmission vers l'arrière d'un microlot particulier. Le transfert CPU-GPU chevauche également le calcul. 

Pour régler le début du rechargement des activations dans le GPU, vous pouvez utiliser le paramètre de configuration `"activation_loading_horizon"` (la valeur par défaut est 4, doit être un `int` supérieur à 0). Avec un horizon de chargement d'activation plus grand, le rechargement des activations sur le GPU se produirait plus tôt. Si l'horizon est trop grand, l'efficacité du déchargement de l'activation pour réduire la mémoire utilisée pourrait être réduite. Si l'horizon est trop petit, il se peut que les activations ne soient pas rechargées à temps, ce qui réduirait la quantité de chevauchement et nuirait aux performances.

**Astuce**  
Le déchargement de l'activation peut être utile pour les grands modèles comportant plus de cent milliards de paramètres.

**Configuration d'un SageMaker PyTorch estimateur**

```
mpi_options = {
    "enabled" : True,
    "processes_per_host" : 8,               # 8 processes
    "custom_mpi_options" : "--mca btl_vader_single_copy_mechanism none "
}

smp_options = {
    "enabled":True,
    "parameters": {
        "microbatches": 4,
        "pipeline_parallel_degree": 2,    # alias for "partitions"
        "placement_strategy": "cluster",
        "tensor_parallel_degree": 2,      # tp over 2 devices
        "ddp": True,
        "offload_activations": True,
        "activation_loading_horizon": 4   # optional. default is 4.
    }
}
```

# FP16 Entraînement avec le parallélisme des modèles
<a name="model-parallel-extended-features-pytorch-fp16"></a>

Pour la FP16 formation, appliquez les modifications suivantes à votre script d'entraînement et à votre estimateur.

**Note**  
Cette fonctionnalité est disponible PyTorch dans la bibliothèque de parallélisme des SageMaker modèles v1.10.0 et versions ultérieures.

**Adaptez votre script PyTorch d'entraînement**

1. Enveloppez votre modèle en utilisant le gestionnaire de contexte [smdistributed.modelparallel.torch.model\$1creation ()](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.model_creation).

   ```
   # fp16_training_script.py
   
   import torch
   import smdistributed.modelparallel.torch as smp
   
   with smp.model_creation(
       dtype=torch.float16 if args.fp16 else torch.get_default_dtype()
   ):
       model = ...
   ```
**Astuce**  
Si vous utilisez le parallélisme des tenseurs, ajoutez `tensor_parallelism=smp.tp_size() > 1` au gestionnaire de contexte `smp.model_creation`. L'ajout de cette ligne aide également à détecter automatiquement si le parallélisme des tenseurs est activé ou non.  

   ```
   with smp.model_creation(
       ... ,
       tensor_parallelism=smp.tp_size() > 1
   ):
       model = ...
   ```

1. Lorsque vous enveloppez l'optimiseur avec `smdistributed.modelparallel.torch.DistributedOptimizer`, définissez l'argument `static_loss_scaling` ou `dynamic_loss_scaling`. Par défaut, `static_loss_scaling` a la valeur de `1.0`, et `dynamic_loss_scaling` a la valeur `False`. Si vous définissez `dynamic_loss_scale=True`, vous pouvez introduire les options de mise à l'échelle dynamique des pertes sous forme de dictionnaire via l'argument `dynamic_loss_args`. Dans la plupart des cas, nous vous recommandons d'utiliser l'échelle dynamique de perte avec les options par défaut. [Pour plus d'informations, d'options et d'exemples de la fonction wrapper de l'optimiseur, consultez le fichier smdistributed.modelparallel.torch. DistributedOptimizer](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed-modelparallel-torch-distributedoptimizer) API.

   Le code suivant est un exemple d'encapsulation d'un objet d'`Adadelta`optimisation avec une mise à l'échelle dynamique des pertes à des fins d' FP16 entraînement.

   ```
   optimizer = torch.optim.Adadelta(...)
   optimizer = smp.DistributedOptimizer(
       optimizer,
       static_loss_scale=None,
       dynamic_loss_scale=True,
       dynamic_loss_args={
           "scale_window": 1000,
           "min_scale": 1,
           "delayed_shift": 2
       }
   )
   ```

**Configuration d'un SageMaker PyTorch estimateur**

Ajoutez le FP16 paramètre (`"fp16"`) à la configuration de distribution pour le parallélisme du modèle lors de la création d'un objet SageMaker PyTorch estimateur. Pour trouver une liste complète de paramètres de configuration pour le parallélisme de modèle, consultez [les paramètres pour `smdistributed`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#parameters-for-smdistributed).

```
from sagemaker.pytorch import PyTorch

smp_options = {
    "enabled": True,
    "parameters":  {
        "microbatches":  4,
        "pipeline_parallel_degree":  2,
        "tensor_parallel_degree":  2,
        ...,

        "fp16": True
    }
}

fp16_estimator = PyTorch(
    entry_point="fp16_training_script.py", # Specify your train script
    ...,

    distribution={
        "smdistributed": {"modelparallel": smp_options},
        "mpi": {...}
    }
)

fp16_estimator.fit(...)
```

Lorsque l' FP16 entraînement commence, le modèle et l'optimiseur sont `FP16_Optimizer` respectivement encapsulés par `FP16_Module` des `smdistributed` versions modifiées des [utilitaires Apex](https://nvidia.github.io/apex/fp16_utils.html#apex-fp16-utils). `FP16_Module`convertit le modèle en FP16 dtype et gère la transmission directe. FP16

**Astuce**  
Vous pouvez appliquer un écrêtage de gradient en appelant `clip_master_grads` avant `optimizer.step`.  

```
optimizer.clip_master_grads(max_norm)     # max_norm(float or int): max norm of the gradients
```

**Astuce**  
Lors de l'utilisation `torch.optim.lr_scheduler` et de la FP16 formation, vous devez passer `optimizer.optimizer` au planificateur LR plutôt qu'à l'optimiseur. Voici l'exemple de code suivant :  

```
from torch.optim.lr_scheduler import StepLR

scheduler = StepLR(
    optimizer.optimizer if smp.state.cfg.fp16 else optimizer,
    step_size=1,
    gamma=args.gamma
)
```

# Support pour FlashAttention
<a name="model-parallel-attention-head-size-for-flash-attention"></a>

Support de FlashAttention est une fonctionnalité de la bibliothèque applicable uniquement au modèle de *transformateur distribué*, qui est un modèle de transformateur intégré [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed-modelparallel-torch-distributedmodel](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed-modelparallel-torch-distributedmodel)pour l'apprentissage parallèle entre modèles. Cette fonctionnalité est également compatible avec [Parallélisme de tenseur](model-parallel-extended-features-pytorch-tensor-parallelism.md). 

La [FlashAttention](https://github.com/HazyResearch/flash-attention)bibliothèque ne prend en charge les modèles que lorsqu'elle `attention_head_size` est définie sur une valeur multiple de 8 et inférieure à 128. Par conséquent, lorsque vous entraînez un transformateur distribué et que vous vous assurez qu'il FlashAttention fonctionne correctement, vous devez ajuster les paramètres pour que la taille de la tête d'attention soit conforme aux exigences. Pour plus d'informations, voir également [Installation et fonctionnalités](https://github.com/HazyResearch/flash-attention#installation-and-features) du *FlashAttention GitHubréférentiel*.

Supposons, par exemple, que vous configurez un modèle Transformer avec `hidden_width=864` et `num_heads=48`. La taille de la tête de FlashAttention est calculée comme suit`attention_head_size = hidden_width / num_heads = 864 / 48 = 18`. Pour l'activer FlashAttention, vous devez ajuster le `num_heads` paramètre à`54`, de sorte que`attention_head_size = hidden_width / num_heads = 864 / 54 = 16`, soit un multiple de 8.

# Exécutez un travail de formation SageMaker distribué avec Model Parallelism
<a name="model-parallel-use-api"></a>

Apprenez à exécuter une tâche d'entraînement parallèle à un modèle à partir de votre propre script d'entraînement à l'aide du SDK SageMaker Python associé à la bibliothèque de parallélisme des SageMaker modèles.

Il existe trois scénarios d'utilisation pour exécuter une tâche de SageMaker formation.

1. Vous pouvez utiliser l'un des conteneurs d'apprentissage AWS profond prédéfinis pour TensorFlow et PyTorch. Cette option est recommandée si c'est la première fois que vous utilisez la bibliothèque de parallélisme de modèles. Pour trouver un didacticiel expliquant comment exécuter une tâche d'entraînement parallèle sur des SageMaker modèles, consultez les exemples de carnets de notes présentés lors de l'[PyTorch entraînement avec la bibliothèque de parallélisme de modèles d'Amazon SageMaker AI](https://github.com/aws/amazon-sagemaker-examples/tree/main/training/distributed_training/pytorch/model_parallel).

1. Vous pouvez étendre les conteneurs prédéfinis pour gérer toute exigence fonctionnelle supplémentaire pour votre algorithme ou modèle que l'image SageMaker Docker prédéfinie ne prend pas en charge. Pour apprendre comment étendre un conteneur préconçu, consultez [Extension d’un conteneur préconçu](prebuilt-containers-extend.md).

1. Vous pouvez adapter votre propre conteneur Docker pour qu'il fonctionne avec l' SageMaker IA à l'aide de la boîte à [outils de SageMaker formation](https://github.com/aws/sagemaker-training-toolkit). Pour obtenir un exemple, consultez [Adaptation de votre propre conteneur d'entraînement](https://docs.aws.amazon.com/sagemaker/latest/dg/adapt-training-container.html).

Pour les options 2 et 3 de la liste précédente, consultez [Étendre un conteneur Docker prédéfini qui contient SageMaker la bibliothèque parallèle de modèles distribués](model-parallel-sm-sdk.md#model-parallel-customize-container) pour savoir comment installer la bibliothèque de modèles parallèles dans un conteneur Docker étendu ou personnalisé. 

Dans tous les cas, vous lancez votre tâche de formation en configurant un `PyTorch` estimateur SageMaker `TensorFlow` ou un estimateur pour activer la bibliothèque. Pour en savoir plus, consultez les rubriques suivantes.

**Topics**
+ [Étape 1 : Modifiez votre propre script d'entraînement à l'aide SageMaker de la bibliothèque parallèle de modèles distribués](model-parallel-customize-training-script.md)
+ [Étape 2 : Lancer un job de formation à l'aide du SDK SageMaker Python](model-parallel-sm-sdk.md)

# Étape 1 : Modifiez votre propre script d'entraînement à l'aide SageMaker de la bibliothèque parallèle de modèles distribués
<a name="model-parallel-customize-training-script"></a>

Utilisez cette section pour apprendre à personnaliser votre script de formation afin d'utiliser les fonctionnalités principales de la bibliothèque de parallélisme de modèles Amazon SageMaker AI. Pour utiliser les fonctions et paramètres d'API spécifiques à la bibliothèque, nous vous recommandons d'utiliser cette documentation en plus de la [bibliothèque SageMaker model parallel APIs](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) dans la documentation du *SDK SageMaker Python*.

Les exemples de script d'entraînement fournis dans ces sections sont simplifiés et conçus pour mettre en évidence les modifications nécessaires à l'utilisation de la bibliothèque. Pour des end-to-end exemples de blocs-notes exécutables qui montrent comment utiliser un script TensorFlow ou un script d' PyTorch apprentissage avec la bibliothèque de parallélisme des SageMaker modèles, voir. [Exemples de bibliothèque de parallélisme de modèles Amazon SageMaker AI v2](distributed-model-parallel-v2-examples.md)

**Topics**
+ [Divisez le modèle de votre script d'entraînement à l'aide de la bibliothèque de parallélisme des SageMaker modèles](#model-parallel-model-splitting-using-smp-lib)
+ [Modifier un script TensorFlow d'entraînement](model-parallel-customize-training-script-tf.md)
+ [Modifier un script PyTorch d'entraînement](model-parallel-customize-training-script-pt.md)

## Divisez le modèle de votre script d'entraînement à l'aide de la bibliothèque de parallélisme des SageMaker modèles
<a name="model-parallel-model-splitting-using-smp-lib"></a>

Il existe deux manières de modifier votre script d'entraînement pour configurer le fractionnement des modèles : le fractionnement automatique ou le fractionnement manuel.

### Fractionnement automatisé du modèle
<a name="model-parallel-automated-model-splitting"></a>

Lorsque vous utilisez SageMaker la bibliothèque de parallélisme des modèles, vous pouvez tirer parti du *fractionnement automatique des modèles*, également appelé partitionnement *automatique* des modèles. La bibliothèque utilise un algorithme de partitionnement qui équilibre la mémoire, réduit la communication entre les périphériques et optimise la performance. Vous pouvez configurer l'algorithme de partitionnement automatique de sorte à optimiser la vitesse ou la mémoire. 

Vous pouvez également utiliser la division manuelle du modèle. Nous vous recommandons la division automatisée du modèle, sauf si vous connaissez très bien l'architecture du modèle et que vous savez déjà comment partitionner efficacement votre modèle.

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

Le partitionnement automatique intervient dès la première étape d'entraînement, lors du tout premier appel de la fonction décorée `smp.step`. Durant cet appel, la bibliothèque commence par créer une version du modèle sur la RAM du CPU (pour éviter les limitations de mémoire GPU), puis elle analyse le graphe du modèle et décide du partitionnement. À partir de cette décision, chaque partition de modèle est chargée sur un GPU, et ce n'est qu'alors que la première étape est exécutée. Ces étapes d'analyse et de partitionnement peuvent contribuer à allonger la première étape de l'entraînement. 

Dans les deux frameworks, la bibliothèque gère la communication entre les appareils via son propre backend, optimisé pour AWS l'infrastructure.

La conception de la partition automatique s'adapte aux caractéristiques du cadre, et la bibliothèque effectue le partitionnement au niveau de granularité le plus naturel dans chaque cadre. Par exemple, dans TensorFlow, chaque opération spécifique peut être affectée à un appareil différent, tandis que dans PyTorch, l'attribution est effectuée au niveau du module, où chaque module comprend plusieurs opérations. La section qui suit examine les spécificités de conception dans chaque cadre.

##### Découpage automatique des modèles avec PyTorch
<a name="model-parallel-auto-model-split-pt"></a>

Durant la première étape d'entraînement, la bibliothèque de parallélisme de modèles exécute en interne une étape de traçage destinée à créer le graphe du modèle et à déterminer les formes du tenseur et des paramètres. Après cette étape de traçage, la bibliothèque crée un arbre, qui se compose des objets `nn.Module` imbriqués dans le modèle, ainsi que de données supplémentaires collectées à partir du traçage, comme la quantité de `nn.Parameters` stockés et le temps d'exécution de chaque `nn.Module`. 

Ensuite, la bibliothèque traverse cet arbre depuis la racine et exécute un algorithme de partitionnement qui affecte chaque `nn.Module` à un périphérique, ce qui équilibre la charge de calcul (mesurée par le temps d'exécution du module) et l'utilisation de la mémoire (mesurée par la taille totale des `nn.Parameter` stockés et les activations). Si plusieurs `nn.Modules` partagent le même `nn.Parameter`, ces modules sont alors placés sur le même périphérique afin de ne pas conserver plusieurs versions du même paramètre. Une fois la décision de partitionnement prise, les modules et les poids affectés sont chargés sur leurs périphériques.

Pour obtenir des instructions sur la façon d'enregistrer le `smp.step` décorateur dans votre script d' PyTorch entraînement, reportez-vous [Fractionnement automatique avec PyTorch](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16) à.

##### Découpage automatique des modèles avec TensorFlow
<a name="model-parallel-auto-model-split-tf"></a>

La bibliothèque de parallélisme de modèles analyse les tailles des variables entraînables et la structure du graphe, et utilise en interne un algorithme de partitionnement des graphes. Cet algorithme affecte un périphérique pour chaque opération afin de réduire le volume de communication nécessaire entre les périphériques, sous réserve des deux contraintes suivantes : 
+ Équilibrage du nombre de variables stockées dans chaque périphérique
+ Équilibrage du nombre d'opérations exécutées dans chaque périphérique

Si vous spécifiez `speed` pour `optimize` (dans les paramètres de parallélisme de modèles dans le kit SDK Python), la bibliothèque essaie d'équilibrer le nombre d'opérations et d'objets `tf.Variable` dans chaque périphérique. Sinon, elle essaie d'équilibrer la taille totale de `tf.Variables`.

Une fois la décision de partitionnement prise, la bibliothèque crée une représentation sérialisée du sous-graphe que chaque périphérique doit exécuter et l'importe sur chaque périphérique. Lors du partitionnement, la bibliothèque place les opérations qui consomment la même `tf.Variable` et les opérations qui font partie de la même couche Keras sur le même périphérique. Il respecte également les contraintes de colocation imposées par TensorFlow. Cela signifie, par exemple, que si deux couches Keras partagent une `tf.Variable`, toutes les opérations qui font partie de ces couches sont placées sur un seul périphérique.

Pour obtenir des instructions sur la façon d'enregistrer le `smp.step` décorateur dans votre script d' PyTorch entraînement, reportez-vous [Fractionnement automatique avec TensorFlow](model-parallel-customize-training-script-tf.md#model-parallel-customize-training-script-tf-23) à.

##### Comparaison du fractionnement automatisé du modèle entre les frameworks
<a name="model-parallel-auto-model-split-comparison"></a>

Dans TensorFlow, l'unité fondamentale de calcul est a`tf.Operation`, et TensorFlow représente le modèle sous la forme d'un graphe acyclique dirigé (DAG) de `tf.Operation` s. Par conséquent, la bibliothèque de parallélisme du modèle partitionne ce DAG de telle sorte que chaque nœud soit attribué à un périphérique. Ce qui est intéressant ici est que les objets `tf.Operation` sont suffisamment riches en attributs personnalisables et qu'ils sont universels, c'est-à-dire que chaque modèle comprendra obligatoirement un graphe de ces objets. 

PyTorch d'autre part, n'a pas une notion de fonctionnement équivalente suffisamment riche et universelle. L'unité de calcul la plus proche présentant ces caractéristiques est un`nn.Module`, qui se trouve à un niveau de granularité beaucoup plus élevé, et c'est pourquoi la bibliothèque effectue le partitionnement à ce niveau dans. PyTorch PyTorch

### Division manuelle du modèle
<a name="model-parallel-manual-model-splitting"></a>

Si vous voulez spécifier manuellement le partitionnement de votre modèle entre les dispositifs, utilisez le gestionnaire de contexte `smp.partition`. Pour obtenir des instructions sur le partitionnement manuel du gestionnaire de contexte, consultez les pages suivantes.
+ [Découpage manuel avec TensorFlow](model-parallel-customize-training-script-tf.md#model-parallel-customize-training-script-tf-manual)
+ [Découpage manuel avec PyTorch](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16-hvd)

Pour utiliser cette option après avoir apporté des modifications, à l'étape 2, vous devez `auto_partition` définir `False` et définir a `default_partition` dans la classe d'estimateur du SDK SageMaker Python. Toute opération non explicitement placée sur une partition à l'aide du gestionnaire de contexte de `smp.partition` est exécutée sur la `default_partition`. Dans ce cas, la logique de division automatisée est contournée et chaque opération est placée de la façon dont vous le spécifiez. En s'appuyant sur la structure de graphe ainsi obtenue, la bibliothèque de parallélisme de modèles crée automatiquement un calendrier d'exécution de pipeline.

# Modifier un script TensorFlow d'entraînement
<a name="model-parallel-customize-training-script-tf"></a>

Dans cette section, vous apprendrez à modifier les scripts d' TensorFlow apprentissage afin de configurer la bibliothèque de parallélisme des SageMaker modèles pour le partitionnement automatique et le partitionnement manuel. Cette sélection d'exemples inclut également un exemple intégré à Horovod pour le modèle hybride et le parallélisme des données.

**Note**  
Pour connaître les TensorFlow versions prises en charge par la bibliothèque, consultez[Frameworks pris en charge et Régions AWS](distributed-model-parallel-support.md).

Les modifications que vous devez apporter à votre script d'entraînement pour utiliser la bibliothèque sont répertoriées dans [Fractionnement automatique avec TensorFlow](#model-parallel-customize-training-script-tf-23).

Pour savoir comment modifier votre script d'entraînement pour utiliser un modèle hybride et le parallélisme de données avec Horovod, consultez [Division automatisée avec Horovod TensorFlow et Horovod pour le parallélisme des modèles hybrides et des données](#model-parallel-customize-training-script-tf-2.3).

Si vous optez pour le partitionnement manuel, consultez également [Découpage manuel avec TensorFlow](#model-parallel-customize-training-script-tf-manual). 

Les rubriques suivantes présentent des exemples de scripts de formation que vous pouvez utiliser pour configurer la bibliothèque SageMaker de parallélisme des modèles pour le partitionnement automatique et les modèles de partitionnement manuel. TensorFlow 

**Note**  
Le partitionnement automatique est activé par défaut. Sauf indication contraire, les exemples de scripts utilisent le partitionnement automatique.

**Topics**
+ [Fractionnement automatique avec TensorFlow](#model-parallel-customize-training-script-tf-23)
+ [Division automatisée avec Horovod TensorFlow et Horovod pour le parallélisme des modèles hybrides et des données](#model-parallel-customize-training-script-tf-2.3)
+ [Découpage manuel avec TensorFlow](#model-parallel-customize-training-script-tf-manual)
+ [Fonctionnalités de framework non prises en charge](#model-parallel-tf-unsupported-features)

## Fractionnement automatique avec TensorFlow
<a name="model-parallel-customize-training-script-tf-23"></a>

Les modifications de script d'entraînement suivantes sont nécessaires pour exécuter un TensorFlow modèle avec SageMaker la bibliothèque de parallélisme des modèles :

1. Importez et initialisez la bibliothèque avec [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. Définissez un modèle Keras en héritant de [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) au lieu de la classe de modèles Keras. Renvoyez les sorties du modèle à partir de la méthode d'appel de l'objet `smp.DistributedModel`. N'oubliez pas que tous les tenseurs renvoyés par la méthode d'appel seront diffusés sur des périphériques avec parallélisme des modèles. Comme cela induira un surdébit de communication, évitez de renvoyer les tenseurs qui ne sont pas nécessaires en dehors de la méthode d'appel (activations intermédiaires, par exemple).

1. Définissez `drop_remainder=True` dans la méthode `tf.Dataset.batch()`. Cela vise à garantir que la taille du lot est toujours divisible par le nombre de micro-lots.

1. Ensemencez les opérations aléatoires dans le pipeline de données en utilisant`smp.dp_rank()`, par exemple, `shuffle(ds, seed=smp.dp_rank())` pour garantir la cohérence des échantillons de données GPUs contenant différentes partitions de modèles.

1. Mettez la logique en avant et en arrière dans une fonction étape et décorez-la avec `smp.step`.

1. Effectuez un post-traitement sur les sorties des différents micro-lots à l'aide de méthodes [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) telles que `reduce_mean`. La fonction [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) doit avoir une valeur de retour qui dépend de la sortie de `smp.DistributedModel`.

1. De façon similaire, s'il y a une étape d'évaluation, placez la logique en avant dans une fonction décorée `smp.step` et post-traitez les sorties en utilisant l'[API `StepOutput`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput).

Pour en savoir plus sur l'API SageMaker de la bibliothèque de parallélisme des modèles, consultez la documentation de l'[API](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html). 

Le script Python suivant est un exemple de script d'entraînement après application des modifications.

```
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()
```

Si vous avez fini de préparer votre scénario d'entraînement, passez à [Étape 2 : Lancer un job de formation à l'aide du SDK SageMaker Python](model-parallel-sm-sdk.md). Si vous souhaitez exécuter une tâche d'entraînement parallèle modèle et données hybride, passez à la section suivante.

## Division automatisée avec Horovod TensorFlow et Horovod pour le parallélisme des modèles hybrides et des données
<a name="model-parallel-customize-training-script-tf-2.3"></a>

Vous pouvez utiliser la bibliothèque de parallélisme de SageMaker modèles avec Horovod pour le parallélisme de modèles hybrides et de données. Pour en savoir plus sur la façon dont la bibliothèque divise un modèle pour le parallélisme hybride, reportez-vous à [Parallélisme du pipeline (disponible pour PyTorch et) TensorFlow](model-parallel-intro.md#model-parallel-intro-pp).

Dans cette étape, nous nous concentrons sur la manière de modifier votre script d'entraînement afin d'adapter la bibliothèque de parallélisme du SageMaker modèle.

Pour configurer correctement votre script d'entraînement afin qu'il prenne en compte la configuration du parallélisme hybride que vous définirez dans [Étape 2 : Lancer un job de formation à l'aide du SDK SageMaker Python](model-parallel-sm-sdk.md), utilisez les fonctions d'aide de la bibliothèque, `smp.dp_rank()` et `smp.mp_rank()`, qui détectent automatiquement le rang parallèle des données et le rang parallèle du modèle, respectivement. 

Pour trouver toutes les primitives MPI prises en charge par la bibliothèque, consultez les [bases du MPI dans la documentation](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#mpi-basics) du SDK SageMaker Python. 

Les modifications à apporter au script sont les suivantes :
+ Ajouter `hvd.allreduce`
+ Diffuser des variables après le premier lot, comme l'exige Horovod
+ Seeding, shuffling, sharding, opérations de and/or sharding dans le pipeline de données avec. `smp.dp_rank()`

**Note**  
Lorsque vous utilisez Horovod, vous ne devez pas faire appel directement à `hvd.init` dans votre script d'entraînement. Au lieu de cela, vous devrez le `"horovod"` définir `True` dans les `modelparallel` paramètres du SDK SageMaker Python dans[Étape 2 : Lancer un job de formation à l'aide du SDK SageMaker Python](model-parallel-sm-sdk.md). Cela permet à la bibliothèque d'initialiser Horovod en interne en se basant sur les affectations de périphériques des partitions du modèle. Le fait d'appeler directement `hvd.init()` dans votre script d'entraînement peut poser des problèmes.

**Note**  
L'utilisation de l'API `hvd.DistributedOptimizer` directement dans votre script d'entraînement peut entraîner une baisse des performances et de la vitesse d'entraînement, car l'API place implicitement l'opération `AllReduce` à l'intérieur de `smp.step`. Nous vous recommandons d'utiliser la bibliothèque de parallélisme de modèles avec Horovod en appelant directement `hvd.allreduce` après l'appel à `accumulate()` ou à `reduce_mean()` sur les gradients retournés par `smp.step`, comme le montre l'exemple suivant.

Pour en savoir plus sur l'API SageMaker de la bibliothèque de parallélisme des modèles, consultez la documentation de l'[API](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))
```

## Découpage manuel avec TensorFlow
<a name="model-parallel-customize-training-script-tf-manual"></a>

Utilisez les gestionnaires de contexte `smp.partition` pour placer les opérations dans une partition spécifique. Toute opération non placée dans un contexte `smp.partition` est placée dans le `default_partition`. Pour en savoir plus sur l'API SageMaker de la bibliothèque de parallélisme des modèles, consultez la documentation de l'[API](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()
```

## Fonctionnalités de framework non prises en charge
<a name="model-parallel-tf-unsupported-features"></a>

Les TensorFlow fonctionnalités suivantes ne sont pas prises en charge par la bibliothèque :
+ `tf.GradientTape()` n'est pas prise en charge pour le moment. À la place, vous pouvez utiliser `Optimizer.get_gradients()` ou `Optimizer.compute_gradients()` pour calculer les gradients.
+ L'API `tf.train.Checkpoint.restore()` n'est pas prise en charge pour le moment. Pour le pointage, utilisez `smp.CheckpointManager`, qui fournit la même API et la même fonctionnalité. Les restaurations de point de contrôle avec `smp.CheckpointManager` doivent intervenir après la première étape.

# Modifier un script PyTorch d'entraînement
<a name="model-parallel-customize-training-script-pt"></a>

Dans cette section, vous apprendrez à modifier les scripts d' PyTorch apprentissage afin de configurer la bibliothèque de parallélisme des SageMaker modèles pour le partitionnement automatique et le partitionnement manuel.

**Note**  
Pour connaître les PyTorch versions prises en charge par la bibliothèque, consultez[Frameworks pris en charge et Régions AWS](distributed-model-parallel-support.md).

**Astuce**  
Pour obtenir des exemples de end-to-end blocs-notes illustrant l'utilisation d'un script de PyTorch formation avec la bibliothèque de parallélisme des SageMaker modèles, reportez-vous à. [Exemples de bibliothèque de parallélisme de modèles Amazon SageMaker AI v1](distributed-model-parallel-examples.md)

Vous noterez que le partitionnement automatique est activé par défaut. Sauf indication contraire, les scripts suivants utilisent le partitionnement automatique. 

**Topics**
+ [Fractionnement automatique avec PyTorch](#model-parallel-customize-training-script-pt-16)
+ [Découpage manuel avec PyTorch](#model-parallel-customize-training-script-pt-16-hvd)
+ [Considérations](#model-parallel-pt-considerations)
+ [Fonctionnalités de framework non prises en charge](#model-parallel-pt-unsupported-features)

## Fractionnement automatique avec PyTorch
<a name="model-parallel-customize-training-script-pt-16"></a>

Les modifications de script d'entraînement suivantes sont nécessaires pour exécuter un script d' PyTorch entraînement avec SageMaker la bibliothèque de parallélisme des modèles :

1. Importez et initialisez la bibliothèque avec [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. Enveloppez le modèle avec [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). N'oubliez pas que tous les tenseurs renvoyés par la méthode `forward` de l'objet `nn.Module` sous-jacent seront diffusés sur des périphériques avec parallélisme des modèles. Comme cela induira un surdébit de communication, évitez de renvoyer les tenseurs qui ne sont pas nécessaires en dehors de la méthode d'appel (activations intermédiaires, par exemple).
**Note**  
Pour la FP16 formation, vous devez utiliser le gestionnaire de contexte [smdistributed.modelparallel.torch.model\$1creation () pour encapsuler](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html) le modèle. Pour de plus amples informations, veuillez consulter [FP16 Entraînement avec le parallélisme des modèles](model-parallel-extended-features-pytorch-fp16.md).

1. Enveloppez l'optimiseur avec [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).
**Note**  
Pour l' FP16 entraînement, vous devez configurer une échelle statique ou dynamique des pertes. Pour de plus amples informations, veuillez consulter [FP16 Entraînement avec le parallélisme des modèles](model-parallel-extended-features-pytorch-fp16.md).

1. Utilisez l'objet `DistributedModel` renvoyé au lieu d'un modèle utilisateur.

1. Mettez la logique en avant et en arrière dans une fonction étape et décorez-la avec [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. Restreignez chaque processus à son propre périphérique via `torch.cuda.set_device(smp.local_rank())`.

1. Déplacez les tenseurs d'entrée vers le GPU à l'aide de l'API `.to()` avant l'appel `smp.step` (voir l'exemple ci-dessous).

1. Remplacez `torch.Tensor.backward` et `torch.autograd.backward` par `DistributedModel.backward`.

1. Effectuez un post-traitement sur les sorties des différents micro-lots à l'aide de méthodes [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) telles que `reduce_mean`.

1. De façon similaire, s'il y a une étape d'évaluation, placez la logique en avant dans une fonction décorée `smp.step` et post-traitez les sorties en utilisant l'[API `StepOutput`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput).

1. Définissez `drop_last=True` dans `DataLoader`. Vous pouvez également ignorer manuellement un lot dans la boucle d'entraînement si la taille du lot n'est pas divisible par le nombre de micro-lots.

Pour en savoir plus sur l'API SageMaker de la bibliothèque de parallélisme des modèles, consultez la documentation de l'[API](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)
```

## Découpage manuel avec PyTorch
<a name="model-parallel-customize-training-script-pt-16-hvd"></a>

Utilisez les gestionnaires de contexte [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) pour placer les modules dans des périphériques spécifiques. Tout module non placé dans un contexte `smp.partition` est placé dans le `default_partition`. La `default_partition` doit être fournie si `auto_partition` est défini sur `False`. Les modules qui sont créés dans un contexte `smp.partition` spécifique sont placés sur la partition correspondante.

Pour en savoir plus sur l'API SageMaker de la bibliothèque de parallélisme des modèles, consultez la documentation de l'[API](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)
```

## Considérations
<a name="model-parallel-pt-considerations"></a>

Lorsque vous configurez un script d' PyTorch entraînement à l'aide SageMaker de la bibliothèque de parallélisme des modèles, vous devez tenir compte des points suivants :
+ Si vous utilisez une technique d'optimisation reposant sur des normes de gradient globales, par exemple une norme de gradient du modèle tout entier, comme certaines variantes de l'optimiseur LAMB ou de l'écrêtage de gradient global, vous devez rassembler toutes les normes entre toutes les partitions de modèle pour vérifier l'exactitude. Pour ce faire, vous pouvez utiliser les types de données de base de communication de la bibliothèque.
+ Tous les arguments `torch.Tensor` aux méthodes de transmission des modules `nn.Modules` dans votre modèle doivent être utilisés dans le calcul de la sortie du module. En d'autres termes, la bibliothèque ne prend pas en charge le cas où il existe un argument `torch.Tensor` à un module dont la sortie du module ne dépend pas.
+ L'argument à l'appel `smp.DistributedModel.backward()` doit dépendre de toutes les sorties du modèle. En d'autres termes, il ne peut pas y avoir de sortie de l'appel `smp.DistributedModel.forward` qui ne soit pas utilisée dans le calcul du tenseur qui est intégré à l'appel `smp.DistributedModel.backward`.
+ S'il y a des appels `torch.cuda.synchronize()` dans votre code, vous devrez peut-être appeler `torch.cuda.set_device(smp.local_rank())` immédiatement avant l'appel de synchronisation. Sinon, des contextes CUDA inutiles pourraient être créés dans le périphérique 0, ce qui consommerait de la mémoire inutilement.
+ Comme la bibliothèque place `nn.Modules` sur différents périphériques, les modules du modèle ne doivent pas dépendre d'un état global modifié dans `smp.step`. Tout état qui reste fixe durant tout l'entraînement, ou qui est modifié en dehors de `smp.step` d'une manière visible par tous les processus, est autorisé.
+ Lorsque vous utilisez la bibliothèque, vous n'avez pas besoin de déplacer le modèle vers le GPU (par exemple, en utilisant `model.to(device)`). Si vous essayez de déplacer le modèle vers le GPU avant la partition du modèle (avant le premier appel `smp.step`), l'appel de déplacement est ignoré. La bibliothèque déplace automatiquement la partie du modèle affectée à un rang, vers son GPU. Une fois que l'entraînement avec la bibliothèque démarre, ne déplacez pas le modèle vers le CPU et ne l'utilisez pas, car il ne contiendra pas des paramètres corrects pour les modules non affectés à la partition maintenue par le processus. Si vous souhaitez réentraîner un modèle ou l'utiliser à des fins d'inférence sans la bibliothèque après l'avoir entraîné à l'aide de la bibliothèque de parallélisme des modèles, la méthode recommandée est d'enregistrer le modèle complet à l'aide de notre API de point de contrôle et de le charger à nouveau dans un module normal. PyTorch 
+ Si vous avez une liste de modules telle que la sortie de l'un en alimente un autre, vous pouvez améliorer la performance de façon significative en remplaçant cette liste par `nn.Sequential`.
+ La mise à jour du poids (`optimizer.step()`) doit se produire en dehors de `smp.step` car c'est à ce moment que la transmission vers l'arrière est entièrement terminée et que les gradients sont prêts. Lors de l'utilisation d'un modèle hybride avec parallélisme des modèles et des données, à ce stade, AllReduce la fin des dégradés est également garantie.
+ Lorsque vous utilisez la bibliothèque en combinaison avec le parallélisme des données, assurez-vous que le nombre de lots sur tous les classements data parallel est le même afin de AllReduce ne pas attendre un rang qui ne participe pas à l'étape.
+ Si vous lancez une tâche d'entraînement à l'aide d'un type d'instance ml.p4d (tel que ml.p4d.24xlarge), vous devez définir la variable `num_workers=0` du chargeur de données. Par exemple, vous pouvez définir votre `DataLoader` de la façon suivante :

  ```
  dataloader = torch.utils.data.DataLoader(
              data,
              batch_size=batch_size,
              num_workers=0,
              pin_memory=True,
              drop_last=True,
              shuffle=shuffle,
          )
  ```
+ Les entrées de `smp.step` doivent être les entrées de modèle générées par le `DataLoader`. En effet, `smp.step` divise en interne les tenseurs d'entrée sur toute la dimension du lot et les exécute en pipeline. Transmettre le `DataLoader` lui-même à la fonction `smp.step` pour générer les entrées de modèle à l'intérieur ne fonctionne donc pas. 

  Par exemple, si vous définissez un `DataLoader` de la façon suivante :

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

  Vous devez accéder aux entrées de modèle générées par le `train_loader` et les transmettre à une fonction décorée `smp.step`. Ne faites pas transmettre le `train_loader` directement à `smp.step`.

  ```
  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
  ```
+ Les tenseurs d'entrée à `smp.step` doivent être déplacés vers le périphérique actuel à l'aide de l'API `.to()`, et cela après l'appel `torch.cuda.set_device(local_rank())`.

  Par exemple, vous pouvez définir la fonction `train` de la façon suivante. Cette fonction ajoute `data` et `target` sur le périphérique actuel à l'aide de l'API `.to()` avant d'utiliser ces tenseurs d'entrée pour appeler `train_step`.

  ```
  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()
  ```

  Dans la fonction `train` ci-dessus, les tenseurs d'entrée de cette fonction décorée `smp.set` ont été déplacés vers le périphérique actuel. Le modèle *ne doit pas* être déplacé vers le périphérique actuel. La bibliothèque déplace automatiquement la partie du modèle affectée à un rang, vers son 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
  ```

## Fonctionnalités de framework non prises en charge
<a name="model-parallel-pt-unsupported-features"></a>

Les PyTorch fonctionnalités suivantes ne sont pas prises en charge par SageMaker la bibliothèque de parallélisme des modèles :
+ Si vous utilisez le parallélisme des données avec le [PyTorch DDP](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html) natif, le module [https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html](https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html)wrapper n'est pas pris en charge par la bibliothèque. La bibliothèque gère en interne l'intégration au PyTorch DDP, y compris la diffusion des paramètres et le gradient AllReduce. Lors de l'utilisation de la bibliothèque, les tampons de module ne sont diffusés qu'une seule fois au début de l'entraînement. Si votre modèle possède des tampons de module qui doivent être synchronisés entre des groupes de données parallèles à chaque étape, vous pouvez le faire à l'aide de l'API `torch.distributed`, en utilisant le groupe de processus qui peut être obtenu via `smp.get_dp_process_group()`.
+ Pour l'entraînement de précision mixte, le module `apex.amp` n'est pas pris en charge. Nous vous recommandons d'utiliser la bibliothèque avec une précision mixte automatique en utilisant `torch.cuda.amp`, à la seule exception d'utiliser `smp.amp.GradScaler` au lieu de la mise en œuvre dans Torch.
+ `torch.jit.ScriptModules` ou `ScriptFunctions` ne sont pas pris en charge par `smp.DistributedModel`.
+ `apex` : `FusedLayerNorm`, `FusedAdam`, `FusedLAMB` et `FusedNovoGrad` de `apex` ne sont pas pris en charge. Vous pouvez utiliser les implémentations de ces bibliothèques par le biais `smp.optimizers` et à la `smp.nn` APIs place.

# Étape 2 : Lancer un job de formation à l'aide du SDK SageMaker Python
<a name="model-parallel-sm-sdk"></a>

Le SDK SageMaker Python prend en charge l'entraînement géré des modèles avec des frameworks ML tels que TensorFlow et PyTorch. Pour lancer une tâche de formation à l'aide de l'un de ces frameworks, vous devez définir un SageMaker [TensorFlow estimateur, un estimateur ou](https://sagemaker.readthedocs.io/en/v2.199.0/frameworks/tensorflow/sagemaker.tensorflow.html#tensorflow-estimator) un SageMaker [PyTorch estimateur](https://sagemaker.readthedocs.io/en/v2.199.0/frameworks/pytorch/sagemaker.pytorch.html#pytorch-estimator) SageMaker générique pour utiliser le script de formation modifié et [modéliser](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/estimators.html#sagemaker.estimator.Estimator) la configuration du parallélisme.

**Topics**
+ [Utilisation des SageMaker TensorFlow PyTorch estimateurs et](#model-parallel-using-sagemaker-pysdk)
+ [Étendre un conteneur Docker prédéfini qui contient SageMaker la bibliothèque parallèle de modèles distribués](#model-parallel-customize-container)
+ [Créez votre propre conteneur Docker avec la bibliothèque parallèle de modèles SageMaker distribués](#model-parallel-bring-your-own-container)

## Utilisation des SageMaker TensorFlow PyTorch estimateurs et
<a name="model-parallel-using-sagemaker-pysdk"></a>

Les classes TensorFlow et PyTorch estimator contiennent le `distribution` paramètre, que vous pouvez utiliser pour spécifier des paramètres de configuration pour l'utilisation de frameworks d'apprentissage distribués. La bibliothèque SageMaker model parallel utilise en interne MPI pour les données hybrides et le parallélisme des modèles. Vous devez donc utiliser l'option MPI avec la bibliothèque.

Le modèle d' PyTorch estimateur TensorFlow or suivant montre comment configurer le `distribution` paramètre d'utilisation de la bibliothèque model parallel SageMaker avec MPI.

------
#### [ Using the SageMaker TensorFlow estimator ]

```
import sagemaker
from sagemaker.tensorflow import TensorFlow

smp_options = {
    "enabled":True,              # Required
    "parameters": {
        "partitions": 2,         # Required
        "microbatches": 4,
        "placement_strategy": "spread",
        "pipeline": "interleaved",
        "optimize": "speed",
        "horovod": True,         # Use this for hybrid model and data parallelism
    }
}

mpi_options = {
    "enabled" : True,            # Required
    "processes_per_host" : 8,    # Required
    # "custom_mpi_options" : "--mca btl_vader_single_copy_mechanism none"
}

smd_mp_estimator = TensorFlow(
    entry_point="your_training_script.py", # Specify your train script
    source_dir="location_to_your_script",
    role=sagemaker.get_execution_role(),
    instance_count=1,
    instance_type='ml.p3.16xlarge',
    framework_version='2.6.3',
    py_version='py38',
    distribution={
        "smdistributed": {"modelparallel": smp_options},
        "mpi": mpi_options
    },
    base_job_name="SMD-MP-demo",
)

smd_mp_estimator.fit('s3://my_bucket/my_training_data/')
```

------
#### [ Using the SageMaker PyTorch estimator ]

```
import sagemaker
from sagemaker.pytorch import PyTorch

smp_options = {
    "enabled":True,
    "parameters": {                        # Required
        "pipeline_parallel_degree": 2,     # Required
        "microbatches": 4,
        "placement_strategy": "spread",
        "pipeline": "interleaved",
        "optimize": "speed",
        "ddp": True,
    }
}

mpi_options = {
    "enabled" : True,                      # Required
    "processes_per_host" : 8,              # Required
    # "custom_mpi_options" : "--mca btl_vader_single_copy_mechanism none"
}

smd_mp_estimator = PyTorch(
    entry_point="your_training_script.py", # Specify your train script
    source_dir="location_to_your_script",
    role=sagemaker.get_execution_role(),
    instance_count=1,
    instance_type='ml.p3.16xlarge',
    framework_version='1.13.1',
    py_version='py38',
    distribution={
        "smdistributed": {"modelparallel": smp_options},
        "mpi": mpi_options
    },
    base_job_name="SMD-MP-demo",
)

smd_mp_estimator.fit('s3://my_bucket/my_training_data/')
```

------

Pour activer la bibliothèque, vous devez transmettre des dictionnaires de configuration aux `"mpi"` clés `"smdistributed"` et via l'`distribution`argument des constructeurs de l' SageMaker estimateur.

**Paramètres de configuration pour le parallélisme SageMaker du modèle**
+ Pour la clé `"smdistributed"`, transmettez un dictionnaire avec la clé `"modelparallel"` et les dictionnaires internes suivants. 
**Note**  
L'utilisation de `"modelparallel"` et `"dataparallel"` dans la même tâche d'entraînement n'est pas pris en charge. 
  + `"enabled"` : obligatoire. Pour activer le parallélisme des modèles, définissez `"enabled": True`.
  + `"parameters"` : obligatoire. Spécifiez un ensemble de paramètres pour le parallélisme SageMaker du modèle.
    + Pour une liste complète des paramètres courants, consultez la section [Paramètres pour `smdistributed`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#smdistributed-parameters) dans la *documentation du SDK SageMaker Python*.

      Pour TensorFlow, voir [Paramètres TensorFlow spécifiques](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#tensorflow-specific-parameters).

      Pour PyTorch, voir [Paramètres PyTorch spécifiques](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#pytorch-specific-parameters).
    + `"pipeline_parallel_degree"` (ou `"partitions"` dans `smdistributed-modelparallel<v1.6.0`) — obligatoire. Parmi les [paramètres de `smdistributed`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#smdistributed-parameters), ce paramètre est nécessaire pour spécifier le nombre de partitions de modèle dans lesquelles vous souhaitez effectuer la répartition.
**Important**  
Il y a une modification avec rupture dans le nom du paramètre. Le paramètre `"pipeline_parallel_degree"` remplace les `"partitions"` depuis la v1.6.0 de `smdistributed-modelparallel`. Pour plus d'informations, consultez la section [Paramètres communs](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#common-parameters) pour la configuration SageMaker du parallélisme des modèles et les [notes de version de SageMaker Distributed Model Parallel](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_release_notes/smd_model_parallel_change_log.html) dans la documentation du *SDK SageMaker Python*.
+ Pour la clé `"mpi"`, transmettez un dictionnaire contenant les éléments suivants :
  + `"enabled"` : obligatoire. Permet à `True` de lancer la tâche d'entraînement distribuée avec MPI.
  + `"processes_per_host"` : obligatoire. Spécifiez le nombre de processus que la MPI doit lancer sur chaque hôte. Dans l' SageMaker IA, un hôte est une instance Amazon EC2 ML unique. Le SDK SageMaker Python assure un one-to-one mappage entre les processus et GPUs entre le parallélisme des modèles et des données. Cela signifie que l' SageMaker IA planifie chaque processus sur un seul GPU distinct et qu'aucun GPU ne contient plus d'un processus. Si vous utilisez PyTorch, vous devez limiter chaque processus à son propre appareil`torch.cuda.set_device(smp.local_rank())`. Pour en savoir plus, veuillez consulter la section [Fractionnement automatique avec PyTorch](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16).
**Important**  
 `process_per_host`ne *doit* pas être supérieur au nombre de GPUs par instance et sera généralement égal au nombre de GPUs par instance.
  + `"custom_mpi_options"` (obligatoire) : utilisez cette clé pour transmettre toutes les options MPI personnalisées dont vous pouvez avoir besoin. Si vous ne transmettez aucune option personnalisée MPI à la clé, l'option MPI est définie par défaut sur l'indicateur suivant.

    ```
    --mca btl_vader_single_copy_mechanism none
    ```
**Note**  
Vous n'avez pas besoin de spécifier explicitement cet indicateur par défaut à la clé. Si vous le spécifiez explicitement, votre tâche d'entraînement parallèle de modèle distribué peut échouer avec l'erreur suivante :  

    ```
    The following MCA parameter has been listed multiple times on the command line: 
    MCA param: btl_vader_single_copy_mechanism MCA parameters can only be listed once 
    on a command line to ensure there is no ambiguity as to its value. 
    Please correct the situation and try again.
    ```
**Astuce**  
Si vous lancez une tâche d'entraînement à l'aide d'un type d'instance compatible EFA, tel que `ml.p4d.24xlarge` et `ml.p3dn.24xlarge`, utilisez l'indicateur suivant pour de meilleures performances :  

    ```
    -x FI_EFA_USE_DEVICE_RDMA=1 -x FI_PROVIDER=efa -x RDMAV_FORK_SAFE=1
    ```

Pour lancer la tâche d'entraînement à l'aide de l'estimateur et du script d'entraînement configuré en SageMaker parallèle de votre modèle, exécutez la `estimator.fit()` fonction.

Utilisez les ressources suivantes pour en savoir plus sur l'utilisation des fonctionnalités de parallélisme des modèles dans le SDK SageMaker Python :
+ [Utilisation TensorFlow avec le SDK SageMaker Python](https://sagemaker.readthedocs.io/en/v2.199.0/frameworks/tensorflow/using_tf.html)
+ [Utilisation PyTorch avec le SDK SageMaker Python](https://sagemaker.readthedocs.io/en/v2.199.0/frameworks/pytorch/using_pytorch.html)
+ Nous vous recommandons d'utiliser une instance de SageMaker bloc-notes si vous êtes de nouveaux utilisateurs. Pour voir un exemple de la façon dont vous pouvez lancer une tâche de formation à l'aide d'une instance de SageMaker bloc-notes, consultez[Exemples de bibliothèque de parallélisme de modèles Amazon SageMaker AI v2](distributed-model-parallel-v2-examples.md).
+ Vous pouvez également envoyer une tâche d'entraînement distribué à partir de votre machine en utilisant AWS CLI. Pour effectuer AWS CLI la configuration sur votre machine, consultez les sections [Configurer vos AWS informations d'identification et Région pour le développement](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html).

## Étendre un conteneur Docker prédéfini qui contient SageMaker la bibliothèque parallèle de modèles distribués
<a name="model-parallel-customize-container"></a>

Pour étendre un conteneur prédéfini et utiliser SageMaker sa bibliothèque de modèles de parallélisme, vous devez utiliser l'une des images AWS Deep Learning Containers (DLC) disponibles pour ou. PyTorch TensorFlow La bibliothèque de parallélisme des SageMaker modèles est incluse dans les images DLC TensorFlow (2.3.0 et versions ultérieures) et PyTorch (1.6.0 et versions ultérieures) avec CUDA (). `cuxyz` Pour obtenir la liste complète des images des DLC, consultez la section Images [Deep Learning Containers disponibles](https://github.com/aws/deep-learning-containers/blob/master/available_images.md) dans le * GitHub référentiel AWS Deep Learning Containers*.

**Astuce**  
Nous vous recommandons d'utiliser l'image contenant la dernière version TensorFlow ou d'accéder PyTorch à la version la plus récente de la up-to-date bibliothèque de parallélisme de SageMaker modèles.

Par exemple, votre Dockerfile devrait contenir une instruction `FROM` similaire à la suivante :

```
# Use the SageMaker DLC image URI for TensorFlow or PyTorch
FROM aws-dlc-account-id.dkr.ecr.aws-region.amazonaws.com/framework-training:{framework-version-tag}

# Add your dependencies here
RUN ...

ENV PATH="/opt/ml/code:${PATH}"

# this environment variable is used by the SageMaker AI container to determine our user code directory.
ENV SAGEMAKER_SUBMIT_DIRECTORY /opt/ml/code
```

En outre, lorsque vous définissez un TensorFlow estimateur PyTorch or, vous devez le spécifier `entry_point` pour votre script d'entraînement. Il doit être identique au chemin d'accès que celui identifié avec `ENV SAGEMAKER_SUBMIT_DIRECTORY`dans votre Dockerfile. 

**Astuce**  
Vous devez transférer ce conteneur Docker vers Amazon Elastic Container Registry (Amazon ECR) et utiliser l'URI de l'image (`image_uri`) pour définir un estimateur pour l'entraînement. SageMaker Pour de plus amples informations, veuillez consulter [Extension d’un conteneur préconçu](prebuilt-containers-extend.md). 

Une fois que vous avez fini d'héberger le conteneur Docker et d'avoir récupéré l'URI de l'image du conteneur, créez un objet SageMaker `PyTorch` estimateur comme suit. Cet exemple suppose que vous avez déjà défini les `smp_options` et `mpi_options`. 

```
smd_mp_estimator = Estimator(
    entry_point="your_training_script.py",
    role=sagemaker.get_execution_role(),
    instance_type='ml.p3.16xlarge',
    sagemaker_session=sagemaker_session,
    image_uri='your_aws_account_id.dkr.ecr.region.amazonaws.com/name:tag'
    instance_count=1,
    distribution={
        "smdistributed": smp_options,
        "mpi": mpi_options
    },
    base_job_name="SMD-MP-demo",
)

smd_mp_estimator.fit('s3://my_bucket/my_training_data/')
```

## Créez votre propre conteneur Docker avec la bibliothèque parallèle de modèles SageMaker distribués
<a name="model-parallel-bring-your-own-container"></a>

Pour créer votre propre conteneur Docker à des fins de formation et utiliser la bibliothèque SageMaker model parallel, vous devez inclure les dépendances correctes et les fichiers binaires des bibliothèques parallèles SageMaker distribuées dans votre Dockerfile. Cette section fournit l'ensemble minimal de blocs de code que vous devez inclure pour préparer correctement un environnement de SageMaker formation et la bibliothèque model parallel dans votre propre conteneur Docker.

**Note**  
Cette option Docker personnalisée avec la bibliothèque SageMaker model parallel sous forme de binaire n'est disponible que pour PyTorch.

**Pour créer un Dockerfile avec le kit de SageMaker formation et la bibliothèque model parallel**

1. Commencez par l'une des [images de base NVIDIA CUDA](https://hub.docker.com/r/nvidia/cuda).

   ```
   FROM <cuda-cudnn-base-image>
   ```
**Astuce**  
Les images officielles du AWS Deep Learning Container (DLC) sont créées à partir des images de [base NVIDIA CUDA](https://hub.docker.com/r/nvidia/cuda). Nous vous recommandons de consulter les [Dockerfiles officiels de AWS Deep Learning PyTorch Container pour](https://github.com/aws/deep-learning-containers/tree/master/pytorch/training/docker) savoir quelles versions des bibliothèques vous devez installer et comment les configurer. Les Dockerfiles officiels sont complets, testés et gérés par les équipes de service et de SageMaker Deep Learning Container. Dans le lien fourni, choisissez la PyTorch version que vous utilisez, choisissez le dossier CUDA (`cuxyz`) et choisissez le Dockerfile se terminant par ou. `.gpu` `.sagemaker.gpu`

1. Pour configurer un environnement d'entraînement distribué, vous devez installer des logiciels de communication et de mise en réseau, tels que [Elastic Fabric Adapter (EFA)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html), [NVIDIA Collective Communications Library (NCCL)](https://developer.nvidia.com/nccl) et [Open MPI](https://www.open-mpi.org/). Selon les versions PyTorch et CUDA que vous choisissez, vous devez installer des versions compatibles des bibliothèques.
**Important**  
Étant donné que la bibliothèque SageMaker model parallel nécessite la bibliothèque SageMaker data parallel dans les étapes suivantes, nous vous recommandons vivement de suivre les instructions de la section [Créez votre propre conteneur Docker avec la bibliothèque SageMaker AI distributed data parallel library](data-parallel-bring-your-own-container.md) pour configurer correctement un environnement de SageMaker formation pour la formation distribuée.

   Pour plus d'informations sur la configuration de l'EPT avec NCCL et Open MPI, consultez les rubriques [Get started with EFA and MPI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html) (Démarrer avec EFA et MPI) et [Get started with EFA and NCCL](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start-nccl.html) (Démarrer avec EFA et NCCL).

1. Ajoutez les arguments suivants pour spécifier les modules URLs de formation SageMaker distribués pour PyTorch. La bibliothèque SageMaker model parallel nécessite que la bibliothèque SageMaker data parallel utilise le Remote Direct Memory Access (RDMA) entre nœuds.

   ```
   ARG SMD_MODEL_PARALLEL_URL=https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-1.10.0/build-artifacts/2022-02-21-19-26/smdistributed_modelparallel-1.7.0-cp38-cp38-linux_x86_64.whl
   ARG SMDATAPARALLEL_BINARY=https://smdataparallel.s3.amazonaws.com/binary/pytorch/1.10.2/cu113/2022-02-18/smdistributed_dataparallel-1.4.0-cp38-cp38-linux_x86_64.whl
   ```

1. Installez les dépendances requises par la bibliothèque SageMaker model parallel.

   1. Installez la bibliothèque [METIS](http://glaros.dtc.umn.edu/gkhome/metis/metis/overview).

      ```
      ARG METIS=metis-5.1.0
      
      RUN rm /etc/apt/sources.list.d/* \
        && wget -nv http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/${METIS}.tar.gz \
        && gunzip -f ${METIS}.tar.gz \
        && tar -xvf ${METIS}.tar \
        && cd ${METIS} \
        && apt-get update \
        && make config shared=1 \
        && make install \
        && cd .. \
        && rm -rf ${METIS}.tar* \
        && rm -rf ${METIS} \
        && rm -rf /var/lib/apt/lists/* \
        && apt-get clean
      ```

   1. Installez la [bibliothèque du gestionnaire de mémoire RAPIDS](https://github.com/rapidsai/rmm#rmm-rapids-memory-manager). Cela nécessite la version [CMake](https://cmake.org/)3.14 ou une version ultérieure.

      ```
      ARG RMM_VERSION=0.15.0
      
      RUN  wget -nv https://github.com/rapidsai/rmm/archive/v${RMM_VERSION}.tar.gz \
        && tar -xvf v${RMM_VERSION}.tar.gz \
        && cd rmm-${RMM_VERSION} \
        && INSTALL_PREFIX=/usr/local ./build.sh librmm \
        && cd .. \
        && rm -rf v${RMM_VERSION}.tar* \
        && rm -rf rmm-${RMM_VERSION}
      ```

1. Installez la bibliothèque SageMaker model parallel.

   ```
   RUN pip install --no-cache-dir -U ${SMD_MODEL_PARALLEL_URL}
   ```

1. Installez la bibliothèque SageMaker Data Parallel.

   ```
   RUN SMDATAPARALLEL_PT=1 pip install --no-cache-dir ${SMDATAPARALLEL_BINARY}
   ```

1. Installez la [boîte à outils d'entraînement Sagemaker](https://github.com/aws/sagemaker-training-toolkit). La boîte à outils contient les fonctionnalités communes nécessaires pour créer un conteneur compatible avec la plateforme de SageMaker formation et le SDK SageMaker Python.

   ```
   RUN pip install sagemaker-training
   ```

1. Une fois la création du Dockerfile terminée, consultez la section [Adapting Your Own Training Container](https://docs.aws.amazon.com/sagemaker/latest/dg/adapt-training-container.html) (Adapter votre propre conteneur d'entraînement) pour découvrir comment créer le conteneur Docker et l'héberger dans Amazon ECR.

**Astuce**  
Pour des informations plus générales sur la création d'un Dockerfile personnalisé pour l'entraînement à l' SageMaker IA, consultez [Utiliser vos propres algorithmes d'entraînement](https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-training-algo.html).

# Point de contrôle et optimisation d'un modèle grâce au parallélisme de modèles
<a name="distributed-model-parallel-checkpointing-and-finetuning"></a>

La bibliothèque de parallélisme des SageMaker modèles fournit des points de contrôle APIs pour enregistrer l'état du modèle et l'état de l'optimiseur divisés par les différentes stratégies de parallélisme des modèles, et pour charger des points de contrôle pour la formation continue à partir desquels vous souhaitez reprendre l'entraînement et le peaufiner. Ils prennent APIs également en charge les options permettant d'enregistrer partiellement ou totalement les états du modèle et de l'optimiseur.

**Topics**
+ [Point de contrôle d'un modèle distribué](#distributed-model-parallel-checkpoint)
+ [Optimisation d'un modèle distribué](#distributed-model-parallel-fine-tuning)

## Point de contrôle d'un modèle distribué
<a name="distributed-model-parallel-checkpoint"></a>

Choisissez l'une des rubriques suivantes en fonction du framework entre PyTorch TensorFlow et de la version de la bibliothèque de parallélisme de SageMaker modèles que vous utilisez.

**Topics**
+ [Vérification d'un PyTorch modèle distribué (pour la bibliothèque de parallélisme des SageMaker modèles v1.10.0 et versions ultérieures)](#model-parallel-extended-features-pytorch-checkpoint)
+ [Vérification d'un PyTorch modèle distribué (pour la bibliothèque de parallélisme des SageMaker modèles entre v1.6.0 et v1.9.0)](#model-parallel-extended-features-pytorch-saving-loading-checkpoints)
+ [Contrôle d'un modèle distribué TensorFlow](#distributed-model-parallel-checkpoint-tensorflow)

### Vérification d'un PyTorch modèle distribué (pour la bibliothèque de parallélisme des SageMaker modèles v1.10.0 et versions ultérieures)
<a name="model-parallel-extended-features-pytorch-checkpoint"></a>

La bibliothèque de parallélisme des SageMaker modèles fournit des points de contrôle APIs pour enregistrer et charger des points de contrôle complets ou partiels de l'état du modèle distribué et de son état d'optimiseur.

**Note**  
Cette méthode de point de contrôle est recommandée si vous utilisez PyTorch et SageMaker modélisez la bibliothèque de parallélisme v1.10.0 ou version ultérieure.

**Point de contrôle partiel**

Pour enregistrer les points de contrôle d'un modèle entraîné avec le parallélisme de modèles, utilisez l'API [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save_checkpoint](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save_checkpoint) avec l'option de point de contrôle partiel définie sur true (`partial=True`). Cela permet d'enregistrer chaque partition de modèle individuellement. Outre le modèle et l'état de l'optimiseur, vous pouvez également enregistrer des données personnalisées supplémentaires via l'argument `user_content`. Le modèle de point de contrôle, l'optimiseur et le contenu utilisateur sont enregistrés dans des fichiers séparés. L'appel d'API `save_checkpoint` crée des dossiers de points de contrôle selon la structure suivante. 

```
- path
  - ${tag}_partial (folder for partial checkpoints)
    - model_rankinfo.pt
    - optimizer_rankinfo.pt
    - fp16_states_rankinfo.pt
    - user_content.pt
  - $tag (checkpoint file for full checkpoints)
  - user_content_$tag (user_content file for full checkpoints)
  - newest (a file that indicates the newest checkpoint)
```

Pour reprendre l'entraînement à partir de points de contrôle partiels, utilisez l'API [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.resume_from_checkpoint](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.resume_from_checkpoint) avec `partial=True` et spécifiez le répertoire du point de contrôle et la balise utilisée lors de l'enregistrement des points de contrôle partiels. Notez que le chargement réel des poids du modèle se produit après le partitionnement du modèle, lors de la première exécution de la fonction d'étape d'entraînement décorée par `smdistributed.modelparallel.torch.step`.

Lors de l'enregistrement d'un point de contrôle partiel, la bibliothèque enregistre également la décision de partition de modèle sous forme de fichiers avec extension de fichier `.pt`. Inversement, lors de la reprise à partir du point de contrôle partiel, la bibliothèque charge les fichiers de décision de partition. Une fois la décision de partition chargée, vous ne pouvez pas la modifier.

L'extrait de code suivant montre comment définir le point de contrôle APIs dans un PyTorch script d'entraînement.

```
import smdistributed.modelparallel.torch as smp

model = ...
model = smp.DistributedModel(model)
optimizer = ...
optimizer = smp.DistributedOptimizer(optimizer)
user_content = ...     # additional custom data
checkpoint_path = "/opt/ml/checkpoint/model_parallel"

# Save a checkpoint.
smp.save_checkpoint(
    path=checkpoint_path,
    tag=f"total_steps{total_steps}",
    partial=True,
    model=model,
    optimizer=optimizer,
    user_content=user_content
    num_kept_partial_checkpoints=5
)

# Load a checkpoint.
# This automatically loads the most recently saved checkpoint.
smp_checkpoint = smp.resume_from_checkpoint(
    path=checkpoint_path, 
    partial=True
)
```

**Point de contrôle complet**

Pour enregistrer l'artefact du modèle final à des fins d'inférence, utilisez l'API `smdistributed.modelparallel.torch.save_checkpoint` avec `partial=False`, qui combine les partitions du modèle pour créer un artefact de modèle unique. Notez que cela ne combine pas les états de l'optimiseur.

Pour initialiser l'entraînement avec des poids particuliers, à partir d'un point de contrôle complet du modèle, vous pouvez utiliser l'API `smdistributed.modelparallel.torch.resume_from_checkpoint` avec `partial=False`. Notez que cela ne charge pas les états de l'optimiseur.

**Note**  
Avec le parallélisme des tenseurs, en général, `state_dict` doit être traduit entre l'implémentation du modèle d'origine et l'implémentation `DistributedModel`. Vous pouvez éventuellement fournir la fonction de traduction `state_dict` en tant qu'argument à `smdistributed.modelparallel.torch.resume_from_checkpoint`. Cependant, pour [Modèles pris en charge prêts à l'emploi](model-parallel-extended-features-pytorch-hugging-face.md#model-parallel-extended-features-pytorch-hugging-face-out-of-the-box), la bibliothèque se charge de cette traduction automatiquement.

Le code suivant montre un exemple d'utilisation du point de contrôle APIs pour vérifier complètement un PyTorch modèle entraîné avec le parallélisme des modèles.

```
import smdistributed.modelparallel.torch as smp

model = ...
model = smp.DistributedModel(model)
optimizer = ...
optimizer = smp.DistributedOptimizer(optimizer)
user_content = ...     # additional custom data
checkpoint_path = "/opt/ml/checkpoint/model_parallel"

# Save a checkpoint.
smp.save_checkpoint(
    path=checkpoint_path,
    tag=f"total_steps{total_steps}",
    partial=False,
    model=model,
    optimizer=optimizer,
    user_content=user_content
    num_kept_partial_checkpoints=5
)

# Load a checkpoint.
# This automatically loads the most recently saved checkpoint.
smp_checkpoint = smp.resume_from_checkpoint(
    path=checkpoint_path, 
    partial=False
)
```

### Vérification d'un PyTorch modèle distribué (pour la bibliothèque de parallélisme des SageMaker modèles entre v1.6.0 et v1.9.0)
<a name="model-parallel-extended-features-pytorch-saving-loading-checkpoints"></a>

La bibliothèque de parallélisme des SageMaker modèles fournit des fonctions Python permettant d'enregistrer des points de contrôle partiels ou complets pour les tâches d'entraînement avec le parallélisme des tenseurs. La procédure suivante explique comment utiliser [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save) et [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.load](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.load) pour enregistrer et charger un point de contrôle lors de l'utilisation du parallélisme de tenseur.

**Note**  
Cette méthode de point de contrôle est recommandée si vous utilisez PyTorch[Parallélisme de tenseur](model-parallel-extended-features-pytorch-tensor-parallelism.md), et la bibliothèque de parallélisme du SageMaker modèle entre les versions v1.6.0 et v1.9.0.

1. Préparez un objet de modèle et enveloppez-le avec la fonction wrapper `smp.DistributedModel()` de la bibliothèque.

   ```
   model = MyModel(...)
   model = smp.DistributedModel(model)
   ```

1. Préparez un optimiseur pour le modèle. Un ensemble de paramètres de modèle est un argument itérable requis par les fonctions de l'optimiseur. Pour préparer un ensemble de paramètres de modèle, vous devez procéder `model.parameters()` pour attribuer des paramètres de modèle uniques IDs à chaque modèle. 

   Si certains paramètres sont dupliqués IDs dans le paramètre itérable du modèle, le chargement de l'état de l'optimiseur à point de contrôle échoue. Pour créer un itérable de paramètres de modèle uniques IDs pour votre optimiseur, consultez ce qui suit :

   ```
   unique_params = []
   unique_params_set = set()
   for p in model.parameters():
     if p not in unique_params_set:
       unique_params.append(p)
       unique_params_set.add(p)
   del unique_params_set
   
   optimizer = MyOpt(unique_params, ...)
   ```

1. Enveloppez l'optimiseur à l'aide de la fonction wrapper `smp.DistributedOptimizer()` de la bibliothèque.

   ```
   optimizer = smp.DistributedOptimizer(optimizer)
   ```

1. Enregistrez le modèle et l'état de l'optimiseur à l'aide de [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save). Selon la manière dont vous souhaitez enregistrer les points de contrôle, choisissez l'une des deux options suivantes :
   + **Option 1 : **enregistrez un modèle partiel sur chaque `mp_rank` pour un `MP_GROUP` unique.

     ```
     model_dict = model.local_state_dict() # save a partial model
     opt_dict = optimizer.local_state_dict() # save a partial optimizer state
     # Save the dictionaries at rdp_rank 0 as a checkpoint
     if smp.rdp_rank() == 0:
         smp.save(
             {"model_state_dict": model_dict, "optimizer_state_dict": opt_dict},
             f"/checkpoint.pt",
             partial=True,
         )
     ```

     Avec le parallélisme de tenseur, la bibliothèque enregistre les fichiers à points de contrôle nommés selon le format suivant : `checkpoint.pt_{pp_rank}_{tp_rank}`.
**Note**  
Avec le parallélisme de tenseur, assurez-vous de définir l'instruction if comme `if smp.rdp_rank() == 0` et non comme `if smp.dp_rank() == 0`. Si l'état de l'optimiseur est partitionné avec un parallélisme de tenseur, tous les rangs parallèles aux données réduites doivent enregistrer leur propre partition de l'état de l'optimiseur. L'utilisation d'une mauvaise instruction *if* pour les points de contrôle peut entraîner un blocage de la tâche d'entraînement. Pour plus d'informations sur l'utilisation du parallélisme `if smp.dp_rank() == 0` sans tenseur, consultez les [instructions générales pour l'enregistrement et le chargement dans la documentation](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#general-instruction-for-saving-and-loading) du SDK *SageMaker Python*. 
   + **Option 2 :** enregistrez le modèle complet.

     ```
     if smp.rdp_rank() == 0:
         model_dict = model.state_dict(gather_to_rank0=True) # save the full model
         if smp.rank() == 0:
             smp.save(
                 {"model_state_dict": model_dict},
                 "/checkpoint.pt",
                 partial=False,
             )
     ```
**Note**  
Tenez compte des points suivants pour la création de points de contrôle complets :   
Si vous définissez `gather_to_rank0=True`, tous les rangs autres que `0` renvoient des dictionnaires vides.
Pour la création de points de contrôle complets, vous ne pouvez créer des points de contrôle que pour le modèle. La création de points de contrôle complets des états de l'optimiseur n'est actuellement pas prise en charge.
Le modèle complet doit uniquement être enregistré sur `smp.rank() == 0`.

1. Chargez les points de contrôle à l'aide de [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.load](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.load). Selon la manière dont vous avez enregistré les points de contrôle à l'étape précédente, choisissez l'une des deux options suivantes :
   + **Option 1 :** chargez les points de contrôle partiels.

     ```
     checkpoint = smp.load("/checkpoint.pt", partial=True)
     model.load_state_dict(checkpoint["model_state_dict"], same_partition_load=False)
     optimizer.load_state_dict(checkpoint["optimizer_state_dict"])
     ```

     Vous pouvez définir `same_partition_load=True` dans `model.load_state_dict()` pour une charge plus rapide si vous savez que la partition ne changera pas.
   + **Option 2 :** chargez les points de contrôle complets.

     ```
     if smp.rdp_rank() == 0:
         checkpoint = smp.load("/checkpoint.pt", partial=False)
         model.load_state_dict(checkpoint["model_state_dict"])
     ```

     La condition `if smp.rdp_rank() == 0` n'est pas nécessaire, mais elle peut aider à éviter un chargement redondant entre différents `MP_GROUP`. La création de points de contrôle complets du dictionnaire des états de l'optimiseur n'est actuellement pas prise en charge avec le parallélisme de tenseur.

### Contrôle d'un modèle distribué TensorFlow
<a name="distributed-model-parallel-checkpoint-tensorflow"></a>

Pour enregistrer un TensorFlow modèle pendant l'entraînement au parallélisme des modèles, utilisez les fonctions suivantes fournies par la bibliothèque de parallélisme des SageMaker modèles.
+ [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_tensorflow.html#smp.DistributedModel.save_model](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_tensorflow.html#smp.DistributedModel.save_model)
+ [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_tensorflow.html#smp.CheckpointManager](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_tensorflow.html#smp.CheckpointManager)

## Optimisation d'un modèle distribué
<a name="distributed-model-parallel-fine-tuning"></a>

L'optimisation doit être configurée dans votre script d'entraînement. L'extrait de code suivant montre un exemple de structure de script d'entraînement utilisant la classe [AutoModelForCausalLM](https://huggingface.co/docs/transformers/main/en/model_doc/auto#transformers.AutoModelForCausalLM) de Hugging Face Transformers avec des modifications pour l'enregistrement des modules et des paramètres pour un `smdistributed.model.parallel.torch` réglage précis.

**Note**  
Le réglage fin d'un transformateur distribué (un modèle de transformateur encapsulé par`smp.DistributedModel()`) avec la fonction [smp.delayed\$1param\$1initialization](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.delay_param_initialization) activée nécessite que la tâche de réglage fin soit configurée avec un système de fichiers pour Lustre. FSx Si vous souhaitez affiner un modèle à grande échelle avec l'option d'initialisation différée des paramètres, vous devez configurer un système de fichiers FSx pour Lustre.

```
import argparse
from transformers import AutoModelForCausalLM
import smdistributed.modelparallel
import smdistributed.modelparallel.torch as smp

def parse_args():

    parser = argparse.ArgumentParser()

    # set an arg group for model
    model_grp = parser.add_argument_group(
        title="model", description="arguments to describe model configuration"
    )

    ... # set up numerous args to parse from the configuration dictionary to the script for training

    # add arg for activating fine-tuning
    model_grp.add_argument(
        "--fine_tune",
        type=int,
        default=0,
        help="Fine-tune model from checkpoint or pretrained model",
    )

def main():
    """Main function to train GPT."""
    args = parse_args()

    ... # parse numerous args

    if args.fine_tune > 0 and args.delayed_param > 0 and smp.rank() == 0:
        pretrained_model = AutoModelForCausalLM.from_pretrained(
            args.model_name or args.model_dir
        )
        model_state_dict = pretrained_model.state_dict()
        path = os.path.join(args.model_dir, "fullmodel.pt")
        torch.save(model_state_dict, path)

    # create a Transformer model and wrap by smp.model_creation() 
    # with options to configure model parallelism parameters offered by SageMaker AI
    with smp.model_creation(
        tensor_parallelism=smp.tp_size() > 1 or args.use_distributed_transformer > 0,
        zero_init=args.use_distributed_transformer == 0,
        dtype=dtype,
        distribute_embedding=args.sharded_data_parallel_degree > 1 and smp.tp_size() > 1,
        use_alibi=args.alibi > 0,
        attention_in_fp32=args.attention_in_fp32 > 0,
        fp32_residual_addition=args.residual_addition_in_fp32 > 0,
        query_key_layer_scaling=args.query_key_layer_scaling > 0 and args.bf16 < 1,
        fused_softmax=args.fused_softmax > 0,
        fused_dropout=args.fused_dropout > 0,
        fused_bias_gelu=args.fused_bias_gelu > 0,
        flash_attention=args.flash_attention > 0,
    ):
        if args.fine_tune > 0 and args.delayed_param == 0:
            model = AutoModelForCausalLM.from_pretrained(
                args.model_name or args.model_dir
            )
        else:
            model = AutoModelForCausalLM.from_config(model_config)

    # wrap the model by smp.DistributedModel() to apply SageMaker model parallelism
    model = smp.DistributedModel(
        model, trace_device="gpu", backward_passes_per_step=args.gradient_accumulation
    )

    # wrap the optimizer by smp.DistributedOptimizer() to apply SageMaker model parallelism
    optimizer= ... # define an optimizer
    optimizer = smp.DistributedOptimizer(
        optimizer,
        static_loss_scale=None,
        dynamic_loss_scale=True,
        dynamic_loss_args={"scale_window": 1000, "min_scale": 1, "delayed_shift": 2},
    )

    # for fine-tuning, use smp.resume_from_checkpoint() to load a pre-trained model
    if args.fine_tune > 0 and args.delayed_param > 0:
        smp.resume_from_checkpoint(args.model_dir, tag="fullmodel.pt", partial=False)
```

*Pour un exemple complet de scripts d'entraînement et de blocs-notes Jupyter, consultez les [exemples GPT-2 disponibles PyTorch dans le référentiel AI Examples](https://github.com/aws/amazon-sagemaker-examples/tree/main/training/distributed_training/pytorch/model_parallel/gpt2). SageMaker GitHub* 

# Exemples de bibliothèque de parallélisme de modèles Amazon SageMaker AI v1
<a name="distributed-model-parallel-examples"></a>

Cette page fournit une liste de blogs et de blocs-notes Jupyter présentant des exemples pratiques d'implémentation de la bibliothèque de parallélisme des SageMaker modèles (SMP) v1 pour exécuter des tâches de formation distribuées sur l'IA. SageMaker 

## Blogs et études de cas
<a name="distributed-model-parallel-examples-blog"></a>

Les blogs suivants traitent d’études de cas sur l’utilisation de SMP v1.
+ [Nouvelles améliorations des performances de la bibliothèque de parallélisme de modèles Amazon SageMaker AI](https://aws.amazon.com/blogs/machine-learning/new-performance-improvements-in-amazon-sagemaker-model-parallel-library/), *AWS Machine Learning Blog* (16 décembre 2022)
+ [Entraînez des modèles gigantesques avec une mise à l'échelle quasi linéaire à l'aide du parallélisme de données fragmenté sur SageMaker Amazon](https://aws.amazon.com/blogs/machine-learning/train-gigantic-models-with-near-linear-scaling-using-sharded-data-parallelism-on-amazon-sagemaker/) AI, *Machine AWS Learning* Blog (31 octobre 2022)

## Exemples de blocs-notes
<a name="distributed-model-parallel-examples-pytorch"></a>

Des carnets d'exemples sont fournis dans le [ GitHub référentiel d'exemples d'SageMaker IA](https://github.com/aws/amazon-sagemaker-examples/tree/master/training/distributed_training/). Pour les télécharger, exécutez la commande suivante afin de cloner le référentiel et d’accéder à `training/distributed_training/pytorch/model_parallel`.

**Note**  
Clonez et exécutez les exemples de blocs-notes dans l' SageMaker AI ML IDEs suivant.  
[SageMaker JupyterLab](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated-jl.html)(disponible dans [Studio](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated.html) créé après décembre 2023)
[SageMaker Éditeur de code](https://docs.aws.amazon.com/sagemaker/latest/dg/code-editor.html) (disponible dans [Studio](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated.html) créé après décembre 2023)
[Studio Classic](https://docs.aws.amazon.com/sagemaker/latest/dg/studio.html) (disponible sous forme d’application dans [Studio](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated.html), créé après décembre 2023)
[SageMaker Instances d'ordinateurs portables](https://docs.aws.amazon.com/sagemaker/latest/dg/nbi.html)

```
git clone https://github.com/aws/amazon-sagemaker-examples.git
cd amazon-sagemaker-examples/training/distributed_training/pytorch/model_parallel
```

**Exemples de blocs-notes SMP v1 pour PyTorch**
+ [Entraînez le GPT-2 avec une mise à l'échelle quasi linéaire à l'aide de la technique de parallélisme de données fragmentée de la bibliothèque de parallélisme du modèle SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/smp-train-gpt-sharded-data-parallel.ipynb)
+ [Ajustez le GPT-2 avec une mise à l'échelle quasi linéaire à l'aide de la technique de parallélisme des données fragmentée dans la bibliothèque de parallélisme des modèles SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/smp-fine-tune-gpt-sharded-data-parallel.ipynb)
+ [Entraînez le GPT-NeoX-20b avec une mise à l'échelle quasi linéaire à l'aide de la technique de parallélisme de données fragmentée de la bibliothèque de parallélisme de modèles SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt-neox/smp-train-gpt-neox-sharded-data-parallel.ipynb)
+ [Entraînez le GPT-J 6B en utilisant les techniques de parallélisme des données fragmentées et de parallélisme des tenseurs de la bibliothèque de parallélisme des modèles SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt-j/smp-train-gptj-sharded-data-parallel-tp.ipynb)
+ [Entraînez le FLAN-T5 avec une mise à l'échelle quasi linéaire à l'aide de la technique de parallélisme de données fragmenté dans la bibliothèque de parallélisme du modèle SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/flan-t5/smp-train-t5-sharded-data-parallel.ipynb)
+ [Entraînez Falçon avec une mise à l'échelle quasi linéaire à l'aide de la technique de parallélisme de données fragmenté dans la bibliothèque de parallélisme des modèles SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/falcon/smp-train-falcon-sharded-data-parallel.ipynb)

**Exemples de blocs-notes SMP v1 pour TensorFlow**
+ [CNN avec TensorFlow 2.3.1 et la bibliothèque de parallélisme des SageMaker modèles](https://sagemaker-examples.readthedocs.io/en/latest/training/distributed_training/tensorflow/model_parallel/mnist/tensorflow_smmodelparallel_mnist.html)
+ [HuggingFace avec bibliothèque de parallélisme de modèles TensorFlow distribués Formation sur l'IA SageMaker ](https://github.com/huggingface/notebooks/blob/master/sagemaker/04_distributed_training_model_parallelism/sagemaker-notebook.ipynb)

# SageMaker Meilleures pratiques en matière de parallélisme des modèles distribués
<a name="model-parallel-best-practices"></a>

Suivez les instructions suivantes lorsque vous exécutez une tâche de formation distribuée avec la bibliothèque SageMaker model parallel.

## Installation de la bonne configuration pour un modèle donné
<a name="model-parallel-best-practices-configuration"></a>

Lors de la mise à l'échelle d'un modèle, nous vous recommandons de passer en revue la liste suivante dans l'ordre. Chaque élément de la liste explique l'avantage d'utiliser les techniques de la bibliothèque ainsi que les compromis qui pourraient survenir. 

**Astuce**  
Si un modèle peut bien s'adapter à l'aide d'un sous-ensemble des fonctionnalités de la bibliothèque, l'ajout d'autres fonctionnalités de parallélisme de modèle ou d'économie de mémoire n'améliore généralement pas les performances.

**Utilisation de types d'instance GPU volumineux**
+ Dans le domaine du parallélisme des modèles, il est préférable d'utiliser des instances puissantes dotées de grandes mémoires GPU pour gérer les surcharges liées aux opérations de parallélisme des modèles, telles que le partitionnement des modèles sur plusieurs. GPUs Nous vous recommandons d'utiliser les instances `ml.p4d` ou `ml.p3dn` pour former des modèles DL volumineux. Ces instances sont également équipées d'un adaptateur Elastic Fabric Adapter (EFA), qui fournit une bande passante réseau plus élevée et permet une formation à grande échelle avec le parallélisme des modèles.

**Partitionnement de l'état de l'optimiseur**
+ L'impact du partitionnement de l'état de l'optimiseur dépend du nombre de rangs parallèles de données. En règle générale, un degré plus élevé de parallélisme des données (proportionnel à la taille du nœud de calcul) peut améliorer l'efficacité de l'utilisation de la mémoire.

  Lorsque vous souhaitez réduire la taille d'un cluster, assurez-vous de vérifier la configuration du partition de l'état de l'optimiseur. Par exemple, un modèle DL de grande taille avec partitionnement de l'état de l'optimiseur qui s'adapte à un cluster de calcul de 16 GPUs (par exemple, deux instances P4d ou P4de) peut ne pas toujours s'adapter à un nœud de 8 GPUs (par exemple, une seule instance P4d ou P4de). En effet, la mémoire combinée de 8 GPUs est inférieure à la mémoire combinée de 16 GPUs, et la mémoire requise par GPU pour le sharding sur 8 GPUs est également supérieure à la mémoire par GPU pour le sharding sur le scénario de 16 GPU. Par conséquent, l'augmentation de la quantité de mémoire requise risque de ne pas être adaptée au plus petit cluster.

  Pour de plus amples informations, veuillez consulter [Partitionnement de l'état de l'optimiseur](model-parallel-extended-features-pytorch-optimizer-state-sharding.md).

**Points de contrôle d'activation**
+ L'efficacité de la mémoire peut être améliorée en utilisant le point de contrôle d'activation pour un groupe de modules. Plus vous regroupez les modules, plus l'utilisation de la mémoire est efficace. Lorsque vous effectuez un pointage de modules séquentiels pour des couches, l'argument `strategy` de la fonction `smp.set_activation_checkpointing` regroupe les couches ensemble pour le point de contrôle. Par exemple, le regroupement de deux couches ou plus pour un point de contrôle est plus efficace en mémoire que le point de contrôle une couche à la fois, ce qui permet d'échanger un temps de calcul supplémentaire pour réduire l'utilisation de la mémoire.

  Pour de plus amples informations, veuillez consulter [Points de contrôle d'activation](model-parallel-extended-features-pytorch-activation-checkpointing.md).

**Parallélisme de tenseur**
+ Le degré de parallélisme des tenseurs doit être une puissance de deux (2, 4, 8,..., 2 n), le degré maximum devant être égal au nombre de GPUs par nœud. Par exemple, si vous utilisez un nœud avec 8 GPUs, les nombres possibles pour le degré de parallélisme des tenseurs sont 2, 4 et 8. Nous ne recommandons pas de nombres arbitraires (tels que 3, 5, 6 et 7) pour le degré de parallélisme de tenseur. Lorsque vous utilisez plusieurs nœuds, une mauvaise configuration du degré de parallélisme de tenseur peut entraîner l'exécution du parallélisme de tenseur entre les nœuds. Cela entraîne une surcharge importante due à la communication des activations entre les nœuds et peut devenir coûteuse sur le plan informatique.

  Pour de plus amples informations, veuillez consulter [Parallélisme de tenseur](model-parallel-extended-features-pytorch-tensor-parallelism.md).<a name="model-parallel-best-practices-configuration-pipeline-across-nodes"></a>

**Parallélisme de pipeline entre nœuds**
+ Vous pouvez exécuter le parallélisme de pipeline à la fois au sein d'un seul nœud et sur plusieurs nœuds. Lorsque vous utilisez le parallélisme de pipeline en combinaison avec le parallélisme de tenseur, nous vous recommandons d'exécuter le parallélisme de pipeline sur plusieurs nœuds et de conserver le parallélisme de tenseur au sein de nœuds individuels. 
+ Le parallélisme de pipeline comprend les trois boutons suivants : `microbatches`, `active_microbatches`, et `prescaled_batch`.
  + Lorsque vous utilisez le parallélisme de tenseur et le parallélisme de pipeline, nous vous recommandons d'activer `prescaled_batch` afin que la taille des lots par groupe parallèle de modèles puisse être augmentée pour un pipelining efficace. Avec `prescaled_batch` activé, la taille du lot définie dans le script d'entraînement devient `tp_size` fois la taille du lot définie pour chaque rang sans `prescaled_batch`.
  + Augmentation du nombre de `microbatches` permet d'atteindre un pipelining efficace et de meilleures performances. Notez que la taille effective des microlots correspond à la taille du lot divisée par le nombre de microlots. Si vous augmentez le nombre de microlots tout en gardant la taille du lot constante, chaque microlot traite moins d'échantillons.
  + Le nombre de `active_microbatches` est le nombre maximal de microlots qui sont simultanément en cours de traitement pendant le pipelining. Pour chaque microlot actif en cours de traitement, ses activations et ses dégradés occupent la mémoire GPU. Par conséquent, augmenter `active_microbatches` consomme plus de mémoire GPU.
+ Si la mémoire GPU et GPU sont sous-utilisées, augmentez `active_microbatches` pour une meilleure parallélisation pendant le pipelining.
+ Pour plus d'informations sur l'utilisation du parallélisme de tenseur et du parallélisme de pipeline, consultez [Parallélisme de tenseur associé au parallélisme de pipeline](model-parallel-extended-features-pytorch-tensor-parallelism-examples.md#model-parallel-extended-features-pytorch-tensor-and-pipeline-parallelism).
+ Pour obtenir une description des paramètres susmentionnés, consultez la section [Paramètres pour `smdistributed`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#parameters-for-smdistributed) dans la *documentation du SDK SageMaker Python*.

**Déchargement des activations vers le CPU**
+ Assurez-vous que cela est utilisé en combinaison avec le point de contrôle d'activation et le parallélisme de pipeline. Pour garantir que le déchargement et le préchargement se produisent en arrière-plan, spécifiez une valeur supérieure à 1 pour le paramètre de microlots. 
+ Lors du déchargement des activations, vous pouvez augmenter `active_microbatches` et parfois faire correspondre au nombre total de microlots. Cela dépend des modules qui sont contrôlés et de la façon dont le modèle est partitionné.

  Pour de plus amples informations, veuillez consulter [Déchargement de l'activation](model-parallel-extended-features-pytorch-activation-offloading.md).

### Référence de configurations
<a name="model-parallel-best-practices-configuration-reference"></a>

L'équipe de formation au parallélisme des SageMaker modèles fournit les points de référence suivants sur la base d'expériences avec le modèle GPT-2, d'une longueur de séquence de 512 et d'une taille de vocabulaire de 50 000. 


| Le nombre de paramètres de modèle | Type d’instance | Parallélisme de pipeline | Parallélisme de tenseur | Partitionnement de l'état de l'optimiseur | Points de contrôle d'activation | Lot précadré | Taille de lot | 
| --- | --- | --- | --- | --- | --- | --- | --- | 
| 10 milliards | 16 ml.p4d.24xlarge | 1 | 4 | True | Chaque couche de transformateur | True | batch\$1size=40 | 
| 30 milliards | 16 ml.p4d.24xlarge | 1 | 8 | True | Chaque couche de transformateur | True | batch\$1size=32 | 
| 60 milliards | 32 ml.p4d.24xlarge | 2 | 8 | True | Chaque couche de transformateur | True | batch\$1size=56, microbatches=4, active\$1microbatches=2 | 

Vous pouvez extrapoler à partir des configurations précédentes pour estimer l'utilisation de la mémoire GPU pour la configuration de votre modèle. Par exemple, si vous augmentez la longueur de séquence d'un modèle de 10 milliards de paramètres ou si vous augmentez la taille du modèle à 20 milliards, vous pouvez commencer par réduire la taille du lot. Si le modèle ne convient toujours pas, essayez d'augmenter le degré de parallélisme de tenseur.

## Modification de votre script d'entraînement
<a name="model-parallel-best-practices-modify-training-script"></a>
+ Avant d'utiliser les fonctionnalités de la bibliothèque SageMaker model parallel dans votre script d'entraînement, passez en revue[Conseils et pièges de configuration de la bibliothèque de parallélisme des modèles SageMaker distribués](model-parallel-customize-tips-pitfalls.md).
+ Pour lancer une tâche de formation plus rapidement, utilisez le [mode local de l'SageMaker IA](https://sagemaker.readthedocs.io/en/v2.199.0/overview.html?highlight=local%20mode#local-mode). Cela vous permet d'exécuter rapidement une tâche de formation en local sur une instance de SageMaker bloc-notes. En fonction de l'échelle de l'instance ML sur laquelle s'exécute votre instance de SageMaker bloc-notes, vous devrez peut-être ajuster la taille de votre modèle en modifiant les configurations du modèle, telles que la largeur cachée, le nombre de couches de transformation et les têtes d'attention. Vérifiez si le modèle réduit fonctionne correctement sur l'instance de bloc-notes avant d'utiliser un cluster volumineux pour former le modèle complet. 

## Surveillance et enregistrement d'un travail de formation à l'aide de la console SageMaker AI et d'Amazon CloudWatch
<a name="model-parallel-best-practices-monitoring"></a>

Pour surveiller les indicateurs au niveau du système tels que l'utilisation de la mémoire du processeur, l'utilisation de la mémoire du processeur graphique et l'utilisation du processeur graphique, utilisez la visualisation fournie par la console [SageMaker AI](https://console.aws.amazon.com/sagemaker/).

1. Dans le panneau de navigation de gauche, choisissez **Training** (Entraînement).

1. Choisissez **Training jobs (Tâches d'entraînement)**.

1. Dans le volet principal, sélectionnez le nom de la tâche d'entraînement dont vous voulez afficher plus de détails.

1. Parcourez le volet principal et trouvez la section **Monitor** (Contrôler) pour voir la visualisation automatisée.

1. Pour voir les journaux des tâches d'entraînement, choisissez **View logs** (Afficher des journaux)dans la section **Monitor** (Contrôler). Vous pouvez accéder aux journaux de tâches de formation distribués de la tâche de formation dans CloudWatch. Si vous avez lancé un entraînement distribué à plusieurs nœuds, vous devriez voir plusieurs flux de journaux avec des balises au format de **algo-n-1234567890**. Leflux de journaux **algo-1** suit les journaux d'entraînement à partir du nœud principal (0e).

Pour de plus amples informations, veuillez consulter [Amazon CloudWatch Metrics pour le suivi et l'analyse des offres de formation](training-metrics.md).

## Permissions
<a name="model-parallel-best-practices-permissions"></a>

Pour exécuter une tâche de SageMaker formation avec le parallélisme des modèles ou les [carnets d'exemples de formation SageMaker distribués](https://sagemaker-examples.readthedocs.io/en/latest/training/distributed_training/index.html), assurez-vous de disposer des autorisations appropriées pour votre rôle IAM, telles que les suivantes :
+ À utiliser [FSx pour Lustre](https://aws.amazon.com/fsx/), ajoutez [https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonFSxFullAccess](https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonFSxFullAccess).
+ Pour utiliser Amazon S3 comme canal de données, ajoutez [https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonS3FullAccess](https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonS3FullAccess).
+ Pour utiliser Docker, créez votre propre conteneur et le transférer vers Amazon ECR, ajoutez [https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonEC2ContainerRegistryFullAccess](https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonEC2ContainerRegistryFullAccess).
+ Pour avoir un accès complet à l'utilisation de l'ensemble des fonctionnalités de l' SageMaker IA, ajoutez [https://console.aws.amazon.com/iam/home#/policies/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonSageMakerFullAccess](https://console.aws.amazon.com/iam/home#/policies/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonSageMakerFullAccess). 

# Conseils et pièges de configuration de la bibliothèque de parallélisme des modèles SageMaker distribués
<a name="model-parallel-customize-tips-pitfalls"></a>

Consultez les conseils et astuces suivants avant d'utiliser la bibliothèque de parallélisme de modèles d'Amazon SageMaker AI. Cette liste contient des conseils qui s'appliquent à tous les cadres. Pour TensorFlow des conseils PyTorch spécifiques, voir [Modifier un script TensorFlow d'entraînement](model-parallel-customize-training-script-tf.md) et[Modifier un script PyTorch d'entraînement](model-parallel-customize-training-script-pt.md), respectivement. 

## Taille de lot et nombre de micro-lots
<a name="model-parallel-customize-tips-pitfalls-batch-size"></a>
+ La bibliothèque est la plus efficace lorsque la taille du lot est augmentée. Dans les cas d'utilisation où le modèle tient dans un seul périphérique, mais ne peut être entraîné qu'avec un lot de petite taille, la taille du lot peut et doit être augmentée après l'intégration de la bibliothèque. Le parallélisme des modèles permet d'économiser de la mémoire pour les grands modèles, ce qui permet un entraînement avec des tailles de lots qui ne tenaient pas dans la mémoire auparavant.
+ Choisir un nombre de micro-lots trop petit ou trop grand peut baisser les performances. La bibliothèque exécute chaque micro-lot séquentiellement dans chaque périphérique, de sorte que la taille du micro-lot (taille du lot divisée par le nombre de micro-lots) doit être suffisamment grande pour utiliser pleinement chaque GPU. Dans le même temps, comme l'efficacité du pipeline augmente avec le nombre de micro-lots, il est important de trouver le bon équilibre. Normalement, un bon point de départ consiste à essayer 2 ou 4 micro-lots, en augmentant la taille du lot jusqu'à la limite de mémoire, puis à expérimenter avec des tailles de lot et un nombre de micro-lots supérieurs. L'augmentation du nombre de micro-lots permet d'envisager des tailles de lots supérieures, si un pipeline entrelacé est utilisé.
+ La taille de votre lot doit toujours être divisible par le nombre de micro-lots. Veuillez noter que, selon la taille du jeu de données, la taille du dernier lot de chaque époque peut parfois être inférieure au reste, mais ce petit lot doit également être divisible par le nombre de micro-lots. Si ce n'est pas le cas, vous pouvez définir `drop_remainder=True` l'`tf.Dataset.batch()`appel (in TensorFlow) ou le définir `DataLoader` (`drop_last=True`in PyTorch), afin que ce dernier petit lot ne soit pas utilisé. Si vous utilisez une API différente pour le pipeline de données, vous devrez peut-être ignorer manuellement le dernier lot chaque fois qu'il n'est pas divisible par le nombre de micro-lots.

## Partitionnement manuel
<a name="model-parallel-customize-tips-pitfalls-manual-partitioning"></a>
+ Si vous utilisez le partitionnement manuel, pensez toujours aux paramètres qui sont utilisés par plusieurs opérations et modules de votre modèle, tels que la table d'incorporation dans les architectures de transformateur. À des fins d'exactitude, les modules qui partagent le même paramètre doivent être placés dans le même périphérique. Lorsque vous utilisez le partitionnement automatique, la bibliothèque applique automatiquement cette contrainte.

## Préparation des données
<a name="model-parallel-customize-tips-pitfalls-data-preparation"></a>
+ Si le modèle utilise plusieurs entrées, veillez à répartir les opérations aléatoires dans votre pipeline de données (remaniement, par exemple) avec `smp.dp_rank()`. Si le jeu de données est partitionné de manière déterministe entre des périphériques parallèles de données, assurez-vous que la partition est indexée par `smp.dp_rank()`. Ceci permet de garantir la cohérence de l'ordre des données affichées sur tous les rangs qui forment une partition de modèle.

## Renvoyer les tenseurs à partir de `smp.DistributedModel`
<a name="model-parallel-customize-tips-pitfalls-return-tensors"></a>
+ Tout tenseur renvoyé par la fonction `smp.DistributedModel.call` (for TensorFlow) ou `smp.DistributedModel.forward` (for PyTorch) est diffusé vers tous les autres rangs, à partir du rang qui a calculé ce tenseur particulier. Par conséquent, tout tenseur qui n'est pas nécessaire en dehors des méthodes d'appel et de transmission (activations intermédiaires, par exemple) ne doit pas être renvoyé, car cela provoque un surdébit inutile de communication et de mémoire et nuit aux performances.

## Le décorateur `@smp.step`
<a name="model-parallel-customize-tips-pitfalls-smp-step-decorator"></a>
+ Si l'argument tenseur d'une fonction décorée `smp.step` n'a pas de dimension de lot, le nom de l'argument doit être fourni dans la liste `non_split_inputs` lors de l'appel `smp.step`. Cela empêche la bibliothèque d'essayer de diviser le tenseur en micro-lots. Pour plus d’informations, consultez [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_common_api.html](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_common_api.html) dans la documentation sur l’API.

## Retarder l'initialisation des paramètres
<a name="model-parallel-customize-tips-pitfalls-delaying-param-initialization"></a>

Pour les très grands modèles comportant plus de 100 milliards de paramètres, l'initialisation du poids via la mémoire du processeur peut entraîner une out-of-memory erreur. Pour contourner ce problème, la bibliothèque propose un gestionnaire de contexte `smp.delay_param_initialization`. Cela retarde l'allocation physique des paramètres jusqu'à ce qu'ils se déplacent vers le GPU lors de la première exécution d'une fonction décorée `smp.step`. Cela évite l'utilisation inutile de la mémoire du processeur pendant l'initialisation de la formation. Utilisez le gestionnaire de contexte lorsque vous créez un objet de modèle comme illustré dans le code suivant.

```
with smp.delay_param_initialization(enabled=True):    
    model = MyModel()
```

## Parallélisme tensoriel pour PyTorch
<a name="model-parallel-customize-tips-pitfalls-tensor-parallelism-pytorch"></a>
+ Si vous utilisez une graine pour des résultats déterministes, définissez la graine en fonction de `smp.dp_rank()` (par exemple, `torch.manual_seed(42 + smp.dp_rank())`). Si vous ne le faites pas, différentes partitions d'un paramètre `nn.Parameter` sont initialisés de la même manière, ce qui a un impact sur la convergence. 
+ SageMakerde la bibliothèque de parallélisme des modèles utilise NCCL pour implémenter les collectifs nécessaires à la distribution des modules. En particulier pour les modèles plus petits, si trop d'appels NCCL sont programmés simultanément sur le GPU, l'utilisation de la mémoire peut augmenter en raison de l'espace supplémentaire utilisé par NCCL. Pour contrer cela, `smp` limite les appels NCCL de sorte que le nombre d'opérations de la NCCL en cours à un moment donné soit inférieur ou égal à une limite donnée. La limite par défaut est 8, mais elle peut être ajustée à l'aide de la variable d'environnement `SMP_NCCL_THROTTLE_LIMIT`. Si vous constatez une utilisation de la mémoire plus importante que prévu lors de l'utilisation du parallélisme de tenseur, vous pouvez essayer de réduire cette limite. Toutefois, le choix d'une limite trop faible peut entraîner une perte de débit. Pour désactiver complètement la limitation, vous pouvez définir `SMP_NCCL_THROTTLE_LIMIT=-1`. 
+ L'identité suivante, qui s'applique lorsque le degré de parallélisme de tenseur est de 1, ne tient pas lorsque le degré de parallélisme de tenseur est supérieur à 1 : `smp.mp_size() * smp.dp_size() == smp.size()`. En effet, le groupe de parallélisme de tenseur fait partie du groupe de parallélisme du modèle et du groupe de parallélisme des données. Si votre code contient déjà des références à `mp_rank`, `mp_size`, `MP_GROUP`, et ainsi de suite, et si vous souhaitez travailler uniquement avec le groupe parallèle de pipeline, vous devrez peut-être remplacer les références par `smp.pp_size()`. Les identités suivantes sont toujours vraies : 
  +  `smp.mp_size() * smp.rdp_size() == smp.size()` 
  +  `smp.pp_size() * smp.dp_size() == smp.size()` 
  +  `smp.pp_size() * smp.tp_size() * smp.rdp_size() == smp.size()` 
+ Depuis la fonction wrapper `smp.DistributedModel` modifie les paramètres du modèle lorsque le parallélisme de tenseur est activé, l'optimiseur doit être créé après l'appel `smp.DistributedModel`, avec les paramètres distribués. Par exemple, les éléments suivants ne fonctionnent pas : 

  ```
  ## WRONG
  model = MyModel()
  optimizer = SomeOptimizer(model.parameters())
  model = smp.DistributedModel(model)  # optimizer now has outdated parameters! 
  ```

  Au lieu de cela, l'optimiseur doit être créé avec les paramètres du `smp.DistributedModel` comme suit :

  ```
  ## CORRECT
  model = smp.DistributedModel(MyModel())
  optimizer = SomeOptimizer(model.optimizers())
  ```
+ Lorsqu'un module est remplacé par son homologue distribué par parallélisme de tenseur, le module distribué n'hérite pas de ses poids du module d'origine et initialise de nouveaux poids. Cela signifie que, par exemple, si les pondérations doivent être initialisées dans un appel particulier (par exemple, via un appel `load_state_dict`), cela doit se produire après l'appel `smp.DistributedModel`, une fois que la distribution du module a eu lieu. 
+ Lorsque vous accédez directement aux paramètres des modules distribués, notez que le poids n'a pas la même forme que le module d'origine. Par exemple,  

  ```
  with smp.tensor_parallelism():
      linear = nn.Linear(60, 60)
  
  # will pass
  assert tuple(linear.weight.shape) == (60, 60)
  
  distributed_linear = smp.DistributedModel(linear)
  
  # will fail. the number of input channels will have been divided by smp.tp_size()
  assert tuple(distributed_linear.module.weight.shape) == (60, 60)
  ```
+ A l'aide de `torch.utils.data.distributed.DistributedSampler` est fortement recommandé pour le parallélisme de tenseur. Cela garantit que chaque classement parallèle de données reçoit le même nombre d'échantillons de données, ce qui évite les blocages pouvant résulter de différents `dp_rank` prenant un certain nombre de mesures différentes. 
+ Si vous utilisez l'`join`API PyTorch de la `DistributedDataParallel` classe pour gérer les cas dans lesquels différents rangs parallèles de données comportent un nombre de lots différent, vous devez tout de même vous assurer que les rangs appartenant à la même classe `TP_GROUP` contiennent le même nombre de lots ; sinon, les collectifs de communication utilisés dans l'exécution distribuée des modules risquent de se bloquer. Les rangs qui sont dans des `TP_GROUP` différents peuvent avoir un nombre différent de lots, à condition que l'API `join` est utilisé. 
+ Si vous souhaitez contrôler votre modèle et utiliser le parallélisme tenseur, tenez compte des points suivants : 
  + Pour éviter les conditions de décrochage et de course lors de l'enregistrement et du chargement des modèles lorsque vous utilisez le parallélisme de tenseurs, assurez-vous d'appeler les fonctions appropriées à partir des états de modèle et d'optimiseur suivants dans un rang de parallélisme réduit des données.
  + Si vous faites la transition d'un script parallèle de pipeline existant et que vous activez le parallélisme de tenseur pour le script, veillez à modifier n'importe quel bloc `if smp.dp_rank() == 0` utilisé pour enregistrer et charger avec les blocs `if smp.rdp_rank() == 0`. Sinon, cela pourrait entraîner le blocage de votre tâche d'entraînement. 

  Pour en savoir plus sur les points de contrôle d'un modèle avec parallélisme de tenseur, consultez [Point de contrôle d'un modèle distribué](distributed-model-parallel-checkpointing-and-finetuning.md#distributed-model-parallel-checkpoint).

# Dépannage pour les modèles parallèles
<a name="distributed-troubleshooting-model-parallel"></a>

Si vous rencontrez une erreur, vous pouvez utiliser la liste suivante pour essayer de résoudre votre tâche d'entraînement. Si le problème persiste, contactez le [support AWS](https://aws.amazon.com/premiumsupport). 

**Topics**
+ [Considérations relatives à l'utilisation du SageMaker débogueur avec la bibliothèque de parallélisme de SageMaker modèles](#distributed-ts-model-parallel-debugger)
+ [Sauvegarde des points de contrôle](#distributed-ts-model-parallel-checkpoints)
+ [Convergence à l'aide du modèle parallèle et TensorFlow](#distributed-ts-model-parallel-tf-convergence)
+ [Ralentissement ou plantage des tâches d'entraînement distribuée](#distributed-ts-model-parallel-training-issues)
+ [Réception d'une erreur NCCL pour un job de formation PyTorch](#distributed-ts-model-parallel-nccl-error)
+ [Reçu `RecursionError` pour un poste PyTorch de formation](#distributed-ts-model-parallel-super-forward-not-supported)

## Considérations relatives à l'utilisation du SageMaker débogueur avec la bibliothèque de parallélisme de SageMaker modèles
<a name="distributed-ts-model-parallel-debugger"></a>

SageMaker Le débogueur n'est pas disponible pour la bibliothèque de parallélisme du SageMaker modèle. Le débogueur est activé par défaut pour toutes les tâches SageMaker TensorFlow et les tâches de PyTorch formation, et il est possible que le message d'erreur suivant s'affiche : 

```
FileNotFoundError: [Errno 2] No such file or directory: '/opt/ml/checkpoints/metadata.json.sagemaker-uploading
```

Pour résoudre ce problème, désactivez Debugger en transmettant `debugger_hook_config=False` lors de la création d'un cadre `estimator`, comme illustré dans l'exemple suivant.

```
bucket=sagemaker.Session().default_bucket()
base_job_name="sagemaker-checkpoint-test"
checkpoint_in_bucket="checkpoints"

# The S3 URI to store the checkpoints
checkpoint_s3_bucket="s3://{}/{}/{}".format(bucket, base_job_name, checkpoint_in_bucket)

estimator = TensorFlow(
    ...

    distribution={"smdistributed": {"modelparallel": { "enabled": True }}},
    checkpoint_s3_uri=checkpoint_s3_bucket,
    checkpoint_local_path="/opt/ml/checkpoints",
    debugger_hook_config=False
)
```

## Sauvegarde des points de contrôle
<a name="distributed-ts-model-parallel-checkpoints"></a>

Vous pouvez rencontrer l'erreur suivante lors de l'enregistrement des points de contrôle d'un grand modèle sur SageMaker AI : 

```
InternalServerError: We encountered an internal error. Please try again
```

Cela peut être dû à une limitation de l' SageMaker IA lors du téléchargement du point de contrôle local sur Amazon S3 pendant l'entraînement. Pour désactiver le point de contrôle dans SageMaker AI, utilisez l'exemple suivant pour télécharger explicitement les points de contrôle.

Si vous rencontrez l'erreur précédente, ne l'utilisez pas `checkpoint_s3_uri` avec l' SageMaker `estimator`appel. Lors de la sauvegarde des points de contrôle pour les modèles plus volumineux, nous vous recommandons de sauvegarder les points de contrôle dans un répertoire personnalisé et de les transmettre à la fonction d'assistance (en tant qu'argument `local_path`).

```
import os

def aws_s3_sync(source, destination):
    """aws s3 sync in quiet mode and time profile"""
    import time, subprocess
    cmd = ["aws", "s3", "sync", "--quiet", source, destination]
    print(f"Syncing files from {source} to {destination}")
    start_time = time.time()
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    p.wait()
    end_time = time.time()
    print("Time Taken to Sync: ", (end_time-start_time))
    return

def sync_local_checkpoints_to_s3(local_path="/opt/ml/checkpoints", s3_uri=os.path.dirname(os.path.dirname(os.getenv('SM_MODULE_DIR', '')))+'/checkpoints'):
    """ sample function to sync checkpoints from local path to s3 """

    import boto3
    #check if local path exists
    if not os.path.exists(local_path):
        raise RuntimeError("Provided local path {local_path} does not exist. Please check")

    #check if s3 bucket exists
    s3 = boto3.resource('s3')
    if not s3_uri.startswith("s3://"):
        raise ValueError(f"Provided s3 uri {s3_uri} is not valid.")

    s3_bucket = s3_uri.replace('s3://','').split('/')[0]
    print(f"S3 Bucket: {s3_bucket}")
    try:
        s3.meta.client.head_bucket(Bucket=s3_bucket)
    except Exception as e:
        raise e
    aws_s3_sync(local_path, s3_uri)
    return

def sync_s3_checkpoints_to_local(local_path="/opt/ml/checkpoints", s3_uri=os.path.dirname(os.path.dirname(os.getenv('SM_MODULE_DIR', '')))+'/checkpoints'):
    """ sample function to sync checkpoints from s3 to local path """

    import boto3
    #try to create local path if it does not exist
    if not os.path.exists(local_path):
        print(f"Provided local path {local_path} does not exist. Creating...")
        try:
            os.makedirs(local_path)
        except Exception as e:
            raise RuntimeError(f"Failed to create {local_path}")

    #check if s3 bucket exists
    s3 = boto3.resource('s3')
    if not s3_uri.startswith("s3://"):
        raise ValueError(f"Provided s3 uri {s3_uri} is not valid.")

    s3_bucket = s3_uri.replace('s3://','').split('/')[0]
    print(f"S3 Bucket: {s3_bucket}")
    try:
        s3.meta.client.head_bucket(Bucket=s3_bucket)
    except Exception as e:
        raise e
    aws_s3_sync(s3_uri, local_path)
    return
```

Utilisation des fonctions d'assistance :

```
#base_s3_uri - user input s3 uri or save to model directory (default)
#curr_host - to save checkpoints of current host
#iteration - current step/epoch during which checkpoint is saved

# save checkpoints on every node using local_rank
if smp.local_rank() == 0:
    base_s3_uri = os.path.dirname(os.path.dirname(os.getenv('SM_MODULE_DIR', '')))
    curr_host = os.environ['SM_CURRENT_HOST']
    full_s3_uri = f'{base_s3_uri}/checkpoints/{curr_host}/{iteration}'
    sync_local_checkpoints_to_s3(local_path=checkpoint_dir, s3_uri=full_s3_uri)
```

## Convergence à l'aide du modèle parallèle et TensorFlow
<a name="distributed-ts-model-parallel-tf-convergence"></a>

Lorsque vous utilisez l'entraînement multi-nœuds basé sur l' SageMaker IA TensorFlow et la bibliothèque de parallélisme du modèle, la perte risque de ne pas converger comme prévu, car l'ordre des fichiers d'entrée d'entraînement peut être différent sur chaque nœud. Certains rangs différents du même groupe de modèles parallèles peuvent alors travailler sur différents fichiers d'entrée, ce qui provoque des incohérences. Pour éviter cela, assurez-vous que les fichiers d'entrée sont ordonnés de la même manière dans tous les rangs avant qu'ils ne soient convertis en TensorFlow ensembles de données. Une façon d'y parvenir consiste à trier les noms de fichiers d'entrée dans le script d'entraînement.

## Ralentissement ou plantage des tâches d'entraînement distribuée
<a name="distributed-ts-model-parallel-training-issues"></a>

Si votre tâche d'entraînement présente un ralentissement, un plantage ou ne répond pas, lisez les éléments de dépannage suivants pour identifier la cause du problème. Si vous avez besoin d'une assistance supplémentaire, contactez l'équipe de formation SageMaker distribuée via le [AWS support](https://aws.amazon.com/premiumsupport).
+  Si vous voyez **une tâche d'entraînement distribuée qui ralentit à l'étape d'initialisation de la NCCL**, considérez ce qui suit : 
  + Si vous utilisez l'une des instances compatibles EFA (`ml.p4d` ou `ml.p3dn`) avec un VPC personnalisé et son sous-réseau, assurez-vous que le groupe de sécurité utilisé dispose de connexions entrantes et sortantes pour tous les ports vers et depuis le même SG. En règle générale, vous avez également besoin de connexions sortantes à n'importe quelle adresse IP en tant que règle distincte (pour l'accès Internet). Pour obtenir des instructions sur la façon d'ajouter des règles entrantes et sortantes pour la communication de l'EPT, consultez [SageMaker La tâche de formation distribuée basée sur l'IA est bloquée lors de l'initialisation](distributed-troubleshooting-data-parallel.md#distributed-ts-data-parallel-efa-sg).
+ Si vous voyez une **tâche d'entraînement distribuée qui ralentit lors du pointage** du modèle complet, c'est peut-être parce que l'appel `state_dict()` sur le modèle ou l'optimiseur n'a pas été fait dans tous les rangs avec `rdp_rank()==0` (lors de l'utilisation du parallélisme de tenseur) ou `dp_rank()==0` (lorsque vous utilisez uniquement le parallélisme de pipeline). Ces grades doivent communiquer pour construire le point de contrôle à sauvegarder. Des problèmes de blocage similaires peuvent également survenir lors de l'optimisation partielle du point de contrôle si `shard_optimizer_state` est activé. 

  Pour en savoir plus sur la création de points de contrôle d'un modèle avec parallélisme, consultez la section [General Instruction for Saving and Loading](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#general-instruction-for-saving-and-loading) et [Vérification d'un PyTorch modèle distribué (pour la bibliothèque de parallélisme des SageMaker modèles entre v1.6.0 et v1.9.0)](distributed-model-parallel-checkpointing-and-finetuning.md#model-parallel-extended-features-pytorch-saving-loading-checkpoints).
+ Si le travail de formation tombe en panne avec une **erreur de mémoire insuffisante CUDA**, cela signifie que la configuration de formation distribuée doit être ajustée pour s'adapter au modèle sur le cluster GPU. Pour plus d’informations et de bonnes pratiques, consultez [Installation de la bonne configuration pour un modèle donné](model-parallel-best-practices.md#model-parallel-best-practices-configuration).
+ Si la tâche de formation se bloque en raison d'une **[erreur ECC](https://docs.nvidia.com/deploy/a100-gpu-mem-error-mgmt/index.html) non corrigible**, cela signifie que l'une des tâches du cluster est GPUs défectueuse. Si vous avez besoin d'une assistance technique, partagez l'ARN de la tâche avec l'équipe AWS et redémarrez votre tâche d'entraînement à partir d'un point de contrôle si possible.
+ Dans de rares cas, une configuration de tâche qui fonctionnait auparavant mais qui est proche des limites de la mémoire GPU peut échouer ultérieurement avec un cluster différent en raison d'une **erreur de mémoire insuffisante CUDA**. Cela peut être dû au fait que certains GPU ont une mémoire disponible plus faible que d'habitude en raison d'erreurs ECC.
+ Un **crash du délai d'expiration du réseau** peut se produire lors de l'exécution d'une tâche à nœuds multiples qui n'utilise pas tout GPUs le contenu du nœud. Pour contourner ce problème, utilisez tout GPUs sur le nœud en vous assurant que le `processes_per_host` paramètre est défini sur le nombre de GPUs dans chaque instance. Par exemple, il s'agit de `processes_per_host=8` pour les instances `ml.p3.16xlarge`, `ml.p3dn.24xlarge`, et `ml.p4d.24xlarge`.
+ Si vous constatez que votre tâche de formation prend beaucoup de temps pendant la phase de téléchargement des données, assurez-vous que le chemin Amazon S3 que vous avez indiqué `checkpoint_s3_uri` pour le SageMaker `Estimator` cours est unique pour le poste de formation en cours. Si ce chemin est réutilisé dans plusieurs tâches d'entraînement exécutées simultanément, tous ces points de contrôle sont téléchargés et téléchargés sur le même chemin Amazon S3 et peuvent augmenter considérablement le temps de chargement des points de contrôle.
+  FSx À utiliser pour Lustre lorsque vous traitez des données et des modèles volumineux.
  + Si votre jeu de données est volumineux et que son extraction prend du temps, nous vous recommandons de le conserver dans [FSx Lustre](https://aws.amazon.com/fsx/lustre/).
  + Lorsque les modèles d'entraînement dépassent 10 milliards de paramètres, nous vous recommandons d'utiliser FSx for Lustre pour le point de contrôle.
  + Une fois que vous avez créé un système de fichiers, veillez à attendre que le statut devienne **disponible** avant de démarrer une tâche d'entraînement pour l'utiliser. 

## Réception d'une erreur NCCL pour un job de formation PyTorch
<a name="distributed-ts-model-parallel-nccl-error"></a>

Si vous avez rencontré l'erreur suivante, cela peut être dû à un processus à court de mémoire GPU.

```
NCCL error in: ../torch/lib/c10d/ProcessGroupNCCL.cpp:825, unhandled system error, NCCL version 2.7.8
ncclSystemError: System call (socket, malloc, munmap, etc) failed.
```

Vous pouvez résoudre ce problème en réduisant la taille du lot ou `active_microbatches`. Si le partitionnement automatique n'entraîne pas un partitionnement équilibré, vous devrez peut-être envisager un partitionnement manuel. Pour de plus amples informations, veuillez consulter [Parallélisme de pipeline entre nœuds](model-parallel-best-practices.md#model-parallel-best-practices-configuration-pipeline-across-nodes).

## Reçu `RecursionError` pour un poste PyTorch de formation
<a name="distributed-ts-model-parallel-super-forward-not-supported"></a>

La bibliothèque ne prend pas en charge les appels `super.forward()` dans l'appel indirect d'un module. Si vous utilisez `super.forward()`, vous risquez de recevoir le message d'erreur suivant. 

```
RecursionError: maximum recursion depth exceeded
```

Pour corriger l'erreur, au lieu d'appeler `super.forward()`, vous devez appeler `super()._orig_forward()`. 