FLATest / optim.py
Asilarknes's picture
Upload checkpoint (step 2000)
554a35b verified
Raw
History Blame Contribute Delete
3.21 kB
"""GrokAdamW: AdamW c уклоном в обобщение.
- decoupled weight decay (только на матрицах, не на нормах/эмбеддингах);
- cautious-маскинг (C-AdamW): применяем компоненты шага, согласованные по
знаку с градиентом -> стабильнее и чуть быстрее сходимость;
- Grokfast (опц., gf_lambda>0): усиление медленной компоненты градиента.
Для большого претрейна обычно держим gf_lambda=0 (нужен для grokking на
маленьких алгоритмических задачах, не для масштабного обучения).
"""
import math
import torch
class GrokAdamW(torch.optim.Optimizer):
def __init__(self, params, lr=3e-4, betas=(0.9, 0.95), eps=1e-8,
weight_decay=0.1, grokfast_lambda=0.0, grokfast_alpha=0.98,
cautious=True):
defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay,
grokfast_lambda=grokfast_lambda, grokfast_alpha=grokfast_alpha,
cautious=cautious)
super().__init__(params, defaults)
@torch.no_grad()
def step(self, closure=None):
loss = closure() if closure is not None else None
for grp in self.param_groups:
lr, (b1, b2), eps = grp["lr"], grp["betas"], grp["eps"]
wd, gfl, gfa, caut = (grp["weight_decay"], grp["grokfast_lambda"],
grp["grokfast_alpha"], grp["cautious"])
for p in grp["params"]:
if p.grad is None:
continue
g = p.grad
st = self.state[p]
if not st:
st["step"] = 0
st["m"] = torch.zeros_like(p)
st["v"] = torch.zeros_like(p)
if gfl > 0:
st["ema"] = g.clone()
if gfl > 0:
ema = st["ema"]; ema.mul_(gfa).add_(g, alpha=1 - gfa)
g = g.add(ema, alpha=gfl)
m, v = st["m"], st["v"]
st["step"] += 1; t = st["step"]
m.mul_(b1).add_(g, alpha=1 - b1)
v.mul_(b2).addcmul_(g, g, value=1 - b2)
denom = (v.sqrt() / math.sqrt(1 - b2 ** t)).add_(eps)
step_size = lr / (1 - b1 ** t)
if wd != 0:
p.mul_(1 - lr * wd)
upd = m / denom
if caut:
mask = (upd * g > 0).to(upd.dtype)
mask.mul_(mask.numel() / (mask.sum() + 1))
upd.mul_(mask)
p.add_(upd, alpha=-step_size)
return loss
def param_groups(model, weight_decay):
decay, no_decay = [], []
for name, p in model.named_parameters():
if not p.requires_grad:
continue
(no_decay if p.ndim < 2 or name.endswith(".bias") else decay).append(p)
return [{"params": decay, "weight_decay": weight_decay},
{"params": no_decay, "weight_decay": 0.0}]