"""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}]