PyTorch
Traga seu próprio modelo do PyTorch para o SageMaker e execute o trabalho de treinamento com o SageMaker Training Compiler.
Modelos PyTorch com transformadores Hugging Face
Os modelos PyTorch com Hugging Face TransformersPyTorch
ou o estimador HuggingFace
com a configuração do SageMaker Training Compiler quando passar para o próximo tópico em Habilitar o SageMaker Training Compiler.
dica
Quando criar um tokenizador para um modelo de PNL usando Transformers em seu script de treinamento, certifique-se de usar uma forma de tensor de entrada estática especificando padding='max_length'
. Não use padding='longest'
porque o preenchimento da sequência mais longa do lote pode alterar a forma do tensor de cada lote de treinamento. A forma de entrada dinâmica pode acionar a recompilação do modelo e aumentar o tempo total de treinamento. Para obter mais informações sobre as opções de preenchimento dos tokenizadores Transformers, consulte Preenchimento e truncamento
Tópicos
Modelos de linguagem grandes usando a classe Trainer
de Hugging Face Transformers
Se você usa a classe Trainer da biblioteca transformers, não precisa fazer nenhuma alteração adicional em seu script de treinamento. O SageMaker Training Compiler compila automaticamente seu modelo Trainer se você ativá-lo por meio da classe estimador. O código a seguir mostra a forma básica de um script de treinamento do PyTorch com a API Hugging Face Trainer.
from transformers import Trainer, TrainingArguments training_args=TrainingArguments(**kwargs) trainer=Trainer(args=training_args, **kwargs)
Tópicos
Para treinamento em uma única GPU
Você não precisa alterar o código quando usar a classe transformers.Trainer
Para treinamento distribuído
PyTorch v1.11.0 e versões posteriores
Para executar um treinamento distribuído com o SageMaker Training Compiler, adicione a função_mp_fn()
a seguir em seu script de treinamento e agrupe a função main()
. As chamadas de função _mp_fn(index)
do runtime distribuído do SageMaker são redirecionadas para PyTorch (pytorchxla
) para a função main()
do seu script de treinamento.
def _mp_fn(index): main()
Essa função aceita o argumento index
para indicar a classificação da GPU atual no cluster para treinamento distribuído. Para encontrar mais exemplos de scripts, consulte os scripts de exemplo de modelagem da linguagem Hugging Face Transformers.
Para Transformers v4.17 e anteriores com PyTorch v1.10.2 e anteriores
O SageMaker Training Compiler usa um mecanismo alternativo para iniciar um trabalho de treinamento distribuído e você não precisa fazer nenhuma modificação em seu script de treinamento. Em vez disso, o SageMaker Training Compiler exige que você passe um script de inicialização de treinamento distribuído do SageMaker para o argumento entry_point
e passe seu script de treinamento para o argumento hyperparameters
no estimador Hugging Face do SageMaker.
Melhores práticas para usar o SageMaker Training Compiler com Trainer
-
Certifique-se de usar os otimizadores SyncFree definindo o argumento
optim
comoadamw_torch_xla
ao configurar Transformers.trainingArgument. Veja também Optimizer na documentação do Hugging Face Transformers. -
Certifique-se de que a taxa de transferência do pipeline de processamento de dados seja maior do que o throughput do treinamento. Você pode ajustar os argumentos
dataloader_num_workers
epreprocessing_num_workers
da classe transformers.TrainingArgumentpara fazer isso. Normalmente, eles precisam ser maiores ou iguais ao número de GPUs, mas menores que o número de CPUs.
Depois de concluir a adaptação do seu roteiro de treinamento, prossiga para Execute trabalhos de treinamento do PyTorch com o SageMaker Training Compiler.
Modelos de linguagem grandes usando PyTorch diretamente (sem a API Hugging Face Transformers Trainer)
Se você tiver um script de treinamento que usa o PyTorch diretamente, precisará fazer alterações adicionais no script de treinamento do PyTorch para implementar o PyTorch/XLA. Siga as instruções para modificar seu script para configurar adequadamente as primativas PyTorch/XLA.
Tópicos
Para treinamento em uma única GPU
-
Importe as bibliotecas de otimização.
import torch_xla import torch_xla.core.xla_model as xm
-
Altere o dispositivo de destino para XLA em vez de
torch.device("cuda")
device=xm.xla_device()
-
Se você estiver usando a Precisão Mista Automática
(AMP) do PyTorch, faça o seguinte: -
Substitua
torch.cuda.amp
pelo seguinte:import torch_xla.amp
-
Substitua
torch.optim.SGD
etorch.optim.Adam
por um dos seguintes:import torch_xla.amp.syncfree.Adam as adam import torch_xla.amp.syncfree.SGD as SGD
-
Substitua
torch.cuda.amp.GradScaler
pelo seguinte:import torch_xla.amp.GradScaler as grad_scaler
-
-
Se você não estiver usando AMP, substitua
optimizer.step()
pelo seguinte:xm.optimizer_step(optimizer)
-
Se estiver usando um carregador de dados distribuído, envolva seu carregador de dados na classe
ParallelLoader
do PyTorch/XLA:import torch_xla.distributed.parallel_loader as pl parallel_loader=pl.ParallelLoader(dataloader, [device]).per_device_loader(device)
-
Adicione
mark_step
no final do ciclo de treinamento quando não estiver usandoparallel_loader
:xm.mark_step()
-
Para verificar seu treinamento, use o método de ponto de verificação do modelo PyTorch/XLA:
xm.save(model.state_dict(), path_to_save)
Depois de concluir a adaptação do seu roteiro de treinamento, prossiga para Execute trabalhos de treinamento do PyTorch com o SageMaker Training Compiler.
Para treinamento distribuído
Além das alterações listadas na seção Para treinamento em uma única GPU anterior, adicione as seguintes alterações para distribuir adequadamente o workload entre as GPUs.
-
Se estiver usando AMP, adicione
all_reduce
depoisscaler.scale(loss).backward()
:gradients=xm._fetch_gradients(optimizer) xm.all_reduce('sum', gradients, scale=1.0/xm.xrt_world_size())
-
Se você precisar definir variáveis para
local_ranks
eworld_size
, use um código semelhante ao seguinte:local_rank=xm.get_local_ordinal() world_size=xm.xrt_world_size()
-
Para qualquer
world_size
(num_gpus_per_node*num_nodes
) maior que1
, defina uma amostra de treino que deve ser semelhante ao seguinte:import torch_xla.core.xla_model as xm if xm.xrt_world_size() > 1: train_sampler=torch.utils.data.distributed.DistributedSampler( train_dataset, num_replicas=xm.xrt_world_size(), rank=xm.get_ordinal(), shuffle=True ) train_loader=torch.utils.data.DataLoader( train_dataset, batch_size=args.batch_size, sampler=train_sampler, drop_last=args.drop_last, shuffle=False if train_sampler else True, num_workers=args.num_workers )
-
Faça as seguintes alterações para garantir que você use o
parallel_loader
fornecido pelo módulotorch_xla distributed
.import torch_xla.distributed.parallel_loader as pl train_device_loader=pl.MpDeviceLoader(train_loader, device)
As funções
train_device_loader
são como um carregador PyTorch normal da seguinte forma:for step, (data, target) in enumerate(train_device_loader): optimizer.zero_grad() output=model(data) loss=torch.nn.NLLLoss(output, target) loss.backward()
Com todas essas mudanças, você deve ser capaz de iniciar o treinamento distribuído com qualquer modelo do PyTorch sem a API do Transformer Trainer. Observe que essas instruções podem ser usadas tanto para várias GPUs de nó único quanto para várias GPUs de vários nós.
-
Para PyTorch v1.11.0 e versões posteriores
Para executar um treinamento distribuído com o SageMaker Training Compiler, adicione a função
_mp_fn()
a seguir em seu script de treinamento e agrupe a funçãomain()
. As chamadas de função_mp_fn(index)
do runtime distribuído do SageMaker são redirecionadas para PyTorch (pytorchxla
) para a funçãomain()
do seu script de treinamento.def _mp_fn(index): main()
Essa função aceita o argumento
index
para indicar a classificação da GPU atual no cluster para treinamento distribuído. Para encontrar mais exemplos de scripts, consulte os scripts de exemplo de modelagem da linguagem Hugging Face Transformers.Para Transformers v4.17 e anteriores com PyTorch v1.10.2 e anteriores
O SageMaker Training Compiler usa um mecanismo alternativo para iniciar um trabalho de treinamento distribuído e exige que você passe um script inicializador de treinamento distribuído do SageMaker para o argumento
entry_point
e passe seu script de treinamento para o argumentohyperparameters
no estimador Hugging Face do SageMaker.
Depois de concluir a adaptação do seu script de treinamento, prossiga para Execute trabalhos de treinamento do PyTorch com o SageMaker Training Compiler.
Melhores práticas para usar o SageMaker Training Compiler com PyTorch/XLA
Se quiser aproveitar o compilador de treinamento do SageMaker em seu script de treinamento nativo do PyTorch, talvez queira primeiro se familiarizar com o PyTorch em dispositivos XLA
nota
Esta seção de melhores práticas pressupõe que você use os seguintes módulos PyTorch/XLA:
import torch_xla.core.xla_model as xm import torch_xla.distributed.parallel_loader as pl
Entenda o modo lazy em PyTorch/XLA
Uma diferença significativa entre o PyTorch/XLA e o PyTorch nativo é que o sistema PyTorch/XLA é executado no modo lazy, enquanto o PyTorch nativo é executado no modo eager. Os tensores no modo lazy são espaços reservados para construir o gráfico computacional até que sejam materializados após a conclusão da compilação e avaliação. O sistema PyTorch/XLA cria o gráfico computacional dinamicamente quando chamamos as APIs do PyTorch para criar a computação usando tensores e operadores. O gráfico computacional é compilado e executado quando xm.mark_step()
é chamado explícita ou implicitamente porpl.MpDeviceLoader/pl.ParallelLoader
, ou quando você solicita explicitamente o valor de um tensor, como, por exemplo, chamando loss.item()
ou print(loss)
.
Minimize o número de compilações e execuções usando pl.MpDeviceLoader/pl.ParallelLoader
e xm.step_closure
Para obter o melhor desempenho, lembre-se das formas possíveis de iniciar a compilação e as execuções, conforme descrito em Entenda o modo lazy em PyTorch/XLA e tente minimizar o número de compilações e execuções. Idealmente, apenas uma compilação e execução é necessária por iteração de treinamento e é iniciada automaticamente pelo pl.MpDeviceLoader/pl.ParallelLoader
. O MpDeviceLoader
é otimizado para XLA e sempre deve ser usado, se possível, para obter o melhor desempenho. Durante o treinamento, talvez você queira examinar alguns resultados intermediários, como valores de perda. Nesse caso, a impressão de tensores lazy deve ser empacotada usando-se xm.add_step_closure()
para evitar compilações e execuções desnecessárias.
Use AMP e otimizadores syncfree
O treinamento no modo Automatic Mixed Precision (AMP) acelera significativamente sua velocidade de treinamento ao aproveitar os núcleos tensores das GPUs NVIDIA. O SageMaker Training Compiler fornece otimizadores syncfree
que são otimizados para XLA para melhorar o desempenho do AMP. Atualmente, os três otimizadores syncfree
a seguir estão disponíveis e devem ser usados, se possível, para obtenção do melhor desempenho.
torch_xla.amp.syncfree.SGD torch_xla.amp.syncfree.Adam torch_xla.amp.syncfree.AdamW
Esses otimizadores syncfree
devem ser combinados para escalonamento/desescalonamento de gradiente torch_xla.amp.GradScaler
.
dica
A partir do PyTorch 1.13.1, o SageMaker Training Compiler melhora o desempenho ao permitir que o PyTorch/XLA substitua automaticamente os otimizadores (como SGD, Adam, AdamW) em torch.optim
ou transformers.optimization
com suas versões sem sincronização em torch_xla.amp.syncfree
(como torch_xla.amp.syncfree.SGD
, torch_xla.amp.syncfree.Adam
, torch_xla.amp.syncfree.AdamW
). Você não precisa alterar as linhas de código nas quais define otimizadores em seu script de treinamento.