

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

# (Archiviata) Libreria SageMaker Model Parallelism v1.x
<a name="model-parallel"></a>

**Importante**  
A partire dal 19 dicembre 2023, viene rilasciata la libreria SageMaker Model Parallelism (SMP) v2. Le funzionalità di SMP v1 non saranno più supportate nelle versioni future a favore della libreria SMP v2. La sezione e gli argomenti seguenti sono archiviati e riguardano specificamente l’uso della libreria SMP v1. Per informazioni su come utilizzare la libreria SMP v2, consulta [Libreria SageMaker Model Parallelism v2](model-parallel-v2.md).

Utilizza la libreria parallela di modelli di Amazon SageMaker AI per addestrare modelli di deep learning (DL) di grandi dimensioni che sono difficili da addestrare a causa delle limitazioni di memoria della GPU. La libreria suddivide automaticamente ed efficacemente un modello su più GPU e istanze. Utilizzando la libreria, puoi raggiungere più rapidamente l'obiettivo di precisione di previsione addestrando in modo efficiente modelli DL più grandi con miliardi o trilioni di parametri.

Puoi utilizzare la libreria per partizionare automaticamente i tuoi modelli TensorFlow e PyTorch su più GPU e più nodi con modifiche minime al codice. Puoi accedere all'API della libreria tramite SageMaker Python SDK.

Utilizza le seguenti sezioni per saperne di più sul parallelismo dei modelli e sulla libreria parallela di modelli SageMaker. La documentazione API di questa libreria è disponibile nella sezione [API di addestramento distribuito](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) della *documentazione di SageMaker Python SDK v2.199.0*. 

**Topics**
+ [Introduzione al parallelismo dei modelli](model-parallel-intro.md)
+ [Framework supportati e Regioni AWS](distributed-model-parallel-support.md)
+ [Caratteristiche principali della SageMaker Model Parallelism Library](model-parallel-core-features.md)
+ [Esegui un job di formazione SageMaker distribuito con Model Parallelism](model-parallel-use-api.md)
+ [Checkpoint e ottimizzazione di un modello con il parallelismo dei modelli](distributed-model-parallel-checkpointing-and-finetuning.md)
+ [Esempi della libreria di parallelismo dei modelli Amazon SageMaker AI v1](distributed-model-parallel-examples.md)
+ [SageMaker Best practice per il parallelismo dei modelli distribuiti](model-parallel-best-practices.md)
+ [Suggerimenti e insidie per la configurazione della SageMaker Distributed Model Parallelism Library](model-parallel-customize-tips-pitfalls.md)
+ [Risoluzione dei problemi del parallelismo dei modelli](distributed-troubleshooting-model-parallel.md)

# Introduzione al parallelismo dei modelli
<a name="model-parallel-intro"></a>

Il parallelismo dei modelli è un metodo di addestramento distribuito in cui il modello di deep learning è partizionato su più dispositivi, all'interno o tra istanze. Questa pagina introduttiva fornisce una panoramica di alto livello sul parallelismo dei modelli, una descrizione di come può aiutare a superare i problemi che sorgono durante l'addestramento di modelli DL che in genere sono di dimensioni molto grandi ed esempi di ciò che offre la libreria SageMaker parallela del modello per aiutare a gestire le strategie parallele dei modelli e il consumo di memoria.

## Che cos'è il parallelismo dei modelli?
<a name="model-parallel-what-is"></a>

L'aumento delle dimensioni dei modelli di deep learning (livelli e parametri) consente di ottenere una maggiore precisione per attività complesse come la visione artificiale e l'elaborazione del linguaggio naturale. Tuttavia, esiste un limite alla dimensione massima del modello che è possibile inserire nella memoria di una singola GPU. Durante l'addestramento dei modelli DL, le limitazioni della memoria della GPU possono rappresentare un ostacolo nei seguenti modi:
+ Limitano le dimensioni del modello che è possibile addestrare, poiché l'ingombro di memoria di un modello si ridimensiona proporzionalmente al numero di parametri.
+ Limitano la dimensione del batch per GPU durante l'addestramento, riducendo l'utilizzo della GPU e l'efficienza dell'addestramento.

Per superare i limiti associati all'addestramento di un modello su una singola GPU, SageMaker fornisce la libreria model parallel per aiutare a distribuire e addestrare i modelli DL in modo efficiente su più nodi di calcolo. Inoltre, con la libreria, è possibile ottenere un addestramento distribuito più ottimizzato utilizzando dispositivi supportati da EFA, che migliorano le prestazioni della comunicazione tra i nodi con bassa latenza, throughput elevato e bypass del sistema operativo.

## Stima dei requisiti di memoria prima di utilizzare il parallelismo dei modelli
<a name="model-parallel-intro-estimate-memory-requirements"></a>

Prima di utilizzare la libreria SageMaker model parallel, considerate quanto segue per avere un'idea dei requisiti di memoria necessari per addestrare modelli DL di grandi dimensioni.

Per un processo di formazione che utilizza gli ottimizzatori AMP (FP16) e Adam, la memoria GPU richiesta per parametro è di circa 20 byte, che possiamo suddividere come segue:
+ Un FP16 parametro \$1 2 byte
+ Un FP16 gradiente \$1 2 byte
+ Uno stato di FP32 ottimizzazione di \$1 8 byte basato sugli ottimizzatori Adam
+ Una FP32 copia del parametro \$1 4 byte (necessaria per il funzionamento (OA`optimizer apply`))
+ Una FP32 copia di gradient \$1 4 byte (necessaria per il funzionamento OA)

Anche per un modello DL relativamente piccolo con 10 miliardi di parametri, possono essere necessari almeno 200 GB di memoria, che è una dimensione molto più grande della tipica memoria GPU (ad esempio, NVIDIA A100 con 40 GB/80 GB di memoria e V100 con 16/32 GB) disponibile su una singola GPU. Tieni presente che oltre ai requisiti di memoria per gli stati del modello e dell'ottimizzatore, ci sono altri utenti di memoria, come le attivazioni generate nel forward pass. La memoria richiesta può essere molto superiore a 200 GB.

