İçeriğe geç

Optimization: SGD'den AdamW'a, Lion'a, Muon'a — Modern LLM'in Tüm Optimizer'ları

Gradient descent ailesinin geçmişi ve geleceği: GD, SGD, Momentum (Heavy ball, Nesterov), AdaGrad, RMSProp, Adam, AdamW, Lion, Muon. Learning rate schedules: linear warmup + cosine decay. Loss landscape: sharp vs flat minima.

Şükrü Yusuf KAYA
45 dakikalık okuma
Orta
Optimization: SGD'den AdamW'a, Lion'a, Muon'a — Modern LLM'in Tüm Optimizer'ları
⚙️ Bu ders LLM eğitiminin motor odasını açıyor
Llama 3 70B'yi eğitirken hangi optimizer? Cevap: AdamW. Niye? Niye Lion değil? Muon hangisinden daha iyi? Bu sorulara cevap verebilen mühendis sayısı çok az — çünkü çoğu kaynak "Adam kullan" deyip geçiyor. 45 dakika sonra optimizer seçimini matematiksel sezgi + empirik kanıtla yapabileceksin.

Ders Haritası#

  1. Optimizasyon problemi: convex vs non-convex
  2. Vanilla GD ve sınırları
  3. SGD ve mini-batch: stokastik gürültü, hız
  4. Momentum: Heavy ball + Nesterov
  5. Adaptive optimizers: AdaGrad, RMSProp
  6. Adam, AdamW — endüstri standardı
  7. Lion (2023) ve Muon (2024) — yeni nesil
  8. Learning rate schedules: warmup, cosine, linear
  9. Loss landscape: saddles, sharp/flat minima
  10. Pratik: Llama 3 / DeepSeek-V3 / Qwen optimizer config'leri

1. Convex vs Non-Convex#

Convex function: Bir parça doğrusu fonksiyon grafiğinin üstünde kalır. Örn.
f(x) = x²
,
f(x) = e^x
.
Özellik: Her local minimum globaldir. Optimizasyon "kolay" (gradient descent yeter).
Non-convex function: Birden fazla local minimum olabilir, saddle point'ler vardır. Örn. NN loss surface.

NN loss landscape#

Deep network'lerin loss surface'i çok yüksek boyutlu ve non-convex. Klasik dert: "local minima'da takılırsın". Ama çağdaş görüş (Choromanska 2015, Goodfellow 2014):
  • Yüksek boyutta saddle point'ler local minima'dan çok daha yaygın
  • Çoğu local minimum global minimum'a yakın (loss değerinde)
  • Asıl sorun: saddle'lardan kurtulmak, "flat" minima'lar bulmak
Modern optimizer'ların hedefi: saddle'lardan kaç, flat region'lar bul.

2. Vanilla Gradient Descent#

θt+1=θtηL(θt)\theta_{t+1} = \theta_t - \eta \nabla L(\theta_t)

Sınırları#

  • Tüm dataset'te gradient hesaplar → büyük veride yavaş
  • Sabit lr → adaptif değil
  • Convex'te garanti, non-convex'te saddle'da takılabilir
  • Highly conditioned loss'ta (uzun "vadi" şeklinde) zigzag

Convergence#

Convex L için
O(1/√t)
(SGD ile),
O(1/t)
(full-batch). NN'lerde teorik garantiler yok ama pratikte çalışıyor.

3. Stochastic Gradient Descent (SGD) ve Mini-batch#

Her step'te dataset'ten rastgele bir batch seç, onun üzerinde gradient hesapla:
θt+1=θtηLbatch(θt)\theta_{t+1} = \theta_t - \eta \nabla L_{\text{batch}}(\theta_t)

Avantajlar#

  • Hız: 1M sample'lık dataset'te tek batch (256 sample) tüm dataset'ten 4000x hızlı gradient
  • Generalization: gürültülü gradient implicit regularization yapar (Keskar 2017)
  • Saddles: gürültü saddle'lardan kaçmaya yardımcı

Mini-batch boyutu#

