Gradient accumulation over ℝ — the acc{k}x / lambacc{k}x recipes' two phases #
The ℝ reference for what RenderKit.optOne emits under .adamwAccum k / .lambAccum k. One
graph serves both phases, two runtime scalars deciding which it is:
- the accumulator
Gt = akeep·G + gismomVNextFat(μ := %akeep, v := G), i.e.Proofs.momVNext;%akeepis0on the first micro-batch of a cycle (the reset) and1after, so afterkmicro-batchesGtis their SUM (accumCycle_sum); - the accumulate phase (
%aup = 0) feeds the momentsβ = 1,1 − β = 0and the parameterlr = 0: the moments and the parameter pass through unchanged (adamWStepAcc_accumulate,lambStepAcc_accumulate); - the apply phase (
%aup = 1) feeds the moments the hand-written pair(1 − β₁)/kand(1 − β₂)/k²on the SUMGt(RenderKit.accumScalarConsts, where the1/k²on the second moment is explained). That pair at the sum IS the plain step at the MEANGt/k(adamWStepAcc_eq_mean,lambStepAcc_eq_mean), which is what makes accumulation a real large-batch step rather than a mean of per-micro-batch second moments.
Claim boundary. The typed graph's adamMNextF/adamVNextF carry one β and read the two
scalar operands as β and 1 − β; the /k and /k² live in the hand-written scalar block
the train-step banner names (trainStepHandNote acc). So the faithfulness theorems in
StableHLO.Basic cover the ops at the mean, and the identities here are what connects the
emitted constants to that reading. They are ring identities over ℝ, nothing more.
A cycle's accumulator: the reset on the first micro-batch, then k − 1 additions.
Equations
- Proofs.accumCycle gs = List.foldl (fun (G g : Proofs.Vec n) => Proofs.momVNext 1 G g) (fun (x : Fin n) => 0) gs
Instances For
The mean gradient Gt/k, which the render never materialises.
Equations
- Proofs.meanOf k Gt i = Gt i / k
Instances For
The AdamW parameter update as the apply phase computes it (adamWParamF reads the same
%ob1/%ob2).
Equations
- Proofs.adamWParamAcc β₁ β₂ ε lr wd bc₁ bc₂ k θ m v Gt i = θ i - lr * (Proofs.adamMNextAcc β₁ k m Gt i / bc₁ / (√(Proofs.adamVNextAcc β₂ k v Gt i / bc₂) + ε)) - wd * lr * θ i
Instances For
The (θ', m', v') triple of an accumulating AdamW render on one micro-batch.
Equations
- Proofs.adamWStepAcc β₁ β₂ ε lr wd bc₁ bc₂ k θ m v Gt = (Proofs.adamWParamAcc β₁ β₂ ε lr wd bc₁ bc₂ k θ m v Gt, Proofs.adamMNextAcc β₁ k m Gt, Proofs.adamVNextAcc β₂ k v Gt)
Instances For
Apply phase: the accumulating step at the SUM is the plain AdamW step at the MEAN.
LAMB's direction as the apply phase computes it.
Equations
- Proofs.lambDirAcc β₁ β₂ ε wd bc₁ bc₂ k θ m v Gt i = Proofs.adamMNextAcc β₁ k m Gt i / bc₁ / (√(Proofs.adamVNextAcc β₂ k v Gt i / bc₂) + ε) + wd * θ i
Instances For
Apply phase: the accumulating LAMB step at the SUM is lambStep at the MEAN — RSB-A3's
actual optimizer, lambaccdp4x, read as LAMB on the 2048-image batch.
Accumulate phase for LAMB: lr = 0 discards the direction, the moments pass through.
The direction computed on an accumulate micro-batch is built from β₁·m rather than a real
moment (StableHLO.OptRecipe.lambAccum says so); this is why that is harmless.