A2 的球只有一個權重。現在有兩個權重,loss 變成一張地形圖,顏色越深越高。講義說純 SGD 有兩個典型麻煩:狹長山谷(一個方向很陡、另一個方向很平,球左右彈來彈去,往谷底的那個方向卻走得很慢),和鞍點(某些方向往上、某些往下,中間的梯度幾乎是 0,球停在那裡不動)。下面四顆球每一步都用真的公式在算,看誰先到門檻。
v ← βv + g 在方向一致時等於把步長放大約 1/(1−β) 倍。換到彎曲山谷,Adam 反而最慢:η 小的時候它每步只走大約 η,沿著長長的彎道要走很多步,這正是講義說的「Adam 不是永遠比較好」。打開雜訊看看誰比較穩。地形、起點、門檻都是示意用的數字;Momentum 用講義 slide 10 的寫法,Adam 的 β₂ 固定 0.999、RMSProp 的 ρ 固定 0.9。Nesterov momentum:普通 momentum 是「在現在的位置算梯度,再加上慣性」。Nesterov 先假裝照慣性走一步,在預測的位置算梯度,再做真正的更新。講義的比喻是開車:不是到了彎道才煞車,而是轉彎前先估計煞車距離。實驗台裡打開「Nesterov」,在 Rosenbrock 類的彎谷特別看得出它比較少衝過頭。
Adam 的完整一步:
典型預設 β₁ ≈ 0.9、β₂ ≈ 0.999,ε 只是防止除以 0。講義筆記提到:β₁ = 0 時 Adam 基本上就退化成 RMSProp。
為什麼要 bias correction:m 和 v 都是指數移動平均(EMA),從 0 開始。第一步 m₁ = (1−β₁)g₁ = 0.1·g₁,只有真正梯度的十分之一,被起始值 0 拉小了。所以要除以 (1−β₁ᵗ):m̂₁ = 0.1·g₁ / 0.1 = g₁,剛好補回來。隨著 t 變大,β₁ᵗ 趨近 0,修正就自動消失。v 的 β₂ = 0.999 更慢:第 1000 步時 1−β₂ᵗ 還只有約 0.63,要到幾千步之後修正才幾乎消失。講義提醒兩件事:這也是 warmup 和訓練初期行為互相糾纏的原因之一;實作上不要自己刪掉 bias correction 再拿預設的 learning rate 去比。
講義引用的視覺化觀察:在等高線地形上,Adagrad、Adadelta、RMSprop 幾乎一開始就朝對的方向走;Momentum 和 NAG 會先被帶偏、像球滾下山一樣衝過頭,但 NAG 因為「往前看」很快修正。在鞍點上,SGD、Momentum、NAG 很難打破對稱,後兩者最後才逃出來;自適應的方法很快就往負斜率的方向下去。
Full batch 和 mini-batch:每一步用全部資料,梯度雜訊小,但一步很貴,大資料幾乎不可行。mini-batch 矩陣運算效率高、容易平行,但梯度帶雜訊。講義說這個雜訊既是缺點,也可能形成 implicit regularization。實驗台的「mini-batch 雜訊」就是在每一步的梯度上加一點隨機擾動。
SGD 讓所有權重共用同一個 learning rate。講義指出這對「出現頻率不同的特徵」很不利:常出現的特徵每一步都有梯度,很少出現的特徵難得才有一次,卻需要比較大的更新。AdaGrad 的想法是記下每個權重梯度平方的總和 r,梯度一直很大的就走小步、很少更新的就走大步。問題是 r 只會增加,步長最後小到幾乎不動。RMSProp 把「一直加總」改成指數移動平均 v,舊的歷史會被忘掉。
運算都是逐元素(element-wise)的:每個權重有自己的 r 或 v。講義筆記的常用值:AdaGrad 的 η 約 0.01、ε 約 1e-8;RMSProp 的 ρ 約 0.9。
AdaDelta:另一個解決 AdaGrad 步長趨近 0 的方法,連初始 learning rate 都不用設,用之前的步長們估計下一步的步長。講義也指出這一類「固定時間窗口」的方法的風險:資料若突然變化,分母時大時小,訓練後期可能讓 learning rate 震盪、無法收斂。
為什麼 Transformer 特別依賴 Adam:講義列出 Transformer 內部各組參數的梯度尺度差異極大。Embedding table 稀疏、梯度變異大;Q/K/V projection 對數值尺度敏感;attention output 和 FFN 的量級隨深度累積;LayerNorm 的 scale 和 bias 維度很小卻影響很大。單一 learning rate 很難同時照顧這些群組。Adam 逐元素的正規化把跨層的尺度差異消掉,深層網路因此訓練得穩。這也是上面 PROBE A 狹長山谷的放大版:幾百萬個方向,每個方向陡度都不一樣。
為了不讓模型過度擬合,常見做法是每一步把權重往 0 拉一點,叫 weight decay。另一種寫法是在 loss 加上 (λ/2)‖θ‖²,叫 L2 正則化。在 SGD 裡這兩件事完全一樣。但在 Adam 裡,L2 的那一項 λθ 會混進梯度,跟著梯度一起被 1/√v 除掉。結果是:歷史梯度大的權重幾乎沒被拉,歷史梯度小的權重被拉過頭。AdamW 的修正只有一件事:把 weight decay 從梯度裡拿出來,單獨做。
SGD 裡 L2 = weight decay。設 loss 是 f(θ),L2 版本是 f̃(θ) = f(θ) + (λ/2)‖θ‖²,梯度多一項 λθ:
直接做 weight decay:梯度只來自 f,更新時另外乘上 (1−ηλ)。寫出來是同一條式子。
Adam 裡不等價。Adam + L2 把 g̃ = ∇f + λθ 送進 m 和 v,更新變成 η(gₜ + λθₜ)/(√vₜ+ε)。拆開看,衰減的那一項是 ηλθₜ/(√vₜ+ε):每個權重被除以不同的數,所以不再是固定比例。更糟的是 λθ 本身也污染了 v。
梯度和 v 保持乾淨,衰減量恆為 ηλθₜ,回到真正和權重大小成正比的縮小。這已經是框架的預設:PyTorch 的 torch.optim.AdamW 明確寫著 decoupled。講義筆記的實務規則:LayerNorm、BatchNorm 的 scale/shift 和 bias 通常排除在 weight decay 之外;大型公開設定(講義舉 Llama 2)是 AdamW + warmup 加 cosine、wd = 0.1、global-norm clip = 1.0。
Adam 的三大限制(講義):
即使如此,講義的結論是 AdamW 仍是現代 Transformer / LLM 的成熟 baseline,Llama 3、OLMo 2 等大型公開 recipe 仍以 AdamW 為主,所以新的 optimizer 必須和一個公平、調好的 AdamW 比。
SGD 不用存任何額外的東西。Momentum 每個參數多存一份速度。Adam 多存 m 和 v 兩份。模型小的時候這無所謂;到了幾十億、幾百億個參數,optimizer 的狀態比模型本身還大。講義的帳:用 BF16 權重訓練,加上 FP32 master weight、一階 moment、二階 moment,每個參數約 16 bytes。拆開來大約是:BF16 權重 2 bytes、FP32 master 4 bytes、m 4 bytes、v 4 bytes,再加上 BF16 的 gradient 2 bytes(這個拆法是我們的說明,講義只給總數)。拉參數數量看看。
Adafactor:只存行和列。一個 R × C 的權重矩陣,Adam 的 v 也是 R × C。講義的例子:10240 × 10240 的矩陣,光是 v 就要存一億多個數。Adafactor 只存兩個向量:每一列梯度平方的 EMA(長度 R)和每一行的 EMA(長度 C),需要時用外積 (R ⊗ C) / mean(R) 近似回原本的 v。記憶體從 O(R × C) 降到 O(R + C)。講義的比喻是圖片壓縮:不存整張高解析度圖,只存水平和垂直的投影,用的時候再乘回去。代價是 v 是近似的,行為和 Adam 不完全一樣;對 embedding 和 Transformer 的大矩陣特別自然。
8-bit optimizer:把 m 和 v 量化成 8 位元,通常用 block-wise 的縮放、對離群值特別處理、小的 tensor 不量化。優點是記憶體和通訊都下降,很適合微調大模型;限制是量化的額外運算、離群值、長期累積的誤差需要驗證。
Lion:只留 momentum 的符號。透過程式搜尋找到的 optimizer:捨棄二階 moment,更新只用 momentum 的 sign(每個方向只走 +1 或 −1 乘上步長)。比 AdamW 少一半額外記憶體,計算也簡單。講義的注意事項:要重新調 learning rate 和 weight decay,不能直接套 AdamW 的參數;batch 小於 64 時效果不如 AdamW(sign 本身帶雜訊,小 batch 又加雜訊);優勢依任務而異,不是全面取代。
四代 optimizer:coordinate → matrix → norm → architecture(講義的整理):
SAM 和 Lookahead:不只看 training loss。Lookahead 維護一組快的權重和一組慢的權重,快的走 k 步後,慢的往快的內插,降低軌跡的變異、讓超參數比較不敏感。SAM(sharpness-aware minimization)先往梯度方向試探最糟的擾動,強迫找平坦的最低點,代價是接近兩倍的 forward / backward 時間。講義提醒:flatness 會受參數化方式影響,不能簡化成唯一的泛化解釋。
實務 baseline(講義):
| 情境 | 合理的起點 | 理由 |
|---|---|---|
| CNN 監督式 | SGD + momentum + cosine | 泛化強、記憶體低 |
| ViT / Transformer | AdamW + warmup + decay | 參數尺度異質,自適應比較穩 |
| LLM pretraining | AdamW baseline,再測 Muon / SOAP / Sophia | 要公平比較 token 數和時間 |
| 記憶體受限 | Adafactor、8-bit Adam、GaLore、Adam-mini | 降低 optimizer state |
| 超大 batch | LARS / LAMB / 調好的 AdamW | 逐層的 trust ratio |
| Fine-tuning | AdamW,必要時 8-bit | 穩定、好調、省顯存 |
評估準則:loss 對 token 數、loss 對實際時間、optimizer state 記憶體、通訊量、下游任務品質。先建立強 baseline,再看新 optimizer 是否真的縮短「到達同樣品質的時間」。
三個「診斷 → 對策」(講義):
講義最後列了六個認知偏差,這裡挑和本模組最相關的四個。共同的錯是把訓練 loss、泛化、速度和記憶體混為一談。