

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Dicas e armadilhas de configuração da SageMaker Distributed Model Parallelism Library
<a name="model-parallel-customize-tips-pitfalls"></a>

Analise as dicas e armadilhas a seguir antes de usar a biblioteca de SageMaker paralelismo de modelos da Amazon AI. Essa lista inclui dicas que são aplicáveis em todos os frameworks. Para obter TensorFlow dicas PyTorch específicas, consulte [Modificar um script TensorFlow de treinamento](model-parallel-customize-training-script-tf.md) e[Modificar um script PyTorch de treinamento](model-parallel-customize-training-script-pt.md), respectivamente. 

## Tamanho do lote e número de microlotes
<a name="model-parallel-customize-tips-pitfalls-batch-size"></a>
+ A biblioteca é mais eficiente quando o tamanho do lote é aumentado. Para casos de uso em que o modelo cabe em um dispositivo único, mas pode ser treinado apenas com um tamanho de lote pequeno, o tamanho do lote pode e deve ser aumentado após a integração da biblioteca. O paralelismo de modelos economiza memória para modelos grandes, habilitando o treinamento usando tamanhos do lote que antes não cabiam na memória.
+ Escolher um número de microlotes muito pequenos ou muito grandes pode reduzir a performance. A biblioteca executa cada microlote sequencialmente em cada dispositivo, portanto, o tamanho do microlote (tamanho do lote dividido pelo número de microlotes) deve ser grande o suficiente para utilizar totalmente cada GPU. Ao mesmo tempo, a eficiência do pipeline aumenta com o número de microlotes, portanto, é importante encontrar o equilíbrio certo. Normalmente, um bom ponto de partida é experimentar 2 ou 4 microlotes, aumentando o tamanho do lote até o limite de memória e, em seguida, experimentar tamanhos do lote e números de microlotes maiores. À medida que o número de microlotes aumenta, tamanhos do lote maiores podem se tornar viáveis se um pipeline intercalado for usado.
+ O tamanho do lote deve ser sempre divisível pelo número de microlotes. Observe que, dependendo do tamanho do conjunto de dados, às vezes, o último lote de cada epoch pode ser menor que o resto e esse lote menor também precisa ser divisível pelo número de microlotes. Se não estiver, você pode definir `drop_remainder=True` a `tf.Dataset.batch()` chamada (in TensorFlow) ou definir `drop_last=True` in `DataLoader` (in PyTorch), para que esse último lote pequeno não seja usado. Se você estiver usando uma API diferente para o pipeline de dados, talvez seja necessário ignorar manualmente o último lote sempre que ele não for divisível pelo número de microlotes.

## Particionamento manual
<a name="model-parallel-customize-tips-pitfalls-manual-partitioning"></a>
+ Se você usa o particionamento manual, esteja atento aos parâmetros que são consumidos por várias operações e módulos em seu modelo, como a tabela de incorporação nas arquiteturas do transformador. Módulos que compartilham o mesmo parâmetro devem ser colocados no mesmo dispositivo para que estejam corretos. Quando o particionamento automático é usado, a biblioteca aplica automaticamente essa restrição.

## Preparação de dados
<a name="model-parallel-customize-tips-pitfalls-data-preparation"></a>
+ Se o modelo usar várias entradas, certifique-se de semear as operações aleatórias em seu data pipeline (por exemplo, embaralhar) com `smp.dp_rank()`. Se o conjunto de dados estiver sendo fragmentado de forma determinística em dispositivos em paralelo de dados, certifique-se de que o fragmento seja indexado por `smp.dp_rank()`. Isso irá garantir que a ordem dos dados vistos em todas as classificações que formam uma partição de modelo seja consistente.

## Retornar tensores de `smp.DistributedModel`
<a name="model-parallel-customize-tips-pitfalls-return-tensors"></a>
+ Qualquer tensor retornado da função `smp.DistributedModel.call` (for TensorFlow) ou `smp.DistributedModel.forward` (for) é transmitido para PyTorch todas as outras classificações, a partir da classificação que calculou esse tensor específico. Como resultado, qualquer tensor que não é necessário fora dos métodos de chamada e encaminhamento (ativações intermediárias, por exemplo) não deve ser retornado, pois isso causa comunicação desnecessária e sobrecarga da memória e prejudica a performance.

## O Decorator do `@smp.step`
<a name="model-parallel-customize-tips-pitfalls-smp-step-decorator"></a>
+ Se uma função decorada por `smp.step` tiver um argumento de tensor que não tenha uma dimensão de lote, o nome do argumento deverá ser fornecido na lista `non_split_inputs` durante a chamada de `smp.step`. Isso evita que a biblioteca tente dividir o tensor em microlotes. Para obter mais informações, consulte [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) na documentação de API.

## Atrasar a inicialização do parâmetro
<a name="model-parallel-customize-tips-pitfalls-delaying-param-initialization"></a>

Para modelos muito grandes com mais de 100 bilhões de parâmetros, a inicialização do peso por meio da memória da CPU pode resultar em um out-of-memory erro. Para contornar isso, a biblioteca oferece um gerenciador de contexto `smp.delay_param_initialization`. Isso atrasa a alocação física dos parâmetros até que eles sejam movidos para a GPU durante a primeira execução de uma função decorada por `smp.step`. Isso evita o uso desnecessário de memória da CPU durante a inicialização do treinamento. Use o gerenciador de contexto ao criar um objeto de modelo, conforme exibido no código a seguir.

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

