

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Caratteristiche principali della SageMaker Model Parallelism Library
<a name="model-parallel-core-features"></a>

La libreria di parallelismo dei modelli di Amazon SageMaker AI offre strategie di distribuzione e tecniche di risparmio di memoria, come il parallelismo dei dati condivisi, il parallelismo tensoriale, il partizionamento dei modelli per livelli per la pianificazione delle pipeline e il checkpoint. Le strategie e le tecniche di parallelismo dei modelli aiutano a distribuire modelli di grandi dimensioni su più dispositivi, ottimizzando al contempo la velocità di addestramento e il consumo di memoria. La libreria fornisce anche funzioni di supporto in Python, gestori di contesto e funzioni wrapper per adattare lo script di addestramento per il partizionamento automatico o manuale del modello.

Quando implementi il parallelismo dei modelli nel tuo processo di formazione, mantieni lo stesso flusso di lavoro in due fasi mostrato nella sezione [Esegui un processo di SageMaker formazione distribuito con parallelismo del modello](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-use-api.html). Per adattare lo script di addestramento, aggiungerete zero o poche righe di codice aggiuntive allo script di addestramento. Per avviare un processo di addestramento dello script di addestramento adattato, è necessario impostare i parametri di configurazione della distribuzione per attivare le funzioni di risparmio di memoria o per trasmettere i valori relativi al grado di parallelismo.

