Transformers documentation

Otimizadores e agendadores

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Otimizadores e agendadores

Um otimizador atualiza os pesos do modelo durante o treinamento. O agendador envolve o otimizador e ajusta a taxa de aprendizado a cada etapa de treinamento. O Trainer cria ambos quando chama create_optimizer_and_scheduler().

                                    ┌────────────┐         ┌──────────────┐
                                    │ Optimizer  │         │  Scheduler   │
                                    │ (adamw_torch_fused)◄─│  (linear)    │
                                    │            │         │              │
                                    │ param_groups         |              |
                                    │  └ lr       ◄────────┤              |
                                    │  └ weight_decay      │              │
                                    └──────┬─────┘         └──────────────┘
                                           │                      
  ┌──── EACH TRAINING STEP ───────────────────────────────────────────┐
  │                                        │                          │
  │   model(batch)                         │                          │
  │       │                                │                          │
  │       ▼                                │                          │
  │     loss ──► loss.backward() ──► param.grad                       │
  │                                        │                          │
  │                          ┌─────────────┘                          │
  │                          ▼                                        │
  │              optimizer.step()                                     │
  │                          │                                        │
  │                          ▼                                        │
  │                   param.data updated                              │
  │                          │                                        │
  │                          ▼                                        │
  │              lr_scheduler.step()  ──► recalculates lr             │
  │                          │            writes to optimizer         │
  │                          ▼            .param_groups['lr']         │
  │              model.zero_grad()                                    │
  │                                                                   │
  └───────────────────────────────────────────────────────────────────┘

Configure o comportamento do otimizador e do agendador, como lr_scheduler_type() e optim(), em TrainingArguments. Os padrões (otimizador adamw_torch e agendador de aquecimento linear) são um bom ponto de partida para a maioria das execuções de ajuste fino.

from transformers import TrainingArguments

args = TrainingArguments(
    ...,
    # Optimizer
    optim="adamw_torch",          # or "adamw_torch_fused", "adafactor", "sgd", etc.
    learning_rate=2e-5,
    weight_decay=0.01,
    adam_beta1=0.9,
    adam_beta2=0.999,
    adam_epsilon=1e-8,
    # Scheduler
    lr_scheduler_type="cosine",   # "linear", "cosine", "constant_with_warmup", etc.
    warmup_steps=500,
    lr_scheduler_kwargs={"num_cycles": 3},  # scheduler-specific extras
)

Agendadores baseados em métricas

Alguns agendadores se adaptam à dinâmica do treinamento em vez de seguir um agendamento fixo.

GreedyLR atualiza a taxa de aprendizado a partir dos resultados de avaliação. Ela aumenta a taxa de aprendizado dividindo-a por factor quando a métrica continua melhorando e diminui a taxa de aprendizado multiplicando-a por factor quando a métrica não melhora. Quando a taxa de aprendizado atinge min_lr e não melhora após reset_start etapas, o GreedyLR é reiniciado para o estado inicial e um novo ciclo é iniciado.

GreedyLR requer avaliação durante o treinamento. Defina eval_strategy como "steps" ou "epoch".

args = TrainingArguments(
+   lr_scheduler_type="greedy",
+   lr_scheduler_kwargs={"patience": 10, "factor": 0.95, "min_lr": 1e-5},
+   eval_strategy="steps",
+   eval_steps=200,
    ...  # remaining args from the TrainingArguments intro config
)

O modo padrão mode="min" funciona para a perda. Se você estiver acompanhando uma métrica em que um valor maior é melhor, como a precisão, passe "mode": "max" em lr_scheduler_kwargs.

Consulte a classe GreedyLR para obter a lista completa de parâmetros configuráveis.

Integrações com otimizadores

Transformers integra otimizadores de terceiros para cenários de treinamento especializados.

OtimizadorInstalaroptim="value"Descrição
APOLLOapollo-torchapollo_adamwEficiência de memória em full-param via projeções aleatórias; rank-1 é suficiente
GrokAdamWgrokadamwgrokadamwAlvo a generalização tardia (grokking)
LOMO / AdaLomolomo-optimlomo / adalomoFusion do gradiente + etapa de atualização para ajuste fino de todos os parâmetros com baixo consumo de memória
Agendamento Gratuitoschedulefreeschedule_free_adamw, schedule_free_radam, schedule_free_sgdElimina o annealing de LR; use em conjunto com lr_scheduler_type="constant"
GaLoregalore-torchgalore_adamw, galore_adafactor, galore_adamw_8bitAprendizado de parâmetros completos por projeção de baixo posto do gradiente
StableAdamWtorch-optimistable_adamwRecorte de atualização do AdamW + AdaFactor; não é necessário recorte de gradiente
APOLLO
GrokAdamW
LOMO
Agendamento Gratuito
StableAdamW
GaLore
pip install apollo-torch

