AdamC
Why gradient norms climb at the end of training, and the one-line change to weight decay that stops it.
In long language model runs, people log the size of the gradient as a health check. Near the end of training that number often turns around and climbs. In the run that motivated AdamC it more than doubled. This is strange, because the learning rate is shrinking toward zero at that point and the loss looks fine.
The explanation turns out to be bookkeeping, not instability. Three ordinary ingredients interact. They are normalization layers, weight decay, and a learning rate schedule. AdamW ties the strength of weight decay to the learning rate in a way that makes the weights shrink as the schedule decays, and shrinking weights make gradients look bigger.
AdamC is the fix proposed by Aaron Defazio in a 2025 arXiv note. It multiplies the weight decay coefficient by the same factor as the learning rate schedule. The rest of this page builds up exactly why that works, starting from things you already know.
Roadmap
- AdamW in one line, and where weight decay meets the learning rate.
- A normalized layer cannot see the length of its weights.
- Two consequences for the gradient. It is perpendicular to the weights, and it scales like one over their length.
- Perpendicular steps always make the weights longer.
- Weight decay pulls back, and the two forces settle at an equilibrium.
- A learning rate schedule moves that equilibrium. This is the rising gradient norm.
- The same story for Adam, where it is stronger.
- The fix. Scale weight decay with the schedule.
- A lab where you run AdamW and AdamC side by side.
- What you actually buy. The schedule means what it says.
Notation
| Symbol | Meaning |
|---|---|
| The weights of one layer at step , flattened into a vector with entries. Blue everywhere on this page. | |
| The minibatch gradient of the loss with respect to . Crimson. | |
| , | Learning rate at step , and its peak value over the whole schedule. Amber. |
| Weight decay coefficient. Teal. | |
| Euclidean length of a vector. is the dot product. | |
| Adam's normalized update direction (introduced in Step 1). |
I follow the usual AdamW write-up and use for the learning rate and for weight decay. Defazio's paper writes for the learning rate and for the weights. Same objects, different letters.
AdamW, and where weight decay meets the learning rate
You already know Adam. It keeps a running average of the gradient and of the squared gradient , and it steps along their ratio. Call that ratio the update direction.
Here and are the bias-corrected averages and is a tiny constant that avoids division by zero. AdamW then does two things to the weights in each step. It moves along , and it shrinks the weights slightly toward zero.
Look at the last term. The shrink per step is , the product of learning rate and weight decay. This is how the AdamW paper writes it and how torch.optim.AdamW implements it.
A typical recipe for a small language model uses peak and . At the peak, each step multiplies the decayed weights by . Late in the schedule, when , each step multiplies them by . So the schedule turns down weight decay along with the learning rate, by the same factor.
That sounds harmless, even sensible. The next few steps show that "the same factor" is the wrong amount.
A normalized layer cannot see the length of its weights
A normalization layer such as RMSNorm or LayerNorm rescales its input vector to a fixed size. Suppose a weight matrix produces , and the very next operation normalizes . If you double every entry of , then doubles, and the normalization divides the doubling right back out.
Take . Its length is , so dividing by the length gives . Now double the weights so that . Its length is , and dividing gives again. Everything downstream sees the identical vector, so the loss is identical.
This property has a name. A loss is scale invariant in if stretching by any positive factor leaves the loss unchanged.
Geometrically, the loss depends only on the direction of . Picture rays coming out of the origin. The loss is constant along each ray and only changes when you rotate from one ray to another.
A caveat to carry with you. This is exact when a linear layer is immediately followed by normalization, as in a ResNet with BatchNorm. In a pre-norm transformer the matrices feed a residual stream that is normalized later, so the property holds only approximately. The paper handles this with a heuristic that I describe in Step 8.
Two consequences for the gradient
If moving along a ray never changes the loss, then the gradient has no reason to point along the ray. It must point sideways. And if you are far from the origin, you have to travel further sideways to rotate by the same angle, so the loss changes more slowly per unit of distance. Both facts drop out of one line of calculus.
Consequence A. The gradient is perpendicular to the weights.
Start from scale invariance and differentiate both sides with respect to the stretch factor .
Consequence B. Longer weights mean smaller gradients.
This time differentiate both sides of with respect to , holding fixed.
Double the weights and the gradient halves. So the product stays the same along a ray. I will call that product . It measures how steep the loss is in direction space, with the arbitrary length of divided out.
Use the toy loss , which only depends on direction. At its gradient is .
Check A. .
Check B. . At the doubled point the gradient is with length , exactly half. The product is both times.
Perpendicular steps always make the weights longer
Take one plain gradient step with no weight decay. You stand at and move at a right angle to it. By Pythagoras, the new point is further from the origin than the old one. It does not matter which sideways direction you chose.
From with , take a deliberately huge step so the numbers are visible. The new point is . Its squared length is . The formula predicts . The length grew from to .
So without any opposing force the weights of a normalized layer grow forever. That growth is not free. By Consequence B a longer means a smaller gradient, and the same step now rotates by a smaller angle. Van Laarhoven (2017) calls the effective step size, and here it decays in a way nobody asked for.
Weight decay pulls back, and the two settle at an equilibrium
Weight decay is the opposing force. Each step it multiplies the weights by a number slightly below one. Now there is a tug of war. Gradient steps push the length up, and decay pulls it down.
The new idea in this step is equilibrium, also called a steady state. Think of a bathtub with the tap running and the drain open. The drain lets out more water when the tub is fuller. So the level rises until outflow matches inflow, and then it stays there. If you start too full, it drains down to that same level. An equilibrium is a value that the process keeps returning to because the two opposing effects cancel exactly there.
Our tug of war has the same shape. Decay removes more length when the weights are long. Gradient steps add more length when the weights are short, because short weights have large gradients. So there is one length where the two cancel. To keep the algebra clean I use plain SGD with weight decay first and return to Adam in Step 7.
Derivation
At equilibrium the length stops changing, so set .
This is the central formula of the paper. At equilibrium the ratio of gradient length to weight length is pinned by the two hyperparameters and by nothing else. Since is a noisy minibatch gradient, read it as holding on average.
We can go one step further using Consequence B, . Substituting gives each length separately.
This second line needs an extra assumption, that stays roughly constant over time. That is reasonable in single-pass training where minibatch noise keeps the gradient from vanishing. It is the route taken by van Laarhoven in 2017. Defazio's main argument avoids it by only talking about the ratio.
Take , , . Then , so and . The ratio is , and the formula says .
Pause and predict.
The plot below starts the same recurrence from two lengths, one far too short and one far too long. Before you look, where do you expect each curve to end up? And if you double , does the final length go up or down, and by a lot or a little?
One more fact from this picture matters later. Reaching equilibrium takes time, on the order of steps. A smaller learning rate means a slower approach.
A schedule moves the equilibrium
Everything so far used a constant learning rate. Real runs use a schedule, usually warmup and then a decay toward zero. Put into the formula and the equilibrium becomes a moving target.
The learning rate sits in the denominator. As the schedule decays, the target ratio rises, and it rises without bound if the schedule goes all the way to zero.
With , a learning rate of gives a target of . A learning rate of gives . Ten times less learning rate, about times more ratio.
How does the ratio actually rise? From the two formulas at the end of Step 5, the weights shrink like and the gradient grows like . Mechanically, a lower learning rate makes the outward push collapse faster than the inward pull . Decay wins, the weights shrink, and by Consequence B shorter weights have bigger gradients.
That is the whole phenomenon. The gradient norm rises at the end of training because the schedule is dragging the equilibrium, and the weights are following it inward.
Pause and predict.
Suppose the learning rate has decayed to one sixteenth of its peak and the layer has kept up with its equilibrium. By what factor has the gradient norm grown under SGD with weight decay?
Reveal
The gradient scales like , and . So it has doubled. Step 7 shows that for AdamW the exponent is , which gives a factor of .
Two honest caveats. First, the equilibrium takes about steps to reach, and that time grows as the learning rate falls. So near the very end the layer cannot keep up, and the real ratio rises less than the target. Defazio's ResNet plot shows exactly this. The prediction tracks the measurement closely until the final stretch. Second, short runs may never reach equilibrium at all. The paper notes that a 10 billion token run was too short to show the uptick that a 200 billion token run showed clearly.
The same story for Adam, where it is stronger
Adam changes one thing in the argument. Its step does not get smaller when the gradient gets smaller. Adam divides the gradient by its own running size, so each entry of the update is roughly or . The paper calls this the sign-descent regime. With entries, no matter how long the weights are.
Rerun the tug of war with this constant-size push. I treat as uncorrelated with on average, which plays the role that exact perpendicularity played for SGD.
Under SGD the push weakened as the weights shrank, which softened the effect to a fourth root. Under Adam the push has fixed size, so the weights respond with a full square root. Then Consequence B gives the gradient.
Take , , . The predicted length is . The lab in Step 9 uses exactly these values and measures about . If the learning rate falls by , the predicted length halves to and the gradient norm doubles.
How this relates to the sources. The formula matches the AdamW equilibrium norm in Kosson, Messmer and Jaggi's rotational equilibrium paper. Defazio states his Adam result differently. He shows the ratio holds when both lengths are measured in norms reweighted by Adam's preconditioner, and then simplifies it to say the largest weight entry is about . That is the per-entry version of the formula above. He labels that simplification as non-rigorous, and the derivation ignores momentum. Adam's update is also not exactly perpendicular to the weights. So treat this step as a good approximation and not a theorem.
The fix
The target ratio is . It moves because the denominator moves and the numerator does not. So let the numerator move too. Replace the constant with a scheduled value that follows the learning rate.
Plug it into the target.
Written as an update rule, AdamC changes only the decay term, and only for normalized layers.
Compare with Step 1. The per-step shrink was . Now it is . When the schedule halves the learning rate, AdamW halves the shrink and AdamC quarters it.
Same values as Step 1, and . At the peak both methods shrink by per step. When , AdamW shrinks by and AdamC by . Ten times gentler, which is what it takes to stop the weights from collapsing inward.
Three design details
Why divide by the peak. Dividing by makes AdamC identical to AdamW at the peak learning rate. So keeps its old meaning and a value tuned for AdamW is a sensible starting point.
Why not make decay independent of the learning rate. You might guess the cure is to stop multiplying decay by at all. Redo Step 5 with a shrink of per step and you get a ratio of . That depends on the schedule even more strongly. The paper makes this point explicitly.
Which parameters. The argument only applies to scale invariant weights. Algorithm 1 in the paper applies the corrected decay to normalized layers and ordinary AdamW decay to everything else. For the transformer experiments the paper treats every linear layer as normalized except the output layer. That is a heuristic, since transformer layers are not literally followed by a norm.
In PyTorch you do not need a new optimizer class. AdamW already multiplies weight_decay by lr, so scheduling weight_decay with the same factor as the learning rate gives the AdamC update. This is my own sketch and not code from the paper.
# groups[0]: weight matrices treated as normalized
# groups[1]: output layer and anything else that gets plain AdamW decay
opt = torch.optim.AdamW(groups, lr=lr_max, weight_decay=wd)
for step in range(total_steps):
f = schedule(step) # lr_t / lr_max, between 0 and 1
for group in opt.param_groups:
group["lr"] = lr_max * f
opt.param_groups[0]["weight_decay"] = wd * f # the AdamC correction
...
opt.step()
Lab. Run both and watch
This lab trains a real, tiny, scale invariant problem in your browser. The weight vector has entries. The loss is half the squared distance between the normalized weights and a noisy target direction, so only the direction of matters. Each step draws fresh noise, like a new minibatch, so the gradient never dies out. Both optimizers see identical noise. The error panel reports of the angle between and the true direction, so zero means perfectly aligned.
Pause and predict.
With a cosine schedule, sketch in your head the weight length and gradient norm for AdamW and for AdamC. Which one keeps a flat weight length? Then guess which one rotates the weights more per step in the middle of training.
With the defaults you should see the uncorrected gradient norm more than double while the corrected one stays flat. The uncorrected weight length follows its dashed prediction inward. The error panel usually ends a little lower for the corrected run, though that gap moves around when you draw new noise.
What you actually buy. The schedule means what it says
A flat gradient norm plot is pleasant, but it is not the point. The point is in the "rotation per step" panel of the lab.
For a scale invariant layer, the only thing that changes the network's function is the direction of . So the honest measure of learning speed is how far the direction rotates per step. For a step of size taken sideways from a point at distance , the rotation angle is about their ratio.
Under AdamW, substitute and the equilibrium length from Step 7.
So under AdamW the rotation per step follows the square root of your schedule. If you ask the learning rate to fall by a factor of 100, the layer only slows down by a factor of 10. The shrinking weights quietly undo half of your schedule, in log terms.
Under AdamC the length is frozen at . Substitute that instead.
Now the rotation is proportional to . A hundredfold decay in the schedule is a hundredfold decay in learning speed.
Provenance. The AdamW expression appears in Kosson, Messmer and Jaggi's table of equilibrium quantities, with an extra factor for momentum that I have left out. The AdamC line is my own algebra using the same recipe. Defazio's note does not phrase its result in terms of rotation. It argues from the gradient to weight ratio and from the observed loss curves.
Is the square-root behaviour of AdamW actually bad? That is an empirical question and not something the derivation settles. One could tune a schedule under AdamW that already compensates for it. What AdamC offers is that the learning rate schedule you write down is the schedule the normalized layers experience.
What the evidence shows, and its limits
Defazio's experiments. The language model run is a 120 million parameter model with the Llama 3 architecture, trained on FineWeb-Edu for 200 billion tokens with a cosine schedule, a batch of 256 thousand tokens and weight decay 0.05. The learning rate was swept from 0.001 to 0.02 for both optimizers. AdamC largely removes the gradient norm increase in the second half of training, keeps the weight norm far more stable, and reaches lower loss. For ResNet-50 on ImageNet with SGD, the corrected version removes the sharp rise at the end, but a slower upward drift across the whole run remains and the theory does not explain it.
Limits. This is a short single-author arXiv note with two test problems. The transformer application relies on the heuristic from Step 8. The Adam analysis is approximate. The paper itself says that many standard benchmarks do not show the uptick at all, because they lack normalized layers, are too short, or overfit.
Follow-up work. Jason Chou's "Correction of Decoupled Weight Decay" (arXiv, December 2025) revisits the question. From its abstract, it agrees that the per-step decay should scale like to keep weight norms stable, but it disputes the perpendicularity argument as the reason. It derives the same scaling from a different assumption, that updates become independent of the weights at steady state. I have only verified that paper at the level of its abstract.
Summary of the whole chain
- AdamW shrinks weights by per step, so the schedule also schedules the decay.
- Normalization makes the loss blind to the length of the weights feeding it.
- That forces and .
- Perpendicular steps lengthen by Pythagoras.
- Decay shortens it. The two balance where .
- A decaying raises that target. Weights shrink and the gradient norm climbs.
- Under Adam the weights scale like , so the effect is stronger.
- Setting cancels the schedule out of the target.
- The result is a constant weight length, a flat gradient norm, and an effective learning rate that follows the schedule you wrote.
Common misconceptions
- "A rising gradient norm means training is going unstable." Not here. For normalized layers the gradient norm is . It can double purely because the weights halved, with the loss surface in direction space unchanged.
- "Decoupled weight decay means decay is independent of the learning rate." Decoupled means the decay is applied directly to the weights instead of being added to the gradient before Adam's normalization. In the standard implementation it is still multiplied by .
- "AdamC just turns weight decay off at the end." It reduces decay in proportion to the learning rate, which is exactly the amount needed to hold the equilibrium still. Removing decay entirely would let the weights grow.
- "The correction applies to every parameter." The argument only covers scale invariant weights. Other parameters keep ordinary AdamW decay.
- "A flat gradient norm is the goal." It is a symptom. The substantive change is in the effective learning rate of Step 10.
- "AdamC is a new optimizer." It is AdamW with a schedule on one hyperparameter for some parameter groups.
Blind spots worth knowing about
- Effective learning rate as the real knob. Zhang and coauthors' "Three Mechanisms of Weight Decay" argues that in normalized networks weight decay mainly works by controlling the effective learning rate, not by regularizing in the classical sense. This reframes as an optimization hyperparameter. It also explains why the best learning rate and the best weight decay tend to move together when you tune them.
- Rotational equilibrium. Kosson, Messmer and Jaggi develop the equilibrium picture for AdamW, SGD with momentum and Lion, per neuron and per layer. They also connect the transient phase before equilibrium to the need for learning rate warmup. That is the natural next paper to read.
- Equilibrium has a time scale. It takes on the order of steps to reach. With the Step 1 values that is about steps at the peak. A run of only ten thousand steps or so has time to approach equilibrium but not much to spare, so whether it shows the late uptick is worth checking in its gradient norm logs rather than assuming.
- Removing the degree of freedom entirely. If the weight length carries no information, you can project the weights back to a fixed length after every step. Then there is no equilibrium to manage. That is the idea behind the rotational optimizer variants of Kosson and coauthors. AdamC is the minimal fix and projection is the structural one.
- Adam's update is not exactly perpendicular. While building the lab I first used a target aligned with a single coordinate axis. Adam's per-coordinate rescaling then amplified a tiny radial gradient component, and the corrected run's weight length drifted upward instead of staying flat. A random target direction removed the artifact. The lesson is that the clean theory depends on Adam's preconditioner not singling out the radial direction.
- Gradient clipping lives in absolute units. Many language model recipes clip the global gradient norm at 1.0. If weight lengths drift, the same threshold bites more or less often over time. This is my own inference and not a claim from the paper.
- Which parameters are decayed at all. Most recipes already exclude embeddings, normalization parameters and biases from decay. So the decayed set is mostly the weight matrices, which is also where AdamC applies.
- Earlier work on the same symptom. Xie and coauthors (2023) documented gradient norms rising because of weight decay and proposed scheduling the decay. Defazio's contribution is a derivation that says exactly which schedule cancels the effect.
Sources and further reading
- Aaron Defazio, Why Gradients Rapidly Increase Near the End of Training, arXiv 2506.02285, June 2025. The AdamC paper.
- Twan van Laarhoven, L2 Regularization versus Batch and Weight Normalization, 2017. The original equilibrium argument.
- Guodong Zhang, Chaoqi Wang, Bowen Xu, Roger Grosse, Three Mechanisms of Weight Decay Regularization, ICLR 2019.
- Atli Kosson, Bettina Messmer, Martin Jaggi, Rotational Equilibrium: How Weight Decay Balances Learning Across Neural Networks, ICML 2024.
- Jason Chuan-Chih Chou, Correction of Decoupled Weight Decay, arXiv 2512.08217.
- Kaiyue Wen and coauthors, The Hitchhiker's Guide to the Weight Norm Theory. A longer blog post on how weight norms evolve under weight decay.
- Ilya Loshchilov, Frank Hutter, Decoupled Weight Decay Regularization, ICLR 2019. The AdamW paper.