Per iniziare con degli esempi, consultate i seguenti notebook Jupyter che dimostrano come utilizzare la libreria di parallelismo dei modelli. SageMaker 
+ [PyTorch quaderni di esempio](https://github.com/aws/amazon-sagemaker-examples/tree/main/training/distributed_training/pytorch/model_parallel)
+ [TensorFlow quaderni di esempio](https://github.com/aws/amazon-sagemaker-examples/tree/main/training/distributed_training/tensorflow/model_parallel/mnist)

Per approfondire le caratteristiche principali della libreria, consulta i seguenti argomenti.

**Nota**  
Le librerie di formazione SageMaker distribuite sono disponibili tramite i contenitori di AWS deep learning per PyTorch Hugging Face e TensorFlow all'interno della piattaforma Training. SageMaker Per utilizzare le funzionalità delle librerie di formazione distribuite, ti consigliamo di utilizzare SageMaker Python SDK. Puoi anche configurare manualmente la sintassi della richiesta JSON se la utilizzi SageMaker APIs tramite SDK for Python (Boto3) o. AWS Command Line Interface In tutta la documentazione, le istruzioni e gli esempi si concentrano su come utilizzare le librerie di formazione distribuite con SageMaker Python SDK.

**Importante**  
La libreria di parallelismo dei SageMaker modelli supporta tutte le funzionalità principali e supporta il parallelismo delle PyTorch pipeline per. TensorFlow

**Topics**
+ [Parallelismo dei dati partizionati](model-parallel-extended-features-pytorch-sharded-data-parallelism.md)
+ [Pipeline di un modello](model-parallel-core-features-pipieline-parallelism.md)
+ [Parallelismo tensoriale](model-parallel-extended-features-pytorch-tensor-parallelism.md)
+ [Partizione dello stato dell'ottimizzatore](model-parallel-extended-features-pytorch-optimizer-state-sharding.md)
+ [Checkpoint di attivazione](model-parallel-extended-features-pytorch-activation-checkpointing.md)
+ [Offload di attivazione](model-parallel-extended-features-pytorch-activation-offloading.md)
+ [FP16 Formazione con Model Parallelism](model-parallel-extended-features-pytorch-fp16.md)
+ [Support per FlashAttention](model-parallel-attention-head-size-for-flash-attention.md)

# Parallelismo dei dati partizionati
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism"></a>

Il *parallelismo dei dati condivisi* è una tecnica di addestramento distribuito che consente di risparmiare memoria che suddivide lo stato di un modello (parametri del modello, gradienti e stati dell'ottimizzatore) in un gruppo parallelo di dati. GPUs 

**Nota**  
Il parallelismo dei dati suddivisi è disponibile nella libreria di parallelismo dei modelli v1.11.0 e versioni successive. PyTorch SageMaker 

Quando si ridimensiona il processo di formazione su un cluster di GPU di grandi dimensioni, è possibile ridurre l'ingombro di memoria per GPU del modello suddividendo lo stato di addestramento del modello su più livelli. GPUs Ciò offre due vantaggi: è possibile utilizzare modelli più grandi, che altrimenti esaurirebbero la memoria con il parallelismo dei dati standard, oppure è possibile aumentare la dimensione del batch utilizzando la memoria della GPU liberata.

La tecnica standard di parallelismo dei dati replica gli stati di addestramento GPUs in tutto il gruppo parallelo di dati ed esegue l'aggregazione del gradiente in base all'operazione. `AllReduce` Il parallelismo dei dati partizionati modifica la procedura di addestramento distribuito standard parallelo ai dati per tenere conto della natura di partizionamento degli stati dell'ottimizzatore. Un gruppo di classificazioni sui cui gli stati del modello e dell'ottimizzatore sono partizionati viene chiamato *gruppo di partizione*. *La tecnica di parallelismo dei dati frammentati suddivide i parametri addestrabili di un modello e i gradienti e gli stati di ottimizzazione corrispondenti all'interno del gruppo di sharding. GPUs *

SageMaker [L'intelligenza artificiale raggiunge il parallelismo condiviso dei dati attraverso l'implementazione di MIC, di cui si parla nel post sul blog Near-linear scaling of gigantic-model training on. AWSAWS](https://www.amazon.science/blog/near-linear-scaling-of-gigantic-model-training-on-aws) In questa implementazione, è possibile impostare il grado di partizionamento come parametro configurabile, che deve essere inferiore al grado di parallelismo dei dati. Durante ogni passaggio in avanti e all'indietro, i MIC ricombinano temporaneamente i parametri del modello durante l'intera operazione. GPUs `AllGather` Dopo il passaggio in avanti o all'indietro di ogni livello, MiCS partiziona nuovamente i parametri per risparmiare memoria della GPU. Durante il passaggio all'indietro, i MIC riducono i gradienti e li suddividono simultaneamente attraverso l'operazione. GPUs `ReduceScatter` Infine, MiCS applica i gradienti locali ridotti e partizionati alle corrispondenti partizioni di parametri locali, utilizzando le partizioni locali degli stati dell'ottimizzatore. Per ridurre il sovraccarico di comunicazione, la libreria di parallelismo dei SageMaker modelli precarica i livelli successivi in avanti o indietro e sovrappone la comunicazione di rete al calcolo.

Lo stato di addestramento del modello viene replicato tra i gruppi di partizione. Ciò significa che prima di applicare i gradienti ai parametri, l'operazione `AllReduce` deve avvenire tra i gruppi di partizione, oltre all'operazione `ReduceScatter` che avviene all'interno del gruppo di partizione.

In effetti, il parallelismo dei dati partizionati introduce un compromesso tra il sovraccarico delle comunicazioni e l'efficienza della memoria della GPU. L'uso del parallelismo dei dati partizionati aumenta i costi della comunicazione, ma l'ingombro della memoria della GPU (escluso l'utilizzo della memoria dovuto alle attivazioni) viene suddiviso per il grado di parallelismo dei dati partizionati, quindi è possibile inserire modelli più grandi nel cluster della GPU.

**Selezione del grado di parallelismo dei dati partizionati**

Quando si seleziona un valore per il grado di parallelismo dei dati partizionati, il valore deve dividere equamente il grado di parallelismo dei dati. Ad esempio, per un processo di parallelismo dei dati a 8 vie, scegli 2, 4 o 8 per il grado di parallelismo dei dati partizionati. Nella scelta del grado di parallelismo dei dati partizionati, si consiglia di iniziare con un numero piccolo e di aumentarlo gradualmente fino a quando il modello non si adatta alla memoria con la dimensione del batch desiderata.

**Selezione della dimensione del batch**

Dopo aver impostato il parallelismo dei dati partizionati, assicurati di trovare la configurazione di addestramento più ottimale che possa essere eseguito correttamente sul cluster GPU. Per addestrare modelli linguistici di grandi dimensioni (LLM), iniziate dalla dimensione del batch 1 e aumentatela gradualmente fino a raggiungere il punto in cui si verificherà l'errore (OOM). out-of-memory Se riscontri l'errore OOM anche con la dimensione del batch più piccola, applica un grado più elevato di parallelismo dei dati partizionati o una combinazione di parallelismo dei dati partizionati e parallelismo tensoriale.

**Topics**
+ [Come applicare il parallelismo dei dati partizionati al tuo processo di addestramento](#model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use)
+ [Configurazioni di riferimento](#model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use-config-sample)
+ [Parallelismo dei dati partizionati con i collettivi SMDDP](#model-parallel-extended-features-pytorch-sharded-data-parallelism-smddp-collectives)
+ [Addestramento misto di precisione con parallelismo di dati partizionati](#model-parallel-extended-features-pytorch-sharded-data-parallelism-16bits-training)
+ [Parallelismo dei dati partizionati con parallelismo tensoriale](#model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism)
+ [Suggerimenti e considerazioni per l'utilizzo del parallelismo dei dati partizionati](#model-parallel-extended-features-pytorch-sharded-data-parallelism-considerations)

## Come applicare il parallelismo dei dati partizionati al tuo processo di addestramento
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use"></a>

Per iniziare con il parallelismo dei dati frammentati, applica le modifiche necessarie allo script di addestramento e configura lo stimatore con i SageMaker PyTorch parametri. sharded-data-parallelism-specific Considera anche di prendere come punto di partenza i valori di riferimento e i notebook di esempio.

### PyTorch Adatta il tuo script di allenamento
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use-modify-script"></a>

Segui le istruzioni riportate nella [Fase 1: Modifica uno script di PyTorch addestramento](model-parallel-customize-training-script-pt.md) per avvolgere il modello e gli oggetti dell'ottimizzatore con i `smdistributed.modelparallel.torch` wrapper dei `torch.nn.parallel` moduli and. `torch.distributed`

**(Facoltativo) Modifica aggiuntiva per registrare i parametri esterni del modello**

Se il modello è costruito con `torch.nn.Module` e utilizza parametri che non sono definiti all'interno della classe del modulo, è necessario registrarli manualmente nel modulo per consentire a SMP di raccogliere i parametri completi. Per registrare i parametri in un modulo, utilizza `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
```

### Configura lo stimatore SageMaker PyTorch
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use-set-estimator"></a>

Quando configuri uno SageMaker PyTorch stimatore[Fase 2: Avviare un job di formazione utilizzando SageMaker Python SDK](model-parallel-sm-sdk.md), aggiungi i parametri per il parallelismo dei dati suddivisi. 

Per attivare il parallelismo dei dati frammentati, aggiungi il parametro all'Estimator. `sharded_data_parallel_degree` SageMaker PyTorch Questo parametro specifica il numero di volte in cui viene suddiviso lo stato GPUs di allenamento. Il valore di `sharded_data_parallel_degree` deve essere un numero intero compreso tra uno e il grado di parallelismo dei dati e deve dividere equamente il grado di parallelismo dei dati. Si noti che la libreria rileva automaticamente il numero di dati, GPUs quindi il grado di parallelità dei dati. I seguenti parametri aggiuntivi sono disponibili per configurare il parallelismo dei dati partizionati.
+ `"sdp_reduce_bucket_size"`*(int, default: 5e8)* — Specifica la dimensione dei [bucket di gradiente PyTorch DDP](https://pytorch.org/docs/stable/notes/ddp.html#internal-design) in numero di elementi del dtype predefinito.
+ `"sdp_param_persistence_threshold"`*(int, default: 1e6)*: specifica la dimensione di un tensore di parametri in numero di elementi che possono persistere in ogni GPU. Il parallelismo dei dati condivisi divide ogni tensore di parametri in un gruppo parallelo di GPUs dati. Se il numero di elementi nel tensore dei parametri è inferiore a questa soglia, il tensore del parametro non viene suddiviso; ciò aiuta a ridurre il sovraccarico di comunicazione perché il tensore del parametro viene replicato su dati paralleli. GPUs
+ `"sdp_max_live_parameters"`*(int, default: 1e9)*: specifica il numero massimo di parametri che possono trovarsi contemporaneamente in uno stato di addestramento ricombinato durante il passaggio in avanti e all'indietro. Il recupero dei parametri con l'operazione `AllGather` si interrompe quando il numero di parametri attivi raggiunge la soglia specificata. Si noti che l'aumento di questo parametro aumenta l'ingombro di memoria.
+ `"sdp_hierarchical_allgather"`*(bool, default: True)*: se impostato su `True`, l'operazione `AllGather`viene eseguita in modo gerarchico: viene eseguita prima all'interno di ogni nodo e poi tra i nodi. Per i processi di addestramento distribuito su più nodi, l'operazione `AllGather` gerarchica viene attivata automaticamente.
+ `"sdp_gradient_clipping"`*(float, default: 1.0)*: specifica una soglia per il ritaglio del gradiente secondo la norma L2 dei gradienti prima di propagarli all'indietro attraverso i parametri del modello. Quando è attivato il parallelismo dei dati partizionati, viene attivato anche il ritaglio del gradiente. La soglia predefinita è `1.0`. Regola questo parametro se hai il problema dei gradienti esplosivi.

Il codice seguente mostra un esempio di come configurare il parallelismo dei dati partizionati.

```
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/')
```

## Configurazioni di riferimento
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use-config-sample"></a>

Il team di formazione SageMaker distribuito fornisce le seguenti configurazioni di riferimento che è possibile utilizzare come punto di partenza. Puoi estrapolare le configurazioni seguenti per sperimentare e stimare l'utilizzo della memoria della GPU per la configurazione del modello. 

Parallelismo dei dati partizionati con i collettivi SMDDP


| Modello/numero di parametri | Numero di istanze | Tipo di istanza | Lunghezza della sequenza | Dimensioni batch globali | Dimensioni del mini-batch | Grado parallelo di dati partizionati | 
| --- | --- | --- | --- | --- | --- | --- | 
| GPT-NEOX-20B | 2 | ml.p4d.24xlarge | 2048 | 64 | 4 | 16 | 
| GPT-NEOX-20B | 8 | ml.p4d.24xlarge | 2048 | 768 | 12 | 32 | 

Ad esempio, se aumenti la lunghezza della sequenza per un modello da 20 miliardi di parametri o aumenti le dimensioni del modello a 65 miliardi di parametri, dovresti prima provare a ridurre la dimensione del batch. Se il modello continua a non adattarsi alla dimensione del batch più piccola (la dimensione del batch pari a 1), prova ad aumentare il grado di parallelismo del modello.

Parallelismo dei dati partizionati con parallelismo tensoriale e collettivi NCCL


| Modello/numero di parametri | Numero di istanze | Tipo di istanza | Lunghezza della sequenza | Dimensioni batch globali | Dimensioni del mini-batch | Grado parallelo di dati partizionati | Grado di parallelo tensoriale | Offload di attivazione | 
| --- | --- | --- | --- | --- | --- | --- | --- | --- | 
| 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'uso combinato del parallelismo dei dati frammentati e del parallelismo tensoriale è utile quando si desidera inserire un modello linguistico di grandi dimensioni (LLM) in un cluster su larga scala utilizzando dati di testo con una lunghezza di sequenza maggiore, il che porta a utilizzare un batch di dimensioni inferiori e, di conseguenza, a gestire l'utilizzo della memoria della GPU per allenarsi con sequenze di testo più lunghe. LLMs Per ulteriori informazioni, consulta [Parallelismo dei dati partizionati con parallelismo tensoriale](#model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism).

Per case study, benchmark e altri esempi di configurazione, consulta il post sul blog [Nuovi miglioramenti delle prestazioni nella libreria parallela del modello Amazon SageMaker AI](https://aws.amazon.com/blogs/machine-learning/new-performance-improvements-in-amazon-sagemaker-model-parallel-library/).

## Parallelismo dei dati partizionati con i collettivi SMDDP
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-smddp-collectives"></a>

La libreria di parallelismo SageMaker dei dati offre primitive di comunicazione collettiva (collettivi SMDDP) ottimizzate per l'infrastruttura. AWS Raggiunge l'ottimizzazione adottando un modello di all-to-all-type comunicazione basato sull'uso di [Elastic Fabric Adapter (](https://aws.amazon.com/hpc/efa/)EFA), che si traduce in collettivi ad alta velocità e meno sensibili alla latenza, scaricando l'elaborazione relativa alla comunicazione sulla CPU e liberando cicli di GPU per il calcolo. Su cluster di grandi dimensioni, i collettivi SMDDP possono offrire miglioramenti nelle prestazioni di addestramento distribuito fino al 40% rispetto a NCCL. Per case study e risultati di benchmark, consulta il blog [Nuovi miglioramenti delle prestazioni nella libreria di parallelismo dei modelli Amazon SageMaker AI](https://aws.amazon.com/blogs/machine-learning/new-performance-improvements-in-amazon-sagemaker-model-parallel-library/).

**Nota**  
Il parallelismo dei dati condivisi con SMDDP Collectives è disponibile nella libreria di parallelismo dei SageMaker modelli v1.13.0 e successive e nella libreria di parallelismo dei dati v1.6.0 e successive. SageMaker Vedi anche [Supported configurations](#sharded-data-parallelism-smddp-collectives-supported-config) per utilizzare il parallelismo dei dati partizionati con i collettivi SMDDP.

Nel parallelismo dei dati partizionati, che è una tecnica comunemente usata nell'addestramento distribuito su larga scala, il collettivo `AllGather` viene utilizzato per ricostituire i parametri dei livelli partizionati per i calcoli dei passaggi avanti e indietro, in parallelo al calcolo della GPU. Per i modelli di grandi dimensioni, eseguire l'operazione `AllGather` in modo efficiente è fondamentale per evitare problemi legati alla GPU e rallentare la velocità di addestramento. Quando viene attivato il parallelismo dei dati partizionati, i collettivi SMDDP entrano a far parte di questi collettivi `AllGather` critici in termini di prestazioni, migliorando la produttività dell'addestramento.

**Addestramento con i collettivi SMDDP**

Quando il processo di addestramento ha attivato il parallelismo dei dati partizionati e soddisfa i requisiti [Supported configurations](#sharded-data-parallelism-smddp-collectives-supported-config), i collettivi SMDDP vengono attivati automaticamente. Internamente, i collettivi SMDDP ottimizzano il collettivo per renderlo efficiente sull'infrastruttura e ricorrono a NCCL per tutti gli altri collettivi. `AllGather` AWS Inoltre, in configurazioni non supportate, tutti i collettivi, incluso `AllGather`, utilizzano automaticamente il back-end NCCL.

A partire dalla versione 1.13.0 della libreria di parallelismo dei SageMaker modelli, il parametro viene aggiunto alle opzioni. `"ddp_dist_backend"` `modelparallel` Il valore predefinito per questo parametro di configurazione è `"auto"`, che utilizza i collettivi SMDDP quando possibile, altrimenti ricorre a NCCL. Per forzare la libreria a utilizzare sempre NCCL, specifica `"nccl"` nel parametro di configurazione `"ddp_dist_backend"`. 

Il seguente esempio di codice mostra come impostare uno PyTorch stimatore utilizzando il parallelismo dei dati frammentati con il `"ddp_dist_backend"` parametro, che è impostato come impostazione predefinita e, pertanto, facoltativo `"auto"` da aggiungere. 

```
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/')
```

**Configurazioni supportate**

L'operazione `AllGather` con i collettivi SMDDP viene attivata nei processi di addestramento quando vengono soddisfatti tutti i seguenti requisiti di configurazione.
+ Il grado di parallelismo dei dati partizionati è maggiore di 1
+ `Instance_count` maggiore di 1 
+ `Instance_type` uguale a `ml.p4d.24xlarge` 
+ SageMaker contenitore di formazione per v1.12.1 o versione successiva PyTorch 
+ La libreria di parallelismo SageMaker dei dati v1.6.0 o successiva
+ La libreria di SageMaker parallelismo dei modelli v1.13.0 o successiva

**Ottimizzazione delle prestazioni e della memoria**

I collettivi SMDDP utilizzano memoria GPU aggiuntiva. Esistono due variabili di ambiente per configurare l'utilizzo della memoria della GPU a seconda dei diversi casi d'uso di addestramento del modello.
+ `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES`: durante l'operazione `AllGather` SMDDP, il buffer di input `AllGather` viene copiato in un buffer temporaneo per la comunicazione tra i nodi. La variabile `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES` controlla la dimensione (in byte) di questo buffer temporaneo. Se la dimensione del buffer temporaneo è inferiore alla dimensione del buffer di input `AllGather`, il collettivo `AllGather` torna a utilizzare NCCL.
  + Valore predefinito: 16 \$1 1024 \$1 1024 (16 MB)
  + Valori accettabili: qualsiasi multiplo di 8192
+  `SMDDP_AG_SORT_BUFFER_SIZE_BYTES`: la variabile `SMDDP_AG_SORT_BUFFER_SIZE_BYTES` serve a dimensionare il buffer temporaneo (in byte) per contenere i dati raccolti dalla comunicazione tra i nodi. Se la dimensione di questo buffer temporaneo è inferiore a `1/8 * sharded_data_parallel_degree * AllGather input size`, il collettivo `AllGather` torna a utilizzare NCCL.
  + Valore predefinito: 128 \$1 1024 \$1 1024 (128 MB)
  + Valori accettabili: qualsiasi multiplo di 8192

**Guida all'ottimizzazione delle variabili relative alla dimensione del buffer**

I valori predefiniti per le variabili di ambiente dovrebbero funzionare bene per la maggior parte dei casi d'uso. Consigliamo di ottimizzare queste variabili solo se durante l'addestramento si verifica l'errore (OOM). out-of-memory 

L'elenco seguente illustra alcuni suggerimenti di ottimizzazione per ridurre l'ingombro di memoria della GPU dei collettivi SMDDP, preservando al contempo il miglioramento delle prestazioni che ne derivano.
+ Ottimizzazione `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES`
  + La dimensione del buffer di input `AllGather` è inferiore per i modelli più piccoli. Pertanto, la dimensione richiesta per `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES` può essere inferiore per i modelli con meno parametri.
  + La dimensione del buffer di `AllGather` input diminuisce all'`sharded_data_parallel_degree`aumentare, poiché il modello viene ulteriormente suddiviso. GPUs Pertanto, la dimensione richiesta per `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES` può essere inferiore per processi di addestramento con valori grandi per `sharded_data_parallel_degree`.
+ Ottimizzazione `SMDDP_AG_SORT_BUFFER_SIZE_BYTES`
  + La quantità di dati raccolti dalla comunicazione tra nodi è inferiore per i modelli con un minor numero di parametri. Pertanto, la dimensione richiesta per `SMDDP_AG_SORT_BUFFER_SIZE_BYTES` può essere inferiore per tali modelli con un numero inferiore di parametri.

Alcuni collettivi potrebbero tornare a utilizzare NCCL; di conseguenza, potresti non ottenere il miglioramento delle prestazioni dai collettivi SMDDP ottimizzati. Se è disponibile memoria GPU aggiuntiva, è possibile valutare la possibilità di aumentare i valori `SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES` e `SMDDP_AG_SORT_BUFFER_SIZE_BYTES` per trarre vantaggio dall'aumento delle prestazioni.

Il codice seguente mostra come configurare le variabili di ambiente aggiungendole `mpi_options` nel parametro di distribuzione dello stimatore. PyTorch 

```
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/')
```

## Addestramento misto di precisione con parallelismo di dati partizionati
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-16bits-training"></a>

Per risparmiare ulteriormente la memoria della GPU con numeri in virgola mobile a mezza precisione e parallelismo dei dati frammentati, puoi attivare il formato a virgola mobile a 16 bit (FP16) o il formato a virgola mobile [Brain () aggiungendo un parametro aggiuntivo alla configurazione di addestramento](https://en.wikichip.org/wiki/brain_floating-point_format) distribuitoBF16.

**Nota**  
L'addestramento misto di precisione con parallelismo dei dati condiviso è disponibile nella libreria di parallelismo dei modelli v1.11.0 e versioni successive. SageMaker 

**Per FP16 la formazione con Sharded Data Parallelism**

Per eseguire l' FP16 allenamento con il parallelismo dei dati condivisi, aggiungilo al dizionario di configurazione. `"fp16": True"` `smp_options` Nello script di addestramento, puoi scegliere tra le opzioni di dimensionamento delle perdite statiche e dinamiche tramite il modulo `smp.DistributedOptimizer`. Per ulteriori informazioni, consulta [FP16 Formazione con Model Parallelism](model-parallel-extended-features-pytorch-fp16.md).

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

**Per la BF16 formazione con Sharded Data Parallelism**

La funzionalità di parallelismo dei dati condivisi dell' SageMaker IA supporta l'addestramento sul tipo di dati. BF16 Il tipo di BF16 dati utilizza 8 bit per rappresentare l'esponente di un numero in virgola mobile, mentre il tipo di dati utilizza 5 bit. FP16 La conservazione degli 8 bit per l'esponente consente di mantenere la stessa rappresentazione dell'esponente di un numero a virgola mobile () a precisione singola a 32 bit. FP32 Ciò semplifica la conversione da un modello all'altro FP32 ed è notevolmente meno incline a causare problemi di overflow e underflow, che spesso si presentano durante l'addestramento, specialmente quando si addestrano modelli BF16 più grandi. FP16 Sebbene entrambi i tipi di dati utilizzino 16 bit in totale, questo maggiore intervallo di rappresentazione dell'esponente nel BF16 formato va a scapito della riduzione della precisione. Per l'addestramento di modelli di grandi dimensioni, questa precisione ridotta è spesso considerata un compromesso accettabile per quanto riguarda la portata e la stabilità dell'addestramento.

**Nota**  
Attualmente, la BF16 formazione funziona solo quando è attivato il parallelismo dei dati suddivisi.

Per eseguire l' BF16 allenamento con il parallelismo dei dati frammentati, aggiungilo al dizionario di configurazione. `"bf16": True` `smp_options`

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

## Parallelismo dei dati partizionati con parallelismo tensoriale
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism"></a>

Se utilizzi il parallelismo dei dati partizionati e devi anche ridurre la dimensione globale del batch, prendi in considerazione l'utilizzo del [parallelismo tensoriale](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-tensor-parallelism.html) con il parallelismo dei dati partizionati. Quando si addestra un modello di grandi dimensioni con parallelismo dei dati partizionati su un cluster di elaborazione molto grande (in genere 128 nodi o più), anche un batch di piccole dimensioni per GPU si traduce in un batch globale di dimensioni molto grandi. Potrebbe portare a problemi di convergenza o a basse prestazioni di calcolo. La riduzione della dimensione del batch per GPU a volte non è possibile con il solo parallelismo dei dati partizionati, quando un singolo batch è già di grandi dimensioni e non può essere ulteriormente ridotto. In questi casi, l'utilizzo del parallelismo dei dati partizionati in combinazione con il parallelismo tensoriale aiuta a ridurre la dimensione globale del batch.

La scelta dei gradi ottimali partizionati di parallelismo dei dati e dei tensori dipende dalla scala del modello, dal tipo di istanza e dalla dimensione globale del batch che è ragionevole per la convergenza del modello. Ti consigliamo di iniziare da un grado di parallelo tensoriale basso per adattare la dimensione globale del batch al cluster di calcolo per risolvere out-of-memory gli errori CUDA e ottenere le migliori prestazioni. Guardate i due casi di esempio seguenti per scoprire come la combinazione del parallelismo tensoriale e del parallelismo dei dati condivisi aiuta a regolare la dimensione globale del batch raggruppando GPUs per il parallelismo del modello, con il risultato di un minor numero di repliche del modello e una dimensione globale del batch più piccola.

**Nota**  
Questa funzionalità è disponibile nella libreria di parallelismo dei modelli v1.15 e supporta la versione 1.13.1. SageMaker PyTorch 

**Nota**  
Questa funzionalità è disponibile per i modelli supportati dalla funzionalità di parallelismo tensoriale della libreria. Per trovare l'elenco dei modelli supportati, consulta [Supporto per i modelli Hugging Face Transformer](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-hugging-face.html). Tieni inoltre presente che devi passare `tensor_parallelism=True` all'argomento `smp.model_creation` mentre modifichi lo script di addestramento. *Per saperne di più, consulta lo script di formazione nell'archivio AI Examples. [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)SageMaker GitHub *

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

Supponiamo di voler addestrare un modello su un cluster di 1536 GPUs (192 nodi con 8 GPUs in ciascuno), impostando il grado di parallelismo dei dati frammentati su 32 (`sharded_data_parallel_degree=32`) e la dimensione del batch per GPU su 1, dove ogni batch ha una lunghezza di sequenza di 4096 token. In questo caso, ci sono 1536 repliche di modelli, la dimensione globale del batch diventa 1536 e ogni batch globale contiene circa 6 milioni di token. 

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

L'aggiunta del parallelismo tensoriale può ridurre la dimensione globale del batch. Un esempio di configurazione può essere l'impostazione del grado parallelo tensoriale su 8 e la dimensione del batch per GPU su 4. Questo forma 192 gruppi tensoriali paralleli o 192 repliche di modelli, in cui ogni replica del modello è distribuita su 8. GPUs La dimensione del batch di 4 è la quantità di dati di addestramento per iterazione e per gruppo parallelo di tensori; ovvero, ogni replica del modello consuma 4 batch per iterazione. In questo caso, la dimensione globale del batch diventa 768 e ogni batch globale contiene circa 3 milioni di token. Pertanto, la dimensione globale del batch è ridotta della metà rispetto al caso precedente con il solo parallelismo dei dati partizionati.

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

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

Quando sono attivati sia il parallelismo dei dati partizionati che il parallelismo tensoriale, la libreria applica innanzitutto il parallelismo tensoriale e partiziona il modello in questa dimensione. Per ogni classificazione parallela dei tensori, il parallelismo dei dati viene applicato come per `sharded_data_parallel_degree`.

Ad esempio, supponiamo di voler impostare 32 GPUs con un grado di parallelo del tensore di 4 (formando gruppi di 4 GPUs), un grado di parallelo dei dati frammentati di 4, finendo con un grado di replica di 2. L'assegnazione crea otto gruppi di GPU in base al grado di parallelismo tensoriale come segue: `(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)`. Cioè, quattro GPUs formano un gruppo parallelo tensoriale. In questo caso, il gruppo parallelo di dati ridotto per il rango 0 GPUs dei gruppi paralleli tensoriali sarebbe. `(0,4,8,12,16,20,24,28)` Il gruppo parallelo di dati ridotto viene suddiviso in base al grado di parallelismo dei dati condivisi pari a 4, ottenendo due gruppi di replica per il parallelismo dei dati. GPUs`(0,4,8,12)`formano un gruppo di sharding, che collettivamente contiene una copia completa di tutti i parametri per lo 0th tensor parallel rank, e GPUs `(16,20,24,28)` formano un altro gruppo di questo tipo. Anche altre classificazioni tensoriali parallele hanno gruppi di partizioni e replica simili.

![\[Figura 1: Gruppi di parallelizzazione tensoriale.\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/sdp_tp_group_tp.jpg)


Figura 1: Gruppi di parallelizzazione tensoriale per (nodi, grado di parallelizzazione dei dati sottoposti a sharding, grado di parallelizzazione tensoriale) = (4, 4, 4), dove ogni rettangolo rappresenta una GPU con indici da 0 a 31. Il parallelismo tensoriale GPUs di forma raggruppa da TPG a TPG. 0 7 I gruppi di replica sono (\$1TPG0, TPG4\$1, \$1TPG1, TPG5\$1, \$1TPG2, TPG6\$1 e \$1TPG3, TPG7\$1); ogni coppia di gruppi di replica condivide lo stesso colore, ma presenta un riempimento diverso.

![\[Figura 2: Gruppi di parallelizzazione dei dati sottoposti a sharding.\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/sdp_tp_group_sdp.jpg)


Figura 2: Gruppi di parallelizzazione dei dati sottoposti a sharding (nodi, grado di parallelizzazione dei dati sottoposti a sharding, grado di parallelizzazione tensoriale) = (4, 4, 4), dove ogni rettangolo rappresenta una GPU con indici da 0 a 31. Il GPUs modulo Sharded Data Parallelism raggruppa da SDPG a SDPG. 0 7 I gruppi di replica sono (\$1SDPG0, SDPG4\$1, \$1SDPG1, SDPG5\$1, \$1SDPG2, SDPG6\$1 e \$1SDPG3, SDPG7\$1); ogni coppia di gruppi di replica condivide lo stesso colore, ma presenta un riempimento diverso.

### Come attivare il parallelismo dei dati partizionati con il parallelismo tensoriale
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism-activate"></a>

Per utilizzare il parallelismo dei dati condivisi con il parallelismo tensoriale, è necessario impostarli entrambi `sharded_data_parallel_degree` e `tensor_parallel_degree` nella configurazione durante la creazione di un oggetto della classe estimator. `distribution` SageMaker PyTorch 

È inoltre necessario attivare `prescaled_batch`. Ciò significa che, invece di leggere il proprio batch di dati, ogni gruppo parallelo tensoriale legge collettivamente un batch combinato della dimensione del batch scelta. In effetti, invece di dividere il set di dati in parti uguali al numero di GPUs (o dimensione parallela dei dati`smp.dp_size()`), lo divide in parti uguali al numero di GPUs diviso per `tensor_parallel_degree` (chiamato anche dimensione parallela dei dati ridotta). `smp.rdp_size()` Per maggiori dettagli sul batch prescalato, consulta [Prescaled Batch](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#prescaled-batch) nella documentazione di *SageMaker Python* SDK. *Vedi anche lo script di addestramento di esempio [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)per GPT-2 nel repository AI Examples. SageMaker GitHub *

Il seguente frammento di codice mostra un esempio di creazione di un oggetto PyTorch estimatore basato sullo scenario sopra menzionato in. [Esempio 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
)
```

## Suggerimenti e considerazioni per l'utilizzo del parallelismo dei dati partizionati
<a name="model-parallel-extended-features-pytorch-sharded-data-parallelism-considerations"></a>

Considerate quanto segue quando utilizzate il parallelismo dei dati frammentati della libreria SageMaker Model Parallelism.
+ Il parallelismo dei dati condivisi è compatibile con la formazione. FP16 Per eseguire l' FP16allenamento, consulta la sezione. [FP16 Formazione con Model Parallelism](model-parallel-extended-features-pytorch-fp16.md)
+ Il parallelismo dei dati partizionati è compatibile con il parallelismo tensoriale. I seguenti elementi sono ciò che potresti dover considerare per utilizzare il parallelismo dei dati partizionati con il parallelismo tensoriale.
  + Quando si utilizza il parallelismo dei dati partizionati con il parallelismo tensoriale, anche i livelli di incorporamento vengono distribuiti automaticamente nel gruppo parallelo tensoriale. In altre parole, il parametro `distribute_embedding` viene impostato automaticamente su `True`. Per maggiori informazioni sul parallelismo tensoriale, consulta [Parallelismo tensoriale](model-parallel-extended-features-pytorch-tensor-parallelism.md).
  + Si noti che il parallelismo dei dati partizionati con il parallelismo tensoriale attualmente utilizza i collettivi NCCL come back-end della strategia di addestramento distribuito.

  Per ulteriori informazioni, consulta la sezione [Parallelismo dei dati partizionati con parallelismo tensoriale](#model-parallel-extended-features-pytorch-sharded-data-parallelism-with-tensor-parallelism).
+ Il parallelismo dei dati partizionati attualmente non è compatibile con il [parallelismo di pipeline](model-parallel-intro.md#model-parallel-intro-pp) o il [partizionamento dello stato dell'ottimizzatore](model-parallel-extended-features-pytorch-optimizer-state-sharding.md). Per attivare il parallelismo dei dati partizionati, disattiva il partizionamento dello stato dell'ottimizzatore e imposta il grado di parallelismo della pipeline su 1.
+ Le funzionalità [checkpoint di attivazione](model-parallel-extended-features-pytorch-activation-checkpointing.md) e [offload di attivazione](model-parallel-extended-features-pytorch-activation-offloading.md) sono compatibili con il parallelismo dei dati partizionati.
+ Per utilizzare il parallelismo dei dati partizionati con l'accumulo di gradienti, impostate l'argomento `backward_passes_per_step` sul numero di fasi di accumulo mentre effettui il wrapping del modello con il modulo [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). Ciò garantisce che l'operazione `AllReduce` del gradiente tra i gruppi di replica del modello (gruppi di partizionamento) avvenga al limite dell'accumulo del gradiente.
+ Puoi eseguire il checkpoint dei tuoi modelli addestrati con il parallelismo dei dati frammentati utilizzando il checkpointing della libreria e. APIs `smp.save_checkpoint` `smp.resume_from_checkpoint` Per ulteriori informazioni, consulta [Verifica di un PyTorch modello distribuito (per la libreria di parallelismo dei SageMaker modelli v1.10.0 e successive)](distributed-model-parallel-checkpointing-and-finetuning.md#model-parallel-extended-features-pytorch-checkpoint).
+ Il comportamento del parametro di configurazione [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) cambia in base al parallelismo dei dati partizionati. Quando queste due funzionalità sono attivate contemporaneamente, i parametri vengono inizializzati immediatamente dopo la creazione del modello in modo partizionato anziché ritardare l'inizializzazione dei parametri, in modo che ogni classificazione inizializzi e memorizzi la propria partizione di parametri.
+ Quando è attivato il parallelismo dei dati partizionati, la libreria esegue internamente il ritaglio del gradiente durante l'esecuzione della chiamata `optimizer.step()`. Non è necessario utilizzare l'utilità per il ritaglio del gradiente, ad APIs esempio. [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) Per regolare il valore di soglia per il ritaglio del gradiente, potete impostarlo tramite il `sdp_gradient_clipping` parametro per la configurazione dei parametri di distribuzione quando costruite lo stimatore, come mostrato nella sezione. SageMaker PyTorch [Come applicare il parallelismo dei dati partizionati al tuo processo di addestramento](#model-parallel-extended-features-pytorch-sharded-data-parallelism-how-to-use)

# Pipeline di un modello
<a name="model-parallel-core-features-pipieline-parallelism"></a>

Una delle caratteristiche principali della libreria di parallelismo dei modelli SageMaker è il parallelismo delle *pipeline, che determina l'ordine in cui vengono eseguiti* i calcoli e i dati vengono elaborati tra i dispositivi durante l'addestramento del modello. Il pipelining è una tecnica per ottenere una vera parallelizzazione nel parallelismo dei modelli, mediante l' GPUs elaborazione simultanea su diversi campioni di dati, e per superare la perdita di prestazioni dovuta al calcolo sequenziale. Quando si utilizza il parallelismo delle pipeline, il processo di addestramento viene eseguito in con pipeline su microbatch per massimizzare l'utilizzo della GPU.

**Nota**  
Il parallelismo delle pipeline, chiamato anche partizionamento dei modelli, è disponibile per entrambi e. PyTorch TensorFlow Per le versioni supportate dei framework, consulta [Framework supportati e Regioni AWS](distributed-model-parallel-support.md).

## Pianificazione di esecuzione della pipeline
<a name="model-parallel-pipeline-execution"></a>

Il pipelining si basa sulla suddivisione di un mini-batch in microbatch, che vengono inseriti nella pipeline one-by-one di formazione e seguono un programma di esecuzione definito dal runtime della libreria. Un *microbatch* è un sottoinsieme più piccolo di un determinato mini-batch di addestramento. La pianificazione della pipeline determina quale microbatch viene eseguito da quale dispositivo per ogni fascia oraria. 

Ad esempio, a seconda della pianificazione della pipeline e della partizione del modello, la GPU `i` potrebbe eseguire il calcolo (in avanti o all'indietro) sul microbatch mentre la GPU `i+1` esegue il calcolo sul microbatch, `b` mantenendo così entrambi attivi contemporaneamente. `b+1` GPUs Durante un singolo passaggio in avanti o indietro, il flusso di esecuzione di un singolo microbatch potrebbe visitare lo stesso dispositivo più volte, a seconda della decisione di partizionamento. Ad esempio, un'operazione che si trova all'inizio del modello potrebbe essere posizionata sullo stesso dispositivo come operazione alla fine del modello, mentre le operazioni intermedie avvengono su dispositivi diversi, il che significa che il dispositivo viene visitato due volte.

La libreria offre due diverse pianificazioni di pipeline, *semplici* e *interlacciate*, che possono essere configurate utilizzando il `pipeline` parametro nell'SDK Python SageMaker . Nella maggior parte dei casi, una pipeline interlacciata può ottenere prestazioni migliori utilizzando la pipeline in modo più efficiente. GPUs 

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

In una pipeline interlacciata, quando possibile, viene data priorità all'esecuzione all'indietro dei microbatch. Ciò consente un rilascio più rapido della memoria utilizzata per le attivazioni, utilizzando la memoria in modo più efficiente. Consente inoltre di aumentare il numero di microbatch, riducendo il tempo di inattività di. GPUs Allo stato stazionario, ogni dispositivo alterna passaggi in avanti e indietro. Ciò significa che il passaggio all'indietro di un microbatch può essere eseguito prima del termine del passaggio in avanti di un altro microbatch.

![\[Esempio di pianificazione di esecuzione per la pipeline interlacciata su 2. GPUs\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/interleaved-pipeline-execution.png)


La figura precedente illustra un esempio di programma di esecuzione per la pipeline interlacciata su 2. GPUs Nella figura, F0 rappresenta il passaggio in avanti del microbatch 0 e B1 rappresenta il passaggio all'indietro del microbatch 1. **Update rappresenta l'aggiornamento** dei parametri da parte dell'ottimizzatore. GPU0 dà sempre la priorità ai passaggi all'indietro quando possibile (ad esempio, esegue B0 prima di F2), il che consente di cancellare la memoria utilizzata per le attivazioni precedenti.

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

Una pipeline semplice, al contrario, termina l'esecuzione del passaggio in avanti di ogni microbatch prima di iniziare il passaggio all'indietro. Ciò significa che convoglia solo le fasi di passaggio in avanti e indietro all'interno di se stesse. La figura seguente illustra un esempio di come funziona, più di 2. GPUs

![\[Esempio di pipeline che esegue il passaggio in avanti di ogni microbatch prima di iniziare il passaggio all’indietro.\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/simple-pipeline-execution.png)


### Esecuzione della pipeline in framework specifici
<a name="model-parallel-pipeline-frameworks"></a>

Utilizza le sezioni seguenti per conoscere la libreria di modelli di parallelismo creata dalla libreria di modelli di parallelismo delle decisioni di pianificazione della pipeline specifica SageMaker del framework per e. TensorFlow PyTorch 

#### Esecuzione della pipeline con TensorFlow
<a name="model-parallel-pipeline-execution-interleaved-tf"></a>

L'immagine seguente è un esempio di un TensorFlow grafico partizionato dalla libreria di parallelismo del modello, utilizzando la suddivisione automatica del modello. Quando un grafico viene suddiviso, ogni sottografo risultante viene replicato B volte (ad eccezione delle variabili), dove B è il numero di microbatch. In questa figura, ogni grafico secondario viene replicato 2 volte (B=2). Un'operazione `SMPInput` viene inserita in ogni input di un grafico secondario e un'operazione `SMPOutput` viene inserita in ogni output. Queste operazioni comunicano con il back-end della libreria per trasferire i tensori da e verso gli altri.

![\[Esempio di TensorFlow grafico partizionato dalla libreria di parallelismo dei modelli, utilizzando la suddivisione automatica del modello.\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/interleaved-pipeline-tf.png)


L'immagine seguente è un esempio di 2 grafici secondari suddivisi con B=2 con l'aggiunta di operazioni di gradiente. Il gradiente di un'operazione `SMPInput` è un'operazione `SMPOutput` e viceversa. Ciò consente ai gradienti di fluire all'indietro durante la retropropagazione.

![\[L’immagine seguente è un esempio di 2 sottografi suddivisi con B=2 con operazioni di gradiente aggiunte.\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/interleaved-pipeline-tf.gif)


Questa GIF mostra un esempio di pianificazione di esecuzione di una pipeline interlacciata con microbatch B=2 e 2 grafici secondari. Ogni dispositivo esegue in sequenza una delle repliche dei grafici secondari per migliorare l'utilizzo della GPU. Man mano che B aumenta, la frazione degli intervalli di inattività scende a zero. Ogni volta che è il momento di eseguire calcoli (in avanti o indietro) su una specifica replica di grafico secondario, il livello della pipeline segnala alle corrispondenti operazioni blu di iniziare l'esecuzione `SMPInput`.

Una volta calcolati i gradienti di tutti i microbatch di un singolo mini-batch, la libreria combina i gradienti tra i microbatch, che possono quindi essere applicati ai parametri. 

#### Esecuzione della pipeline con PyTorch
<a name="model-parallel-pipeline-execution-interleaved-pt"></a>

Concettualmente, il pipelining segue un'idea simile in. PyTorch Tuttavia, poiché PyTorch non prevede grafici statici, la PyTorch funzionalità della libreria di parallelismo dei modelli utilizza un paradigma di pipelining più dinamico. 

Ad esempio TensorFlow, ogni batch è suddiviso in una serie di microbatch, che vengono eseguiti uno alla volta su ciascun dispositivo. Tuttavia, la pianificazione dell'esecuzione viene gestita tramite i server di esecuzione avviati su ciascun dispositivo. Ogni volta che l'output di un sottomodulo posizionato su un altro dispositivo è necessario sul dispositivo corrente, viene inviata una richiesta di esecuzione al server di esecuzione del dispositivo remoto insieme ai tensori di input al sottomodulo. Il server esegue quindi questo modulo con gli input forniti e restituisce la risposta al dispositivo corrente.

Poiché il dispositivo corrente è inattivo durante l'esecuzione del sottomodulo remoto, l'esecuzione locale del microbatch corrente viene messa in pausa e il runtime della libreria commuta l'esecuzione su un altro microbatch su cui il dispositivo corrente può lavorare attivamente. La prioritizzazione dei microbatch è determinata dalla pianificazione della pipeline scelta. Per una pianificazione di pipeline interlacciata, ai microbatch che si trovano nella fase precedente del calcolo viene data priorità ogni volta che è possibile.

# Parallelismo tensoriale
<a name="model-parallel-extended-features-pytorch-tensor-parallelism"></a>

Il *parallelismo tensoriale* è un tipo di parallelismo del modello in cui pesi, gradienti e stati dell'ottimizzatore specifici del modello vengono suddivisi tra i dispositivi. A differenza del parallelismo delle pipeline, che mantiene intatti i singoli pesi ma partiziona il *set* dei pesi, il parallelismo tensoriale suddivide i pesi individuali. Ciò comporta in genere il calcolo distribuito di operazioni, moduli o livelli specifici del modello.

Il parallelismo tensoriale è necessario nei casi in cui un singolo parametro consuma la maggior parte della memoria della GPU (ad esempio tabelle di incorporamento di grandi dimensioni con un vocabolario di grandi dimensioni un livello softmax di grandi dimensioni con un numero elevato di classi). In questo caso, trattare questo tensore o operazione di grandi dimensioni come un'unità atomica è inefficiente e impedisce l'equilibrio del carico di memoria. 

Il parallelismo tensoriale è utile anche per modelli estremamente grandi in cui una pipeline pura semplicemente non è sufficiente. Ad esempio, con i modelli in scala GPT-3 che richiedono il partizionamento su decine di istanze, effettuare la pipeline in microbatch puro è inefficiente perché la profondità della pipeline diventa troppo elevata e il sovraccarico diventa proibitivo.

**Nota**  
Il parallelismo tensoriale è disponibile PyTorch nella libreria di parallelismo dei SageMaker modelli v1.6.0 e successive.

**Topics**
+ [Come funziona il Parallelismo tensoriale](model-parallel-extended-features-pytorch-tensor-parallelism-how-it-works.md)
+ [Esegui un processo di formazione parallela SageMaker su modelli distribuiti con Tensor Parallelism](model-parallel-extended-features-pytorch-tensor-parallelism-examples.md)
+ [Supporto per i modelli Hugging Face Transformer](model-parallel-extended-features-pytorch-hugging-face.md)
+ [Meccanismo di classificazione quando si utilizza una combinazione di parallelismo di pipeline e parallelismo tensoriale](model-parallel-extended-features-pytorch-ranking-mechanism.md)

# Come funziona il Parallelismo tensoriale
<a name="model-parallel-extended-features-pytorch-tensor-parallelism-how-it-works"></a>

Il parallelismo tensoriale avviene a livello di `nn.Modules`; partiziona moduli specifici nel modello tra classificazioni tensoriali parallele. Ciò si aggiunge alla partizione esistente del *set di moduli* utilizzati nel parallelismo delle pipeline.

Quando un modulo viene partizionato tramite il parallelismo tensoriale, la sua propagazione in avanti e all'indietro viene distribuita. La libreria gestisce la comunicazione necessaria tra i dispositivi per implementare l'esecuzione distribuita di questi moduli. I moduli sono partizionati su più classificazioni di dati parallele. Contrariamente alla distribuzione tradizionale dei carichi di lavoro, ogni classificazione di parallelismo dei dati **non** ha la replica completa del modello quando viene utilizzato il parallelismo tensoriale della libreria. Invece, ogni classificazione di parallelismo dei dati può avere solo una partizione dei moduli distribuiti, oltre alla totalità dei moduli che non sono distribuiti.

**Esempio:** considera il parallelismo tensoriale tra le classificazioni di dati parallele, dove il grado di parallelismo dei dati è 4 e il grado di parallelismo tensoriale è 2. Supponiamo di avere un gruppo parallelo di dati che contiene il seguente albero di moduli, dopo aver partizionato il set di moduli.

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

Supponiamo che il parallelismo tensoriale sia supportato per i moduli B, G e H. Un possibile risultato della partizione parallela tensoriale di questo modello potrebbe essere:

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

Ogni riga rappresenta l'insieme di moduli memorizzati in `dp_rank`, e la notazione `X:y` rappresenta la frazione `y` del modulo `X`. Tenere presente quanto segue:

1. Il partizionamento avviene tra sottoinsiemi di classificazioni di dati paralleli, che chiamiamo `TP_GROUP`, non l'intero `DP_GROUP`, in modo che la partizione esatta del modello venga replicata su `dp_rank` 0 e `dp_rank` 2 e analogamente su `dp_rank` 1 e `dp_rank` 3.

1. I moduli `E` e `F` non fanno più parte del modello, poiché il loro modulo principale `B` è partizionato e qualsiasi esecuzione che normalmente fa parte di `E` e `F` avviene all'interno del modulo (partizionato) `B`.

1. Anche se `H` è supportato per il parallelismo tensoriale, in questo esempio non è partizionato, il che evidenzia che il partizionamento di un modulo dipende dall'input dell'utente. Il fatto che un modulo sia supportato per il parallelismo tensoriale non significa necessariamente che sia partizionato.

## Come la libreria adatta il PyTorch `nn.Linear` parallelismo tensoriale al modulo
<a name="model-parallel-extended-for-pytorch-adapt-to-module"></a>

Quando il parallelismo tensoriale viene eseguito su classificazioni di dati parallele, un sottoinsieme dei parametri, dei gradienti e degli stati dell'ottimizzatore viene partizionato tra i dispositivi paralleli tensoriali *per i moduli partizionati*. Per il resto dei moduli, i dispositivi paralleli tensoriali funzionano in modo normale in parallelo ai dati. Per eseguire il modulo partizionato, un dispositivo raccoglie innanzitutto le parti necessarie di *tutti i campioni di dati* su dispositivi peer nello stesso gruppo di parallelismo tensoriale. Il dispositivo esegue quindi la frazione locale del modulo su tutti questi campioni di dati, seguita da un altro ciclo di sincronizzazione che combina le parti dell'output per ciascun campione di dati e restituisce i campioni di dati combinati al punto GPUs da cui ha avuto origine il campione di dati. La figura seguente mostra un esempio di questo processo su un modulo partizionato `nn.Linear`. 

![\[Due figure che mostrano due concetti di parallelizzazione dei tensori.\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/tensor-parallel-concept.png)


La prima figura mostra un modello piccolo con un modulo `nn.Linear` grande con parallelismo dei dati sulle due classificazioni di parallelismo tensoriale. Il modulo `nn.Linear` viene replicato nelle due classificazioni parallele. 

La seconda figura mostra il parallelismo tensoriale applicato su un modello più grande durante la suddivisione del modulo `nn.Linear`. Ciascun `tp_rank` contiene metà del modulo lineare e la totalità del resto delle operazioni. Durante il funzionamento del modulo lineare, ogni `tp_rank` raccoglie la metà pertinente di tutti i campioni di dati e la trasmette attraverso la propria metà del modulo `nn.Linear`. Il risultato deve essere ridotto (con la somma come operazione di riduzione) in modo che ogni classificazione abbia l'output lineare finale dei propri campioni di dati. Il resto del modello viene eseguito nel tipico modo parallelo dei dati.

# Esegui un processo di formazione parallela SageMaker su modelli distribuiti con Tensor Parallelism
<a name="model-parallel-extended-features-pytorch-tensor-parallelism-examples"></a>

In questa sezione, imparerai:
+ Come configurare uno SageMaker PyTorch stimatore e l'opzione di parallelismo del SageMaker modello per utilizzare il parallelismo tensoriale.
+ Come adattare lo script di addestramento utilizzando i moduli `smdistributed.modelparallel` estesi per il parallelismo tensoriale.

Per saperne di più sui `smdistributed.modelparallel` moduli, consulta il [SageMaker modello parallel APIs](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) nella documentazione di *SageMaker Python SDK*.

**Topics**
+ [Solo parallelismo tensoriale](#model-parallel-extended-features-pytorch-tensor-parallelism-alone)
+ [Parallelismo tensoriale combinato con parallelismo di pipeline](#model-parallel-extended-features-pytorch-tensor-and-pipeline-parallelism)

## Solo parallelismo tensoriale
<a name="model-parallel-extended-features-pytorch-tensor-parallelism-alone"></a>

Quello che segue è un esempio di un opzione di addestramento distribuito per attivare il solo parallelismo tensoriale, senza il parallelismo della pipeline. Configura i `smp_options` dizionari `mpi_options` and per specificare le opzioni di formazione distribuite allo estimatore. SageMaker `PyTorch`

**Nota**  
Le funzionalità estese di risparmio della memoria sono disponibili tramite Deep Learning Containers for PyTorch, che implementa la libreria di parallelismo dei SageMaker modelli v1.6.0 o successiva.

**Configura uno stimatore SageMaker PyTorch **

```
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/')
```

**Suggerimento**  
Per trovare un elenco completo dei parametri per`distribution`, consulta Parametri di [configurazione per il parallelismo dei modelli nella documentazione](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html) di SageMaker Python SDK.

**Adatta il tuo script di allenamento PyTorch **

Lo script di addestramento di esempio seguente mostra come adattare la libreria di parallelismo dei SageMaker modelli a uno script di addestramento. In questo esempio, si presume che lo script abbia il nome `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)
```

## Parallelismo tensoriale combinato con parallelismo di pipeline
<a name="model-parallel-extended-features-pytorch-tensor-and-pipeline-parallelism"></a>

Di seguito è riportato un esempio di opzione di addestramento distribuita che abilita il parallelismo tensoriale combinato con il parallelismo della pipeline. Imposta i `smp_options` parametri `mpi_options` and per specificare le opzioni parallele del modello con parallelismo tensoriale quando configuri uno stimatore. SageMaker `PyTorch`

**Nota**  
Le funzionalità estese di risparmio della memoria sono disponibili tramite Deep Learning Containers for PyTorch, che implementa la libreria di parallelismo dei SageMaker modelli v1.6.0 o successiva.

**Configura uno stimatore SageMaker PyTorch **

```
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>**Adatta il tuo script PyTorch di allenamento**

Lo script di addestramento di esempio seguente mostra come adattare la libreria di parallelismo dei SageMaker modelli a uno script di addestramento. Nota che lo script di addestramento ora include il decoratore `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)
```

# Supporto per i modelli Hugging Face Transformer
<a name="model-parallel-extended-features-pytorch-hugging-face"></a>

Il parallelismo tensoriale della libreria di parallelismo dei SageMaker modelli offre supporto per i seguenti modelli Hugging out-of-the-box Face Transformer:
+ GPT-2, BERT e Ro (disponibili nella libreria di parallelismo dei modelli v1.7.0 e successiveBERTa ) SageMaker 
+ GPT-J (disponibile nella libreria di parallelismo dei modelli v1.8.0 e successive) SageMaker 
+ GPT-Neo (disponibile nella libreria di parallelismo dei modelli v1.10.0 e successive) SageMaker 

**Nota**  
[Per qualsiasi altro modello Transformers, è necessario utilizzare 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) per applicare il parallelismo tensoriale.

**Nota**  
Per utilizzare il parallelismo tensoriale per addestrare i modelli Hugging Face Transformer, assicurati di utilizzare Hugging Face Deep Learning Containers perché ha la libreria di parallelismo dei modelli v1.7.0 e successive. PyTorch SageMaker Per ulteriori informazioni[, SageMaker consulta le](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_release_notes/smd_model_parallel_change_log.html) note di rilascio della libreria Model Parallelism.

## Modelli supportati pronti all'uso
<a name="model-parallel-extended-features-pytorch-hugging-face-out-of-the-box"></a>

Per i modelli di trasformatori Hugging Face supportati dalla libreria pronti all'uso, non è necessario implementare manualmente gli hook per tradurre Transformer in livelli di trasformatore. APIs `smdistributed` [È possibile attivare il parallelismo tensoriale utilizzando il gestore di contesto smdistributed.modelparallel.torch.tensor\$1parallelism () e avvolgendo il modello con 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) Non è necessario registrare manualmente gli hook per il parallelismo tensoriale utilizzando l'API `smp.tp_register`.

È possibile accedere alle funzioni di traduzione `state_dict` tra Hugging Face Transformers e `smdistributed.modelparallel` come segue.
+  `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)`(Disponibile nella libreria di parallelismo dei SageMaker modelli v1.8.0 e successive)
+ `smdistributed.modelparallel.torch.nn.huggingface.gptj.translate_hf_gptj_state_dict_to_smdistributed_gptj`(Disponibile nella libreria di parallelismo dei SageMaker modelli v1.8.0 e successive)
+ `smdistributed.modelparallel.torch.nn.huggingface.gptneo.translate_state_dict_to_hf_gptneo(state_dict, max_seq_len=None)`(Disponibile nella libreria di parallelismo dei SageMaker modelli v1.10.0 e successive)
+ `smdistributed.modelparallel.torch.nn.huggingface.gptneo.translate_hf_state_dict_to_smdistributed_gptneo(state_dict)`(Disponibile nella libreria di parallelismo dei SageMaker modelli v1.10.0 e successive)

**Esempio di utilizzo della funzione di traduzione GPT-2**

Inizia effettuando il wrapping del modello come mostrato nel codice seguente.

```
from transformers import AutoModelForCausalLM

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

model = smp.DistributedModel(model)
```

Dato un `state_dict` dall'oggetto `DistributedModel`, puoi caricare i pesi nel modello Hugging Face GPT-2 originale usando la funzione `translate_state_dict_to_hf_gpt2` mostrata nel codice seguente.

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

**Esempio di utilizzo della funzione di traduzione Ro BERTa **

Allo stesso modo, dato un HuggingFace modello supportato`state_dict`, è possibile utilizzare la `translate_hf_state_dict_to_smdistributed` funzione per convertirlo in un formato leggibile da`smp.DistributedModel`. Questo può essere utile nei casi d'uso di apprendimento del trasferimento, in cui un modello pre-addestrato viene caricato in un `smp.DistributedModel` per l'ottimizzazione in parallelo del modello:

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

# Meccanismo di classificazione quando si utilizza una combinazione di parallelismo di pipeline e parallelismo tensoriale
<a name="model-parallel-extended-features-pytorch-ranking-mechanism"></a>

Questa sezione spiega come funziona il meccanismo di classificazione del parallelismo dei modelli con il parallelismo tensoriale. Si tratta di un'estensione di [Ranking Basics](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#ranking-basics) per [Caratteristiche principali della SageMaker Model Parallelism Library](model-parallel-core-features.md). Con il parallelismo tensoriale, la libreria introduce tre tipi di classificazione e gruppo di processi: APIs per `smp.tp_rank()` tensor parallel rank, per `smp.pp_rank()` pipeline parallel rank e per reduced-data parallel rank. `smp.rdp_rank()` I gruppi di processi di comunicazione corrispondenti sono gruppo parallelo dei tensori (`TP_GROUP`), gruppo parallelo di pipeline (`PP_GROUP`) e gruppo parallelo dei dati ridotti (`RDP_GROUP`). I gruppi sono definiti come segue:
+ Un *gruppo parallelo dei tensori* (`TP_GROUP`) è un sottoinsieme divisibile in modo uniforme del gruppo parallelo dei dati, sul quale avviene la distribuzione parallela tensoriale dei moduli. Quando il grado di parallelismo della pipeline è 1, `TP_GROUP` è uguale al *gruppo parallelo del modello* (`MP_GROUP`). 
+ Un *gruppo parallelo di pipeline* (`PP_GROUP`) è il gruppo di processi su cui avviene il parallelismo della pipeline. Quando il grado di parallelismo tensoriale è 1, `PP_GROUP` è uguale a `MP_GROUP`. 
+ Un gruppo *parallelo dei dati ridotti* (`RDP_GROUP`) è un insieme di processi che contengono sia le stesse partizioni di parallelismo della pipeline che le stesse partizioni parallele tensoriali ed eseguono il parallelismo dei dati tra di loro. Questo è chiamato gruppo parallelo dei dati ridotti perché è un sottoinsieme dell'intero gruppo di parallelismo dei dati `DP_GROUP`. Per i parametri del modello distribuito all'interno di `TP_GROUP`, l'operazione `allreduce` di gradiente viene eseguita solo per il gruppo parallelo dei dati ridotti, mentre per i parametri che non sono distribuiti, il gradiente `allreduce` avviene sull'intero `DP_GROUP`. 
+ Un gruppo parallelo del modello (`MP_GROUP`) si riferisce a un gruppo di processi che memorizzano collettivamente l'intero modello. Consiste nell'unione degli `PP_GROUP` di tutte le classificazioni che fanno parte del processo corrente `TP_GROUP`. Quando il grado di parallelismo tensoriale è 1, `MP_GROUP` è equivalente a `PP_GROUP` È inoltre coerente con la definizione esistente di `MP_GROUP` delle versioni precedenti `smdistributed`. Nota che il `TP_GROUP` corrente è un sottoinsieme sia della `DP_GROUP` corrente che del `MP_GROUP` corrente. 

*Per saperne di più sul processo di comunicazione APIs nella libreria di parallelismo dei SageMaker modelli, consulta l'[API Common](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_common_api.html#) e [PyTorch-specific](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html) nella documentazione di Python APIs SageMaker SDK.*

![\[Meccanismo di classificazione, distribuzione dei parametri e operazioni associate AllReduce del parallelismo tensoriale.\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/tensor-parallel-ranking-mechanism.png)


Ad esempio, considerate i gruppi di processi per un singolo nodo con 8 GPUs, dove il grado di parallelismo tensoriale è 2, il grado di parallelismo della pipeline è 2 e il grado di parallelismo dei dati è 4. La parte centrale superiore della figura precedente mostra un esempio di modello con 4 livelli. Le parti in basso a sinistra e in basso a destra della figura illustrano il modello a 4 strati distribuito su 4 GPUs utilizzando sia il parallelismo della pipeline che il parallelismo tensoriale, dove il parallelismo tensoriale viene utilizzato per i due strati intermedi. Queste due figure inferiori sono semplici copie che illustrano le diverse linee di confine dei gruppi. Il modello partizionato viene replicato per il parallelismo dei dati su 0-3 e 4-7. GPUs La figura in basso a sinistra mostra le definizioni di `MP_GROUP`, `PP_GROUP`, e `TP_GROUP`. La figura in basso a destra mostra`RDP_GROUP`, `DP_GROUP` e sullo stesso set di. `WORLD` GPUs I gradienti per i livelli e le porzioni di livello che hanno lo stesso colore vengono `allreduce` assieme per il parallelismo dei dati. Ad esempio, il primo livello (blu chiaro) riceve le operazioni `allreduce` attraverso `DP_GROUP`, mentre la sezione arancione scuro del secondo livello trasmette solo le operazioni `allreduce` all'interno del relativo processo `RDP_GROUP`. Le frecce in grassetto rosso scuro rappresentano i tensori con il batch del loro insieme `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
```

In questo esempio, il parallelismo di pipeline si verifica tra le coppie di GPU (0,1); (2,3); (4,5) e (6,7). Inoltre, il parallelismo dei dati (`allreduce`) avviene su GPUs 0, 2, 4, 6 e indipendentemente su GPUs 1, 3, 5, 7. Il parallelismo tensoriale avviene su sottoinsiemi di `DP_GROUP`, tra le coppie di GPU (0,2); (1,3); (4,6) e (5,7).

  Per questo tipo di parallelismo ibrido tra pipeline e tensori, la matematica per `data_parallel_degree` rimane la stessa di `data_parallel_degree = number_of_GPUs / pipeline_parallel_degree`. La libreria calcola ulteriormente il grado di parallelismo dei dati ridotti dalla seguente relazione `reduced_data_parallel_degree * tensor_parallel_degree = data_parallel_degree`.  

# Partizione dello stato dell'ottimizzatore
<a name="model-parallel-extended-features-pytorch-optimizer-state-sharding"></a>

La *partizione dello stato dell'ottimizzatore* è un'utile tecnica di risparmio di memoria che partiziona lo stato dell'ottimizzatore (l'insieme di pesi che descrive lo stato dell'ottimizzatore) tra gruppi di dispositivi paralleli di dati. È possibile utilizzare la suddivisione dello stato dell'ottimizzatore ogni volta che si utilizza un ottimizzatore con stato (come Adam) o un FP16 ottimizzatore (che memorizza entrambi i parametri e le copie dei parametri). FP16 FP32 

**Nota**  
Lo sharding dello stato dell'ottimizzatore è disponibile PyTorch nella libreria di parallelismo dei modelli v1.6.0 e versioni successive. SageMaker 

## Come usare la partizione dello stato dell'ottimizzatore
<a name="model-parallel-extended-features-pytorch-optimizer-state-sharding-how-to-use"></a>

È possibile attivare la *partizione dello stato dell'ottimizzatore* impostando `"shard_optimizer_state": True` nella configurazione `modelparallel`. 

Quando questa funzione è attivata, la libreria partiziona il set di parametri del modello in base al grado di parallelismo dei dati. I gradienti corrispondenti alla partizione `i` vengono ridotti solo alla classificazione parallela dei dati `i`. Alla fine della prima chiamata a una funzione decoratrice `smp.step`, l'ottimizzatore racchiuso da `smp.DistributedOptimizer` ridefinisce i suoi parametri in modo che siano limitati solo a quelli corrispondenti alla partizione dell'attuale classificazione dei dati parallela. I parametri ridefiniti sono chiamati *parametri virtuali* e condividono lo spazio di archiviazione sottostante con i parametri originali. Durante la prima chiamata a `optimizer.step`, gli stati dell'ottimizzatore vengono creati in base a questi parametri ridefiniti, che vengono partizionati a causa della partizione originale. Dopo l'aggiornamento dell'ottimizzatore, l' AllGatheroperazione (come parte della `optimizer.step` chiamata) viene eseguita su tutti i ranghi paralleli dei dati per ottenere stati dei parametri coerenti.

**Suggerimento**  
La partizione dello stato dell'ottimizzatore può essere utile quando il grado di parallelismo dei dati è maggiore di 1 e il modello ha più di un miliardo di parametri.   
Il grado di parallelismo dei dati viene calcolato da `(processes_per_host * instance_count / pipeline_parallel_degree)` e la funzione `smp.dp_size()` gestisce il dimensionamento in background.

**Configura uno stimatore SageMaker PyTorch **

```
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
    }
}
```

**Adatta il tuo script PyTorch di allenamento**

Vedi [Adatta il tuo script di PyTorch formazione](model-parallel-extended-features-pytorch-tensor-parallelism-examples.md#model-parallel-extended-features-pytorch-tensor-and-pipeline-parallelism-script) nella sezione Parallelismo di *Tensor combinato con parallelismo* della pipeline. Non è richiesta alcuna modifica aggiuntiva per lo script.

# Checkpoint di attivazione
<a name="model-parallel-extended-features-pytorch-activation-checkpointing"></a>

Il *checkpoint di attivazione* (o *checkpoint gradiente*) è una tecnica per ridurre l'utilizzo della memoria cancellando le attivazioni di determinati livelli e ricalcolandole durante un passaggio all'indietro. In effetti, ciò consente di rinunciare a tempi di calcolo aggiuntivi per ridurre l'utilizzo della memoria. Se un modulo è sottoposto a checkpoint, alla fine di un passaggio in avanti, gli input e gli output dal modulo rimangono in memoria. Tutti i tensori intermedi che avrebbero fatto parte del calcolo all'interno di quel modulo vengono liberati durante il passaggio in avanti. Durante il passaggio all'indietro dei moduli di checkpoint, questi tensori vengono ricalcolati. A questo punto, i livelli oltre questo modulo di checkpoint hanno terminato il passaggio all'indietro, quindi il picco di utilizzo della memoria con il checkpoint può essere inferiore.

**Nota**  
Questa funzionalità è disponibile PyTorch nella libreria di parallelismo dei modelli v1.6.0 e successive SageMaker .

## Come usare il checkpoint di attivazione
<a name="model-parallel-extended-for-pytorch-activation-checkpointing-how-to-use"></a>

Con `smdistributed.modelparallel`, è possibile utilizzare il checkpoint di attivazione con la granularità di un modulo. Per tutti i moduli `torch.nn` tranne `torch.nn.Sequential`, è possibile effettuare il checkpoint di un albero di moduli solo se si trova all'interno di una partizione dal punto di vista del parallelismo di pipeline. Nel caso del modulo `torch.nn.Sequential`, ogni albero dei moduli all'interno del modulo sequenziale deve trovarsi completamente all'interno di una partizione affinché il checkpoint di attivazione funzioni. Quando utilizzi il partizionamento manuale, tieni presente queste restrizioni.

Quando si utilizza il [partizionamento automatico dei modelli](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-core-features.html#model-parallel-automated-model-splitting), è possibile trovare i registri delle assegnazioni di partizionamento a partire da `Partition assignments:` nei registri dei processi di addestramento. Se un modulo è partizionato su più livelli (ad esempio, con uno discendente su una classificazione e un altro discendente su una classificazione diversa), la libreria ignora il tentativo di checkpoint del modulo e genera un messaggio di avviso che indica che il modulo non verrà sottoposto a checkpoint.

**Nota**  
La libreria di parallelismo dei SageMaker modelli supporta operazioni di sovrapposizione e non sovrapposizione in combinazione con il checkpoint. `allreduce` 

**Nota**  
PyTorchl'API di checkpointing nativa non è compatibile con. `smdistributed.modelparallel`

**Esempio 1:** il seguente codice di esempio mostra come utilizzare il checkpoint di attivazione quando nello script è presente una definizione del modello.

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

**Esempio 2:** il seguente codice di esempio mostra come utilizzare il checkpoint di attivazione quando nello script è presente un modello sequenziale.

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

**Esempio 3:** Il codice di esempio seguente mostra come utilizzare il checkpoint di attivazione quando si importa un modello predefinito da una libreria, ad esempio PyTorch Hugging Face Transformers. Indipendentemente dal fatto che tu faccia o meno il checkpoint dei i moduli sequenziali, procedi come segue: 

1. Effettua il wrapping del modello per `smp.DistributedModel()`.

1. Definisci un oggetto per i livelli sequenziali.

1. Effettua il wrapping dell'oggetto del livello sequenziale con `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')
```

# Offload di attivazione
<a name="model-parallel-extended-features-pytorch-activation-offloading"></a>

Quando il checkpoint di attivazione e il parallelismo di pipeline sono attivati e il numero di microbatch è maggiore di uno, l'*offload di attivazione* è una funzionalità aggiuntiva che può ridurre ulteriormente l'utilizzo della memoria. L'offload di attivazione sposta in modo asincrono le attivazioni dei checkpoint corrispondenti ai relativi microbatch che non sono attualmente in esecuzione nella CPU. Appena prima che la GPU richieda le attivazioni per il passaggio all'indietro del microbatch, questa funzionalità recupera automaticamente le offload di attivazione scaricate dalla CPU.

**Nota**  
Questa funzionalità è disponibile PyTorch nella libreria di parallelismo dei modelli v1.6.0 e versioni successive SageMaker .

## Come usare l'offload di attivazione
<a name="model-parallel-extended-for-pytorch-activation-offloading"></a>

Utilizza l'offload di attivazione per ridurre l'utilizzo della memoria quando **il numero di microbatch è maggiore di 1 e il checkpoint di attivazione è attivato** (vedi[Checkpoint di attivazione](model-parallel-extended-features-pytorch-activation-checkpointing.md)). Quando il checkpoint di attivazione non viene utilizzato, l'offload di attivazione non ha alcun effetto. Quando viene utilizzato con un solo microbatch, non consente di risparmiare memoria.

Per utilizzare l'offload di attivazione, impostalo `"offload_activations": True` nella configurazione `modelparallel`.

L'offload di attivazione sposta le attivazioni dei checkpoint nei moduli `nn.Sequential` sulla CPU in modo asincrono. Il trasferimento dei dati tramite il PCIe collegamento si sovrappone al calcolo della GPU. L'offload avviene immediatamente, non appena viene calcolato il passaggio in avanti per un particolare livello sottoposto a checkpoint. Le attivazioni vengono caricate nuovamente sulla GPU poco prima di essere necessarie per il passaggio all'indietro di un particolare microbatch. Il trasferimento CPU-GPU si sovrappone in modo analogo al calcolo. 

Per regolare la data di caricamento anticipata delle attivazioni nella GPU, puoi utilizzare il parametro di configurazione `"activation_loading_horizon"` (il valore predefinito è impostato su 4, deve essere `int` maggiore di 0). Un orizzonte di caricamento delle attivazioni più ampio comporterebbe il caricamento anticipato delle attivazioni sulla GPU. Se l'orizzonte è troppo ampio, l'impatto dell'offload di attivazione in termini di risparmio di memoria potrebbe essere ridotto. Se l'orizzonte è troppo piccolo, le attivazioni potrebbero non essere caricate indietro nel tempo, riducendo la sovrapposizione e peggiorando le prestazioni.

**Suggerimento**  
L'offload di attivazione può essere utile per modelli di grandi dimensioni con oltre cento miliardi di parametri.

** SageMaker PyTorch Configura uno stimatore**

```
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 Formazione con Model Parallelism
<a name="model-parallel-extended-features-pytorch-fp16"></a>

Per la FP16 formazione, applica le seguenti modifiche allo script di addestramento e allo stimatore.

**Nota**  
Questa funzionalità è disponibile PyTorch nella libreria di parallelismo dei SageMaker modelli v1.10.0 e versioni successive.

** PyTorch Adatta il tuo script di allenamento**

1. Effettua il wrapping del modello usando il gestore di contesto [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 = ...
   ```
**Suggerimento**  
Se stai usando il parallelismo tensoriale, aggiungi `tensor_parallelism=smp.tp_size() > 1` al gestore di contesto `smp.model_creation`. L'aggiunta di questa linea aiuta anche a rilevare automaticamente se il parallelismo tensoriale è attivato o meno.  

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

1. Quando racchiudi l'ottimizzatore con `smdistributed.modelparallel.torch.DistributedOptimizer`, imposta l'argomento `static_loss_scaling` o `dynamic_loss_scaling`. Per impostazione predefinita, `static_loss_scaling` è impostato su `1.0` e `dynamic_loss_scaling` è impostato su `False`. Se imposti `dynamic_loss_scale=True`, puoi inserire le opzioni di dimensionamento dinamico delle perdite come dizionario tramite l'argomento `dynamic_loss_args`. Nella maggior parte dei casi, si consiglia di utilizzare la scala dinamica delle perdite con le opzioni predefinite. [Per ulteriori informazioni, opzioni ed esempi della funzione wrapper dell'ottimizzatore, consultate 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.

   Il codice seguente è un esempio di avvolgimento di un oggetto `Adadelta` ottimizzatore con una scalatura dinamica delle perdite per l'addestramento. FP16 

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

**Configura uno stimatore SageMaker PyTorch **

Aggiungi il FP16 parametro (`"fp16"`) alla configurazione di distribuzione per il parallelismo del modello durante la creazione di un SageMaker PyTorch oggetto estimatore. Per un elenco completo dei parametri di configurazione per il parallelismo dei modelli, vedere [Parametri per `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(...)
```

[All'inizio dell' FP16 addestramento, il modello e l'ottimizzatore vengono integrati rispettivamente da `FP16_Module` e, `FP16_Optimizer` rispettivamente, `smdistributed` versioni modificate delle utilità Apex.](https://nvidia.github.io/apex/fp16_utils.html#apex-fp16-utils) `FP16_Module`converte il modello in FP16 dtype e si occupa del forward pass in. FP16

**Suggerimento**  
È possibile applicare il ritaglio del gradiente chiamando `clip_master_grads` prima di `optimizer.step`.  

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

**Suggerimento**  
Durante l'utilizzo `torch.optim.lr_scheduler` e l' FP16 addestramento, è necessario passare `optimizer.optimizer` allo scheduler LR anziché all'ottimizzatore. Guarda il codice di esempio seguente.  

```
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 per FlashAttention
<a name="model-parallel-attention-head-size-for-flash-attention"></a>

Support for FlashAttention è una funzionalità della libreria applicabile solo al modello di trasformatore *distribuito, che è un modello Transformer* integrato [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)per l'addestramento in parallelo al modello. Questa funzionalità è compatibile anche con [Parallelismo tensoriale](model-parallel-extended-features-pytorch-tensor-parallelism.md). 

La [FlashAttention](https://github.com/HazyResearch/flash-attention)libreria supporta i modelli solo quando `attention_head_size` è impostata su un valore che è un multiplo di 8 e inferiore a 128. Pertanto, quando si addestra un trasformatore distribuito e ci si assicura che FlashAttention funzioni correttamente, è necessario regolare i parametri per fare in modo che la dimensione della testina di attenzione soddisfi i requisiti. Per ulteriori informazioni, consulta anche [Installazione e funzionalità](https://github.com/HazyResearch/flash-attention#installation-and-features) nel *FlashAttention GitHubrepository*.

Ad esempio, supponiamo di configurare un modello Transformer con `hidden_width=864` e `num_heads=48`. La dimensione della testa di FlashAttention è calcolata come`attention_head_size = hidden_width / num_heads = 864 / 48 = 18`. Per abilitarlo FlashAttention, è necessario regolare il `num_heads` parametro su`54`, in modo che `attention_head_size = hidden_width / num_heads = 864 / 54 = 16` sia un multiplo di 8.