

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

# Inizializzazione ritardata dei parametri
<a name="model-parallel-core-features-v2-delayed-param-init"></a>

L’inizializzazione di un modello di grandi dimensioni per l’addestramento non sempre è possibile se la memoria GPU è limitata. Per risolvere un problema di memoria GPU insufficiente, puoi inizializzare il modello sulla memoria della CPU. Tuttavia, per i modelli più grandi con più di 20 o 40 miliardi di parametri, anche la memoria della CPU potrebbe risultare insufficiente. In tal caso, ti consigliamo di inizializzare il modello su quello che PyTorch chiama *metadispositivo*, che consente la creazione di tensori senza alcun dato ad essi allegato. Un tensore su un metadispositivo necessita solo delle informazioni sulla forma e questo permette di creare un modello di grandi dimensioni con i relativi parametri su metadispositivi. [Hugging Face Accelerate](https://huggingface.co/docs/accelerate/index) fornisce il gestore di contesto `init_empty_weights` che facilita la creazione di tale modello su metadispositivi mentre inizializza i buffer su un dispositivo normale. Prima dell'inizio dell'addestramento, PyTorch FSDP inizializza i parametri del modello. Questa funzionalità di inizializzazione ritardata dei parametri di SMP v2 ritarda la creazione dei parametri del modello dopo che FSDP ha eseguito la suddivisione dei parametri. PyTorch PyTorch FSDP accetta una funzione di inizializzazione dei parametri (`param_init_fn`) durante la suddivisione dei moduli e chiama ogni modulo. `param_init_fn` L’API `param_init_fn` accetta un modulo come argomento e inizializza tutti i parametri in esso contenuti, esclusi i parametri di tutti i moduli secondari. Nota che questo comportamento è *diverso dalla versione* nativa PyTorch 2.0.1, che presenta un bug che causa l'inizializzazione dei parametri più volte.

SMP v2 fornisce l’API [`torch.sagemaker.delayed_param.DelayedParamIniter`](distributed-model-parallel-v2-reference.md#model-parallel-v2-torch-sagemaker-reference-delayed-param-init) per applicare l’inizializzazione ritardata dei parametri.

I seguenti frammenti di codice mostrano come applicare l’API `torch.sagemaker.delayed_param.DelayedParamIniter` allo script di addestramento.

Supponiamo di avere uno script di addestramento PyTorch FSDP come segue.

```
# Creation of model on meta device
from accelerate import init_empty_weights
with init_empty_weights():
    model = create_model()

# Define a param init fn, below is an example for Hugging Face GPTNeoX.
def init_weights(module):
    d = torch.cuda.current_device()
    # Note that below doesn't work if you have buffers in the model
    # buffers will need to reinitialized after this call
    module.to_empty(device=d, recurse=False)
    if isinstance(module, (nn.Linear, Conv1D)):
        module.weight.data.normal_(mean=0.0, std=args.initializer_range)
        if module.bias:
            module.bias.data.zero_()
    elif isinstance(module, nn.Embedding):
        module.weight.data.normal_(mean=0.0, std=args.initializer_range)
        if module.padding_idx:
            module.weight.data[module.padding_idx].zero_()
    elif isinstance(module, nn.LayerNorm):
        module.bias.data.zero_()
        module.weight.data.fill_(1.0)

# Changes to FSDP wrapper.
model = FSDP(
    model,
    ...,
    param_init_fn=init_weights
)

# At this point model is initialized and sharded for sharded data parallelism.
```

Tieni presente che l’approccio di inizializzazione ritardata dei parametri non è indipendente dal modello. Per risolvere questo problema, è necessario scrivere una funzione `init_weights`, come illustrato nell’esempio precedente, in modo che corrisponda all’inizializzazione nella definizione originale del modello e che ne includa tutti i parametri. Per semplificare il processo di preparazione della funzione `init_weights`, SMP v2 implementa questa funzione di inizializzazione per i seguenti modelli: GPT-2, GPT-J, GPT-NeoX e Llama di Hugging Face Transformers. L’API `torch.sagemaker.delayed_param.DelayedParamIniter` funziona anche con l’implementazione parallela del tensore SMP, modello `torch.sagemaker.tensor_parallel.transformer.TransformerLMHead`, che può essere chiamato dopo chiamata API [`torch.sagemaker.transform`](distributed-model-parallel-v2-reference.md#model-parallel-v2-torch-sagemaker-reference-transform).

Utilizzando l'`torch.sagemaker.delayed_param.DelayedParamIniter`API, è possibile adattare lo script PyTorch FSDP come segue. Dopo aver creato un modello con pesi vuoti, registra l’API `torch.sagemaker.delayed_param.DelayedParamIniter` sul modello e definiscine un oggetto. Passa l'oggetto alla classe `param_init_fn` PyTorch FSDP.

```
from torch.sagemaker.delayed_param import DelayedParamIniter
from accelerate import init_empty_weights

with init_empty_weights():
    model = create_model()
    
delayed_initer = DelayedParamIniter(model)

with delayed_initer.validate_params_and_buffers_inited():
    model = FSDP(
        model,
        ...,
        param_init_fn=delayed_initer.get_param_init_fn()
    )
```

**Note sui pesi condivisi**

Quando si allenano modelli con pesi uguali, è necessario prestare particolare attenzione a legare i pesi dopo aver inizializzato i pesi con l'inizializzazione ritardata dei parametri. PyTorch FSDP non dispone di un meccanismo per legare i pesi dopo averli inizializzati utilizzando quanto sopra. `param_init_fn` Per risolvere questi casi, abbiamo aggiunto un’API per consentire a `post_init_hook_fn`, da utilizzare per condividere i pesi. È possibile inserire qualsiasi funzione che accetti il modulo come argomento, ma è presente anche una definizione predefinita `post_param_init_fn` definita in `DelayedParamIniter` che chiama il metodo `tie_weights` del modulo, se esistente. Tieni presente che è sempre sicuro passare in `post_param_init_fn` anche se non esiste un metodo `tie_weights` per il modulo.

```
with delayed_initer.validate_params_and_buffers_inited():
    model = FSDP(
        model,
        ...,
        param_init_fn=delayed_initer.get_param_init_fn(),
        post_param_init_fn=delayed_initer.get_post_param_init_fn()
    )
```