Transformers documentation
Otimizadores e agendadores
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"emlr_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.
| Otimizador | Instalar | optim="value" | Descrição |
|---|---|---|---|
| APOLLO | apollo-torch | apollo_adamw | Eficiência de memória em full-param via projeções aleatórias; rank-1 é suficiente |
| GrokAdamW | grokadamw | grokadamw | Alvo a generalização tardia (grokking) |
| LOMO / AdaLomo | lomo-optim | lomo / adalomo | Fusion do gradiente + etapa de atualização para ajuste fino de todos os parâmetros com baixo consumo de memória |
| Agendamento Gratuito | schedulefree | schedule_free_adamw, schedule_free_radam, schedule_free_sgd | Elimina o annealing de LR; use em conjunto com lr_scheduler_type="constant" |
| GaLore | galore-torch | galore_adamw, galore_adafactor, galore_adamw_8bit | Aprendizado de parâmetros completos por projeção de baixo posto do gradiente |
| StableAdamW | torch-optimi | stable_adamw | Recorte de atualização do AdamW + AdaFactor; não é necessário recorte de gradiente |
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
scalecomon/r, em quené a dimensão do espaço original eré a dimensão do espaço de baixo posto. Ajustar a taxa de aprendizado mantendoscaleno valor padrão produz um efeito semelhante.
| parâmetro | descrição | APOLLO | APOLLO-Mini |
|---|---|---|---|
| rank | rank do subespaço auxiliar para a escalação do gradiente | 256 | 1 |
| scale_type | como os fatores de escala são aplicados | channel (escalonamento por canal) | tensor (escalonamento por tensor) |
| escala | ajusta as atualizações de gradiente para estabilizar o treinamento | 1.0 | 128 |
| update_proj_gap | passos antes de atualizar as matrizes de projeção | 200 | 200 |
| proj | tipo de projeção | random | random |
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
)pip install grokadamw
GrokAdamW é direcionado ao grokking, em que os modelos exibem generalização tardia devido a gradientes de variação lenta.
args = TrainingArguments(
+ optim="grokadamw",
... # remaining args from the TrainingArguments intro config
)pip install lomo-optim
Otimização de Baixa Memória (LOMO) inclui dois otimizadores para ajuste fino de todos os parâmetros com baixa memória, LOMO e AdaLomo. Ambos fundem o cálculo do gradiente e a atualização dos parâmetros em uma única etapa. O AdaLomo adiciona uma taxa de aprendizado adaptativa por parâmetro, semelhante à do Adam.
O AdaLomo funciona melhor sem
grad_norm, melhorando o desempenho e a taxa de transferência.
args = TrainingArguments(
+ optim="adalomo",
learning_rate=2e-6,
... # remaining args from the TrainingArguments intro config
)pip install schedulefree
O otimizador Schedule Free (SFO) substitui o momentum por uma combinação de média e interpolação, eliminando completamente a necessidade de anelar a taxa de aprendizado.
O SFO suporta os otimizadores RAdam (schedule_free_radam), AdamW (schedule_free_adamw) e SGD (schedule_free_sgd). O agendador RAdam não requer warmup_steps.
Combine SFO com lr_scheduler_type="constant". Outros tipos de agendador funcionam, mas afetam o comportamento pretendido do SFO.
args = TrainingArguments(
+ optim="schedule_free_radam",
+ lr_scheduler_type="constant",
learning_rate=2e-6,
... # remaining args from the TrainingArguments intro config
)pip install torch-optimi
StableAdamW incorpora o recorte de atualização do AdaFactor ao AdamW, eliminando a necessidade de recorte de gradiente. Caso contrário, é uma substituição direta para o AdamW.
Se você estiver treinando com tamanhos de lote grandes ou ainda observar picos de perda, tente definir
beta_2entre 0,95 e 0,99.
args = TrainingArguments(
+ optim="stable_adamw",
learning_rate=2e-6,
... # remaining args from the TrainingArguments intro config
)pip install galore-torch trl
Gradient Low-Rank Projection (GaLore) reduz o uso de memória no treinamento de LLMs. Diferentemente de métodos de adaptação de baixo posto, como LoRA, o GaLore preserva o aprendizado de parâmetros completos.
Defina optim em trl.SFTConfig para um otimizador GaLore ("galore_adamw", "galore_adafactor" ou "galore_adamw_8bit"). Especifique os módulos alvo com optim_target_modules e os parâmetros específicos do GaLore (rank, update_proj_gap, scale) por meio de optim_args.
from trl import SFTConfig
args = SFTConfig(
output_dir="./galore",
max_steps=100,
optim="galore_adamw",
optim_target_modules=[r".*.attn.*", r".*.mlp.*"],
optim_args="rank=64, update_proj_gap=100, scale=0.10",
)Adicione _layerwise ao nome do otimizador para otimização por camada ("galore_adamw_layerwise"). Somente as camadas lineares alvo do GaLore usam decomposição de baixo posto. Todas as outras camadas são otimizadas normalmente.
from trl import SFTConfig, SFTTrainer
args = SFTConfig(
output_dir="./galore",
max_steps=100,
optim="galore_adamw_layerwise",
optim_target_modules=[r".*.attn.*", r".*.mlp.*"],
optim_args="rank=64, update_proj_gap=100, scale=0.10",
)O modo Layerwise é experimental. Ele é executado apenas em uma GPU única, não suporta DistributedDataParallel (DDP), e o gradient clipping e o DeepSpeed podem não funcionar.
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
Trainermover 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_schedulerVocê 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