## Paralelismo de tensores para PyTorch
<a name="model-parallel-customize-tips-pitfalls-tensor-parallelism-pytorch"></a>
+ Se você estiver usando uma semente para resultados determinísticos, defina a semente baseada em `smp.dp_rank()` (por exemplo, `torch.manual_seed(42 + smp.dp_rank())`). Se você não fizer isso, partições diferentes de um `nn.Parameter` serão inicializadas da mesma forma, afetando a convergência. 
+ SageMakerA biblioteca de paralelismo de modelos usa NCCL para implementar os coletivos necessários para a distribuição dos módulos. Especialmente para modelos menores, se muitas chamadas de NCCL forem programadas na GPU ao mesmo tempo, o uso de memória poderá aumentar devido ao espaço adicional usado pela NCCL. Para neutralizar isso, `smp` controla as chamadas de NCCL para que, a qualquer momento, o número de operações contínuas de NCCL seja menor ou igual a um determinado limite. O limite padrão é 8, mas isso pode ser ajustado usando a variável de ambiente `SMP_NCCL_THROTTLE_LIMIT`. Se você observar o uso de memória maior do que o esperado ao usar o paralelismo de tensores, tente reduzir esse limite. No entanto, escolher um limite muito pequeno pode causar perda de taxa de transferência. Para desativar completamente o controle de utilização, você pode definir `SMP_NCCL_THROTTLE_LIMIT=-1`. 
+ A seguinte identidade, que é válida quando o grau de paralelismo de tensores é 1, não é válida quando o grau de paralelismo de tensores é maior que 1: `smp.mp_size() * smp.dp_size() == smp.size()`. Isso ocorre porque o grupo em paralelo de tensores faz parte do grupo de paralelismo do modelo e do grupo de paralelismo de dados. Se seu código tiver referências existentes a `mp_rank`, `mp_size`, `MP_GROUP` e assim por diante, e se você quiser trabalhar apenas com o grupo em paralelo do pipeline, talvez seja necessário substituir as referências por `smp.pp_size()`. As seguintes identidades são sempre verdadeiras: 
  +  `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()` 
+ Uma vez que o wrapper do `smp.DistributedModel` modifica os parâmetros do modelo quando o paralelismo de tensores está ativado, o otimizador deve ser criado após a chamada de `smp.DistributedModel`, com os parâmetros distribuídos. Por exemplo, o seguinte não funciona: 

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

  Em vez disso, o otimizador deve ser criado com os seguintes parâmetros de `smp.DistributedModel`:

  ```
  ## CORRECT
  model = smp.DistributedModel(MyModel())
  optimizer = SomeOptimizer(model.optimizers())
  ```
+ Quando um módulo é substituído por sua contraparte distribuída por meio de paralelismo de tensores, o módulo distribuído não herda seus pesos do módulo original e inicializa novos pesos. Isso significa que, por exemplo, se os pesos precisarem ser inicializados em uma chamada específica (por exemplo, por meio de uma chamada de `load_state_dict`), isso precisará acontecer após a chamada de `smp.DistributedModel`, quando a distribuição do módulo ocorrer. 
+ Ao acessar diretamente os parâmetros dos módulos distribuídos, observe que o peso não tem o mesmo formato do módulo original. Por exemplo:  

  ```
  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)
  ```
+ O uso de `torch.utils.data.distributed.DistributedSampler` é altamente recomendado para paralelismo de tensores. Isso garante que cada classificação em paralelo de dados receba o mesmo número de amostras de dados, o que evita interrupções que possam resultar de diferentes `dp_rank`s realizando um número de etapas diferentes. 
+ Se você usar a `join` API da `DistributedDataParallel` classe PyTorch's para lidar com casos em que diferentes classificações paralelas de dados têm números diferentes de lotes, você ainda precisa garantir que as classificações que estão na mesma `TP_GROUP` tenham o mesmo número de lotes; caso contrário, os coletivos de comunicação usados na execução distribuída de módulos podem travar. Classificações que estão em diferentes `TP_GROUP`s podem ter diferentes números de lotes, desde que a API do `join` seja usada. 
+ Se você quiser que seu modelo tenha um ponto de verificação e usar o paralelismo de tensores, considere o seguinte: 
  + Para evitar paradas e condições de corrida ao salvar e carregar modelos ao usar o paralelismo de tensores, certifique-se de chamar as funções apropriadas dos seguintes estados do modelo e do otimizador dentro de uma classificação de paralelismo de dados reduzidos.
  + Se você estiver fazendo a transição de um script em paralelo do pipeline existente e habilitando o tensor em paralelo para o script, certifique-se de modificar qualquer bloco de `if smp.dp_rank() == 0` usado para salvar e carregar os blocos de `if smp.rdp_rank() == 0`. Caso contrário, isso pode fazer com que a tarefa de treinamento pare. 

  Para obter mais informações sobre o ponto de verificação de um modelo com paralelismo de tensores, consulte [Pontos de verificação de um modelo distribuído](distributed-model-parallel-checkpointing-and-finetuning.md#distributed-model-parallel-checkpoint).