BoyutEtki
1 (true SGD)Çok gürültülü, yavaş hardware kullanımı
32-256Klasik DL sweet spot
1024-4096Modern LLM pretrain (data parallelism)
4M+ tokensLlama 3, GPT-4 (huge batch)
Büyük batch ⇒ daha az gürültü ⇒ daha sharp minima'ya doğru (kötü generalization). Çözüm: linear lr scaling (batch'e orantılı lr) + warmup.

Convergence on convex#

O(1/√t)
rate (Robbins-Monro 1951). Non-convex'te sadece "critical point'e" yakınsar (ki bu local min, saddle, flat region olabilir).

4. Momentum — Heavy Ball ve Nesterov#

Vanilla GD'nin "zigzag" problemini çözmek için: gradient'leri akümülasyonla (momentum) topla.

Heavy ball (Polyak 1964)#

vt+1=βvt+L(θt)v_{t+1} = \beta v_t + \nabla L(\theta_t) θt+1=θtηvt+1\theta_{t+1} = \theta_t - \eta v_{t+1}
β
momentum coefficient (tipik 0.9 veya 0.99). Önceki gradient'lerin exponential moving average'ı yön veriyor.
Sezgi: Bir top yokuşta yuvarlanırken zigzag yapmaz, momentum'u onu doğrudan aşağı çeker.

Nesterov Accelerated Gradient (NAG)#

Bir adım "ileri bakıp" o noktadaki gradient'i kullan:
vt+1=βvt+L(θtηβvt)v_{t+1} = \beta v_t + \nabla L(\theta_t - \eta \beta v_t) θt+1=θtηvt+1\theta_{t+1} = \theta_t - \eta v_{t+1}
Convex problem'lerde
O(1/t²)
rate — heavy ball'dan iyi. Non-convex'te genel olarak biraz daha iyi.

Pratik#

LLM pretrain'de Nesterov pek kullanılmıyor (Adam ailesi standart). Ama vision modellerinde SGD+Nesterov hâlâ rakipsiz performans veriyor (örn. ImageNet'te ResNet eğitiminde).
python
import torch
 
# Heavy ball
def sgd_momentum(params, lr=0.01, momentum=0.9):
"""Simple SGD with momentum."""
velocities = {id(p): torch.zeros_like(p) for p in params}
 
def step(grads):
for p, g in zip(params, grads):
v = velocities[id(p)]
v.mul_(momentum).add_(g)
p.data.add_(v, alpha=-lr)
return step
 
# Nesterov (PyTorch built-in)
import torch.optim as optim
model = torch.nn.Linear(10, 5)
opt_nesterov = optim.SGD(model.parameters(), lr=0.01, momentum=0.9, nesterov=True)
 
# Kullanım
x = torch.randn(32, 10)
y = torch.randn(32, 5)
 
for step in range(100):
pred = model(x)
loss = ((pred - y) ** 2).mean()
opt_nesterov.zero_grad()
loss.backward()
opt_nesterov.step()
if step % 20 == 0:
print(f"Step {step}: loss = {loss.item():.4f}")
SGD + Momentum + Nesterov implementasyonu.

5. Adaptive Optimizers — AdaGrad, RMSProp#

Her parametre için ayrı bir learning rate ölçeklendir. Yavaş hareket eden parametrelere yüksek lr, hızlı hareket edenlere düşük.

AdaGrad (Duchi 2011)#

Gt=Gt1+Lt2G_t = G_{t-1} + \nabla L_t^2 θt+1=θtηGt+ϵLt\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{G_t + \epsilon}} \nabla L_t
G_t
: gradient'lerin karelerinin kümülatif toplamı. Her parametre için ayrı.
Sorun:
G_t
sürekli büyür → effective lr sıfıra gider → öğrenme durur.

RMSProp (Tieleman & Hinton 2012)#

AdaGrad'ı düzeltir: kümülatif yerine EMA.
E[g2]t=ρE[g2]t1+(1ρ)gt2E[g^2]_t = \rho E[g^2]_{t-1} + (1 - \rho) g_t^2 θt+1=θtηE[g2]t+ϵgt\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{E[g^2]_t + \epsilon}} g_t
Çoğu RNN/eski DL pratik default'u. Adam'ın atası.

6. Adam ve AdamW — Endüstri Standardı#

