

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.

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