Approximated Gradient Scaling for Memory Efficient LLM Optimization (APOLLO) é um otimizador eficiente em memória para aprendizado de parâmetros completos durante o pré-treinamento e o ajuste fino. Ele atinge o desempenho do AdamW com custo de memória semelhante ao do SGD, usando projeções aleatórias de baixo custo em vez de SVD. Para economias extremas de memória, use APOLLO-Mini, uma variante de rank 1.

Use o parâmetro optim_target_modules para especificar quais camadas treinar.

args = TrainingArguments(
+   optim="apollo_adamw",
+   optim_target_modules=[r".*.attn.*", r".*.mlp.*"],
    ...  # remaining args from the TrainingArguments intro config
)

Passe hiperparâmetros adicionais por meio de optim_args.

Defina scale como n/r, em que n é a dimensão do espaço original e r é a dimensão do espaço de baixo posto. Ajustar a taxa de aprendizado mantendo scale no valor padrão produz um efeito semelhante.

parâmetrodescriçãoAPOLLOAPOLLO-Mini
rankrank do subespaço auxiliar para a escalação do gradiente2561
scale_typecomo os fatores de escala são aplicadoschannel (escalonamento por canal)tensor (escalonamento por tensor)
escalaajusta as atualizações de gradiente para estabilizar o treinamento1.0128
update_proj_gappassos antes de atualizar as matrizes de projeção200200
projtipo de projeçãorandomrandom

Ative o APOLLO-Mini com uma configuração de rank 1.

args = TrainingArguments(
    optim="apollo_adamw",
    optim_target_modules=[r".*.attn.*", r".*.mlp.*"],
    optim_args="proj=random,rank=1,scale=128.0,scale_type=tensor,update_proj_gap=200",
    ...  # remaining args from the TrainingArguments intro config
)

Personalizando o otimizador e o agendador

Crie um otimizador e um agendador personalizados para usar um otimizador ainda não integrado, ajustar as taxas de aprendizado por camada ou aplicar lógica personalizada.

Passe uma classe e kwargs

~Trainer.optimizer_cls_and_kwargs aceita uma classe de otimizador personalizada, delegando a agrupamento de parâmetros e a alocação de dispositivos ao Trainer.

O Trainer adia a criação do otimizador até que create_optimizer() seja executado, de modo que o modelo já esteja no dispositivo correto.

import torch

trainer = Trainer(
    ...
    optimizer_cls_and_kwargs=(
        torch.optim.SGD,
        {"momentum": 0.9, "nesterov": True}
    ),
)

Passar instâncias pré-construídas

Passe um otimizador e um agendador predefinidos para ~Trainer.optimizers. O Trainer ignora create_optimizer() e create_scheduler() quando instâncias pré-criadas são fornecidas. Se você não passar um agendador, o Trainer cria um automaticamente.

Construa o otimizador depois de posicionar o modelo no dispositivo correto. Os parâmetros são resolvidos no momento da construção, antes de Trainer mover o modelo. No treinamento distribuído, dispositivos incompatíveis podem causar comportamento incorreto de forma silenciosa.

import torch
from transformers import Trainer, get_cosine_schedule_with_warmup

optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5)
scheduler = get_cosine_schedule_with_warmup(
    optimizer, num_warmup_steps=500, num_training_steps=10_000
)

trainer = Trainer(
    ...
    optimizers=(optimizer, scheduler),
)

As instâncias pré-criadas ignoram create_optimizer() e create_scheduler(), portanto, você precisa especificar seus próprios grupos de parâmetros.

Substituir os métodos do otimizador e do agendador

Subclasse create_optimizer() e create_scheduler() para controle total. Ambos os métodos são executados durante o train().

Sobrescreva create_scheduler() para usar um scheduler como OneCycleLR que não está disponível em SchedulerType.

Para cada método, certifique-se de atribuir a self e retorná-lo.

import torch
from transformers import Trainer

class MyTrainer(Trainer):

    def create_scheduler(self, num_training_steps, optimizer=None):
        optimizer = optimizer or self.optimizer
        self.lr_scheduler = torch.optim.lr_scheduler.OneCycleLR(
            optimizer,
            max_lr=0.1,
            total_steps=num_training_steps,
        )
        return self.lr_scheduler

Você não precisa sobrescrever create_optimizer() se o otimizador padrão funcionar. Estender um método com super() é mais simples do que substituí-lo por completo. Por exemplo, adicione um grupo de parâmetros extra mantendo o restante igual.

class MyTrainer(Trainer):
    def create_optimizer(self, model=None):
        super().create_optimizer(model)  # builds the default two param groups
        # add extra param group
        self.optimizer.add_param_group({
            "params": self.model.classifier.parameters(),
            "lr": self.args.learning_rate * 10,
        })
        return self.optimizer
Update on GitHub