Sam Babichenko

Reading notes / NanoGPT speedrun

Shampoo

Gupta et al., 2018; Anil et al., 2020; Vyas et al., 2025

Weights and gradients
W∈Rm×nW\in\mathbb R^{m\times n}one weight matrix; rows index outputs, columns inputs
Gt;G_t; gt=vec(Gt)g_t=\mathrm{vec}(G_t)minibatch gradient at step t; the same with rows stacked into a vector
w=vec(W)w=\mathrm{vec}(W)the weights as one vector
η;\eta; t;t; TTlearning rate; step index; number of steps
USV⊤USV^\topsingular value decomposition of the gradient or momentum
Preconditioners
HtH_tfull-matrix AdaGrad statistic ϵImn+∑s≤tgsgs⊤\epsilon I_{mn}+\sum_{s\le t}g_sg_s^\top
Lt;L_t; RtR_tShampoo's factors ϵIm+∑GsGs⊤\epsilon I_m+\sum G_sG_s^\top and ϵIn+∑Gs⊤Gs\epsilon I_n+\sum G_s^\top G_s
L;L; RRaverages E[GG⊤]\mathbb E[GG^\top], E[G⊤G]\mathbb E[G^\top G] (Morwani et al., SOAP)
A⊗BA\otimes BKronecker product; (A⊗B)vec(G)=vec(AGB⊤)(A\otimes B)\mathrm{vec}(G)=\mathrm{vec}(AGB^\top)
StS_tShampoo's preconditioner Lt1/4⊗Rt1/4L_t^{1/4}\otimes R_t^{1/4} (Step 3)
QL,Q_L, λi;\lambda_i; QR,Q_R, μj\mu_jeigenvectors and eigenvalues of L; of R
G~=QL⊤GQR\tilde G=Q_L^\top GQ_Rgradient in the two eigenbases
H=E[gg⊤]H=\mathbb E[gg^\top]second moment of the vectorized gradient (Morwani et al.)
ΔtS;\Delta^{\mathrm S}_t; ΔtA\Delta^{\mathrm A}_tShampoo's and the grafted optimizer's step for one layer
M;M; VVSOAP's momentum; its per-entry second moment of the rotated gradient
Constants
ϵ\epsilonsmall constant on the diagonal of each accumulated matrix
rrbound on the rank of every gradient, in the regret theorem
DDlargest distance ∥Wt−W∗∥F\|W_t-W^*\|_F, in the regret theorem
ft;f_t; W∗W^*loss revealed at step t; comparison matrix, in the regret theorem
β1;\beta_1; β2\beta_2moving-average rates of SOAP's momentum; of its second moment and of L, R
s2s^2variance of each gradient entry in the shape example
τ\tautolerance of the adaptive basis rule (Eschenhagen et al.)
Local to one step
ui,u_i, vi,v_i, σi\sigma_isingular vectors and values of one gradient (Step 1)
X;X; α\alphaϵImn+1r∑gsgs⊤\epsilon I_{mn}+\frac1r\sum g_sg_s^\top; weight of the uneven split (Step 2)
H^t\hat H_t(rϵImn+∑s≤tgsgs⊤)1/2(r\epsilon I_{mn}+\sum_{s\le t}g_sg_s^\top)^{1/2} (Step 3)
θi;\theta_i; Ai,A_i, BiB_isingular values and unit-norm factors of the rearranged H (Step 6)
a;a; c;c; qi,q_i, qˉj\bar q_jrow and column sums of E[G~⊙G~]\mathbb E[\tilde G\odot\tilde G]; columns of QLQ_L, QRQ_R (Step 7)
dij;d_{ij}; ppper-entry scales and power of a rotated step (Step 8)
Q^;\hat Q; Λ^\hat\Lambdalast computed eigenvectors; Q^⊤LQ^\hat Q^\top L\hat Q (Step 8)

Context. the default optimizer for neural networks: it divides each coordinate of a running average of the gradient by the square root of a running average of that coordinate's squared gradient rescales each coordinate of the gradient separately, so its step can only be stretched or shrunk along the coordinate axes. AdaGrad with a dense preconditioner: it multiplies the gradient vector gg by H−1/2H^{-1/2}, where HH is the sum of gg⊤gg^\top over all past gradients can rotate as well, but for a weight matrix with mm rows and nn columns its preconditioner has (mn)2(mn)^2 entries, about 5.6×10125.6\times10^{12} for one 768×3072768\times3072 layer of GPT-2 small, so it is not run on networks. Shampoo (Gupta et al., 2018) keeps two small matrices per weight matrix instead, a running sum of GG⊤GG^\top and one of G⊤GG^\top G, where GG is the matrix's gradient, and multiplies GG on the left and on the right by an inverse root of each. Anil et al. (2020) made it fast enough to beat well-tuned first-order optimizers in wall-clock time, and the PyTorch implementation of Shi et al. (2023) won the AlgoPerf: a benchmark that scores a training algorithm by the time it needs to reach fixed validation targets on eight deep learning workloads; in the external-tuning track each submission supplies a hyperparameter search space and is scored with five tuning trials per workload (Kasimbeg et al., 2025). Morwani et al. (2025) worked out what the two matrices approximate, SOAP (Vyas et al., 2025) runs Adam in their eigenvectors, and the speedrun's optimizer for hidden weight matrices: it replaces the momentum USV⊤USV^\top, written in its singular value decomposition, by UV⊤UV^\top, computed approximately with a few matrix-multiply iterations with its momentum turned off is Shampoo with its sums removed (Bernstein and Newhouse, 2024).