Adam (Kingma & Ba 2014): Momentum + RMSProp'u birleştir.
mt=β1mt1+(1β1)gt(1st moment, momentum)m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t \quad \text{(1st moment, momentum)} vt=β2vt1+(1β2)gt2(2nd moment, adaptive)v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 \quad \text{(2nd moment, adaptive)}
Bias correction (early step'lerde
m, v
sıfıra biased): m^t=mt1β1t,v^t=vt1β2t\hat{m}_t = \frac{m_t}{1 - \beta_1^t}, \quad \hat{v}_t = \frac{v_t}{1 - \beta_2^t}
Update: θt+1=θtηm^tv^t+ϵ\theta_{t+1} = \theta_t - \frac{\eta \hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}

Default'lar#

  • β₁ = 0.9
    ,
    β₂ = 0.999
    (Adam paper)
  • ε = 1e-8
  • η = 1e-3
    (vision),
    3e-4
    (NLP)
LLM pretrain'de β₂'yi 0.95 kullanmak yaygın (gradient varyansının daha hızlı tepkisi için).

AdamW (Loshchilov 2019)#

Adam + decoupled weight decay. Önceki ders (1.6)'de açıkladık.
torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=0.1, betas=(0.9, 0.95))
LLM standart: Llama 3, GPT-4, Qwen 2.5, Mistral, Gemma — hepsi AdamW.
python
# Llama 3.1 8B pretrain config (yaklaşık değerler)
import torch
import torch.nn as nn
 
model = nn.Transformer(d_model=4096, nhead=32, num_encoder_layers=32) # toy
 
optimizer = torch.optim.AdamW(
model.parameters(),
lr=3e-4, # peak lr
betas=(0.9, 0.95), # β₂ standart 0.999 yerine 0.95 (LLM convention)
eps=1e-8,
weight_decay=0.1,
)
 
# Learning rate scheduler: linear warmup + cosine decay
def get_lr(step, warmup_steps=2000, total_steps=100_000, max_lr=3e-4, min_lr=3e-5):
if step < warmup_steps:
return max_lr * step / warmup_steps
if step > total_steps:
return min_lr
# Cosine decay
import math
progress = (step - warmup_steps) / (total_steps - warmup_steps)
coeff = 0.5 * (1.0 + math.cos(math.pi * progress))
return min_lr + coeff * (max_lr - min_lr)
 
# Eğitim döngüsünde:
for step in range(100_000):
lr = get_lr(step)
for pg in optimizer.param_groups:
pg['lr'] = lr
# ... forward + backward + optimizer.step()
AdamW + linear warmup + cosine decay — modern LLM standardı.

7. Lion (2023) — Adam'ın Yumuşak Rakibi#

Lion (EvoLved Sign Momentum, Chen 2023, Google Brain). Symbolic regression ile bulunmuş optimizer.

Algoritma#

ct=β1mt1+(1β1)gtc_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t θt+1=θtηsign(ct)\theta_{t+1} = \theta_t - \eta \cdot \text{sign}(c_t) mt=β2mt1+(1β2)gtm_t = \beta_2 m_{t-1} + (1 - \beta_2) g_t
Anahtar fark: sadece gradient'in işareti kullanılıyor. Magnitude yok. Memory: tek state (m), Adam'ın yarısı.

Defaults#

  • β₁ = 0.9
    ,
    β₂ = 0.99
  • lr = AdamW lr / 3
    (Lion daha agresif, lr küçük olmalı)
  • weight_decay = AdamW × 10
    (kompansa için)

Empirik sonuçlar#

  • Vision (ViT, ConvNeXt): %1-2 daha iyi accuracy, %50 daha az memory
  • LLM (PaLM, T5): comparable veya hafif iyi
  • Edge case'lerde divergence sorunları

Adoption#

  • Adoption sınırlı kaldı (LLama, Qwen hâlâ AdamW kullanıyor)
  • Memory-constrained durumlarda (büyük model, küçük GPU) yararlı
  • Production'da çok denenmiş değil

8. Muon (2024) — Yeni Nesil#

