Transformers documentation
Optimiseurs et planificateurs
Optimiseurs et planificateurs
Un optimiseur met à jour les poids du modèle pendant l’entraînement. Le planificateur encapsule l’optimiseur et ajuste le taux d’apprentissage à chaque étape d’entraînement. Trainer crée les deux lorsqu’il appelle 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() │
│ │
└───────────────────────────────────────────────────────────────────┘Configurez le comportement de l'optimiseur et du planificateur, comme lr_scheduler_type() et optim(), dans TrainingArguments. Les valeurs par défaut (l'optimiseur adamw_torch et le planificateur de montée en charge linear) constituent un bon point de départ pour la plupart des exécutions de fine-tuning.
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
)Planificateurs basés sur des métriques
Certains planificateurs s'adaptent à la dynamique de l'entraînement au lieu de suivre un plan fixe.
GreedyLR met à jour le taux d’apprentissage à partir des résultats d’évaluation. Il augmente le taux d’apprentissage en le divisant par factor lorsque la métrique continue de s’améliorer, et le diminue en le multipliant par factor lorsque la métrique ne s’améliore pas. Lorsque le taux d’apprentissage atteint min_lr et ne s’améliore plus après reset_start étapes, GreedyLR revient à son état initial et démarre un nouveau cycle.
GreedyLR nécessite une évaluation pendant l’entraînement. Définissez eval_strategy sur "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
)Le mode par défaut
mode="min"convient à la perte. Si vous suivez une métrique pour laquelle une valeur plus élevée est préférable, comme la précision, passez"mode": "max"danslr_scheduler_kwargs.
Consultez la classe GreedyLR pour la liste complète des paramètres configurables.
Intégrations d'optimiseurs
Transformers intègre des optimiseurs tiers pour des scénarios d’entraînement spécialisés.
| Optimiseur | Installer | optim="value" | Description |
|---|---|---|---|
| APOLLO | apollo-torch | apollo_adamw | Méthode full-param efficace en mémoire via des projections aléatoires ; un rang de 1 suffit |
| GrokAdamW | grokadamw | grokadamw | Cible la généralisation différée (grokking) |
| LOMO / AdaLomo | lomo-optim | lomo / adalomo | Fusionne l'étape de gradient et l'étape de mise à jour pour l'ajustement fin de tous les paramètres avec une faible consommation mémoire |
| Sans planification | schedulefree | schedule_free_adamw, schedule_free_radam, schedule_free_sgd | Supprime l’annealing du taux d’apprentissage ; à utiliser avec lr_scheduler_type="constant" |
| GaLore | galore-torch | galore_adamw, galore_adafactor, galore_adamw_8bit | Apprentissage à paramètres complets par projection de gradient de faible rang |
| StableAdamW | torch-optimi | stable_adamw | Mise à jour AdamW + AdaFactor avec élagage ; aucun élagage des gradients n'est nécessaire |
pip install apollo-torch
Approximated Gradient Scaling for Memory Efficient LLM Optimization (APOLLO) est un optimiseur économe en mémoire pour l'apprentissage de tous les paramètres lors du pré-entraînement et de l'ajustement fin. Il égale les performances d'AdamW avec un coût mémoire comparable à celui de SGD, en utilisant des projections aléatoires peu coûteuses au lieu de la SVD. Pour des économies de mémoire extrêmes, utilisez APOLLO-Mini, une variante de rang 1.
Utilisez le paramètre optim_target_modules pour spécifier les couches à entraîner.
args = TrainingArguments(
+ optim="apollo_adamw",
+ optim_target_modules=[r".*.attn.*", r".*.mlp.*"],
... # remaining args from the TrainingArguments intro config
)Transmettez des hyperparamètres supplémentaires via optim_args.
Définissez
scalesurn/r, oùnest la dimension de l’espace d’origine etrest la dimension de l’espace de faible rang. Ajuster le taux d’apprentissage tout en maintenantscaleà sa valeur par défaut produit un effet similaire.
| paramètre | description | APOLLO | APOLLO-Mini |
|---|---|---|---|
| rank | rang du sous-espace auxiliaire pour le mise à l'échelle des gradients | 256 | 1 |
| scale_type | comment les facteurs d'échelle sont appliqués | channel (mise à l'échelle par canal) | tensor (mise à l'échelle par tenseur) |
| scale | ajuste les mises à jour des gradients pour stabiliser l'entraînement | 1.0 | 128 |
| update_proj_gap | étapes avant la mise à jour des matrices de projection | 200 | 200 |
| proj | type de projection | random | random |
Activer APOLLO-Mini avec une configuration de rang 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 cible le grokking, un phénomène où les modèles présentent une généralisation retardée en raison de gradients à variation lente.
args = TrainingArguments(
+ optim="grokadamw",
... # remaining args from the TrainingArguments intro config
)pip install lomo-optim
Low-Memory Optimization (LOMO) comprend deux optimiseurs pour l’ajustement fin de tous les paramètres avec une faible consommation mémoire, LOMO et AdaLomo. Les deux fusionnent le calcul des gradients et la mise à jour des paramètres en une seule étape. AdaLomo ajoute un taux d’apprentissage adaptatif par paramètre, similaire à Adam.
AdaLomo fonctionne le mieux sans
grad_norm, ce qui améliore les performances et le débit.
args = TrainingArguments(
+ optim="adalomo",
learning_rate=2e-6,
... # remaining args from the TrainingArguments intro config
)pip install schedulefree
L'optimiseur Schedule Free optimizer (SFO) remplace la quantité de mouvement par une combinaison de moyenne et d'interpolation, éliminant ainsi totalement la nécessité d'annéler le taux d'apprentissage.
SFO prend en charge les optimiseurs RAdam (schedule_free_radam), AdamW (schedule_free_adamw) et SGD (schedule_free_sgd). Le planificateur RAdam ne nécessite pas warmup_steps.
Associez SFO à lr_scheduler_type="constant". D’autres types de planificateurs fonctionnent, mais ils modifient le comportement prévu de 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 intègre le mécanisme de clipping de mise à jour d’AdaFactor dans AdamW, éliminant ainsi le besoin de clipping des gradients. Sinon, il constitue un remplacement direct d’AdamW.
Si vous entraînez avec des tailles de lot importantes ou si vous observez encore des pics de perte, essayez de définir
beta_2entre 0,95 et 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) réduit la mémoire nécessaire à l’entraînement des LLM. Contrairement aux méthodes d’adaptation de rang faible comme LoRA, GaLore préserve l’apprentissage en paramètres complets.
Définissez optim dans trl.SFTConfig sur un optimiseur GaLore ("galore_adamw", "galore_adafactor" ou "galore_adamw_8bit"). Spécifiez les modules cibles avec optim_target_modules et les paramètres spécifiques à GaLore (rank, update_proj_gap, scale) via 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",
)Ajoutez _layerwise au nom de l’optimiseur pour une optimisation par couche ("galore_adamw_layerwise"). Seules les couches linéaires ciblées par GaLore utilisent la décomposition de rang faible. Toutes les autres couches sont optimisées normalement.
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",
)Le mode Layerwise est expérimental. Il ne s’exécute que sur un GPU unique, ne prend pas en charge DistributedDataParallel (DDP), et le gradient clipping ainsi que DeepSpeed peuvent ne pas fonctionner.
Personnalisation de l'optimiseur et du planificateur
Créez un optimiseur et un planificateur personnalisés pour utiliser un optimiseur non encore intégré, ajuster les taux d’apprentissage par couche ou appliquer une logique personnalisée.
Passer une classe et des kwargs
~Trainer.optimizer_cls_and_kwargs accepte une classe d'optimiseur personnalisée tout en déléguant le regroupement des paramètres et l'affectation aux dispositifs à Trainer.
Trainer diffère la création de l’optimiseur jusqu’à l’exécution de create_optimizer(), de sorte que le modèle se trouve déjà sur l’appareil correct.
import torch
trainer = Trainer(
...
optimizer_cls_and_kwargs=(
torch.optim.SGD,
{"momentum": 0.9, "nesterov": True}
),
)Passer des instances préconstruites
Passez un optimiseur et un planificateur prédéfinis à ~Trainer.optimizers. Trainer ignore create_optimizer() et create_scheduler() lorsque des instances préconstruites sont fournies. Si vous ne passez pas de planificateur, Trainer en crée automatiquement un.
Construisez l’optimiseur après avoir placé votre modèle sur l’appareil approprié. Les paramètres sont résolus lors de la construction, avant que
Trainerne déplace le modèle. En entraînement distribué, un désaccord d’appareils peut provoquer silencieusement un comportement incorrect.
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),
)Les instances préconstruites contournent create_optimizer() et create_scheduler(), il est donc nécessaire de spécifier vos propres groupes de paramètres.
Écraser les méthodes de l'optimiseur et du planificateur
Sous-classez create_optimizer() et create_scheduler() pour un contrôle total. Les deux méthodes s'exécutent durant train().
Écrasez create_scheduler() pour utiliser un planificateur tel que OneCycleLR qui n’est pas disponible dans SchedulerType.
Pour chaque méthode, assurez-vous d'assigner à self et de la retourner.
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_schedulerIl n’est pas nécessaire de redéfinir create_optimizer() si l’optimiseur par défaut convient. Étendre une méthode à l’aide de super() est plus simple que de la remplacer entièrement. Par exemple, vous pouvez ajouter un groupe de paramètres supplémentaire tout en conservant le reste inchangé.
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