Shampoo's step is a change of basis and a rescaling: it rotates the gradient into a basis, the eigenvectors of the two accumulated matrices, divides each entry by a scale, and rotates back. In the experiments that separate the two (Steps 7 and 8, on language models up to 660M parameters and small vision models), the basis carries the advantage over Adam and still helps when it is recomputed only every 10 to 100 steps. The scale, a product of the two matrices' eigenvalues to the power 1/41/4, gives differently shaped layers inconsistent step sizes and is updated only when the basis is recomputed. Apart from the engineering that makes the roots affordable (Steps 4 and 5), the fixes that made Shampoo work act on the scale: each layer's step length borrowed from Adam (grafting), a square-root power in place of the fourth root (with a trace factor, in the analysis), and in SOAP, Adam's own per-entry scale computed in Shampoo's basis and updated every step. Muon applies Shampoo's fourth-root formula, with no sums and ϵ=0\epsilon=0, to the current momentum alone, which rotates into the momentum's singular vectors and sets every singular value to one (approximately, in practice).

Setting. Take one weight matrix a weight matrix of the network, W∈Rm×nW\in\mathbb R^{m\times n}; Shampoo treats each weight matrix separately∈Rm×n{}\in\mathbb R^{m\times n} and let the gradient of the minibatch loss at step tt with respect to WW, an m×nm\times n matrix be its minibatch gradient at step tt. Write gtg_t=vec(Gt){}=\mathrm{vec}(G_t) for the gradient with its rows stacked into one vector, and w=vec(W)w=\mathrm{vec}(W). Full-matrix AdaGrad keeps HtH_t=ϵImn+∑s≤tgsgs⊤{}=\epsilon I_{mn}+\sum_{s\le t}g_sg_s^\top and steps w←w−ηHt−1/2gtw\leftarrow w-\eta H_t^{-1/2}g_t, with learning rate the learning rate, the step size multiplying the preconditioned gradient and a small a small constant added to the diagonal so that the accumulated matrices are invertible from the first step; diagonal AdaGrad and Adam keep only the diagonal of HtH_t, Adam with running averages in place of sums. Shampoo keeps one matrix per side,Lt=ϵIm+∑s≤tGsGs⊤,Rt=ϵIn+∑s≤tGs⊤Gs,Wt+1=Wt−η Lt−1/4GtRt−1/4.\begin{aligned}L_t&=\epsilon I_m+\textstyle\sum_{s\le t}G_sG_s^\top,\\R_t&=\epsilon I_n+\textstyle\sum_{s\le t}G_s^\top G_s,\\W_{t+1}&=W_t-\eta\,L_t^{-1/4}G_tR_t^{-1/4}.\end{aligned}Rows of GG index outputs and columns inputs, so Shampoo's left factor, ϵIm+∑s≤tGsGs⊤\epsilon I_m+\sum_{s\le t}G_sG_s^\top, an m×mm\times m matrix of summed inner products between rows of the gradients sums inner products between rows of the gradients and Shampoo's right factor, ϵIn+∑s≤tGs⊤Gs\epsilon I_n+\sum_{s\le t}G_s^\top G_s, an n×nn\times n matrix of summed inner products between columns of the gradients between columns. The for A∈Rm×mA\in\mathbb R^{m\times m} and B∈Rn×nB\in\mathbb R^{n\times n}, the mn×mnmn\times mn matrix A⊗BA\otimes B whose (i,j)(i,j) block is AijBA_{ij}B; with rows stacked, (A⊗B) vec(G)=vec(AGB⊤)(A\otimes B)\,\mathrm{vec}(G)=\mathrm{vec}(AGB^\top) turns this into a preconditioner on the long vector: (A⊗B) vec(G)=vec(AGB⊤)(A\otimes B)\,\mathrm{vec}(G)=\mathrm{vec}(AGB^\top), so Shampoo is AdaGrad's step with Ht1/2H_t^{1/2} replaced by Lt1/4⊗Rt1/4L_t^{1/4}\otimes R_t^{1/4}. It stores m2+n2m^2+n^2 numbers in place of m2n2m^2n^2, and its inverse roots cost O(m3+n3)O(m^3+n^3) in place of O(m3n3)O(m^3n^3). Dropping the step index, write the current factors as L=QL diag(L=Q_L\,\mathrm{diag}(the eigenvalues of LL; QLQ_L is the orthogonal matrix of its eigenvectors, so L=QL diag(λ) QL⊤L=Q_L\,\mathrm{diag}(\lambda)\,Q_L^\top) QL⊤)\,Q_L^\top and R=QR diag(R=Q_R\,\mathrm{diag}(the eigenvalues of RR; QRQ_R is the orthogonal matrix of its eigenvectors, so R=QR diag(μ) QR⊤R=Q_R\,\mathrm{diag}(\mu)\,Q_R^\top) QR⊤)\,Q_R^\top in their the orthonormal eigenvectors of a symmetric matrix, used as new coordinate axes, and G~=QL⊤GQR\tilde G=Q_L^\top GQ_R for the gradient in those coordinates. Then Shampoo's step is a rotation, a rescaling of each entry, and the rotation back:L−1/4GR−1/4=QL[G~ij(λiμj)1/4]QR⊤.\begin{aligned}&L^{-1/4}GR^{-1/4}\\&\quad=Q_L\Big[\frac{\tilde G_{ij}}{(\lambda_i\mu_j)^{1/4}}\Big]Q_R^\top.\end{aligned}A sketch for one matrix, with summed statistics and no momentum:
# one weight matrix W (m x n) with gradient G; L, R start at eps * I
L = L + G @ G.T                        # m x m
R = R + G.T @ G                        # n x n
lam, QL = torch.linalg.eigh(L)         # in practice recomputed every 10-100 steps
mu, QR = torch.linalg.eigh(R)
Gr = QL.T @ G @ QR                     # the gradient in the two eigenbases
scale = torch.outer(lam, mu) ** 0.25   # entry (i, j) is divided by (lam_i * mu_j)^(1/4)
W = W - lr * (QL @ (Gr / scale) @ QR.T)
# SOAP keeps QL and QR but replaces scale by Adam's per-entry second moment of Gr:
# V = b2 * V + (1 - b2) * Gr**2;  scale = V.sqrt() + eps
For a tensor with kk dimensions Shampoo keeps one such matrix per dimension and uses the power −1/(2k)-1/(2k) on each; a matrix is the case k=2k=2.