Per la formazione distribuita, ti consigliamo di utilizzare istanze Amazon EC2 P3 e P4 con NVIDIA V100 e A100 Tensor Core rispettivamente. GPUs Per ulteriori dettagli sulle specifiche quali core della CPU, RAM, volume di archiviazione collegato e larghezza di banda della rete, consulta la sezione *Elaborazione accelerata* nella pagina [Tipi di istanze Amazon EC2](https://aws.amazon.com/ec2/instance-types/).

Anche con le istanze a calcolo accelerato, è ovvio che i modelli con circa 10 miliardi di parametri come Megatron-LM e T5 e i modelli ancora più grandi con centinaia di miliardi di parametri come GPT-3 non possono contenere repliche di modelli in ogni dispositivo GPU. 

## In che modo la libreria utilizza il parallelismo dei modelli e le tecniche di risparmio della memoria
<a name="model-parallel-intro-features"></a>

La libreria comprende vari tipi di funzionalità di parallelismo dei modelli e funzionalità di risparmio di memoria come il partizionamento dello stato dell'ottimizzatore, il checkpoint di attivazione e l'offload dell'attivazione. Tutte queste tecniche possono essere combinate per addestrare in modo efficiente modelli di grandi dimensioni composti da centinaia di miliardi di parametri.

**Topics**
+ [Parallelismo dei dati condiviso (disponibile per) PyTorch](#model-parallel-intro-sdp)
+ [PyTorch TensorFlowParallelismo delle pipeline (disponibile per e)](#model-parallel-intro-pp)
+ [Parallelismo tensoriale (disponibile per) PyTorch](#model-parallel-intro-tp)
+ [Condivisione dello stato dell'ottimizzatore (disponibile per) PyTorch](#model-parallel-intro-oss)
+ [Attivazione, offload e checkpointing (disponibile per) PyTorch](#model-parallel-intro-activation-offloading-checkpointing)
+ [Scelta delle tecniche giuste per il modello](#model-parallel-intro-choosing-techniques)

### Parallelismo dei dati condiviso (disponibile per) PyTorch
<a name="model-parallel-intro-sdp"></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) all'interno di un gruppo parallelo di dati. GPUs 

SageMaker ****[L'intelligenza artificiale implementa il parallelismo dei dati condivisi attraverso l'implementazione di MIC, una libreria che minimizza la comunicazione su larga scala e discussa nel post del blog Near-linear scaling of **gigantic-model** training on. AWS](https://www.amazon.science/blog/near-linear-scaling-of-gigantic-model-training-on-aws)****

Puoi applicare la parallelizzazione dei dati sottoposti a sharding al modello come strategia standalone. Inoltre, se utilizzi le istanze GPU più performanti dotate di NVIDIA A100 Tensor Core GPUs`ml.p4d.24xlarge`, puoi sfruttare la maggiore velocità di formazione offerta dalle `AllGather` operazioni offerte da SMDDP Collectives.

Per approfondire il parallelismo dei dati condivisi e imparare a configurarlo o utilizzare una combinazione del parallelismo dei dati condivisi con altre tecniche come il parallelismo tensoriale e l'addestramento, consulta. FP16 [Parallelismo dei dati partizionati](model-parallel-extended-features-pytorch-sharded-data-parallelism.md)

### PyTorch TensorFlowParallelismo delle pipeline (disponibile per e)
<a name="model-parallel-intro-pp"></a>

Il *parallelismo della pipeline* partiziona l'insieme di livelli o operazioni sull'insieme di dispositivi, lasciando intatta ogni operazione. Quando specificate un valore per il numero di partizioni del modello (`pipeline_parallel_degree`), il numero totale di GPUs (`processes_per_host`) deve essere divisibile per il numero delle partizioni del modello. Per configurarlo correttamente, devi specificare i valori corretti per i parametri `pipeline_parallel_degree` e `processes_per_host`. Il semplice calcolo è il seguente:

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

La libreria si occupa di calcolare il numero di repliche del modello (chiamate anche `data_parallel_degree`) in base ai due parametri di input forniti. 

Ad esempio, se impostate `"pipeline_parallel_degree": 2` e `"processes_per_host": 8` utilizzate un'istanza ML con otto GPU worker, ad esempio`ml.p3.16xlarge`, la libreria configura automaticamente il modello distribuito attraverso il parallelismo dei dati a quattro vie GPUs . L'immagine seguente illustra come un modello viene distribuito tra gli otto sistemi, GPUs ottenendo un parallelismo dei dati a quattro vie e un parallelismo di pipeline bidirezionale. Ogni replica del modello, dove la definiamo come un *gruppo parallelo di pipeline* e la etichettiamo come`PP_GROUP`, è partizionata su due. GPUs Ogni partizione del modello è assegnata a quattro GPUs, dove le quattro repliche di partizione si trovano in un *gruppo parallelo* di dati e sono etichettate come. `DP_GROUP` Senza il parallelismo tensoriale, il gruppo parallelo della pipeline è essenzialmente il gruppo parallelo del modello.

![\[Come viene distribuito un modello tra gli otto, GPUs ottenendo il parallelismo dei dati a quattro vie e il parallelismo delle pipeline a due vie.\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/smdmp-pipeline-parallel-only.png)


Per approfondire la parallelizzazione delle pipeline, consulta [Caratteristiche principali della SageMaker Model Parallelism Library](model-parallel-core-features.md). 

Per iniziare a eseguire il modello utilizzando il parallelismo della pipeline, consulta [Run a Distributed SageMaker Training Job with the SageMaker Model](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-use-api.html) Parallel Library.

### Parallelismo tensoriale (disponibile per) PyTorch
<a name="model-parallel-intro-tp"></a>

Il *parallelismo tensoriale* divide i singoli livelli, o `nn.Modules`, tra dispositivi, per essere eseguiti in parallelo. La figura seguente mostra l'esempio più semplice di come la libreria divide un modello con quattro livelli per ottenere un parallelismo tensoriale bidirezionale (`"tensor_parallel_degree": 2`). Gli strati di ogni replica del modello sono divisi in due e distribuiti in due. GPUs In questo caso di esempio, la configurazione parallela del modello include anche `"pipeline_parallel_degree": 1` e `"ddp": True` (utilizza il PyTorch DistributedDataParallel pacchetto in background), quindi il grado di parallelismo dei dati diventa otto. La libreria gestisce la comunicazione tra le repliche del modello distribuite dai tensori.

![\[L’esempio più semplice di come la libreria divide un modello con quattro livelli per ottenere una parallelizzazione dei tensori bidirezionale ("tensor_parallel_degree": 2).\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/smdmp-tensor-parallel-only.png)


L'utilità di questa funzionalità sta nel fatto che è possibile selezionare livelli specifici o un sottoinsieme di livelli per applicare il parallelismo tensoriale. Per approfondire il parallelismo tensoriale e altre funzionalità di risparmio di memoria e per imparare a impostare una combinazione di parallelismo tensoriale e di pipeline PyTorch, vedi. [Parallelismo tensoriale](model-parallel-extended-features-pytorch-tensor-parallelism.md)

### Condivisione dello stato dell'ottimizzatore (disponibile per) PyTorch
<a name="model-parallel-intro-oss"></a>

Per capire come la libreria esegue il *partizionamento dello stato dell'ottimizzatore*, prendi in considerazione un semplice modello di esempio con quattro livelli. L'idea chiave nell'ottimizzazione dello state sharding è che non è necessario replicare lo stato dell'ottimizzatore in tutti i tuoi. GPUs Piuttosto, una singola replica dello stato dell'ottimizzatore viene suddivisa tra classificazioni parallele ai dati, senza ridondanza tra i dispositivi. Ad esempio, la GPU 0 contiene lo stato dell'ottimizzatore per il primo livello, la GPU 1 successiva contiene lo stato dell'ottimizzatore per L2 e così via. La seguente figura animata mostra una propagazione all'indietro con la tecnica di partizionamento dello stato dell'ottimizzatore. Al termine della propagazione all'indietro, è previsto il tempo di calcolo e di rete necessario all'operazione `optimizer apply` (OA) per aggiornare gli stati dell'ottimizzatore e all'operazione `all-gather` (AG) per aggiornare i parametri del modello per l'iterazione successiva. Soprattutto, l'operazione `reduce` può sovrapporsi al calcolo sulla GPU 0, ottenendo una propagazione all'indietro più efficiente in termini di memoria e più rapida. Nell'attuale implementazione, le operazioni AG e OA non si sovrappongono a `compute`. Può comportare un calcolo esteso durante l'operazione AG, quindi potrebbe esserci un compromesso. 

![\[Una propagazione all’indietro con la tecnica di sharding dello stato dell’ottimizzatore.\]](http://docs.aws.amazon.com/it_it/sagemaker/latest/dg/images/distributed/model-parallel/smdmp-optimizer-state-sharding.gif)


Per ulteriori informazioni su come utilizzare questa funzionalità, consulta [Optimizer State Sharding](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-optimizer-state-sharding.html).

### Attivazione, offload e checkpointing (disponibile per) PyTorch
<a name="model-parallel-intro-activation-offloading-checkpointing"></a>

Per risparmiare memoria della GPU, la libreria supporta il checkpoint di attivazione per evitare di memorizzare le attivazioni interne nella memoria della GPU per i moduli specificati dall'utente durante il passaggio in avanti. La libreria ricalcola queste attivazioni durante il passaggio all'indietro. Inoltre, la funzione di offload dell'attivazione scarica le attivazioni memorizzate nella memoria della CPU e le recupera sulla GPU durante il passaggio all'indietro per ridurre ulteriormente l'ingombro della memoria di attivazione. Per ulteriori informazioni su come utilizzare queste funzionalità, consulta [Activation Checkpoint](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-activation-checkpointing.html) e [Activation Offloading](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-extended-features-pytorch-activation-offloading.html).

### Scelta delle tecniche giuste per il modello
<a name="model-parallel-intro-choosing-techniques"></a>

Per ulteriori informazioni sulla scelta delle tecniche e delle configurazioni corrette, consulta [SageMaker Distributed Model Parallel Best Practice](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-best-practices.html) e Suggerimenti e insidie per la [configurazione](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-customize-tips-pitfalls.html).

# Framework supportati e Regioni AWS
<a name="distributed-model-parallel-support"></a>

Prima di utilizzare la libreria di parallelismo dei SageMaker modelli, controlla i framework e i tipi di istanza supportati e determina se ci sono quote sufficienti nel tuo account e. AWS Regione AWS

**Nota**  
Per controllare gli ultimi aggiornamenti e le note di rilascio della libreria, consulta le [SageMaker Model Parallel Release Notes](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_release_notes/smd_model_parallel_change_log.html) nella documentazione di *SageMaker Python SDK*.

## Framework supportati
<a name="distributed-model-parallel-supported-frameworks"></a>

La libreria di parallelismo dei SageMaker modelli supporta i seguenti framework di deep learning ed è disponibile in AWS Deep Learning Containers (DLC) o scaricabile come file binario.

PyTorch versioni supportate dall'IA e dalla libreria di parallelismo dei modelli SageMaker SageMaker 


| PyTorch versione | SageMaker versione della libreria di parallelismo dei modelli | URI dell’immagine del container DLC integrata `smdistributed-modelparallel` | URL del file binario\$1\$1 | 
| --- | --- | --- | --- | 
| v2.0.0 | smdistributed-modelparallel==v1.15.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:2.0.0-gpu-py310-cu118-ubuntu20.04-sagemaker`  | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-2.0.0/build-artifacts/2023-04-14-20-14/smdistributed\$1modelparallel-1.15.0-cp310-cp310-linux\$1x86\$164.whl | 
| v1.13.1 | smdistributed-modelparallel==v1.15.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.13.1-gpu-py39-cu117-ubuntu20.04-sagemaker`  | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-1.13.1/build-artifacts/2023-04-17-15-49/smdistributed\$1modelparallel-1.15.0-cp39-cp39-linux\$1x86\$164.whl | 
| v1.12.1 | smdistributed-modelparallel==v1.13.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.12.1-gpu-py38-cu113-ubuntu20.04-sagemaker`  | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-1.12.1/build-artifacts/2022-12-08-21-34/smdistributed\$1modelparallel-1.13.0-cp38-cp38-linux\$1x86\$164.whl | 
| v1.12.0 | smdistributed-modelparallel==v1.11.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.12.0-gpu-py38-cu113-ubuntu20.04-sagemaker`   | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-1.12.0/build-artifacts/2022-08-12-16-58/smdistributed\$1modelparallel-1.11.0-cp38-cp38-linux\$1x86\$164.whl | 
| v1.11.0 | smdistributed-modelparallel==v1.10.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.11.0-gpu-py38-cu113-ubuntu20.04-sagemaker`  | https://sagemaker-distributed-model-parallel.s3.us-west-2.amazonaws.com/pytorch-1.11.0/build-artifacts/2022-07-11-19-23/smdistributed\$1modelparallel-1.10.0-cp38-cp38-linux\$1x86\$164.whl | 
| v1.10.2 |  smdistributed-modelparallel==v1.7.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.10.2-gpu-py38-cu113-ubuntu20.04-sagemaker`  | - | 
| v1.10.0 |  smdistributed-modelparallel==v1.5.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.10.0-gpu-py38-cu113-ubuntu20.04-sagemaker`  | - | 
| v1.9.1 |  smdistributed-modelparallel==v1.4.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.9.1-gpu-py38-cu111-ubuntu20.04`  | - | 
| v1.8.1\$1 |  smdistributed-modelparallel==v1.6.0 |  `763104351884.dkr.ecr.<region>.amazonaws.com/pytorch-training:1.8.1-gpu-py36-cu111-ubuntu18.04`  | - | 

**Nota**  
La libreria di parallelismo dei modelli v1.6.0 e successive fornisce funzionalità estese per. SageMaker PyTorch Per ulteriori informazioni, consulta [Caratteristiche principali della SageMaker Model Parallelism Library](model-parallel-core-features.md).

\$1\$1 I file binari servono per l'installazione URLs della libreria di parallelismo del SageMaker modello in contenitori personalizzati. Per ulteriori informazioni, consulta [Crea il tuo contenitore Docker con la Distributed Model Parallel Library SageMaker](model-parallel-sm-sdk.md#model-parallel-bring-your-own-container).

TensorFlow versioni supportate dall' SageMaker IA e dalla libreria di SageMaker parallelismo dei modelli


| TensorFlow versione | SageMaker versione della libreria di parallelismo dei modelli | URI dell’immagine del container DLC integrata `smdistributed-modelparallel` | 
| --- | --- | --- | 
| v2.6.0 | smdistributed-modelparallel==v1.4.0 | 763104351884.dkr.ecr.<region>.amazonaws.com/tensorflow-training:2.6.0-gpu-py38-cu112-ubuntu20.04 | 
| v2.5.1 | smdistributed-modelparallel==v1.4.0  | 763104351884.dkr.ecr.<region>.amazonaws.com/tensorflow-training:2.5.1-gpu-py37-cu112-ubuntu18.04  | 

**Versioni di Hugging Face Transformers supportate dall'IA SageMaker e dalla libreria parallela di dati distribuiti SageMaker**

I AWS Deep Learning Containers for Hugging Face utilizzano i SageMaker Training Containers per PyTorch e TensorFlow come immagini di base. [Per cercare le versioni della libreria Hugging Face Transformers e le versioni abbinate, TensorFlow consulta gli ultimi Hugging Face Containers PyTorch e le versioni precedenti di Hugging [Face](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#huggingface-training-containers) Container.](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#prior-hugging-face-container-versions)

## Regioni AWS
<a name="distributed-model-parallel-availablity-zone"></a>

La libreria parallela di SageMaker dati è disponibile in tutti i paesi in Regioni AWS cui SageMaker sono in servizio i [AWS Deep Learning Containers](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only). Per ulteriori informazioni, consulta [Immagini dei container di deep learning disponibili](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#available-deep-learning-containers-images).

## Tipi di istanze supportati
<a name="distributed-model-parallel-supported-instance-types"></a>

La libreria di parallelismo dei SageMaker modelli richiede uno dei seguenti tipi di istanze ML.


| Tipo di istanza | 
| --- | 
| ml.g4dn.12xlarge | 
| ml.p3.16xlarge | 
| ml.p3dn.24xlarge  | 
| ml.p4d.24xlarge | 
| ml.p4de.24xlarge | 

Per le specifiche dei tipi di istanza, consulta la sezione **Elaborazione accelerata** nella [pagina tipi di istanza Amazon EC2](https://aws.amazon.com/ec2/instance-types/). Per informazioni sui prezzi delle istanze, consulta la pagina [dei prezzi di Amazon SageMaker AI](https://aws.amazon.com/sagemaker/pricing/).

Se hai riscontrato un messaggio di errore simile al seguente, segui le istruzioni in [Richiedi un aumento della quota di servizio per le risorse SageMaker AI](https://docs.aws.amazon.com/sagemaker/latest/dg/regions-quotas.html#service-limit-increase-request-procedure).

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

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

# Esegui un job di formazione SageMaker distribuito con Model Parallelism
<a name="model-parallel-use-api"></a>

Scopri come eseguire un processo di formazione parallelo al modello del tuo script di formazione utilizzando SageMaker Python SDK con la libreria di parallelismo dei modelli. SageMaker 

Esistono tre scenari di utilizzo per l'esecuzione di un processo di formazione. SageMaker 

1. Puoi utilizzare uno dei AWS Deep Learning Container predefiniti per e. TensorFlow PyTorch Questa opzione è consigliata se è la prima volta che utilizzi la libreria di parallelizzazione dei modelli. Per trovare un tutorial su come eseguire un processo di formazione parallela su SageMaker modelli, consulta gli esempi di notebook in training [PyTorch with model parallelism library di Amazon SageMaker AI](https://github.com/aws/amazon-sagemaker-examples/tree/main/training/distributed_training/pytorch/model_parallel).

1. Puoi estendere i contenitori predefiniti per gestire eventuali requisiti funzionali aggiuntivi per il tuo algoritmo o modello che l'immagine Docker predefinita SageMaker non supporta. Per un esempio di come è possibile estendere un container predefinito, consulta [Estensione di un container predefinito](prebuilt-containers-extend.md).

1. [Puoi adattare il tuo contenitore Docker per lavorare con l' SageMaker intelligenza artificiale utilizzando il toolkit di formazione. SageMaker ](https://github.com/aws/sagemaker-training-toolkit) Per un esempio, consulta [Adapting your own training container](https://docs.aws.amazon.com/sagemaker/latest/dg/adapt-training-container.html).

Per le opzioni 2 e 3 nell'elenco precedente, consulta [Estendi un contenitore Docker predefinito che contiene la libreria parallela SageMaker di modelli distribuiti](model-parallel-sm-sdk.md#model-parallel-customize-container) per informazioni su come installare la libreria di parallelismo dei modelli in un container Docker esteso o personalizzato. 

In tutti i casi, avviate il processo di formazione configurando un estimatore SageMaker `TensorFlow` o uno `PyTorch` stimatore per attivare la libreria. Per ulteriori informazioni, consulta i seguenti argomenti.

**Topics**
+ [Passaggio 1: modifica il tuo script di addestramento utilizzando SageMaker la libreria parallela di modelli distribuiti](model-parallel-customize-training-script.md)
+ [Fase 2: Avviare un job di formazione utilizzando SageMaker Python SDK](model-parallel-sm-sdk.md)

# Passaggio 1: modifica il tuo script di addestramento utilizzando SageMaker la libreria parallela di modelli distribuiti
<a name="model-parallel-customize-training-script"></a>

Utilizza questa sezione per scoprire come personalizzare lo script di formazione per utilizzare le funzionalità principali della libreria di parallelismo dei modelli Amazon SageMaker AI. *Per utilizzare le funzioni e i parametri API specifici della libreria, ti consigliamo di utilizzare questa documentazione insieme alla [libreria model SageMaker parallel APIs](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) nella documentazione di Python SageMaker SDK.*

Gli esempi di script di addestramento forniti in queste sezioni sono semplificati e progettati per evidenziare le modifiche necessarie da apportare per utilizzare la libreria. Per end-to-end esempi di notebook eseguibili che dimostrano come utilizzare uno script di PyTorch addestramento TensorFlow o di addestramento con la libreria Model Parallelism, consulta. SageMaker [Esempi di Amazon SageMaker AI Model Parallelism Library v2](distributed-model-parallel-v2-examples.md)

**Topics**
+ [Dividi il modello del tuo script di addestramento utilizzando la libreria di parallelismo dei modelli SageMaker](#model-parallel-model-splitting-using-smp-lib)
+ [Modificare uno script di addestramento TensorFlow](model-parallel-customize-training-script-tf.md)
+ [Modificare uno script PyTorch di addestramento](model-parallel-customize-training-script-pt.md)

## Dividi il modello del tuo script di addestramento utilizzando la libreria di parallelismo dei modelli SageMaker
<a name="model-parallel-model-splitting-using-smp-lib"></a>

Esistono due modi per modificare lo script di addestramento per configurare la suddivisione dei modelli: suddivisione automatica o suddivisione manuale.

### Suddivisione automatica dei modelli
<a name="model-parallel-automated-model-splitting"></a>

*Quando si utilizza SageMaker la libreria di parallelismo dei modelli, è possibile sfruttare la *suddivisione automatica dei modelli*, nota anche come partizionamento automatico dei modelli.* La libreria utilizza un algoritmo di partizionamento che bilancia la memoria, riduce al minimo la comunicazione tra i dispositivi e ottimizza le prestazioni. È possibile configurare l'algoritmo di partizionamento automatico per ottimizzare la velocità o la memoria. 

In alternativa, è possibile ricorrere alla suddivisione manuale dei modelli. Consigliamo la suddivisione automatica dei modelli, a meno che non si abbia molta dimestichezza con l'architettura dei modelli e si abbia una buona idea di come partizionare i modelli in modo efficiente.

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

Il partizionamento automatico avviene durante la prima fase di addestramento, quando viene chiamata per la prima volta la funzione lavorata da `smp.step`. Durante questa chiamata, la libreria costruisce innanzitutto una versione del modello sulla RAM della CPU (per evitare limitazioni di memoria della GPU), quindi analizza il grafico del modello e prende una decisione sul partizionamento. In base a questa decisione, ogni partizione del modello viene caricata su una GPU e solo allora viene eseguita la prima fase. A causa di queste fasi di analisi e partizionamento, la prima fase di addestramento potrebbe richiedere più tempo. 

In entrambi i framework, la libreria gestisce la comunicazione tra i dispositivi tramite il proprio backend, ottimizzato per l'infrastruttura. AWS 

Il design della partizione automatica si adatta alle caratteristiche del framework e la libreria esegue il partizionamento al livello di granularità più naturale in ciascun framework. Ad esempio, in TensorFlow, ogni operazione specifica può essere assegnata a un dispositivo diverso, mentre in PyTorch, l'assegnazione viene eseguita a livello di modulo, dove ogni modulo è composto da più operazioni. La sezione seguente esamina le specifiche di design in ciascun framework.

##### Divisione automatica del modello con PyTorch
<a name="model-parallel-auto-model-split-pt"></a>

Durante la prima fase di addestramento, la libreria di parallelismo dei modelli esegue internamente una fase di tracciamento che ha lo scopo di realizzare il grafico dei modelli e determinare le forme del tensore e dei parametri. Dopo questa fase di tracciamento, la libreria realizza un albero, costituito dagli oggetti `nn.Module` annidati nel modello, oltre ai dati aggiuntivi raccolti dal tracciamento, come la quantità di dati archiviati `nn.Parameters` e il tempo di esecuzione per ciascuno `nn.Module`. 

Successivamente, la libreria attraversa questo albero dalla radice ed esegue un algoritmo di partizionamento che assegna ciascun `nn.Module` a un dispositivo, che bilancia il carico computazionale (misurato dal tempo di esecuzione del modulo) e l'uso della memoria (misurato dalla dimensione `nn.Parameter` totale memorizzata e dalle attivazioni). Se più `nn.Modules` condividono lo stesso `nn.Parameter`, questi moduli vengono posizionati sullo stesso dispositivo per evitare di mantenere più versioni dello stesso parametro. Una volta presa la decisione sul partizionamento, i moduli e i pesi assegnati vengono caricati sui rispettivi dispositivi.

Per istruzioni su come registrare il `smp.step` decoratore nel copione di PyTorch allenamento, consulta. [Divisione automatica con PyTorch](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16)

##### Divisione automatica del modello con TensorFlow
<a name="model-parallel-auto-model-split-tf"></a>

La libreria di parallelismo dei modelli analizza le dimensioni delle variabili addestrabili e la struttura dei grafici e utilizza internamente un algoritmo di partizionamento dei grafici. Questo algoritmo prevede l'assegnazione di un dispositivo per ogni operazione, con l'obiettivo di ridurre al minimo la quantità di comunicazioni necessarie tra i dispositivi, nel rispetto di due vincoli: 
+ Bilanciamento del numero di variabili memorizzate in ogni dispositivo
+ Bilanciamento del numero di operazioni eseguite in ogni dispositivo

Se specifichi `speed` per `optimize` (nei parametri di parallelismo dei modelli in SDK per Python), la libreria tenta di bilanciare il numero di operazioni e gli oggetti `tf.Variable` in ogni dispositivo. Altrimenti, tenta di bilanciare la dimensione totale di `tf.Variables`.

Una volta presa la decisione sul partizionamento, la libreria crea una rappresentazione serializzata del grafico secondario che ogni dispositivo deve eseguire e la importa su ogni dispositivo. Durante il partizionamento, la libreria colloca le operazioni che utilizzano la stessa `tf.Variable` e quelle che fanno parte dello stesso livello Keras sullo stesso dispositivo. Rispetta inoltre i vincoli di colocation imposti da. TensorFlow Ciò significa che, ad esempio, se ci sono due livelli Keras che condividono una `tf.Variable`, tutte le operazioni che fanno parte di questi livelli vengono posizionate su un singolo dispositivo.

Per istruzioni su come registrare il `smp.step` decoratore nel copione di allenamento, consulta. PyTorch [Divisione automatica con TensorFlow](model-parallel-customize-training-script-tf.md#model-parallel-customize-training-script-tf-23)

##### Confronto della suddivisione automatica dei modelli tra framework
<a name="model-parallel-auto-model-split-comparison"></a>

In TensorFlow, l'unità di calcolo fondamentale è a`tf.Operation`, e TensorFlow rappresenta il modello come un grafo aciclico diretto (DAG) di `tf.Operation` s, e quindi la libreria di parallelismo del modello partiziona questo DAG in modo che ogni nodo vada su un dispositivo. È fondamentale che gli oggetti `tf.Operation` siano sufficientemente ricchi di attributi personalizzabili e siano universali, nel senso che è garantito che ogni modello sia costituito di un grafico di tali oggetti. 

PyTorch d'altra parte, non ha una nozione di funzionamento equivalente sufficientemente ricca e universale. L'unità di calcolo più simile PyTorch che presenta queste caratteristiche è an`nn.Module`, che ha un livello di granularità molto più elevato, ed è per questo che la libreria esegue il partizionamento a questo livello in. PyTorch

### Suddivisione manuale dei modelli
<a name="model-parallel-manual-model-splitting"></a>

Se desideri specificare manualmente come partizionare il modello tra i dispositivi, usa il gestore di contesto `smp.partition`. Per istruzioni sulla modalità di impostazione del gestore di contesto per il partizionamento manuale, consulta le pagine seguenti.
+ [Divisione manuale con TensorFlow](model-parallel-customize-training-script-tf.md#model-parallel-customize-training-script-tf-manual)
+ [Divisione manuale con PyTorch](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16-hvd)

Per utilizzare questa opzione dopo aver apportato le modifiche, nel passaggio 2, dovrai impostare `auto_partition` e definire un `default_partition` nella classe di stima del framework dell'SDK Python SageMaker. `False` Qualsiasi operazione che non viene inserita in modo esplicito su una partizione tramite il gestore di contesto `smp.partition` è eseguita su `default_partition`. In questo caso, la logica di suddivisione automatica viene ignorata e ogni operazione viene posizionata in base alle specifiche dell'utente. In base alla struttura del grafico risultante, la libreria di parallelismo dei modelli crea automaticamente una pianificazione di esecuzione in pipeline.

# Modificare uno script di addestramento TensorFlow
<a name="model-parallel-customize-training-script-tf"></a>

In questa sezione, imparerai come modificare gli script di TensorFlow addestramento per configurare la libreria di parallelismo dei SageMaker modelli per il partizionamento automatico e il partizionamento manuale. Gli esempi scelti comprendono anche un esempio integrato con Horovod per il modello ibrido e il parallelismo dei dati.

**Nota**  
Per scoprire quali TensorFlow versioni sono supportate dalla libreria, consulta. [Framework supportati e Regioni AWS](distributed-model-parallel-support.md)

Le modifiche necessarie da apportare allo script di addestramento per utilizzare la libreria sono elencate in [Divisione automatica con TensorFlow](#model-parallel-customize-training-script-tf-23).

Per maggiori informazioni su come modificare lo script di addestramento per utilizzare il modello ibrido e il parallelismo dei dati con Horovod, consulta [Suddivisione automatizzata con TensorFlow e Horovod per modelli ibridi e parallelismo dei dati](#model-parallel-customize-training-script-tf-2.3).

Se desideri utilizzare il partizionamento manuale, consulta anche [Divisione manuale con TensorFlow](#model-parallel-customize-training-script-tf-manual). 

I seguenti argomenti mostrano esempi di script di addestramento che è possibile utilizzare per configurare la libreria di parallelismo SageMaker dei modelli per il partizionamento automatico e i modelli di partizionamento manuale. TensorFlow 

**Nota**  
Il partizionamento automatico è abilitato come impostazione predefinita. Se non diversamente specificato, gli script di esempio utilizzano il partizionamento automatico.

**Topics**
+ [Divisione automatica con TensorFlow](#model-parallel-customize-training-script-tf-23)
+ [Suddivisione automatizzata con TensorFlow e Horovod per modelli ibridi e parallelismo dei dati](#model-parallel-customize-training-script-tf-2.3)
+ [Divisione manuale con TensorFlow](#model-parallel-customize-training-script-tf-manual)
+ [Funzionalità del framework non supportate](#model-parallel-tf-unsupported-features)

## Divisione automatica con TensorFlow
<a name="model-parallel-customize-training-script-tf-23"></a>

Le seguenti modifiche allo script di addestramento sono necessarie per eseguire un TensorFlow modello con la libreria SageMaker di parallelismo dei modelli:

1. Importa e inizializza la libreria con [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init).

1. Definisci un modello Keras ereditandolo da [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_tensorflow.html](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_tensorflow.html) anziché dalla classe di modelli Keras. Restituisci gli output del modello dal metodo di chiamata dell'oggetto `smp.DistributedModel`. Tieni presente che tutti i tensori restituiti dal metodo di chiamata verranno trasmessi su dispositivi paralleli al modello, con un sovraccarico di comunicazione, quindi non dovrebbe essere restituito alcun tensore che non è necessario al di fuori del metodo di chiamata (come le attivazioni intermedie) .

1. Imposta `drop_remainder=True` nel metodo `tf.Dataset.batch()`. Ciò serve a garantire che la dimensione del batch sia sempre divisibile per il numero di microbatch.

1. Semina le operazioni casuali nella pipeline di dati utilizzando`smp.dp_rank()`, ad esempio, `shuffle(ds, seed=smp.dp_rank())` per garantire la coerenza dei campioni di dati su GPUs cui sono presenti diverse partizioni del modello.

1. Inserisci la logica forward e backward in una funzione a fasi e decorala con `smp.step`.

1. Esegui la post-elaborazione sugli output tra i microbatch utilizzando metodi [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput) come `reduce_mean`. La funzione [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init) deve restituire un valore che dipende dall'output di `smp.DistributedModel`.

1. Se è presente una fase di valutazione, inserisci in modo analogo la logica forward all'interno di una funzione decorata `smp.step` e post-elabora gli output utilizzando l'[API `StepOutput`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput).

[Per ulteriori informazioni sull'API della libreria SageMaker di parallelismo dei modelli, consulta la documentazione dell'API.](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) 

Il seguente script Python è un esempio di script di addestramento dopo l'introduzione delle modifiche.

```
import tensorflow as tf

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

# smdistributed: Initialize
smp.init()

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

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

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

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

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

model = MyModel()

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

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

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


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

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

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


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

Se hai finito di preparare lo script di addestramento, procedi con [Fase 2: Avviare un job di formazione utilizzando SageMaker Python SDK](model-parallel-sm-sdk.md). Se desideri eseguire un modello ibrido e un processo di addestramento per il parallelismo dei dati, continua con la sezione successiva.

## Suddivisione automatizzata con TensorFlow e Horovod per modelli ibridi e parallelismo dei dati
<a name="model-parallel-customize-training-script-tf-2.3"></a>

Puoi utilizzare la libreria di parallelismo dei SageMaker modelli con Horovod per il parallelismo ibrido di modelli e dati. Per saperne di più su come la libreria suddivide un modello per il parallelismo ibrido, consulta [PyTorch TensorFlowParallelismo delle pipeline (disponibile per e)](model-parallel-intro.md#model-parallel-intro-pp).

In questo passaggio, ci concentriamo su come modificare lo script di addestramento per adattare la libreria di parallelismo dei modelli. SageMaker

Per configurare correttamente il proprio script di addestramento per acquisire la configurazione di parallelismo ibrido che sarà impostata in [Fase 2: Avviare un job di formazione utilizzando SageMaker Python SDK](model-parallel-sm-sdk.md), usa le funzioni di supporto della libreria, `smp.dp_rank()` e `smp.mp_rank()`, che rilevano automaticamente rispettivamente la classificazione parallela dei dati e la classificazione parallela dei modelli. 

Per trovare tutte le primitive MPI supportate dalla libreria, consulta [MPI Basics](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#mpi-basics) nella documentazione di Python SDK. SageMaker 

Le modifiche richieste nello script sono:
+ Aggiunta di `hvd.allreduce`
+ Variabili di trasmissione dopo il primo batch, come richiesto da Horovod
+ Semina le operazioni di and/or shuffling sharding nella pipeline di dati con. `smp.dp_rank()`

**Nota**  
Quando usi Horovod, non devi chiamare `hvd.init` direttamente nel tuo script di addestramento. Dovrai invece `"horovod"` impostarlo `True` nei parametri dell'SDK `modelparallel` di SageMaker Python in. [Fase 2: Avviare un job di formazione utilizzando SageMaker Python SDK](model-parallel-sm-sdk.md) Ciò consente alla libreria di inizializzare internamente Horovod in base alle assegnazioni dei dispositivi delle partizioni del modello. La chiamata di `hvd.init()` direttamente nello script di addestramento può causare problemi.

**Nota**  
L'utilizzo dell'API `hvd.DistributedOptimizer` direttamente nello script di addestramento potrebbe comportare velocità e prestazioni di addestramento scadenti, poiché l'API inserisce implicitamente l'operazione `AllReduce` all'interno di `smp.step`. Ti consigliamo di utilizzare la libreria di parallelismo dei modelli con Horovod chiamando direttamente `hvd.allreduce` dopo aver chiamato `accumulate()` o `reduce_mean()` sui gradienti restituiti da `smp.step`, come verrà mostrato nell'esempio seguente.

[Per saperne di più sull'API della libreria SageMaker di parallelismo dei modelli, consulta la documentazione dell'API.](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html)

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

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

# smdistributed: Initialize
smp.init()

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

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

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

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

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


model = MyModel()

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

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

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


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

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

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

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


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

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

## Divisione manuale con TensorFlow
<a name="model-parallel-customize-training-script-tf-manual"></a>

Usa i gestori di contesto `smp.partition` per inserire le operazioni in una partizione specifica. Qualsiasi operazione non inserita in alcun contesto `smp.partition` viene inserita in `default_partition`. [Per ulteriori informazioni sull'API della libreria SageMaker di parallelismo dei modelli, consulta la documentazione dell'API.](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) 

```
import tensorflow as tf

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

# smdistributed: Initialize
smp.init()

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

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

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

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

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


model = MyModel()

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

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

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


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

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

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


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

## Funzionalità del framework non supportate
<a name="model-parallel-tf-unsupported-features"></a>

Le seguenti TensorFlow funzionalità non sono supportate dalla libreria:
+ `tf.GradientTape()` non è attualmente supportato. Puoi invece usare `Optimizer.get_gradients()` o `Optimizer.compute_gradients()` per calcolare i gradienti.
+ L'API `tf.train.Checkpoint.restore()` non è attualmente supportata. Per il checkpoint, usa invece `smp.CheckpointManager`, che fornisce la stessa API e funzionalità. Tieni presente che il ripristino dei checkpoint con `smp.CheckpointManager` dovrebbe avvenire dopo la prima fase.

# Modificare uno script PyTorch di addestramento
<a name="model-parallel-customize-training-script-pt"></a>

In questa sezione, imparerai come modificare gli script di PyTorch addestramento per configurare la libreria di parallelismo dei SageMaker modelli per il partizionamento automatico e il partizionamento manuale.

**Nota**  
Per scoprire quali PyTorch versioni sono supportate dalla libreria, consulta. [Framework supportati e Regioni AWS](distributed-model-parallel-support.md)

**Suggerimento**  
Per alcuni esempi di end-to-end quaderni che dimostrano come utilizzare uno script di PyTorch addestramento con la libreria di parallelismo dei SageMaker modelli, vedete. [Esempi della libreria di parallelismo dei modelli Amazon SageMaker AI v1](distributed-model-parallel-examples.md)

Si prega di notare che il partizionamento automatico è abilitato come impostazione predefinita. Se non diversamente specificato, gli script seguenti utilizzano il partizionamento automatico. 

**Topics**
+ [Divisione automatica con PyTorch](#model-parallel-customize-training-script-pt-16)
+ [Divisione manuale con PyTorch](#model-parallel-customize-training-script-pt-16-hvd)
+ [Considerazioni](#model-parallel-pt-considerations)
+ [Funzionalità del framework non supportate](#model-parallel-pt-unsupported-features)

## Divisione automatica con PyTorch
<a name="model-parallel-customize-training-script-pt-16"></a>

Le seguenti modifiche allo script di addestramento sono necessarie per eseguire uno script di PyTorch addestramento con la libreria SageMaker di parallelismo dei modelli:

1. Importa e inizializza la libreria con [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init).

1. Esegui il wrapping del modello con [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedModel](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedModel). Tieni presente che tutti i tensori restituiti dal metodo `forward` dell'oggetto `nn.Module` sottostante verranno trasmessi su dispositivi paralleli al modello, con un sovraccarico di comunicazione, quindi non dovrebbe essere restituito alcun tensore che non è necessario al di fuori del metodo di chiamata (come le attivazioni intermedie).
**Nota**  
Per la FP16 formazione, è necessario utilizzare il gestore di contesto [smdistributed.modelparallel.torch.model\$1creation () per avvolgere il modello.](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html) Per ulteriori informazioni, consulta [FP16 Formazione con Model Parallelism](model-parallel-extended-features-pytorch-fp16.md).

1. Esegui il wrapping dell'ottimizzatore con [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedOptimizer](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedOptimizer).
**Nota**  
Per FP16 la formazione, è necessario impostare la scalabilità statica o dinamica delle perdite. Per ulteriori informazioni, consulta [FP16 Formazione con Model Parallelism](model-parallel-extended-features-pytorch-fp16.md).

1. Utilizza l'oggetto `DistributedModel` restituito anziché un modello utente.

1. Inserisci la logica forward e backward in una funzione a fasi e decorala con [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#smp.init).

1. Limita ciascun processo al proprio dispositivo tramite `torch.cuda.set_device(smp.local_rank())`.

1. Sposta i tensori di input sulla GPU utilizzando l'API `.to()` prima della chiamata `smp.step` (vedi esempio sotto riportato).

1. Sostituisci `torch.Tensor.backward` e `torch.autograd.backward` con `DistributedModel.backward`.

1. Esegui la post-elaborazione sugli output tra i microbatch utilizzando metodi [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput) come `reduce_mean`.

1. Se è presente una fase di valutazione, inserisci in modo analogo la logica forward all'interno di una funzione decorata `smp.step` e post-elabora gli output utilizzando l'[API `StepOutput`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_common_api.html#StepOutput).

1. Imposta `drop_last=True` in `DataLoader`. In alternativa, salta manualmente un batch nel ciclo di addestramento se la dimensione del batch non è suddivisibile per il numero di microbatch.

[Per ulteriori informazioni sull'API della libreria SageMaker di parallelismo dei modelli, consulta la documentazione dell'API.](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) 

```
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchnet.dataset import SplitDataset
from torchvision import datasets

import smdistributed.modelparallel.torch as smp

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

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


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


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

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

        optimizer.step()

# smdistributed: initialize the backend
smp.init()

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

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

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

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

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

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

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

## Divisione manuale con PyTorch
<a name="model-parallel-customize-training-script-pt-16-hvd"></a>

Usa i gestori di contesto [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedOptimizer](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/v1.2.0/smd_model_parallel_pytorch.html#smp.DistributedOptimizer) per posizionare i moduli in dispositivi specifici. Qualsiasi modulo non inserito in alcun contesto `smp.partition` viene inserito in `default_partition`. Deve essere indicata `default_partition` se `auto_partition` è impostata su `False`. I moduli creati in un contesto `smp.partition` specifico vengono posizionati nella partizione corrispondente.

[Per ulteriori informazioni sull'API della libreria SageMaker di parallelismo dei modelli, consulta la documentazione dell'API.](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel.html) 

```
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchnet.dataset import SplitDataset
from torchvision import datasets

import smdistributed.modelparallel.torch as smp

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

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


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


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

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

        optimizer.step()

# smdistributed: initialize the backend
smp.init()

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

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

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

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

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

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

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

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

Quando configurate uno script di PyTorch addestramento utilizzando SageMaker la libreria di parallelismo dei modelli, dovete tenere presente quanto segue:
+ Se utilizzi una tecnica di ottimizzazione che si basa su norme riguardanti i gradienti globali, ad esempio una norma sui gradienti di tutto il modello, come alcune varianti dell'ottimizzatore LAMB o il ritaglio del gradiente globale, è necessario raccogliere tutte le norme delle partizioni del modello per verificarne la correttezza. A tale scopo è possibile utilizzare i tipi di dati di base per la comunicazione della libreria.
+ Tutti gli argomenti `torch.Tensor` relativi ai metodi forward di `nn.Modules` nel modello devono essere utilizzati nel calcolo dell'output del modulo. In altre parole, la libreria non supporta il caso in cui esista un argomento `torch.Tensor` per un modulo da cui l'output del modulo non dipende.
+ L'argomento della chiamata `smp.DistributedModel.backward()` deve dipendere da tutti gli output del modello. In altre parole, non può esserci un output della chiamata `smp.DistributedModel.forward` che non venga utilizzato nel calcolo del tensore utilizzato per la chiamata `smp.DistributedModel.backward`.
+ Se nel codice sono presenti chiamate `torch.cuda.synchronize()`, potrebbe essere necessario chiamare `torch.cuda.set_device(smp.local_rank())` immediatamente prima della chiamata di sincronizzazione. Altrimenti potrebbero essere creati contesti CUDA non necessari nel dispositivo 0, che consumerebbe inutilmente memoria.
+ Poiché la libreria colloca `nn.Modules` su dispositivi diversi, i moduli nel modello non devono dipendere da alcuno stato globale modificato all'interno `smp.step`. È consentito qualsiasi stato che rimanga fisso durante l'addestramento o che venga modificato all'esterno di `smp.step` in modo visibile a tutti i processi.
+ Non è necessario spostare il modello nella GPU (ad esempio, utilizzando `model.to(device)`) quando si utilizza la libreria. Se provi a spostare il modello nella GPU prima che il modello sia partizionato (prima della prima chiamata `smp.step`), la chiamata di spostamento viene ignorata. La libreria sposta automaticamente la parte del modello assegnato a una classificazione nella sua GPU. Una volta iniziato l'addestramento con la libreria, non spostare il modello nella CPU e usalo, poiché non avrà i parametri corretti per i moduli non assegnati alla partizione tenuta dal processo. Se desideri riqualificare un modello o utilizzarlo per l'inferenza senza la libreria dopo che è stato addestrato utilizzando la libreria di parallelismo dei modelli, il modo consigliato è salvare il modello completo utilizzando la nostra API di checkpointing e caricarlo di nuovo su un normale Module. PyTorch 
+ Se disponi di un elenco di moduli tale per cui l'output di un modulo ne alimenta un altro, la sostituzione di tale elenco con `nn.Sequential` può migliorare significativamente le prestazioni.
+ L'aggiornamento del peso (`optimizer.step()`) deve avvenire all'esterno di `smp.step` perché è allora che l'intero passaggio indietro è terminato e i gradienti sono pronti. Quando si utilizza un modello ibrido con parallelismo di modelli e dati, a questo punto è garantito anche il completamento dei gradienti AllReduce .
+ Quando usi la libreria in combinazione con il parallelismo dei dati, assicurati che il numero di batch su tutti i ranghi paralleli dei dati sia lo stesso in modo da AllReduce non bloccare l'attesa di un rank che non partecipa al passaggio.
+ Se avvii un processo di addestramento utilizzando un tipo di istanza ml.p4d (ad esempio ml.p4d.24xlarge), è necessario impostare la variabile del caricatore di dati `num_workers=0`. Ad esempio, puoi definire il tuo `DataLoader` come di seguito indicato:

  ```
  dataloader = torch.utils.data.DataLoader(
              data,
              batch_size=batch_size,
              num_workers=0,
              pin_memory=True,
              drop_last=True,
              shuffle=shuffle,
          )
  ```
+ Gli input per `smp.step` devono essere gli input del modello generati da `DataLoader`. Ciò è necessario perché `smp.step` suddivide internamente i tensori di input lungo la dimensione del batch e li inserisce in pipeline. Di conseguenza, passare `DataLoader` alla funzione `smp.step` per generare gli input del modello all'interno non funziona. 

  Ad esempio, se definisci un `DataLoader` come di seguito indicato:

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

  Dovresti accedere agli input del modello generati da `train_loader` e passarli a una funzione decorata `smp.step`. Non passare `train_loader` direttamente alla funzione `smp.step`.

  ```
  def train(model, device, train_loader, optimizer):
      model.train()
      for batch_idx, (data, target) in enumerate(train_loader):
          ...
          _, loss_mb = train_step(model, data, target)
          ...
  
  @smp.step
  def train_step(model, data, target):
      ...
      return output, loss
  ```
+ I tensori di input per `smp.step` devono essere spostati sul dispositivo attuale utilizzando l'API `.to()`, che deve avvenire dopo la chiamata `torch.cuda.set_device(local_rank())`.

  Ad esempio, puoi definire la funzione `train` nel modo seguente. Questa funzione aggiunge `data` e `target` al dispositivo attuale utilizzando l'API `.to()` prima di utilizzare i tensori di input per chiamare `train_step`.

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

  I tensori di input per questa funzione decorata `smp.set` sono stati spostati nel dispositivo attuale nella funzione `train` sopra riportata. *Non* è necessario spostare il modello nel dispositivo corrente. La libreria sposta automaticamente la parte del modello assegnato a una classificazione nella sua GPU.

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

## Funzionalità del framework non supportate
<a name="model-parallel-pt-unsupported-features"></a>

Le seguenti PyTorch funzionalità non sono supportate dalla SageMaker libreria di parallelismo dei modelli:
+ Se si utilizza il parallelismo dei dati con il [PyTorch DDP](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html) nativo, il modulo [https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html](https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html)wrapper non è supportato dalla libreria. La libreria gestisce internamente l'integrazione con PyTorch DDP, inclusi i parametri broadcast e gradient. AllReduce Quando si utilizza la libreria, i buffer dei moduli vengono trasmessi una sola volta all'inizio dell'addestramento. Se il proprio modello ha buffer di moduli che devono essere sincronizzati tra gruppi paralleli di dati in ogni fase, è possibile farlo tramite l'API `torch.distributed`, utilizzando il gruppo di processi che può essere ottenuto tramite `smp.get_dp_process_group()`.
+ Per l'addestramento di precisione misto, il modulo `apex.amp` non è supportato. Per utilizzare la libreria con precisione mista automatica si consiglia di utilizzare `torch.cuda.amp`, utilizzando tuttavia `smp.amp.GradScaler` anziché l'implementazione in torch.
+ `torch.jit.ScriptModules` e `ScriptFunctions` non sono supportati da `smp.DistributedModel`.
+ `apex`: `FusedLayerNorm`, `FusedAdam`, `FusedLAMB` e `FusedNovoGrad` da `apex` sono supportati. È possibile utilizzare le relative implementazioni della libreria tramite e invece. `smp.optimizers` `smp.nn` APIs 

# Fase 2: Avviare un job di formazione utilizzando SageMaker Python SDK
<a name="model-parallel-sm-sdk"></a>

L'SDK SageMaker Python supporta l'addestramento gestito di modelli con framework ML come e. TensorFlow PyTorch Per avviare un processo di formazione utilizzando uno di questi framework, è necessario definire uno stimatore, uno estimatore o un SageMaker [TensorFlow Estimator](https://sagemaker.readthedocs.io/en/v2.199.0/frameworks/tensorflow/sagemaker.tensorflow.html#tensorflow-estimator) SageMaker generico per utilizzare lo SageMaker [PyTorch script](https://sagemaker.readthedocs.io/en/v2.199.0/frameworks/pytorch/sagemaker.pytorch.html#pytorch-estimator) di addestramento modificato e la configurazione del [parallelismo](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/estimators.html#sagemaker.estimator.Estimator) del modello.

**Topics**
+ [PyTorch Utilizzo degli stimatori e SageMaker TensorFlow](#model-parallel-using-sagemaker-pysdk)
+ [Estendi un contenitore Docker predefinito che contiene la libreria parallela SageMaker di modelli distribuiti](#model-parallel-customize-container)
+ [Crea il tuo contenitore Docker con la Distributed Model Parallel Library SageMaker](#model-parallel-bring-your-own-container)

## PyTorch Utilizzo degli stimatori e SageMaker TensorFlow
<a name="model-parallel-using-sagemaker-pysdk"></a>

Le classi TensorFlow and PyTorch estimator contengono il `distribution` parametro, che è possibile utilizzare per specificare i parametri di configurazione per l'utilizzo di framework di formazione distribuiti. La libreria SageMaker model parallel utilizza internamente MPI per i dati ibridi e il parallelismo dei modelli, pertanto è necessario utilizzare l'opzione MPI con la libreria.

Il seguente modello di PyTorch estimatore TensorFlow or mostra come configurare il `distribution` parametro per l'utilizzo della libreria SageMaker model parallel con MPI.

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

```
import sagemaker
from sagemaker.tensorflow import TensorFlow

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

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

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

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

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

```
import sagemaker
from sagemaker.pytorch import PyTorch

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

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

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

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

------

Per abilitare la libreria, è necessario passare i dizionari di configurazione alle `"mpi"` chiavi `"smdistributed"` and tramite l'`distribution`argomento dei costruttori dello estimatore. SageMaker 

**Parametri di configurazione per il parallelismo dei modelli SageMaker**
+ Per la chiave `"smdistributed"`, passa un dizionario con la chiave `"modelparallel"` e i seguenti dizionari interni. 
**Nota**  
L'utilizzo di `"modelparallel"` e `"dataparallel"` in un unico processo di addestramento non è supportato. 
  + `"enabled"`: obbligatorio Per abilitare il parallelismo dei modelli, imposta `"enabled": True`.
  + `"parameters"`: obbligatorio Specificate un set di parametri per il parallelismo del SageMaker modello.
    + Per un elenco completo dei parametri comuni, consulta [Parametri `smdistributed`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#smdistributed-parameters) nella documentazione di *SageMaker Python SDK*.

      Per TensorFlow, vedi [TensorFlow-specific](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#tensorflow-specific-parameters) Parameters.

      Per PyTorch, vedi [PyTorch-specific](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#pytorch-specific-parameters) Parameters.
    + `"pipeline_parallel_degree"` (o `"partitions"` in `smdistributed-modelparallel<v1.6.0`): obbligatorio. Tra i [parametri per `smdistributed`](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#smdistributed-parameters), questo parametro è necessario per specificare in quante partizioni del modello desideri suddividere.
**Importante**  
C'è una modifica che causerà interruzioni nel nome del parametro. Il parametro `"pipeline_parallel_degree"` sostituisce le `"partitions"` dal `smdistributed-modelparallel` v1.6.0. Per ulteriori informazioni, consulta [Parametri comuni](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#common-parameters) per la configurazione SageMaker del parallelismo del modello e [SageMaker Distributed Model Parallel Release Notes](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_release_notes/smd_model_parallel_change_log.html) nella documentazione di *SageMaker Python* SDK.
+ Per la chiave, passa un dizionario che contenga quanto segue `"mpi"`:
  + `"enabled"`: obbligatorio Imposta `True` per avviare il processo di addestramento distribuito con MPI.
  + `"processes_per_host"`: obbligatorio Specifica il numero di processi che MPI deve avviare su ciascun host. Nell' SageMaker intelligenza artificiale, un host è una singola istanza ML di Amazon EC2. L'SDK SageMaker Python mantiene una one-to-one mappatura tra i processi e il parallelismo GPUs tra modelli e dati. Ciò significa che l' SageMaker IA pianifica ogni processo su un'unica GPU separata e nessuna GPU contiene più di un processo. Se si utilizza PyTorch, è necessario limitare ogni processo al proprio dispositivo tramite. `torch.cuda.set_device(smp.local_rank())` Per ulteriori informazioni, consulta [Divisione automatica con PyTorch](model-parallel-customize-training-script-pt.md#model-parallel-customize-training-script-pt-16).
**Importante**  
 `process_per_host`non *deve* essere maggiore del numero di GPUs istanze e in genere sarà uguale al numero di GPUs per istanza.
  + `"custom_mpi_options"` (facoltativo): utilizza questa chiave per passare le opzioni MPI personalizzate di cui potresti aver bisogno. Se non passi alcuna opzione personalizzata MPI alla chiave, l'opzione MPI viene impostata per impostazione predefinita sul seguente flag.

    ```
    --mca btl_vader_single_copy_mechanism none
    ```
**Nota**  
Non è necessario specificare esplicitamente questo flag predefinito sulla chiave. Se lo specifichi in modo esplicito, il processo di addestramento parallelo del modello distribuito potrebbe fallire con il seguente errore:  

    ```
    The following MCA parameter has been listed multiple times on the command line: 
    MCA param: btl_vader_single_copy_mechanism MCA parameters can only be listed once 
    on a command line to ensure there is no ambiguity as to its value. 
    Please correct the situation and try again.
    ```
**Suggerimento**  
Se avvii un processo di addestramento utilizzando un tipo di istanza compatibile con EFA, ad esempio `ml.p4d.24xlarge` e `ml.p3dn.24xlarge`, utilizza il seguente flag per ottenere prestazioni ottimali:  

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

Per avviare il processo di formazione utilizzando lo stimatore e lo script di addestramento con configurazione parallela del SageMaker modello, esegui la `estimator.fit()` funzione.

Usa le seguenti risorse per saperne di più sull'uso delle funzionalità di parallelismo dei modelli in Python SageMaker SDK:
+ [Usare TensorFlow con SageMaker Python SDK](https://sagemaker.readthedocs.io/en/v2.199.0/frameworks/tensorflow/using_tf.html)
+ [Usare PyTorch con SageMaker Python SDK](https://sagemaker.readthedocs.io/en/v2.199.0/frameworks/pytorch/using_pytorch.html)
+ Ti consigliamo di utilizzare un'istanza SageMaker notebook se sei un nuovo utente. Per vedere un esempio di come è possibile avviare un processo di formazione utilizzando un'istanza di SageMaker notebook, consulta[Esempi di Amazon SageMaker AI Model Parallelism Library v2](distributed-model-parallel-v2-examples.md).
+ Puoi inoltre inviare un processo di addestramento distribuito dal tuo computer utilizzando AWS CLI. Per eseguire la configurazione AWS CLI sul computer, consulta [Configurazione AWS delle credenziali e Regione per lo sviluppo](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html).

## Estendi un contenitore Docker predefinito che contiene la libreria parallela SageMaker di modelli distribuiti
<a name="model-parallel-customize-container"></a>

Per estendere un contenitore precostruito e utilizzare la libreria SageMaker di parallelismo dei modelli, devi utilizzare una delle immagini AWS Deep Learning Containers (DLC) disponibili per o. PyTorch TensorFlow La libreria di parallelismo dei SageMaker modelli è inclusa nelle immagini DLC TensorFlow (2.3.0 e successive) e (1.6.0 e successive) con CUDA PyTorch (). `cuxyz` Per un elenco completo delle immagini dei DLC, consulta Immagini dei [Deep Learning Containers disponibili](https://github.com/aws/deep-learning-containers/blob/master/available_images.md) nel * GitHub repository AWS Deep Learning Containers*.

**Suggerimento**  
Ti consigliamo di utilizzare l'immagine che contiene la versione più recente TensorFlow o di accedere PyTorch alla maggior parte up-to-date della libreria di parallelismo dei SageMaker modelli.

Ad esempio, il Dockerfile deve contenere un'istruzione `FROM` simile alla seguente:

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

# Add your dependencies here
RUN ...

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

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

Inoltre, quando si definisce uno PyTorch TensorFlow stimatore OR, è necessario specificarlo `entry_point` per lo script di addestramento. Questo deve essere lo stesso percorso identificato con `ENV SAGEMAKER_SUBMIT_DIRECTORY` nel Dockerfile. 

**Suggerimento**  
È necessario inviare questo contenitore Docker ad Amazon Elastic Container Registry (Amazon ECR) e utilizzare l'URI dell'immagine (`image_uri`) per definire uno stimatore per la formazione. SageMaker Per ulteriori informazioni, consulta [Estensione di un container predefinito](prebuilt-containers-extend.md). 

Dopo aver completato l'hosting del contenitore Docker e aver recuperato l'URI dell'immagine del contenitore, crea un oggetto estimatore come segue. SageMaker `PyTorch` Questo esempio presuppone che tu abbia già definito `smp_options` e `mpi_options`. 

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

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

## Crea il tuo contenitore Docker con la Distributed Model Parallel Library SageMaker
<a name="model-parallel-bring-your-own-container"></a>

Per creare il tuo contenitore Docker per l'addestramento e utilizzare la libreria parallela del SageMaker modello, devi includere le dipendenze corrette e i file binari delle librerie SageMaker parallele distribuite nel tuo Dockerfile. Questa sezione fornisce il set minimo di blocchi di codice da includere per preparare correttamente un ambiente di SageMaker formazione e la libreria parallela del modello nel proprio contenitore Docker.

**Nota**  
Questa opzione Docker personalizzata con la libreria parallel del SageMaker modello come binario è disponibile solo per PyTorch.

**Per creare un Dockerfile con il toolkit di SageMaker formazione e la libreria parallela del modello**

1. Inizia con una delle [immagini di base di NVIDIA CUDA](https://hub.docker.com/r/nvidia/cuda).

   ```
   FROM <cuda-cudnn-base-image>
   ```
**Suggerimento**  
Le immagini ufficiali del AWS Deep Learning Container (DLC) sono create a partire dalle immagini di base di [NVIDIA](https://hub.docker.com/r/nvidia/cuda) CUDA. Ti consigliamo di consultare i [Dockerfile ufficiali di AWS Deep Learning Container PyTorch per](https://github.com/aws/deep-learning-containers/tree/master/pytorch/training/docker) scoprire quali versioni delle librerie devi installare e come configurarle. I Dockerfile ufficiali sono completi, testati con benchmark e gestiti dai team di assistenza e di Deep Learning SageMaker Container. Nel link fornito, scegli la PyTorch versione che usi, scegli la cartella CUDA (`cuxyz`) e scegli il Dockerfile che termina con o. `.gpu` `.sagemaker.gpu`

1. Per configurare un ambiente di addestramento distribuito, devi installare software per dispositivi di comunicazione e di rete, come [Elastic Fabric Adapter (EFA)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html), [NVIDIA Collective Communications Library (NCCL)](https://developer.nvidia.com/nccl) e[Open MPI](https://www.open-mpi.org/). A seconda delle versioni PyTorch di CUDA scelte, è necessario installare versioni compatibili delle librerie.
**Importante**  
Poiché la libreria parallela del SageMaker modello richiede la libreria parallela SageMaker dei dati nei passaggi successivi, ti consigliamo vivamente di seguire le istruzioni riportate [Crea il tuo contenitore Docker con la libreria parallela di dati distribuiti SageMaker AI](data-parallel-bring-your-own-container.md) per configurare correttamente un ambiente di SageMaker formazione per la formazione distribuita.

   Per ulteriori informazioni sulla configurazione di EFA con NCCL e Open MPI, consulta [Get Started with EFA and MPI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html) e la [Guida introduttiva a EFA e NCCL](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start-nccl.html).

1. Aggiungete i seguenti argomenti per specificare i pacchetti URLs di formazione SageMaker distribuiti per PyTorch. La libreria parallela del SageMaker modello richiede che la libreria parallela SageMaker dei dati utilizzi il Remote Direct Memory Access (RDMA) tra nodi.

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

1. Installa le dipendenze richieste dalla libreria parallela del SageMaker modello.

   1. Installa la libreria [METIS](http://glaros.dtc.umn.edu/gkhome/metis/metis/overview).

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

   1. Installa la libreria [RAPIDS Memory Manager](https://github.com/rapidsai/rmm#rmm-rapids-memory-manager). Ciò richiede la versione [CMake](https://cmake.org/)3.14 o successiva.

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

1. Installa la libreria parallela del SageMaker modello.

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

1. Installa la libreria parallela di SageMaker dati.

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

1. Installa il [toolkit di addestramento sagemaker](https://github.com/aws/sagemaker-training-toolkit). Il toolkit contiene le funzionalità comuni necessarie per creare un contenitore compatibile con la piattaforma di SageMaker formazione e l'SDK SageMaker Python.

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

1. Dopo aver finito di creare il Dockerfile, consulta [Adapting your own training container](https://docs.aws.amazon.com/sagemaker/latest/dg/adapt-training-container.html) per scoprire come creare il container Docker e ospitarlo in Amazon ECR.

**Suggerimento**  
Per informazioni più generali sulla creazione di un Dockerfile personalizzato per l'addestramento nell' SageMaker intelligenza artificiale, consulta [Use](https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-training-algo.html) Your Own Training Algorithms.

# Checkpoint e ottimizzazione di un modello con il parallelismo dei modelli
<a name="distributed-model-parallel-checkpointing-and-finetuning"></a>

La libreria di parallelismo dei SageMaker modelli fornisce il checkpoint APIs per salvare lo stato del modello e lo stato dell'ottimizzatore suddivisi in base alle varie strategie di parallelismo del modello e per caricare i checkpoint per l'addestramento continuo da dove si desidera riavviare l'allenamento e perfezionarlo. Supportano APIs anche opzioni per salvare parzialmente o completamente gli stati del modello e dell'ottimizzatore.

**Topics**
+ [Checkpoint di un modello distribuito](#distributed-model-parallel-checkpoint)
+ [Ottimizzazione di un modello distribuito](#distributed-model-parallel-fine-tuning)

## Checkpoint di un modello distribuito
<a name="distributed-model-parallel-checkpoint"></a>

Scegliete uno dei seguenti argomenti in base al framework tra PyTorch TensorFlow e alla versione della libreria di parallelismo dei SageMaker modelli che utilizzate.

**Topics**
+ [Verifica di un PyTorch modello distribuito (per la libreria di parallelismo dei SageMaker modelli v1.10.0 e successive)](#model-parallel-extended-features-pytorch-checkpoint)
+ [Controllo di un PyTorch modello distribuito (per la libreria di parallelismo dei modelli tra v1.6.0 e SageMaker v1.9.0)](#model-parallel-extended-features-pytorch-saving-loading-checkpoints)
+ [TensorFlow Checkpoint: un modello distribuito](#distributed-model-parallel-checkpoint-tensorflow)

### Verifica di un PyTorch modello distribuito (per la libreria di parallelismo dei SageMaker modelli v1.10.0 e successive)
<a name="model-parallel-extended-features-pytorch-checkpoint"></a>

La libreria di parallelismo dei SageMaker modelli fornisce un checkpoint APIs per salvare e caricare checkpoint completi o parziali dello stato del modello distribuito e del relativo stato dell'ottimizzatore.

**Nota**  
Questo metodo di checkpoint è consigliato se si utilizza la libreria di parallelismo del modello PyTorch v1.10.0 o successiva SageMaker .

**Checkpoint parziale**

Per salvare i checkpoint di un modello addestrato con il parallelismo del modello, utilizza l'API [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save_checkpoint](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save_checkpoint) con l'opzione checkpointing parziale impostata su true (`partial=True`). Ciò salva ogni partizione del modello singolarmente. Oltre al modello e allo stato dell'ottimizzatore, puoi anche salvare eventuali dati personalizzati aggiuntivi tramite l'argomento `user_content`. Il modello Checkpoint, l'ottimizzatore e il contenuto dell'utente vengono salvati come file separati. La chiamata API `save_checkpoint` crea cartelle di checkpoint nella seguente struttura. 

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

Per riprendere l'addestramento da checkpoint parziali, utilizza l'API [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.resume_from_checkpoint](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.resume_from_checkpoint)con `partial=True` e specifica la directory dei checkpoint e il tag utilizzati durante il salvataggio dei checkpoint parziali. Nota che il caricamento effettivo dei pesi del modello avviene dopo il partizionamento del modello, durante la prima esecuzione della funzione della fase di addestramento `smdistributed.modelparallel.torch.step` decorata.

Quando si salva un checkpoint parziale, la libreria salva anche la decisione sulla partizione del modello come file con estensione di file `.pt`. Al contrario, quando si riprende dal checkpoint parziale, la libreria carica insieme i file di decisione sulla partizione. Una volta caricata la decisione sulla partizione, non è possibile modificarla.

Il seguente frammento di codice mostra come impostare il checkpoint in uno script di addestramento. APIs PyTorch

```
import smdistributed.modelparallel.torch as smp

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

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

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

**Checkpoint completo**

Per salvare l'artefatto finale del modello a scopo di inferenza, utilizza l'API `smdistributed.modelparallel.torch.save_checkpoint` con `partial=False`, che combina le partizioni del modello per creare un singolo artefatto del modello. Nota che questo non combina gli stati dell'ottimizzatore.

Per inizializzare l'addestramento con pesi particolari, con un checkpoint completo del modello, puoi utilizzare l'API `smdistributed.modelparallel.torch.resume_from_checkpoint` con `partial=False`. Nota che questo non carica gli stati dell'ottimizzatore.

**Nota**  
Con il parallelismo tensoriale, in generale, `state_dict` deve essere tradotto tra l'implementazione del modello originale e l'implementazione `DistributedModel`. Facoltativamente, puoi fornire la funzione di traduzione `state_dict` come argomento per `smdistributed.modelparallel.torch.resume_from_checkpoint`. Tuttavia, per [Modelli supportati pronti all'uso](model-parallel-extended-features-pytorch-hugging-face.md#model-parallel-extended-features-pytorch-hugging-face-out-of-the-box), la libreria si occupa di questa traduzione automaticamente.

Il codice seguente mostra un esempio di come utilizzare il checkpoint APIs per il checkpoint completo di un PyTorch modello addestrato con il parallelismo dei modelli.

```
import smdistributed.modelparallel.torch as smp

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

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

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

### Controllo di un PyTorch modello distribuito (per la libreria di parallelismo dei modelli tra v1.6.0 e SageMaker v1.9.0)
<a name="model-parallel-extended-features-pytorch-saving-loading-checkpoints"></a>

La libreria di parallelismo dei SageMaker modelli fornisce funzioni Python per il salvataggio di checkpoint parziali o completi per i lavori di formazione con parallelismo tensoriale. La procedura seguente mostra come utilizzare [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save) e [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.load](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.load) per salvare e caricare un checkpoint quando si utilizza il parallelismo tensoriale.

**Nota**  
Questo metodo di checkpoint è consigliato se si utilizza la libreria di parallelismo dei modelli tra la v1.6.0 e la PyTorch [Parallelismo tensoriale](model-parallel-extended-features-pytorch-tensor-parallelism.md) v1.9.0. SageMaker 

1. Prepara un oggetto modello ed esegui il wrapping con la funzione wrapper della libreria `smp.DistributedModel()`.

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

1. Prepara un ottimizzatore per il modello. Un set di parametri del modello è un argomento iterabile richiesto dalle funzioni di ottimizzazione. Per preparare un set di parametri del modello, è necessario procedere per assegnare parametri univoci ai singoli modelli. `model.parameters()` IDs 

   Se ci sono parametri duplicati IDs nel parametro iterabile del modello, il caricamento dello stato dell'ottimizzatore checkpointed non riesce. Per creare un iterabile di parametri del modello con un valore univoco IDs per l'ottimizzatore, consultate quanto segue:

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

1. Esegui il wrapping dell'ottimizzatore usando la funzione wrapper della libreria `smp.DistributedOptimizer()`.

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

1. Salva il modello e lo stato dell'ottimizzatore utilizzando [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.save). A seconda di come desideri salvare i checkpoint, scegli una delle seguenti due opzioni:
   + **Opzione 1:** salva un modello parziale su ciascuno `mp_rank` per uno singolo `MP_GROUP`.

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

     Con il parallelismo tensoriale, la libreria salva i file con checkpoint denominati nel seguente formato: `checkpoint.pt_{pp_rank}_{tp_rank}`.
**Nota**  
Con il parallelismo tensoriale, assicurati di impostare l'istruzione if come `if smp.rdp_rank() == 0` anziché `if smp.dp_rank() == 0`. Quando lo stato dell'ottimizzatore è suddiviso con il parallelismo tensoriale, tutte le classificazioni parallele con dati ridotti devono salvare la propria partizione dello stato dell'ottimizzatore. L'utilizzo di un'istruzione *if* errata per il checkpoint potrebbe comportare l'interruzione del processo di addestramento. *Per ulteriori informazioni sull'utilizzo `if smp.dp_rank() == 0` senza parallelismo tensoriale, vedere [Istruzioni generali per il salvataggio e il caricamento nella](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#general-instruction-for-saving-and-loading) documentazione di Python SageMaker SDK.* 
   + **Opzione 2: salva il modello completo.**

     ```
     if smp.rdp_rank() == 0:
         model_dict = model.state_dict(gather_to_rank0=True) # save the full model
         if smp.rank() == 0:
             smp.save(
                 {"model_state_dict": model_dict},
                 "/checkpoint.pt",
                 partial=False,
             )
     ```
**Nota**  
Per un checkpoint completo:   
Se imposti `gather_to_rank0=True`, tutte le classificazioni diverse da `0` restituiscono dizionari vuoti.
Per il checkpoint completo, puoi solo controllare il modello. Il checkpoint completo degli stati dell'ottimizzatore non è attualmente supportato.
Il modello completo deve solo essere salvato in `smp.rank() == 0`.

1. Carica i checkpoint usando [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.load](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.load). A seconda di come hai fatto il checkpoint della fase precedente, scegli una delle seguenti due opzioni:
   + **Opzione 1:** carica i checkpoint parziali.

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

     Puoi impostare `same_partition_load=True` in `model.load_state_dict()` per un caricamento più veloce, se sai che la partizione non cambierà.
   + **Opzione 2:** carica i checkpoint completi.

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

     La condizione `if smp.rdp_rank() == 0` non è richiesta, ma può aiutare a evitare caricamenti ridondanti tra diversi `MP_GROUP`. Il dizionario completo degli stati dell'ottimizzatore del checkpoint non è attualmente supportato con il parallelismo del tensore.

### TensorFlow Checkpoint: un modello distribuito
<a name="distributed-model-parallel-checkpoint-tensorflow"></a>

Per salvare un TensorFlow modello durante l'addestramento con il parallelismo dei modelli, utilizzate le seguenti funzioni fornite dalla libreria di parallelismo dei SageMaker modelli.
+ [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_tensorflow.html#smp.DistributedModel.save_model](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_tensorflow.html#smp.DistributedModel.save_model)
+ [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_tensorflow.html#smp.CheckpointManager](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_tensorflow.html#smp.CheckpointManager)

## Ottimizzazione di un modello distribuito
<a name="distributed-model-parallel-fine-tuning"></a>

L’ottimizzazione deve essere configurata nello script di addestramento. Il seguente frammento di codice mostra una struttura di esempio di uno script di formazione che utilizza la classe [AutoModelForCausalLM](https://huggingface.co/docs/transformers/main/en/model_doc/auto#transformers.AutoModelForCausalLM) di Hugging Face Transformers con modifiche per la registrazione dei moduli e delle impostazioni per la regolazione fine. `smdistributed.model.parallel.torch`

**Nota**  
[La messa a punto di un trasformatore distribuito (un modello Transformer incluso) con la funzione smp.delayed\$1param\$1initialization attivata richiede la configurazione del processo di fine-tuning con un `smp.DistributedModel()` file system for Lustre.](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#smdistributed.modelparallel.torch.delay_param_initialization) FSx Nei casi in cui si desideri ottimizzare un modello su larga scala con l'opzione di inizializzazione ritardata dei parametri, è necessario configurare un file system for Lustre. FSx 

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

def parse_args():

    parser = argparse.ArgumentParser()

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

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

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

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

    ... # parse numerous args

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

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

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

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

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

[https://github.com/aws/amazon-sagemaker-examples/tree/main/training/distributed_training/pytorch/model_parallel/gpt2](https://github.com/aws/amazon-sagemaker-examples/tree/main/training/distributed_training/pytorch/model_parallel/gpt2) 

# Esempi della libreria di parallelismo dei modelli Amazon SageMaker AI v1
<a name="distributed-model-parallel-examples"></a>

Questa pagina fornisce un elenco di blog e notebook Jupyter che presentano esempi pratici di implementazione della libreria di parallelismo dei SageMaker modelli (SMP) v1 per eseguire lavori di formazione distribuiti sull'intelligenza artificiale. SageMaker 

## Blog e casi di studio
<a name="distributed-model-parallel-examples-blog"></a>

I seguenti blog illustrano casi di studio relativi all’utilizzo di SMP v1.
+ [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/), *AWS Machine Learning Blog* (16 dicembre 2022)
+ [Addestra modelli giganteschi con scalabilità quasi lineare utilizzando il parallelismo dei dati frammentati su Amazon AI, SageMaker Machine](https://aws.amazon.com/blogs/machine-learning/train-gigantic-models-with-near-linear-scaling-using-sharded-data-parallelism-on-amazon-sagemaker/) Learning Blog (31 *AWS ottobre* 2022)

## Notebook di esempio
<a name="distributed-model-parallel-examples-pytorch"></a>

[I taccuini di esempio sono disponibili nell'archivio degli esempi di intelligenza artificiale. SageMaker GitHub ](https://github.com/aws/amazon-sagemaker-examples/tree/master/training/distributed_training/) Per scaricare gli esempi, esegui il comando seguente per clonare il repository e accedere a `training/distributed_training/pytorch/model_parallel`.

**Nota**  
Clona ed esegui i taccuini di esempio nel seguente AI ML. SageMaker IDEs  
[SageMaker JupyterLab](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated-jl.html)(disponibile in [Studio](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated.html) creato dopo dicembre 2023)
[SageMaker Code Editor](https://docs.aws.amazon.com/sagemaker/latest/dg/code-editor.html) (disponibile in [Studio](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated.html) creato dopo dicembre 2023)
[Studio Classic](https://docs.aws.amazon.com/sagemaker/latest/dg/studio.html) (disponibile come applicazione in [Studio](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-updated.html) creata dopo dicembre 2023)
[SageMaker Istanze Notebook](https://docs.aws.amazon.com/sagemaker/latest/dg/nbi.html)

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

**Notebook di esempio SMP v1 per PyTorch**
+ [Addestra GPT-2 con scalabilità quasi lineare utilizzando la tecnica del parallelismo dei dati condivisi nella libreria di parallelismo dei modelli SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/smp-train-gpt-sharded-data-parallel.ipynb)
+ [Ottimizza GPT-2 con scalabilità quasi lineare utilizzando la tecnica del parallelismo dei dati frammentati nella libreria di parallelismo dei modelli SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/smp-fine-tune-gpt-sharded-data-parallel.ipynb)
+ [Addestra GPT-NeOX-20b con una scalabilità quasi lineare utilizzando la tecnica del parallelismo dei dati condiviso nella libreria di parallelismo dei modelli SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt-neox/smp-train-gpt-neox-sharded-data-parallel.ipynb)
+ [Addestra GPT-J 6B utilizzando le tecniche di parallelismo dei dati frammentati e parallelismo tensoriale nella libreria di parallelismo dei modelli SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt-j/smp-train-gptj-sharded-data-parallel-tp.ipynb)
+ [Addestra FLAN-T5 con una scalabilità quasi lineare utilizzando la tecnica del parallelismo dei dati frammentati nella libreria di parallelismo dei modelli SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/flan-t5/smp-train-t5-sharded-data-parallel.ipynb)
+ [Addestra Falcon con una scalabilità quasi lineare utilizzando la tecnica del parallelismo dei dati frammentati nella libreria di parallelismo dei modelli SageMaker ](https://github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/falcon/smp-train-falcon-sharded-data-parallel.ipynb)

**Notebook di esempio SMP v1 per TensorFlow**
+ [CNN con TensorFlow 2.3.1 e la libreria di parallelismo dei modelli SageMaker ](https://sagemaker-examples.readthedocs.io/en/latest/training/distributed_training/tensorflow/model_parallel/mnist/tensorflow_smmodelparallel_mnist.html)
+ [HuggingFace con la libreria di parallelismo dei modelli TensorFlow distribuiti Training on AI SageMaker ](https://github.com/huggingface/notebooks/blob/master/sagemaker/04_distributed_training_model_parallelism/sagemaker-notebook.ipynb)

# SageMaker Best practice per il parallelismo dei modelli distribuiti
<a name="model-parallel-best-practices"></a>

Utilizza le seguenti linee guida quando esegui un processo di formazione distribuito con la libreria SageMaker model parallel.

## Impostazione della configurazione corretta per un determinato modello
<a name="model-parallel-best-practices-configuration"></a>

Quando si ridimensiona un modello, si consiglia di consultare il seguente elenco in ordine. Ogni voce dell'elenco illustra i vantaggi dell'utilizzo delle tecniche della libreria insieme ai compromessi che potrebbero sorgere. 

**Suggerimento**  
Se un modello può adattarsi bene utilizzando un sottoinsieme delle funzionalità della libreria, l'aggiunta di ulteriori funzionalità di parallelismo del modello o di risparmio di memoria di solito non migliora le prestazioni.

**Utilizzo di tipi di istanze GPU di grandi dimensioni**
+ Nell'ambito del parallelismo dei modelli, è preferibile utilizzare istanze potenti con memorie GPU di grandi dimensioni per gestire il sovraccarico dovuto alle operazioni di parallelismo dei modelli, come il partizionamento dei modelli su più modelli. GPUs Consigliamo di utilizzare le nostre istanze `ml.p4d` o `ml.p3dn` per addestrare modelli DL di grandi dimensioni. Queste istanze sono inoltre dotate di Elastic Fabric Adapter (EFA), che fornisce una maggiore larghezza di banda di rete e consente un addestramento su larga scala con parallelismo dei modelli.

**Ripartizione dello stato dell'ottimizzatore**
+ L'impatto dello stato dell'ottimizzatore di ripartizione dipende dal numero di ranghi paralleli dei dati. In genere, un grado più elevato di parallelismo dei dati (proporzionale alla dimensione del nodo di calcolo) può migliorare l'efficienza dell'utilizzo della memoria.

  Quando desideri ridimensionare un cluster, assicurati di controllare la configurazione dello stato di ripartizione dell'ottimizzatore. Ad esempio, un modello DL di grandi dimensioni con ripartizione dello stato dell'ottimizzatore che si adatta a un cluster di elaborazione con 16 GPUs (ad esempio, due istanze P4d o P4de) potrebbe non adattarsi sempre a un nodo con 8 GPUs (ad esempio, una singola istanza P4d o P4de). Questo perché la memoria combinata di 8 GPUs è inferiore alla memoria combinata di 16 GPUs e la memoria richiesta per GPU per lo sharding di oltre 8 GPUs è anche superiore alla memoria per GPU per lo sharding nello scenario a 16 GPU. Di conseguenza, l'aumento del fabbisogno di memoria potrebbe non essere adatto al cluster più piccolo.

  Per ulteriori informazioni, consulta [Partizione dello stato dell'ottimizzatore](model-parallel-extended-features-pytorch-optimizer-state-sharding.md).

**Checkpoint di attivazione**
+ L'efficienza della memoria può essere migliorata utilizzando il checkpoint di attivazione per un gruppo di moduli. Più si raggruppano i moduli, più efficiente è l'utilizzo della memoria. Quando si effettuano il checkpoint dei moduli sequenziali per i livelli, l'argomento `strategy` della funzione `smp.set_activation_checkpointing` raggruppa i livelli per il checkpoint. Ad esempio, il raggruppamento di due o più livelli per il checkpoint è più efficiente in termini di memoria rispetto al checkpoint di un livello alla volta, e ciò consente di rinunciare a un tempo di calcolo aggiuntivo con un utilizzo ridotto della memoria.

  Per ulteriori informazioni, consulta [Checkpoint di attivazione](model-parallel-extended-features-pytorch-activation-checkpointing.md).

**Parallelizzazione tensoriale**
+ Il grado di parallelismo tensoriale deve essere una potenza di due (2, 4, 8,..., 2 n), dove il grado massimo deve essere uguale al numero di per nodo. GPUs Ad esempio, se si utilizza un nodo con 8 GPUs, i numeri possibili per il grado di parallelismo tensoriale sono 2, 4 e 8. Non consigliamo numeri arbitrari (come 3, 5, 6 e 7) per il grado di parallelismo tensoriale. Quando si utilizzano più nodi, una configurazione errata del grado di parallelismo tensoriale potrebbe comportare l'esecuzione del parallelismo tensoriale tra i nodi. Ciò comporta un notevole sovraccarico derivante dalla comunicazione delle attivazioni tra i nodi e può diventare costoso dal punto di vista computazionale.

  Per ulteriori informazioni, consulta [Parallelismo tensoriale](model-parallel-extended-features-pytorch-tensor-parallelism.md).<a name="model-parallel-best-practices-configuration-pipeline-across-nodes"></a>

**Parallelismo delle pipeline tra i nodi**
+ È possibile eseguire il parallelismo delle pipeline sia all'interno di un singolo nodo che su più nodi. Quando utilizzi il parallelismo delle pipeline in combinazione con il parallelismo tensoriale, ti consigliamo di eseguire il parallelismo della pipeline su più nodi e di mantenere il parallelismo tensoriale all'interno dei singoli nodi. 
+ Il parallelismo della pipeline viene fornito con le seguenti tre manopole: `microbatches`, `active_microbatches` e `prescaled_batch`.
  + Quando si utilizza il parallelismo tensoriale con il parallelismo della pipeline, si consiglia di attivare `prescaled_batch` modo da aumentare la dimensione del batch per gruppo parallelo del modello per una pipeline efficiente. Con `prescaled_batch` attivato, la dimensione del batch impostata nello script di addestramento diventa `tp_size` moltiplicata per la dimensione del batch impostata per ogni classificazione senza `prescaled_batch`.
  + L'aumento del numero di `microbatches` consente di ottenere una pipelining efficiente e prestazioni migliori. Si noti che la dimensione effettiva dei microbatch è la dimensione del batch divisa per il numero di microbatch. Se si aumenta il numero di microbatch mantenendo costante la dimensione del batch, ogni microbatch elabora un numero inferiore di campioni.
  + Il numero di `active_microbatches` è il numero massimo di microbatch che vengono processati contemporaneamente durante la pipeline. Per ogni microbatch attivo in corso, le relative attivazioni e i gradienti occupano la memoria della GPU. Pertanto, l'aumento di `active_microbatches` richiede più memoria GPU.
+ Se sia la memoria della GPU che quella della GPU sono sottoutilizzate, aumenta `active_microbatches` per una migliore parallelizzazione durante la pipeline.
+ Per ulteriori informazioni su come utilizzare il parallelismo tensoriale con il parallelismo della pipeline, consulta [Parallelismo tensoriale combinato con parallelismo di pipeline](model-parallel-extended-features-pytorch-tensor-parallelism-examples.md#model-parallel-extended-features-pytorch-tensor-and-pipeline-parallelism).
+ Per trovare le descrizioni dei parametri sopra menzionati, consulta [Parameters for `smdistributed` nella documentazione](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smd_model_parallel_general.html#parameters-for-smdistributed) di *SageMaker Python* SDK.

**Trasferimento delle attivazioni sulla CPU**
+ Assicurati che venga utilizzato in combinazione con il checkpoint di attivazione e il parallelismo della pipeline. Per garantire che l'offload e il preload avvengano in background, specifica un valore maggiore di 1 per il parametro microbatch. 
+ Durante lo scaricamento delle attivazioni, è possibile aumentare `active_microbatches` e talvolta far corrispondere il numero totale di microbatch. Ciò dipende da quali moduli sono sottoposti a checkpoint e da come è partizionato il modello.

  Per ulteriori informazioni, consulta [Offload di attivazione](model-parallel-extended-features-pytorch-activation-offloading.md).

### Configurazioni di riferimento
<a name="model-parallel-best-practices-configuration-reference"></a>

Il team di formazione sul parallelismo dei SageMaker modelli fornisce i seguenti punti di riferimento basati su esperimenti con il modello GPT-2, sulla lunghezza della sequenza di 512 e sulla dimensione del vocabolario di 50.000. 


| Il numero di parametri del modello | Tipo di istanza | Parallelismo della pipeline | Parallelismo tensoriale | Ripartizione dello stato dell'ottimizzatore | Checkpoint di attivazione | Batch pre-ridimensionato | Dimensione batch | 
| --- | --- | --- | --- | --- | --- | --- | --- | 
| 10 miliardi | 16 ml.p4d.24xlarge | 1 | 4 | True | Ogni livello del trasformatore | True | batch\$1size=40 | 
| 30 miliardi | 16 ml.p4d.24xlarge | 1 | 8 | True | Ogni livello del trasformatore | True | batch\$1size=32 | 
| 60 miliardi | 32 ml.p4d.24xlarge | 2 | 8 | True | Ogni livello del trasformatore | True | batch\$1size=56, microbatches=4, active\$1microbatches=2 | 

È possibile estrapolare le configurazioni precedenti per stimare l'utilizzo della memoria GPU per la configurazione del modello. Ad esempio, se aumenti la lunghezza della sequenza per un modello da 10 miliardi di parametri o aumenti le dimensioni del modello a 20 miliardi, potresti voler ridurre prima la dimensione del batch. Se il modello continua a non adattarsi, prova ad aumentare il grado di parallelismo tensoriale.

## Modifica dello script di addestramento
<a name="model-parallel-best-practices-modify-training-script"></a>
+ Prima di utilizzare le funzionalità della libreria SageMaker model parallel nello script di addestramento, rivedi[Suggerimenti e insidie per la configurazione della SageMaker Distributed Model Parallelism Library](model-parallel-customize-tips-pitfalls.md).
+ Per avviare più rapidamente un processo di formazione, utilizza la [modalità locale SageMaker AI](https://sagemaker.readthedocs.io/en/v2.199.0/overview.html?highlight=local%20mode#local-mode). Ciò consente di eseguire rapidamente un processo di formazione localmente su un'istanza di SageMaker notebook. A seconda della scala dell'istanza di ML su cui è in esecuzione l'istanza del SageMaker notebook, potrebbe essere necessario regolare le dimensioni del modello modificando le configurazioni del modello, ad esempio la larghezza nascosta, il numero di livelli del trasformatore e le testine di attenzione. Verifica se il modello ridotto funziona bene sull'istanza del notebook prima di utilizzare un cluster di grandi dimensioni per addestrare il modello completo. 

## Monitoraggio e registrazione di un lavoro di formazione utilizzando la console SageMaker AI e Amazon CloudWatch
<a name="model-parallel-best-practices-monitoring"></a>

[Per monitorare metriche a livello di sistema come l'utilizzo della memoria CPU, l'utilizzo della memoria GPU e l'utilizzo della GPU, utilizza la visualizzazione fornita tramite la console AI. SageMaker ](https://console.aws.amazon.com/sagemaker/)

1. Nel pannello di navigazione a sinistra scegli **Addestramento**.

1. Scegli **Processi di addestramento**.

1. Nel riquadro principale, scegli il nome del processo di addestramento per il quale desideri visualizzare ulteriori dettagli.

1. Sfoglia il pannello principale e trova la sezione **Monitora** per vedere la visualizzazione automatizzata.

1. Per visualizzare i log dei processi di addestramento , scegli **Visualizza log** nella sezione **Monitora**. È possibile accedere ai registri distribuiti dei lavori di formazione relativi al processo di formazione in. CloudWatch Se hai avviato l’addestramento distribuito su più nodi, dovresti vedere più flussi di log con tag nel formato **algo-n-1234567890**. Il flusso di log **algo-1** tiene traccia dei log di addestramento dal nodo principale (0°).

Per ulteriori informazioni, consulta [Amazon CloudWatch Metrics per il monitoraggio e l'analisi dei lavori di formazione](training-metrics.md).

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

Per eseguire un processo di SageMaker formazione con il parallelismo dei modelli o i [notebook di esempio di formazione SageMaker distribuiti](https://sagemaker-examples.readthedocs.io/en/latest/training/distributed_training/index.html), assicurati di disporre delle autorizzazioni giuste nel tuo ruolo IAM, come le seguenti:
+ [Da usare per Lustre, aggiungi. FSx [https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonFSxFullAccess](https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonFSxFullAccess)](https://aws.amazon.com/fsx/)
+ Per utilizzare Amazon S3 come canale dati, aggiungi [https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonS3FullAccess](https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonS3FullAccess).
+ Per utilizzare Docker, creare il tuo container e inviarlo ad Amazon ECR, aggiungi [https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonEC2ContainerRegistryFullAccess](https://console.aws.amazon.com/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonEC2ContainerRegistryFullAccess).
+ Per avere accesso completo all'intera suite di funzionalità di SageMaker intelligenza artificiale, aggiungi [https://console.aws.amazon.com/iam/home#/policies/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonSageMakerFullAccess](https://console.aws.amazon.com/iam/home#/policies/iam/home#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonSageMakerFullAccess). 

# Suggerimenti e insidie per la configurazione della SageMaker Distributed Model Parallelism Library
<a name="model-parallel-customize-tips-pitfalls"></a>

Esamina i seguenti suggerimenti e insidie prima di utilizzare la libreria di parallelismo dei modelli di Amazon SageMaker AI. Questo elenco include suggerimenti applicabili a tutti i framework. Per TensorFlow suggerimenti PyTorch specifici, consulta [Modificare uno script di addestramento TensorFlow](model-parallel-customize-training-script-tf.md) e[Modificare uno script PyTorch di addestramento](model-parallel-customize-training-script-pt.md), rispettivamente. 

## Dimensione del batch e numero di microbatch
<a name="model-parallel-customize-tips-pitfalls-batch-size"></a>
+ La libreria è più efficiente quando la dimensione del batch viene aumentata. Nei casi d'uso in cui il modello si inserisce in un singolo dispositivo, ma può essere addestrato solo con batch di piccole dimensioni, la dimensione del batch può e deve essere aumentata dopo l'integrazione della libreria. Il parallelismo dei modelli consente di risparmiare memoria per i modelli di grandi dimensioni, consentendovi di addestrare utilizzando batch di dimensioni che in precedenza non rientravano nella memoria.
+ La scelta di un numero di microbatch troppo piccolo o troppo grande può ridurre le prestazioni. La libreria esegue ogni microbatch in sequenza in ogni dispositivo, pertanto la dimensione del microbatch (dimensione del batch divisa per il numero di microbatch) deve essere sufficientemente grande da consentire l'utilizzo completo di ciascuna GPU. Allo stesso tempo, l'efficienza della pipeline aumenta con il numero di microbatch, quindi è importante trovare il giusto equilibrio. In genere, un buon punto di inizio è provare 2 o 4 microbatch, aumentando la dimensione del batch fino al limite di memoria, e quindi sperimentare con batch di dimensioni e numeri di microbatch più grandi. Con l'aumento del numero di microbatch, potrebbero diventare possibili lotti di dimensioni maggiori se si utilizza una pipeline interlacciata.
+ La dimensione del batch deve essere sempre divisibile per il numero di microbatch. Tieni presente che, a seconda delle dimensioni del set di dati, a volte l'ultimo batch di ogni epoca può avere dimensioni inferiori rispetto al resto e questo batch più piccolo deve essere divisibile anche per il numero di microbatch. `drop_remainder=True`In caso contrario, è possibile impostare la `tf.Dataset.batch()` chiamata (in TensorFlow) o impostare `DataLoader` (`drop_last=True`in PyTorch), in modo che quest'ultimo, piccolo batch non venga utilizzato. Se si utilizza un'API diversa per la pipeline di dati, potrebbe essere necessario saltare manualmente l'ultimo batch ogni volta che non è divisibile per il numero di microbatch.

## Partizionamento manuale
<a name="model-parallel-customize-tips-pitfalls-manual-partitioning"></a>
+ Se utilizzi il partizionamento manuale, tieni presente i parametri utilizzati da più operazioni e moduli del modello, come la tabella di incorporamento nelle architetture dei trasformatori. I moduli che condividono lo stesso parametro devono essere collocati nello stesso dispositivo per motivi di correttezza. Quando viene utilizzato il partizionamento automatico, la libreria applica automaticamente questo vincolo.

## Preparazione dei dati
<a name="model-parallel-customize-tips-pitfalls-data-preparation"></a>
+ Se il modello richiede più input, assicurati di impostare le operazioni casuali nella data pipeline (ad esempio, lo shuffling) con `smp.dp_rank()`. Se il set di dati viene suddiviso in modo deterministico su dispositivi di parallelismo dei dati, assicurati che lo shard sia indicizzato da `smp.dp_rank()`. Questo serve a garantire che l'ordine dei dati visualizzati su tutte le classificazioni che formano una partizione del modello sia coerente.

## Restituzione di tensori da `smp.DistributedModel`
<a name="model-parallel-customize-tips-pitfalls-return-tensors"></a>
+ Qualsiasi tensore restituito dalla funzione `smp.DistributedModel.call` (for TensorFlow) o `smp.DistributedModel.forward` (for PyTorch) viene trasmesso a tutti gli altri ranghi, dal rango che ha calcolato quel particolare tensore. Di conseguenza, qualsiasi tensore non necessario al di fuori dei metodi call e forward (attivazioni intermedie, ad esempio) non dovrebbe essere restituito, poiché ciò causa inutili comunicazioni e sovraccarico di memoria e danneggia le prestazioni.

## Il decoratore `@smp.step`
<a name="model-parallel-customize-tips-pitfalls-smp-step-decorator"></a>
+ Se una funzione `smp.step` decorata ha un argomento di tensore che non ha una dimensione batch, il nome dell'argomento deve essere fornito nell'elenco `non_split_inputs`durante la chiamata `smp.step`. Ciò impedisce alla libreria di tentare di dividere il tensore in microbatch. Per ulteriori informazioni, consulta [https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_common_api.html](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_common_api.html) nella documentazione API.

## Ritardo dell'inizializzazione dei parametri
<a name="model-parallel-customize-tips-pitfalls-delaying-param-initialization"></a>

Per modelli molto grandi con oltre 100 miliardi di parametri, l'inizializzazione del peso tramite la memoria della CPU potrebbe causare un errore. out-of-memory Per ovviare a questo problema, la libreria offre un gestore di contesto `smp.delay_param_initialization`. Ciò ritarda l'allocazione fisica dei parametri fino a quando non passano alla GPU durante la prima esecuzione di una funzione `smp.step` decorata. Ciò evita un utilizzo non necessario della memoria della CPU durante l'inizializzazione dell'addestramento. Utilizza il gestore di contesto quando crei un oggetto modello, come mostrato nel codice seguente.

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

## Tensor Parallelism per PyTorch
<a name="model-parallel-customize-tips-pitfalls-tensor-parallelism-pytorch"></a>
+ Se stai usando un seed per risultati deterministici, imposta il seed in base a `smp.dp_rank()` (ad esempio, `torch.manual_seed(42 + smp.dp_rank())`). Se non effettui questa operazione, diverse partizioni di un `nn.Parameter` vengono inizializzate nello stesso modo, con un impatto sulla convergenza. 
+ SageMakerla libreria di parallelismo dei modelli utilizza NCCL per implementare i collettivi necessari per la distribuzione dei moduli. Soprattutto per i modelli più piccoli, se sulla GPU sono programmate troppe chiamate NCCL contemporaneamente, l'utilizzo della memoria potrebbe aumentare a causa dello spazio aggiuntivo utilizzato da NCCL. Per ovviare a questo problema, `smp` limita le chiamate NCCL in modo che il numero di operazioni NCCL in corso in un dato momento sia inferiore o uguale a un determinato limite. Il limite predefinito è 8, ma può essere regolato utilizzando la variabile di ambiente `SMP_NCCL_THROTTLE_LIMIT`. Se osservi un utilizzo della memoria maggiore del previsto durante l'utilizzo del parallelismo tensoriale, puoi provare a ridurre questo limite. Tuttavia, la scelta di un limite troppo piccolo potrebbe causare una perdita di throughput. Per disabilitare completamente la limitazione, puoi impostare `SMP_NCCL_THROTTLE_LIMIT=-1`. 
+ La seguente identità, che vale quando il grado di parallelismo tensoriale è 1, non vale quando il grado di parallelismo tensoriale è maggiore di 1: `smp.mp_size() * smp.dp_size() == smp.size()`. Questo perché il gruppo parallelo tensoriale fa parte sia del gruppo di parallelismo del modello che del gruppo di parallelismo dei dati. Se il codice contiene riferimenti esistenti a `mp_rank`, `mp_size`, `MP_GROUP` e così via e se desideri lavorare solo con il gruppo pipeline parallel, potrebbe essere necessario sostituire i riferimenti con `smp.pp_size()`. Le seguenti identità sono sempre vere: 
  +  `smp.mp_size() * smp.rdp_size() == smp.size()` 
  +  `smp.pp_size() * smp.dp_size() == smp.size()` 
  +  `smp.pp_size() * smp.tp_size() * smp.rdp_size() == smp.size()` 
+ Poiché il wrapper `smp.DistributedModel` modifica i parametri del modello quando il parallelismo tensoriale è abilitato, l'ottimizzatore deve essere creato dopo la chiamata a `smp.DistributedModel`, con i parametri distribuiti. Ad esempio, quanto segue non funziona: 

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

  Invece, l'ottimizzatore dovrebbe essere creato con i seguenti parametri del `smp.DistributedModel`:

  ```
  ## CORRECT
  model = smp.DistributedModel(MyModel())
  optimizer = SomeOptimizer(model.optimizers())
  ```
+ Quando un modulo viene sostituito con la sua controparte distribuita tramite il parallelismo tensoriale, il modulo distribuito non eredita i suoi pesi dal modulo originale e inizializza nuovi pesi. Ciò significa che, ad esempio, se i pesi devono essere inizializzati in una particolare chiamata (ad esempio, tramite una chiamata `load_state_dict`), ciò deve avvenire dopo la chiamata `smp.DistributedModel`, una volta avvenuta la distribuzione del modulo. 
+ Quando accedi direttamente ai parametri dei moduli distribuiti, tieni presente che il peso non ha la stessa forma del modulo originale. Ad esempio,  

  ```
  with smp.tensor_parallelism():
      linear = nn.Linear(60, 60)
  
  # will pass
  assert tuple(linear.weight.shape) == (60, 60)
  
  distributed_linear = smp.DistributedModel(linear)
  
  # will fail. the number of input channels will have been divided by smp.tp_size()
  assert tuple(distributed_linear.module.weight.shape) == (60, 60)
  ```
+ L'uso di `torch.utils.data.distributed.DistributedSampler` è fortemente consigliato per il parallelismo tensoriale. Ciò garantisce che ogni classificazione di parallelismo dei dati riceva lo stesso numero di campioni di dati, il che impedisce i blocchi che potrebbero derivare dall'esecuzione di diversi numeri di fasi da parte di diversi `dp_rank`. 
+ Se si utilizza la `DistributedDataParallel` classe `join` API of PyTorch per gestire i casi in cui ranghi paralleli di dati diversi hanno un numero diverso di batch, è comunque necessario assicurarsi che i ranghi che si trovano nello stesso `TP_GROUP` numero di batch; altrimenti i collettivi di comunicazione utilizzati nell'esecuzione distribuita dei moduli potrebbero bloccarsi. Le classificazioni che si trovano in `TP_GROUP` diversi possono avere un numero diverso di batch, purché venga utilizzata l'API `join`. 
+ Se desideri controllare il tuo modello e utilizzare il parallelismo tensoriale, considera quanto segue: 
  + Per evitare situazioni di stallo e condizioni di competizione durante il salvataggio e il caricamento dei modelli quando utilizzi il parallelismo tensoriale, assicurati di richiamare le funzioni appropriate dai seguenti stati del modello e dell'ottimizzatore all'interno di una classificazione di parallelismo dei dati ridotta.
  + Se stai effettuando la transizione di uno script parallelo di pipeline esistente e abiliti il parallelismo tensoriale per lo script, assicurati di modificare qualsiasi blocco `if smp.dp_rank() == 0` utilizzato per il salvataggio e il caricamento con blocchi `if smp.rdp_rank() == 0`. In caso contrario, il processo di addestramento potrebbe bloccarsi. 

  Per ulteriori informazioni sul checkpoint di un modello con parallelismo tensoriale, consulta [Checkpoint di un modello distribuito](distributed-model-parallel-checkpointing-and-finetuning.md#distributed-model-parallel-checkpoint).

# Risoluzione dei problemi del parallelismo dei modelli
<a name="distributed-troubleshooting-model-parallel"></a>

Se riscontri un errore, puoi utilizzare il seguente elenco per provare a risolvere il tuo processo di addestramento. Se il problema persiste, contatta l’[Assistenza AWS](https://aws.amazon.com/premiumsupport). 

**Topics**
+ [Considerazioni sull'utilizzo di SageMaker Debugger con la Model Parallelism Library SageMaker](#distributed-ts-model-parallel-debugger)
+ [Salvataggio dei checkpoint](#distributed-ts-model-parallel-checkpoints)
+ [Convergenza utilizzando Model Parallel e TensorFlow](#distributed-ts-model-parallel-tf-convergence)
+ [Blocco o arresto anomalo dei processi di addestramento distribuiti](#distributed-ts-model-parallel-training-issues)
+ [Ricezione di un errore NCCL per un job di formazione PyTorch](#distributed-ts-model-parallel-nccl-error)
+ [Ricezione `RecursionError` per un PyTorch tirocinio](#distributed-ts-model-parallel-super-forward-not-supported)

## Considerazioni sull'utilizzo di SageMaker Debugger con la Model Parallelism Library SageMaker
<a name="distributed-ts-model-parallel-debugger"></a>

SageMaker Debugger non è disponibile per la libreria di parallelismo dei modelli. SageMaker Il debugger è abilitato per impostazione predefinita per tutti i processi di PyTorch formazione SageMaker TensorFlow e potresti visualizzare un errore simile al seguente: 

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

Per risolvere questo problema, disabilita Debugger passando `debugger_hook_config=False` durante la creazione di un framework `estimator`, come mostrato nell'esempio seguente.

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

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

estimator = TensorFlow(
    ...

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

## Salvataggio dei checkpoint
<a name="distributed-ts-model-parallel-checkpoints"></a>

Potresti riscontrare il seguente errore durante il salvataggio dei checkpoint di un modello di grandi dimensioni su AI: SageMaker 

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

Ciò potrebbe essere causato da una limitazione dell' SageMaker IA durante il caricamento del checkpoint locale su Amazon S3 durante la formazione. Per disabilitare il checkpoint nell' SageMaker IA, usa il seguente esempio per caricare esplicitamente i checkpoint.

Se riscontri l'errore precedente, non utilizzarlo con la chiamata. `checkpoint_s3_uri` SageMaker `estimator` Durante il salvataggio dei checkpoint per modelli più grandi, consigliamo di salvare i checkpoint in una directory personalizzata e di passarli alla funzione di supporto (come argomento `local_path`).

```
import os

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

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

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

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

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

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

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

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

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

Utilizzo delle funzioni di supporto:

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

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

## Convergenza utilizzando Model Parallel e TensorFlow
<a name="distributed-ts-model-parallel-tf-convergence"></a>

Quando si utilizza l' SageMaker intelligenza artificiale multinodo TensorFlow e la libreria di parallelismo dei modelli, la perdita potrebbe non convergere come previsto perché l'ordine dei file di input di addestramento potrebbe essere diverso su ciascun nodo. Ciò può far sì che ranghi diversi nello stesso gruppo parallelo del modello lavorino su file di input diversi, causando incongruenze. Per evitare ciò, assicurati che i file di input siano ordinati allo stesso modo in tutti i ranghi prima che vengano convertiti in set di dati. TensorFlow Un modo per raggiungere questo obiettivo è ordinare i nomi dei file di input nello script di addestramento.

## Blocco o arresto anomalo dei processi di addestramento distribuiti
<a name="distributed-ts-model-parallel-training-issues"></a>

Se il processo di addestramento presenta problemi di blocco, arresto anomalo o mancata risposta, leggi i seguenti articoli per la risoluzione dei problemi per identificare la causa del problema. Se hai bisogno di ulteriore assistenza, contatta il team di formazione SageMaker distribuito tramite [AWS Support](https://aws.amazon.com/premiumsupport).
+  Se vedi **un processo di addestramento distribuito che si blocca durante la fase di inizializzazione NCCL**, considera quanto segue: 
  + Se utilizzi una delle istanze (istanze `ml.p4d` o `ml.p3dn`) abilitate per EFA con un VPC personalizzato e relativa sottorete, assicurati che il gruppo di sicurezza utilizzato disponga di connessioni in entrata e in uscita per tutte le porte da e verso lo stesso SG. In genere sono inoltre necessarie connessioni in uscita a qualsiasi IP come regola separata (per l'accesso a Internet). Per trovare istruzioni su come aggiungere regole in entrata e in uscita per le comunicazioni EFA, consulta [SageMaker Il processo di formazione distribuito dall'IA si blocca durante l'inizializzazione](distributed-troubleshooting-data-parallel.md#distributed-ts-data-parallel-efa-sg).
+ Se noti che un **processo di addestramento distribuito si blocca durante il checkpoint** del modello completo, ciò potrebbe essere dovuto al fatto che la chiamata `state_dict()` al modello o all'ottimizzatore non è stata effettuata a tutti i livelli con `rdp_rank()==0` (quando si utilizza il parallelismo tensoriale) o `dp_rank()==0` (quando si utilizza solo il parallelismo delle pipeline). Questi livelli devono comunicare per costruire il checkpoint da salvare. Problemi di stallo simili possono verificarsi anche quando l'ottimizzatore parziale di checkpoint `shard_optimizer_state` è abilitato. 

  Per ulteriori informazioni sul checkpoint di un modello con parallelismo del modello, vedere [Istruzioni generali per il salvataggio e il caricamento](https://sagemaker.readthedocs.io/en/v2.199.0/api/training/smp_versions/latest/smd_model_parallel_pytorch.html#general-instruction-for-saving-and-loading) e[Controllo di un PyTorch modello distribuito (per la libreria di parallelismo dei modelli tra v1.6.0 e SageMaker v1.9.0)](distributed-model-parallel-checkpointing-and-finetuning.md#model-parallel-extended-features-pytorch-saving-loading-checkpoints).
+ Se il processo di addestramento si blocca con un **errore CUDA Memoria esaurita**, significa che la configurazione di addestramento distribuito deve essere adattata al modello sul cluster GPU. Per ulteriori informazioni e best practice, consulta [Impostazione della configurazione corretta per un determinato modello](model-parallel-best-practices.md#model-parallel-best-practices-configuration).
+ Se il processo di formazione si blocca con un **[errore ECC](https://docs.nvidia.com/deploy/a100-gpu-mem-error-mgmt/index.html) non correggibile**, significa che uno dei componenti del GPUs cluster non funziona correttamente. Se hai bisogno di supporto tecnico, condividi l'ARN del processo con il AWS team e, se possibile, riavvia il processo di addestramento da un checkpoint.
+ In rari casi, la configurazione di un processo che funzionava in precedenza ma che è vicina ai limiti della memoria della GPU potrebbe fallire in seguito con un cluster diverso a causa di un **errore CUDA Memoria esaurita**. Ciò potrebbe essere dovuto al fatto che alcune GPU hanno una memoria disponibile inferiore al solito a causa di errori ECC.
+ Un **arresto anomalo del timeout di rete** potrebbe verificarsi quando si esegue un processo multinodo che non utilizza tutto il nodo. GPUs Per ovviare a questo problema, usa all GPUs on the node assicurandoti che il `processes_per_host` parametro sia impostato sul numero di GPUs in ogni istanza. Ad esempio, questo è `processes_per_host=8` per le istanze `ml.p3.16xlarge`, `ml.p3dn.24xlarge`, e `ml.p4d.24xlarge`.
+ Se ritieni che il tuo processo di formazione richieda molto tempo durante la fase di download dei dati, assicurati che il percorso Amazon S3 che hai fornito `checkpoint_s3_uri` per il SageMaker `Estimator` corso sia unico per il corso di formazione corrente. Se questo percorso viene riutilizzato in più processi di addestramento eseguiti contemporaneamente, tutti i checkpoint vengono caricati e scaricati sullo stesso percorso Amazon S3 e potrebbero aumentare significativamente il tempo di caricamento dei checkpoint.
+ Utilizzalo FSx per Lustre quando gestisci dati e modelli di grandi dimensioni.
  + [Se il set di dati è di grandi dimensioni e il recupero richiede molto tempo, ti consigliamo di conservare il set di dati per Lustre. FSx ](https://aws.amazon.com/fsx/lustre/)
  + Quando i modelli di addestramento superano i 10 miliardi di parametri, consigliamo di utilizzare Lustre FSx per il checkpoint.
  + Dopo aver creato un file system, assicurati di attendere che lo status diventi **disponibile** prima di iniziare un processo di addestramento che lo utilizzi. 

## Ricezione di un errore NCCL per un job di formazione PyTorch
<a name="distributed-ts-model-parallel-nccl-error"></a>

Se hai riscontrato il seguente errore, potrebbe essere dovuto a un processo che sta esaurendo la memoria della GPU.

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

È possibile risolvere questo problema riducendo la dimensione del batch o `active_microbatches`. Se il partizionamento automatico non porta a un partizionamento ben bilanciato, potrebbe essere necessario prendere in considerazione il partizionamento manuale. Per ulteriori informazioni, consulta [Parallelismo delle pipeline tra i nodi](model-parallel-best-practices.md#model-parallel-best-practices-configuration-pipeline-across-nodes).

## Ricezione `RecursionError` per un PyTorch tirocinio
<a name="distributed-ts-model-parallel-super-forward-not-supported"></a>

La libreria non supporta le chiamate `super.forward()` all'interno della chiamata inoltrata di un modulo. Se utilizzi `super.forward()`, potresti visualizzare il seguente messaggio di errore: 

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

Per correggere l'errore, invece di chiamare `super.forward()`, dovresti chiamare `super()._orig_forward()`. 