Optimizers & Schedules
DantinoX ships five optimizers and four LR schedules, all configurable from TrainingConfig. The optimizer is built by build_optimizer(model, config, total_steps) which returns an nnx.Optimizer ready for use in the training loop.
Optimizers
|
Algorithm |
Notes |
|---|---|---|
|
AdamW |
Default. |
|
Adafactor |
Memory-efficient: no second-moment state. Use for large models on tight VRAM. |
|
Lion |
Sign-gradient update. Typically needs 3–10× lower LR than AdamW. |
|
Adam |
No weight decay. Useful for fine-tuning when decay hurts. |
|
Muon |
Newton-Schulz orthogonalization for 2D weights. Strong empirical results on LM pre-training. |
Muon notes
Muon (optax.contrib.muon) applies Newton-Schulz iterations to orthogonalize 2D parameter updates before applying them. This is equivalent to computing the unitary factor of the polar decomposition and has been shown to improve training stability and convergence speed on language model pre-training.
# Muon skips the outer grad-clip chain — it handles normalization internally.
# All other optimizers: optax.chain(clip_by_global_norm, base_optimizer)
# Muon: optax.contrib.muon(lr_schedule) (no chain)
LR schedules
Cosine ("cosine")
Linear warmup → cosine decay to 1 % of peak.
lr
▲
│ ████
│ ██ ██
│ █ ██
│█ ████████
└──────────────────────► step
warmup decay
Linear ("linear")
Linear warmup → linear decay to 1 % of peak.
Constant ("constant")
Linear warmup → flat plateau at peak LR.
WSD — Warm-Stable-Decay ("wsd")
Three phases: linear warmup → 40 % stable plateau → cosine decay.
lr
▲
│ ████████████████
│ ██ ████
│ █ ████████
│█
└──────────────────────────────► step
warmup stable decay
!!! tip “WSD for long runs” WSD tends to outperform cosine on long pre-training runs (>100 K steps) because the stable phase allows the optimizer to settle before the final decay.
Usage
from dantinox.core.config import TrainingConfig
from dantinox.training.optimizer import build_optimizer, build_schedule
cfg = TrainingConfig(
lr=3e-4,
optimizer="muon",
lr_schedule="wsd",
grad_clip=1.0,
epochs=10,
)
optimizer = build_optimizer(model, cfg, total_steps=50_000)
LoRA-aware optimization
When the model contains LoRAParam variables, build_optimizer automatically applies optax.multi_transform so that only adapter parameters receive gradient updates. Base nnx.Param weights are frozen at the type level — no manual masking required.
# Verified by build_optimizer internals:
# if _model_has_lora(model):
# tx = optax.multi_transform(
# {"lora": base_optimizer, "frozen": optax.set_to_zero()},
# label_fn,
# )
CLI
dantinox train --config configs/default_config.yaml \
--optimizer muon \
--lr_schedule wsd \
--lr 1e-4
Any TrainingConfig field can be overridden via CLI flags. Config YAML values are the base; CLI flags override on top.