The Kronecker product of the two square roots dominates full-matrix AdaGrad. If every gradient has rank at most a bound on the rank of every gradient GtG_t; for a linear layer each example's gradient is an outer product, so a batch of BB examples gives r≤min⁡(m,n,B)r\le\min(m,n,B), then for every ttϵImn+1r∑s≤tgsgs⊤⪯Lt1/2⊗Rt1/2\epsilon I_{mn}+\frac1r\sum_{s\le t}g_sg_s^\top\preceq L_t^{1/2}\otimes R_t^{1/2}in the A⪯BA\preceq B means that B−AB-A is positive semidefinite, so v⊤Av≤v⊤Bvv^\top Av\le v^\top Bv for every vector vv (Steps 1 and 2). The left side is Ht/rH_t/r up to the ϵ\epsilon term, so the Kronecker product is at least that large in every direction. The analysis of full-matrix AdaGrad then goes through with Lt1/4⊗Rt1/4L_t^{1/4}\otimes R_t^{1/4}, the square root of the right side, in place of Ht1/2H_t^{1/2}, and Shampoo keeps AdaGrad's the total loss over the steps minus the total loss of the best fixed weight matrix chosen in hindsight; regret that grows more slowly than the number of steps means the average loss approaches the best fixed one of order T\sqrt T after the number of steps steps (Step 3). The fourth roots in Shampoo come from this square root.

Squared, the Shampoo preconditioner is close to the best Kronecker approximation, and that points to the power 1/21/2. The bound above holds up to the factor rr and so leaves open how close the Kronecker product is to the full matrix. Morwani et al. (2025) take a distribution of gradients, the second-moment matrix of the vectorized gradient; for AdaGrad the expectation is the average over past steps, for the Gauss-Newton reading it is over data with labels sampled from the model, and ask for the Kronecker product A⊗BA\otimes B closest to HH in Frobenius norm. Rearranging the entries of HH turns every A⊗BA\otimes B into the rank-one matrix vec(A)vec(B)⊤\mathrm{vec}(A)\mathrm{vec}(B)^\top (Van Loan and Pitsianis), so the answer is the top singular pair of the rearranged HH, and the method that finds the top singular vectors of a matrix MM by repeating a←Mba\leftarrow Mb, b←M⊤ab\leftarrow M^\top a on it reads, in matrix form, A←E[GBG⊤]A\leftarrow\mathbb E[GBG^\top] and B←E[G⊤AG]B\leftarrow\mathbb E[G^\top AG]. Started from identity matrices, one step gives E[GG⊤]\mathbb E[GG^\top] and E[G⊤G]\mathbb E[G^\top G], the averages of what Shampoo accumulates. With the expectation taken over past steps these are Lt/tL_t/t and Rt/tR_t/t up to the ϵ\epsilon term, so we keep the letters: write L=E[GG⊤]L=\mathbb E[GG^\top] and R=E[G⊤G]R=\mathbb E[G^\top G]. So L⊗RL\otimes R, the square of Shampoo's L1/2⊗R1/2L^{1/2}\otimes R^{1/2}, is one power-iteration step toward the best Kronecker approximation, and in their measurements it is nearly as close to HH as the optimum while Shampoo's own product is much further away (Step 6). If HH is exactly a Kronecker product, then H=L⊗R/tr LH=L\otimes R/\mathrm{tr}\,L, and AdaGrad's H−1/2H^{-1/2} becomes a square-root power on each side:(L⊗Rtr L)−1/2vec(G)=tr L  vec(L−1/2GR−1/2).\begin{aligned}&\Big(\frac{L\otimes R}{\mathrm{tr}\,L}\Big)^{-1/2}\mathrm{vec}(G)\\&\quad=\sqrt{\mathrm{tr}\,L}\;\mathrm{vec}\big(L^{-1/2}GR^{-1/2}\big).\end{aligned}Shi et al. (2023) report this power as often effective, found by tuning (Step 5).

The scale is where Shampoo is weak, and the practical fixes act on it. In the rotated form of the Setting, the basis QL,QRQ_L,Q_R changes slowly once training is under way (Step 8), so a basis computed tens of steps earlier is still close to current. The scale is weaker in two ways. Its size depends on the layer's shape: if the gradient entries are independent with mean zero and variance the variance of each gradient entry in the example, assumed equal for all entries of the layer, then L=ns2ImL=ns^2I_m and R=ms2InR=ms^2I_n (with averages in place of sums), Shampoo's step is (mn)−1/4G/s(mn)^{-1/4}G/s, while Adam's is G/sG/s. So Shampoo's step is an eighth of Adam's for a 64×6464\times64 matrix and about a forty-fifth for a 1024×40961024\times4096 matrix (our computation; Eschenhagen et al., 2025, prove bounds with this dimension factor), so one learning rate cannot give both layers Adam-sized steps. And the eigenvalues are refreshed only with the basis, while the size of the gradient changes every step. Agarwal et al.'s (2020) rule: rescale each layer's update direction from one optimizer to the Frobenius norm of the update another optimizer would take for that layer at the same step, used in the large-scale results of Anil et al. and Shi et al. (Steps 4 and 5), rescales each layer's Shampoo step ΔtS\Delta^{\mathrm S}_t to the length of the step ΔtA\Delta^{\mathrm A}_t that Adam (or AdaGrad, or SGD) would take on that layer:Wt+1=Wt−η ∥ΔtA∥F∥ΔtS∥F ΔtS.W_{t+1}=W_t-\eta\,\frac{\|\Delta^{\mathrm A}_t\|_F}{\|\Delta^{\mathrm S}_t\|_F}\,\Delta^{\mathrm S}_t.Eschenhagen et al. (2025) show that grafting compensates for the eigenvalues: the basis never changes a step's length, and a scale that is correct and current made grafting unnecessary in their tests (Step 8). The trace-scaled square-root form of the previous paragraph is correct in the example above, where it gives exactly G/sG/s (our check). SOAP keeps it current: in Shampoo's eigenbasis that form is a memory-saving variant of Adam that replaces the per-entry average of squared gradients by a rank-one estimate built from its row sums and column sums, whose estimate of the squared rotated gradient has row sums λi\lambda_i and column sums μj\mu_j, and SOAP replaces it by Adam's full per-entry average, updated every step even while the basis is stale (Step 7).