Muon (Jordan 2024, NanoGPT speedrun'ı sırasında ortaya çıktı). Hidden weight'ler için Newton-Schulz iteration ile gradient orthogonalize ediliyor.

Sezgi#

Bir matrix gradient'in eigenvalue'larını "balance" et — bazı yönlerdeki büyük gradient'leri kıs, küçükleri büyüt. Bu effective lr'ı homogenize ediyor.

Algoritma (yaklaşık)#

m_t = β m_{t-1} + g_t # momentum g_t = orthogonalize(m_t) # Newton-Schulz iteration θ_{t+1} = θ_t - η g_t
orthogonalize
≈ SVD'nin Σ'sını identity yapma (numeric approximation).

Empirik sonuç (Jordan 2024)#

NanoGPT speedrun'ında AdamW'dan %35 daha az step ile aynı validation loss. Modular code'da net iyileşme.

Sınırlar#

  • Sadece matrix parametreler için (linear layer weight'leri)
  • Embedding ve LayerNorm için AdamW kullanılır (hybrid setup)
  • Çok yeni, production-tested değil
  • DeepSeek-V3 paper'ında bahsediliyor (henüz adopte etmediler ama izliyor)

Hangi optimizer 2026?#

SenaryoÖnerilen
LLM pretrain (büyük)AdamW (kanıtlı, stabil)
Eğitim hızı kritikMuon (deneysel, %20-35 hızlı)
Memory-constrainedLion (%50 daha az state)
Vision/ImageNetSGD + Nesterov (hâlâ rakipsiz)
Fine-tuningAdamW (paqaramı küçük, fark az)

9. Learning Rate Schedules — Modern LLM'in 3 Aşaması#

Modern LLM pretrain learning rate şu yapıdadır:

1. Linear Warmup#

İlk N step'te lr 0'dan max_lr'a doğrusal artar. Tipik N = 2000-10000 step.
Niye: Eğitim başında parametreler random, gradient çok büyük olabilir. Hızlı yüksek lr ile başlamak NaN'a sebep olur. Yavaşça başla, model "settle" etsin.

2. Cosine Decay#

Warmup sonrası lr cosine function ile düşer: ηt=ηmin+0.5(ηmaxηmin)(1+cos(πt/T))\eta_t = \eta_{min} + 0.5 (\eta_{max} - \eta_{min})(1 + \cos(\pi t / T))
T
toplam decay step sayısı. Final lr'a yumuşak iniş.
Niye: Eğitim sonuna doğru lr küçük olmalı (rafine etmek). Cosine yumuşak ama linear decay'den daha "agressive" başlangıçta.

3. Constant Floor#

Decay sonrası lr_min'de kal. Genelde
lr_max / 10
.

Llama 3 örneği#

  • lr_max = 3e-4
  • warmup = 8000 step
  • cosine decay over 10M step
  • lr_min = 3e-5

Alternatif schedules#

  • Inverse square root (T5):
    lr ∝ 1/√t
  • Linear decay: cosine yerine düz çizgi
  • WSD (Warmup-Stable-Decay) (MiniCPM 2024): constant middle phase
  • Schedule-free (Defazio 2024): scheduler yok, optimizer kendi ayarlıyor

10. Loss Landscape — Sharp vs Flat Minima#

Modern view: NN loss surface çok yüksek boyutlu, flat region'lar generalize ediyor, sharp olanlar overfit.

Sharp minimum#

  • Eigenvalue'lar büyük (Hessian'da)
  • Test loss training loss'tan çok yüksek
  • Train sırasında küçük perturbation çıktıyı ciddi değiştirir

Flat minimum#

  • Eigenvalue'lar küçük
  • Test ≈ train loss
  • Generalize daha iyi

Bu yüzden:#

  • Büyük batch → sharp minima → kötü generalize
  • Küçük batch + lr scale → flat minima → iyi generalize
  • SAM (Sharpness-Aware Minimization): özellikle flat minima'ya doğru çek
  • Weight averaging (SWA, EMA, model souping): birkaç çözümün ortalaması → flat region

LLM ölçeğinde#

Bu kavramlar daha karmaşık. Ama temel sezgi: batch size'ı arttırırken lr'ı orantılı arttır (linear scaling rule, Goyal 2017). Bu sweet spot Llama 3 pretrain'inde kullanılıyor.
python
import torch
import torch.nn as nn
 
# Bir trained model'in loss surface'ini 2 yönde "filter normalized" olarak görselleştir
# (Li et al. 2018 — "Visualizing the Loss Landscape of Neural Nets")
 
model = nn.Sequential(nn.Linear(10, 32), nn.ReLU(), nn.Linear(32, 1))
 
# Trained weights'ı kaydet
theta_star = [p.detach().clone() for p in model.parameters()]
 
# İki rastgele yönde "filter-wise normalize" perturbation
def random_direction(params):
dirs = []
for p, p_star in zip(params, theta_star):
d = torch.randn_like(p)
# Filter-wise normalize: ||d_i|| = ||θ_i||
d = d * (p_star.norm() / d.norm())
dirs.append(d)
return dirs
 
d1 = random_direction(model.parameters())
d2 = random_direction(model.parameters())
 
# 2D grid'de loss hesapla
import numpy as np
alphas = np.linspace(-1, 1, 20)
betas = np.linspace(-1, 1, 20)
loss_surface = np.zeros((20, 20))
 
x = torch.randn(64, 10)
y = torch.randn(64, 1)
criterion = nn.MSELoss()
 
for i, alpha in enumerate(alphas):
for j, beta in enumerate(betas):
# θ = θ* + α·d1 + β·d2
for p, p_star, dd1, dd2 in zip(model.parameters(), theta_star, d1, d2):
p.data = p_star + alpha * dd1 + beta * dd2
with torch.no_grad():
loss = criterion(model(x), y).item()
loss_surface[i, j] = loss
 
# Plot ile sharp vs flat görünür
# import matplotlib.pyplot as plt
# plt.contourf(alphas, betas, loss_surface, levels=20)
# plt.colorbar()
# plt.show()
print(f"Loss surface min: {loss_surface.min():.4f}, max: {loss_surface.max():.4f}")
Loss landscape 2D görselleştirme — sharp vs flat sezgisi.

11. Mini Egzersizler#

  1. Momentum etkisi: β=0 ile β=0.9 momentum farkı, "uzun vadi" loss surface'inde nasıl?
  2. Bias correction: Adam'ın bias correction'ı olmadan ilk step'lerde ne olur?
  3. Linear scaling rule: Batch 256, lr=1e-4 ile eğitim çalışıyor. Batch 4096'ya çıkarırsan, lr ne olmalı?
  4. Warmup step sayısı: 100K toplam step'lik pretrain için warmup ne kadar olmalı? 2K mı 10K mı? Hangi durumda hangisi?
  5. AdamW vs Lion: Aynı model + aynı dataset. Lion için lr ve weight_decay ayarı AdamW'dan nasıl farklı?

Bu Derste Neler Öğrendik?#

Convex vs non-convex: NN'ler non-convex ama yüksek boyutta saddle baskın ✓ SGD + mini-batch: gürültü hem hız hem implicit regularization ✓ Momentum (Heavy ball, Nesterov): zigzag'i kır ✓ Adaptive (AdaGrad, RMSProp): per-parameter lr ✓ Adam = momentum + adaptive, AdamW = Adam + decoupled weight decayLion (2023): sign-based, %50 daha az memory ✓ Muon (2024): orthogonalized gradient, NanoGPT speedrun ✓ Linear warmup + cosine decay — LLM standardı ✓ Sharp vs flat minima: flat region'lar generalize

Sıradaki Ders#

1.9 — Numerik Stabilite: Log-Sum-Exp, FP16 Tuzakları, NaN Avı Floating point'in gerçek dünyası. BF16 vs FP16, log-sum-exp trick, softmax stability, mixed precision pratiği. Pretrain'de loss spike'ları nasıl anlaşılır ve düzeltilir.

Sık Sorulan Sorular

β₂ = 0.999 → second moment EMA window ~1000 step (yavaş). Büyük modelde gradient varyansı hızlı değişiyor, 1000 step gecikme adaptive lr'ı geride bırakıyor. β₂ = 0.95 → window ~20 step. Hızlı tepki, daha stabil eğitim. Trade-off: noisy v estimate → \(\hat{v}\) noise. Llama 1 (2023) bu hack'i popüleleştirdi; şimdi LLM pretrain'in standartı.

Yorumlar & Soru-Cevap

(0)
Yorum yazmak için giriş yap.
Yorumlar yükleniyor...

İlgili İçerikler