The guarantee (Gupta et al., 2018). Gupta et al. analyze Shampoo as an algorithm for a repeated game: at each step the learner commits to WtW_t, then a convex loss ftf_t is revealed and the learner incurs ft(Wt)f_t(W_t); stochastic optimization is the case of losses drawn independently from one distribution: at each step tt a convex loss the loss revealed at step tt, for example the loss on step tt's minibatch, convex in WW arrives after the learner has chosen WtW_t, and regret compares the learner's total loss with that of a fixed matrix any fixed comparison matrix, typically a minimizer of the total loss. An online-to-batch conversion turns a regret bound into a stochastic optimization error of order regret divided by TT. The theorem says Shampoo's regret grows like T\sqrt T, the best possible rate in this setting, with a constant made of the traces of the final fourth roots. If every ftf_t is why: the regret bound for preconditioned online gradient steps (Step 3) uses convexity to bound ft(Wt)−ft(W∗)f_t(W_t)-f_t(W^*) by ⟨Gt,Wt−W∗⟩\langle G_t,W_t-W^*\rangle and every GtG_t has why: Step 1 splits the gradient into rr rank-one pieces, and the Cauchy-Schwarz inequality used there loses a factor rr; with no rank bound one takes r=min⁡(m,n)r=\min(m,n), then Shampoo with η=D/2r\eta=D/\sqrt{2r} satisfies, for every W∗W^*,∑t≤Tft(Wt)−∑t≤Tft(W∗)⏟regret≤2r D tr(LT1/4)⏟left tr(RT1/4)⏟right,\begin{aligned}&\underbrace{\sum_{t\le T}f_t(W_t)-\sum_{t\le T}f_t(W^*)}_{\text{regret}}\\&\quad\le\sqrt{2r}\,D\,\underbrace{\mathrm{tr}(L_T^{1/4})}_{\text{left}}\,\underbrace{\mathrm{tr}(R_T^{1/4})}_{\text{right}},\end{aligned}where DD=max⁡t≤T∥Wt−W∗∥F{}=\max_{t\le T}\|W_t-W^*\|_F. With ϵ=0\epsilon=0 and gradients of spectral norm at most 1, GtGt⊤⪯ImG_tG_t^\top\preceq I_m gives tr(LT1/4)≤mT1/4\mathrm{tr}(L_T^{1/4})\le mT^{1/4}, and likewise tr(RT1/4)≤nT1/4\mathrm{tr}(R_T^{1/4})\le nT^{1/4}, so the regret is at most 2r D mnT\sqrt{2r}\,D\,mn\sqrt T. For a tensor with kk dimensions the bound is a product of kk traces of 1/(2k)1/(2k) powers.

Measured gains. The theorem is for convex losses; the case for Shampoo in deep learning is empirical. On large models Anil et al. (2020) reached the same quality as Adam or AdaGrad in about half the steps on WMT'14 English to French translation with a Transformer, cutting training from about 12 to 6.7 hours, and reached the target AUC of a click-through-rate model in 31,000 steps where the tuned baseline needed 64,000. With the same hyperparameters as a tuned SGD-with-Nesterov recipe for ResNet-50 on ImageNet, Shi et al. (2023) reached the recipe's 90-epoch accuracy with 1.5 times fewer steps and 1.35 times less time. Across the eight AlgoPerf workloads their implementation trained about 28% faster on average than the Adam with Nesterov momentum and decoupled weight decay, the AlgoPerf baseline baseline (Kasimbeg et al., 2025). SOAP reached AdamW's final loss with at least 40% fewer steps and 35% less time on 360M- and 660M-parameter language models trained with 2-million-token batches, and with about 20% less of both than Shampoo (Vyas et al., 2025). The costs are a slower step, about 2m2+2n22m^2+2n^2 extra numbers per matrix for the factors and their roots or eigenvectors, eigendecompositions in float32 or float64, and the engineering in Steps 4 and 5.

Where it stands. Against Adam-type optimizers the Shampoo family needs fewer steps in every comparison above, and on AlgoPerf it was also fastest in time; elsewhere, whether it wins on time depends on how cheaply its matrix roots can be computed. Remove the sums and set ϵ=0\epsilon=0, keeping the original power −1/4-1/4. Then L=GG⊤L=GG^\top and R=G⊤GR=G^\top G give L−1/4GR−1/4=UV⊤L^{-1/4}GR^{-1/4}=UV^\top for G=USV⊤G=USV^\top, with the inverse roots taken on the range of GG (the reduced singular value decomposition); a small ϵ>0\epsilon>0 gives US(S2+ϵ)−1/2V⊤US(S^2+\epsilon)^{-1/2}V^\top instead (our check). This is Muon's orthogonalized update applied to the gradient, which Bernstein and Newhouse (2024) read as steepest descent under the spectral norm. With the square-root power the same computation gives US−1V⊤US^{-1}V^\top, which enlarges the weakest directions most (our check), so Muon is the accumulation-free form of the original fourth-root Shampoo. Muon applies the map to its momentum instead of the gradient, every step and with no grafting, and approximates UV⊤UV^\top with a few matrix multiplications in bfloat16 that leave the singular values only roughly at one; it stores nothing beyond its momentum. On the speedrun's own comparison at about 2.7 billion tokens (Jordan et al., 2024), SOAP ended at Muon's loss, the distributed Shampoo slightly higher, and Adam clearly higher; Muon reached the target first, at 142 milliseconds per step on 8 H100 GPUs against 301 for SOAP and 154 to 179 for Shampoo (the times printed in the post's figure legends; Jordan et al. mark SOAP's implementation as under development). The speedrun also has an optimization track that scores the number of steps to a validation loss of 3.28 (modded-nanogpt Track 3 records). Its table lists Muon with no momentum and Shampoo with no accumulation, no momentum, power −1/4-1/4 and roots every step as one entry, and its record as of November 2026 (2690 steps) runs Muon on momentum first preconditioned with SOAP's row and column statistics, refreshed every step. Open questions are how often to recompute the basis, whether full-matrix AdaGrad or Adam is the right target to approximate at all (Eschenhagen et al. end on this), and how the gains hold at the largest scales; SOAP's tests stop at 660M parameters.

Step 1 (Gupta et al.)

One gradient's outer product is bounded by each one-sided factor. Write the gradient in its singular value decomposition G=USV⊤=∑i≤rσiuivi⊤G=USV^\top=\sum_{i\le r}\sigma_iu_iv_i^\top, with ui,viu_i,v_i the columns of U,VU,V, so g=vec(G)=∑iσi ui⊗vig=\mathrm{vec}(G)=\sum_i\sigma_i\,u_i\otimes v_i. For any vectors w1,…,wrw_1,\dots,w_r, (∑iwi)(∑iwi)⊤⪯r∑iwiwi⊤(\sum_iw_i)(\sum_iw_i)^\top\preceq r\sum_iw_iw_i^\top, because (∑ix⊤wi)2≤r∑i(x⊤wi)2(\sum_ix^\top w_i)^2\le r\sum_i(x^\top w_i)^2 for every vector xx by Cauchy-Schwarz; hence gg⊤⪯r∑iσi2(uiui⊤)⊗(vivi⊤)gg^\top\preceq r\sum_i\sigma_i^2(u_iu_i^\top)\otimes(v_iv_i^\top). Bounding vivi⊤⪯Inv_iv_i^\top\preceq I_n leaves GG⊤⊗InGG^\top\otimes I_n, and bounding uiui⊤⪯Imu_iu_i^\top\preceq I_m leaves Im⊗G⊤GI_m\otimes G^\top G:1r gg⊤⪯(GG⊤)⊗In,1r gg⊤⪯Im⊗(G⊤G).\begin{aligned}\tfrac1r\,gg^\top&\preceq(GG^\top)\otimes I_n,\\\tfrac1r\,gg^\top&\preceq I_m\otimes(G^\top G).\end{aligned}Each bound alone discards the structure of one side; the factor rr is the Cauchy-Schwarz loss over rr rank-one pieces.

Step 2 (Gupta et al.)

The geometric mean of the two bounds is the Kronecker bound. Sum Step 1 over s≤ts\le t and add ϵImn\epsilon I_{mn}. With X=ϵImn+1r∑s≤tgsgs⊤X=\epsilon I_{mn}+\frac1r\sum_{s\le t}g_sg_s^\top, this gives X⪯Lt⊗InX\preceq \htmlData{gr=g11}{L_t}\otimes I_n and X⪯Im⊗RtX\preceq I_m\otimes \htmlData{gr=g12}{R_t}. The two right sides commute, and for commuting positive semidefinite matrices the geometric mean is monotone in each argument (Ando et al.), soX=X1/2X1/2⪯(Lt⊗In)1/2(Im⊗Rt)1/2=Lt1/2⊗Rt1/2.\begin{aligned}X&=X^{1/2}X^{1/2}\\&\preceq(L_t\otimes I_n)^{1/2}(I_m\otimes R_t)^{1/2}\\&=L_t^{1/2}\otimes R_t^{1/2}.\end{aligned}The square roots come from splitting the two bounds evenly. Anil et al. (2020) split unevenly: weights α\alpha and 1−α1-\alpha give X⪯Ltα⊗Rt1−αX\preceq L_t^{\alpha}\otimes R_t^{1-\alpha} for any α∈[0,1]\alpha\in[0,1], and α=1\alpha=1 keeps only the left factor, so AdaGrad's square root gives the step Lt−1/2GL_t^{-1/2}G, which is how they precondition layers too large for a right factor.

Step 3 (Gupta et al.)

AdaGrad's regret argument goes through with the Kronecker preconditioner. Write StS_t=Lt1/4⊗Rt1/4{}=L_t^{1/4}\otimes R_t^{1/4}, so the step is w←w−ηSt−1gtw\leftarrow w-\eta S_t^{-1}\htmlData{gr=g7}{g_t}; StS_t increases with tt because LtL_t and RtR_t do. The standard bound for preconditioned online gradient steps with nondecreasing preconditioners givesRegret≤D22η tr ST+η2∑t≤Tgt⊤St−1gt.\begin{aligned}\mathrm{Regret}\le{}&\frac{D^2}{2\eta}\,\mathrm{tr}\,S_T\\&+\frac\eta2\sum_{t\le T}g_t^\top S_t^{-1}g_t.\end{aligned}The sum is where Step 2 enters. Let H^t=(rϵImn+∑s≤tgsgs⊤)1/2\hat H_t=(r\epsilon I_{mn}+\sum_{s\le t}g_sg_s^\top)^{1/2}, full-matrix AdaGrad's preconditioner with ϵ\epsilon multiplied by rr. Step 2 times rr, and the operator monotonicity of the square root (Loewner), give H^t⪯r St\hat H_t\preceq\sqrt r\,S_t. AdaGrad's own potential argument gives ∑tgt⊤H^t−1gt≤2 tr H^T\sum_tg_t^\top\hat H_t^{-1}g_t\le2\,\mathrm{tr}\,\hat H_T. Chaining the two, ∑tgt⊤St−1gt≤r⋅2 tr H^T≤2r tr ST\sum_tg_t^\top S_t^{-1}g_t\le\sqrt r\cdot2\,\mathrm{tr}\,\hat H_T\le2r\,\mathrm{tr}\,S_T. Choosing η=D/2r\eta=D/\sqrt{2r} balances the two terms at 2r D tr ST\sqrt{2r}\,D\,\mathrm{tr}\,S_T, and tr(A⊗B)=trA trB\mathrm{tr}(\htmlData{gr=gn5}{A\otimes B})=\mathrm{tr}A\,\mathrm{tr}B gives the theorem. The tensor case is the same argument with a geometric mean of kk one-sided bounds.

Step 4 (Anil et al., 2020)

Roots on idle CPUs, partial preconditioners for large layers, and grafting make Shampoo run at scale. The inverse roots were the bottleneck, up to 100 times a training step. For a Transformer layer the factor's condition number was 10710^7 to 10910^9 during training, and an inverse root loses about log⁡2\log_2 of the condition number in bits of precision, so the roots need float64, which accelerators do slowly. Anil et al. compute them with the an iteration for inverse matrix roots that uses only matrix products and stays numerically stable (Guo and Higham; Iannazzo); here started from the previous root, warm-started from the previous root, in float64 on the CPUs attached to the accelerators, asynchronously, and swap in new roots every few hundred steps; recomputing them that rarely had no significant effect on quality. Large layers get partial preconditioners: embedding and softmax layers use one side only (L−1/2GL^{-1/2}G, from the unequal split in Step 2), and large dense layers are cut into blocks, each its own Shampoo matrix. Grafting from AdaGrad, or from the layer-wise scaling of LAMB, sets each layer's step length, because the preconditioners' norms spread over a wide range across layers and caused instability. They also report that treating the power as a hyperparameter sometimes helped, and they used the square root on each side in their autoencoder experiments. On a Transformer for WMT'14 English to French (93M parameters) Shampoo needed 1.95 times fewer steps at about 16% more time per step; on a click-through-rate model on the 1 TB Criteo data it reached the target AUC of 80.25% in 30,970 steps against 64,000; BERT-Large needed 16% fewer steps than LAMB; and ResNet-50 at batch size 32,768 reached 75.9% top-1 accuracy in 1,729 steps against 2,512.

Step 5 (Shi et al., 2023)

Spreading the preconditioners across GPUs keeps the step within 10% of Adam's, and the result won AlgoPerf. In standard data-parallel training every worker repeats the whole optimizer step, which is cheap for Adam but would make some large models' Shampoo steps 50% to 75% slower. Shi et al. assign each layer's factors and grafting state to one worker, balanced greedily by size, let each worker compute only its layers' preconditioned directions, and gather the directions with one AllGather; the step then costs at most about 10% more than a diagonal method's. The roots use a symmetric eigendecomposition in float32 (retried in float64 if it fails), with the eigenvalues shifted to be at least ϵ\epsilon. They describe grafting as one of the main requirements for Shampoo to work in practice, and report that the square-root power (or the fourth-root power multiplied by 1.82) is often effective for networks made mostly of linear layers. On ResNet-50 for ImageNet, with roots recomputed every 50 steps, blocks of at most 2048 dimensions and grafting from SGD with the tuned Nesterov recipe's hyperparameters unchanged, Shampoo reached 77.44% validation accuracy in 90 epochs against 76.85% (means over five seeds) at 8% more time, and the Nesterov 90-epoch accuracy with 1.5 times fewer steps and 1.35 times less time. With Adam grafting and roots every 100 steps, the implementation won the external-tuning track of AlgoPerf, about 28% faster on average than the NAdamW baseline and about 2% faster than the second-place entry, though five different entries were fastest on at least one workload (Kasimbeg et al., 2025).

Step 6 (Morwani et al., 2025)

L⊗RL\otimes R is one power-iteration step toward the best Kronecker approximation, and one step is enough in practice. Rearrange HH so that the entry E[GijGkl]\mathbb E[G_{ij}G_{kl}] sits at row (i,k)(i,k) and column (j,l)(j,l). A Kronecker product A⊗BA\otimes B then becomes vec(A)vec(B)⊤\mathrm{vec}(A)\mathrm{vec}(B)^\top, the Frobenius distance is preserved, and multiplying the rearranged HH by vec(B)\mathrm{vec}(B) gives vec(E[GBG⊤])\mathrm{vec}(\mathbb E[GBG^\top]); this is the matrix form of power iteration in the mechanism above. Starting from B=InB=I_n and A=ImA=I_m gives LL and RR. Why one step suffices: write the singular value decomposition of the rearranged HH as ∑iθi vec(Ai)vec(Bi)⊤\sum_i\theta_i\,\mathrm{vec}(A_i)\mathrm{vec}(B_i)^\top, with unit-norm matrices Ai,BiA_i,B_i. One step from the identity gives ∑iθi(tr Bi)Ai\sum_i\theta_i(\mathrm{tr}\,B_i)A_i, so it lands near the top factor A1A_1 when θ1tr B1\theta_1\mathrm{tr}\,B_1 is large next to the other θitr Bi\theta_i\mathrm{tr}\,B_i. The top factor B1B_1 is positive semidefinite, and among positive semidefinite matrices of unit Frobenius norm the scaled identity has the largest worst-case overlap with the others, while if B1B_1 is positive definite the later BiB_i are not positive semidefinite, so their traces can cancel. In their measurements on binary MNIST, CIFAR-5M and ImageNet, the cosine similarity of L⊗RL\otimes R with HH stayed close to that of the optimal Kronecker product throughout training, and Shampoo's L1/2⊗R1/2L^{1/2}\otimes R^{1/2} was clearly lower, for HH both AdaGrad's statistic and the the Hessian of the loss with the network linearized at the current weights, J⊤∇f2ℓ JJ^\top\nabla_f^2\ell\,J, where JJ is the Jacobian of the network output with respect to the weights and ∇f2ℓ\nabla_f^2\ell the Hessian of the loss in the output; for cross-entropy it equals E[gg⊤]\mathbb E[gg^\top] with labels sampled from the model. If H=A⊗BH=A\otimes B exactly, then L=(tr B)AL=(\mathrm{tr}\,B)A and R=(tr A)BR=(\mathrm{tr}\,A)B, so H=L⊗R/tr LH=L\otimes R/\mathrm{tr}\,L. Since practitioners tune the power anyway, the paper notes that squaring adds no new power to try; it changes which power to expect. For the Gauss-Newton reading they also find that averaging gradients over a batch is harmless with labels sampled from the model; with the real labels, as Shampoo uses, the approximation is still good at batch size 1 but degrades at larger batches, because real-label gradients do not average to zero.

Step 7 (Vyas et al., 2025)

In Shampoo's eigenbasis the square-root form is Adafactor, so SOAP runs Adam there instead. Take the idealized Shampoo with averages over the data, the square-root power and the trace factor, so entry (i,j)(i,j) of G~\tilde G is divided by λiμj/tr L\sqrt{\htmlData{gr=g14}{\lambda_i}\mu_j/\mathrm{tr}\,L}. Adafactor run on G~\tilde G estimates E[G~⊙G~]\mathbb E[\tilde G\odot\tilde G] by a c⊤/∑iaia\,c^\top/\sum_ia_i from its row sums aa and column sums cc, andai=∑jE[(qi⊤Gqˉj)2]=E∥qi⊤G∥2=qi⊤Lqi=λi,\begin{aligned}a_i&=\textstyle\sum_j\mathbb E[(q_i^\top G\bar q_j)^2]\\&=\mathbb E\|q_i^\top G\|^2=q_i^\top Lq_i=\lambda_i,\end{aligned}with qiq_i the ii-th column of QLQ_L and qˉj\bar q_j the jj-th column of QRQ_R; likewise cj=μjc_j=\htmlData{gr=g15}{\mu_j}, and ∑iai=tr L\sum_ia_i=\mathrm{tr}\,L. The two scales are the same. Shampoo can update its scale only when it recomputes QL,QRQ_L,Q_R, but the per-entry average is cheap, so SOAP keeps it as Adam does, with momentum SOAP's momentum, an exponential moving average of the gradient with rate β1\beta_1, kept in the original coordinates and rotated each step and second moment SOAP's per-entry second moment, an exponential moving average with rate β2\beta_2 of the squared rotated gradient G~⊙G~\tilde G\odot\tilde G updated every step:V←β2V+(1−β2) G~⊙G~,W←W−η QL(QL⊤MQRV+ϵ)QR⊤.\begin{aligned}V&\leftarrow\beta_2V+(1-\beta_2)\,\tilde G\odot\tilde G,\\W&\leftarrow W-\eta\,Q_L\Big(\frac{Q_L^\top MQ_R}{\sqrt V+\epsilon}\Big)Q_R^\top.\end{aligned}Here the exponential-moving-average rates of the momentum and of the second moment (and of LL and RR), as in Adam are Adam's rates, and LL and RR are themselves moving averages with rate β2\beta_2. The basis is refreshed every 10 steps in the main runs by one step of power iteration with a QR decomposition, started from the previous QL,QRQ_L,Q_R; one-dimensional parameters run plain Adam, and a very large dimension keeps the identity on its side. Grafting goes away, and the only hyperparameter beyond Adam's is how often to refresh the basis. Anil et al. (2020) had described essentially this algorithm for matrices in an appendix and reported no gain in unpublished experiments; Vyas et al. attribute the difference to implementation details. On 360M- and 660M-parameter language models with batches of 2 million tokens, SOAP needed at least 40% fewer steps and 35% less time than AdamW to reach AdamW's final loss, and about 20% less of both than the distributed Shampoo. As the refresh interval grew from 1 to 100 steps both beat AdamW throughout, they were close at 1, and SOAP lost quality much more slowly. At 256,000-token batches the gain fell to 25% fewer steps than AdamW and about 10% fewer than Shampoo. SOAP stores 2m2+2n2+3mn2m^2+2n^2+3mn numbers per matrix, as the distributed Shampoo does, against AdamW's 3mn3mn (both counts include the gradient). The times were measured on one GPU with gradient accumulation.

Step 8 (Eschenhagen et al., 2025)

Grafting corrects Shampoo's eigenvalues, and a correct, current scale removes the need for it. Without grafting and with roots recomputed every 100 steps, Shampoo trained worse than AdamW at every learning rate and ϵ\epsilon tried, for a vision transformer and a ConvNeXt V2 on Imagewoof, and many settings diverged. Any step of the form QL[G~ij/dij p]QR⊤Q_L[\tilde G_{ij}/d_{ij}^{\,p}]Q_R^\top, with orthogonal QL,QRQ_L,Q_R, per-entry scales dij>0d_{ij}>0 and a power p>0p>0, has Frobenius norm between (max⁡d)−p∥G∥F(\max d)^{-p}\|G\|_F and (min⁡d)−p∥G∥F(\min d)^{-p}\|G\|_F, so only the scale sets a step's length; the basis never does. For full-matrix Adam, diagonal Adam and the per-entry-corrected Shampoo, all with p=1/2p=1/2, the limits can be taken as λmax⁡(E[gg⊤])−p∥G∥F\lambda_{\max}(\mathbb E[gg^\top])^{-p}\|G\|_F and λmin⁡(E[gg⊤])−p∥G∥F\lambda_{\min}(\mathbb E[gg^\top])^{-p}\|G\|_F; for Shampoo, with independent gradient entries, they carry the extra factor (mn)−1/4(mn)^{-1/4} of the example in the mechanism above, and stale eigenvalues can push the step outside them. With roots recomputed every step, the trace-scaled square-root Shampoo matched or beat grafted Shampoo; with the basis recomputed every 100 steps and a per-entry scale updated every step, as in SOAP, the result matched or beat grafted Shampoo, and Adam's best learning rate carried over. On AlgoPerf workloads it needed 2,536 steps against 4,301 on FastMRI (10.4 against 14.0 minutes) and 8,320 against 12,574 on OGBG (means over the runs that reached the target), and about the same on ImageNet with a vision transformer. For the basis they propose recomputing a factor only when the rotated factor Λ^=Q^⊤LQ^\hat\Lambda=\hat Q^\top L\hat Q, with Q^\hat Q the last computed eigenvectors, has drifted from diagonal; while ∥Λ^−diag(Λ^)∥F≤\|\hat\Lambda-\mathrm{diag}(\hat\Lambda)\|_F\le the tolerance of the adaptive rule: a factor's eigenbasis is recomputed only when the off-diagonal part of the rotated factor exceeds this fraction of its Frobenius norm∥Λ^∥F\|\hat\Lambda\|_F, the old basis is kept. On the Imagewoof vision transformer, recomputing every 100 steps took 20% more time than this rule checked every 50 steps with τ=0.1\tau=0.1. On the same vision transformer, an accurate basis mattered mostly early in training: a basis computed at the first step and never updated still beat AdamW (final training loss about 0.12 against 0.3), and the whole gap to AdamW came from the bases of two-dimensional parameters, so vectors can be left to Adam.

Terms

Shampoo
W←W−ηL−1/4GR−1/4W\leftarrow W-\eta L^{-1/4}GR^{-1/4} with L,RL,R running sums of GG⊤GG^\top, G⊤GG^\top G; full-matrix AdaGrad with H1/2≈L1/4⊗R1/4H^{1/2}\approx L^{1/4}\otimes R^{1/4}
Rotate, rescale, rotate back
L−1/4GR−1/4=QL[G~ij/(λiμj)1/4]QR⊤L^{-1/4}GR^{-1/4}=Q_L[\tilde G_{ij}/(\lambda_i\mu_j)^{1/4}]Q_R^\top with G~=QL⊤GQR\tilde G=Q_L^\top GQ_R
Kronecker bound
rank ≤r\le r gradients: ϵI+1r∑gg⊤⪯L1/2⊗R1/2\epsilon I+\frac1r\sum gg^\top\preceq L^{1/2}\otimes R^{1/2}; gives O(T)O(\sqrt T) regret
Regret bound
2r D tr(LT1/4) tr(RT1/4)\sqrt{2r}\,D\,\mathrm{tr}(L_T^{1/4})\,\mathrm{tr}(R_T^{1/4}) for convex losses
Shampoo squared
E[GG⊤]⊗E[G⊤G]\mathbb E[GG^\top]\otimes\mathbb E[G^\top G] is one power-iteration step toward the best Kronecker approximation of E[gg⊤]\mathbb E[gg^\top]; exact up to tr L\mathrm{tr}\,L when that is a Kronecker product
Square-root power
tr L L−1/2GR−1/2\sqrt{\mathrm{tr}\,L}\,L^{-1/2}GR^{-1/2}: AdaGrad's step under the Kronecker approximation; a power practitioners found by tuning
Grafting
rescale each layer's Shampoo step to the Frobenius norm of Adam's (or SGD's) step; compensates for mis-scaled, stale eigenvalues
SOAP
Adam run on the gradient rotated into Shampoo's eigenbasis; basis refreshed every 10 steps, scale every step; no grafting
Shampoo and Adafactor
in Shampoo's eigenbasis the trace-scaled square-root step is Adafactor, whose row and column sums are the eigenvalues of L and R
Accumulation-free Shampoo
(GG⊤)−1/4G(G⊤G)−1/4=UV⊤(GG^\top)^{-1/4}G(G^\top G)^{-1/4}=UV^\top with ϵ=0\epsilon=0, Muon's map without momentum; with power −1/2-1/2 it is US−1V⊤US^{-1}V^\top
Distributed Shampoo
factors split across GPUs, directions gathered with one AllGather; at most about 10% slower per step than Adam; AlgoPerf external-tuning winner

Quiz

  1. Gradient entries of a layer are independent with variance s2s^2. Why can one learning rate not give Shampoo (fourth roots, no grafting) Adam-sized steps on both a 64×6464\times64 and a 1024×40961024\times4096 layer?
  2. Removing the sums from Shampoo, so L=GG⊤L=GG^\top and R=G⊤GR=G^\top G for G=USV⊤G=USV^\top, gives Muon's UV⊤UV^\top with the original power −1/4-1/4 and ϵ=0\epsilon=0. What does the square-root power give instead?
  3. On the speedrun's comparison at about 2.7 billion tokens, SOAP matched Muon's loss per token. Why did Muon still reach the target first?

Sources