← Blog/blog/softmax-target-gradient-cliff

The fixed softmax still needs something to stop the logits

Softmax turns logits—unbounded class scores—into probabilities. Cross-entropy then penalizes the negative log-probability of the target class. The standard max-shift implementation prevents exponential overflow, but Barron, Gnanapragasam, and Tschannen show that it still breaks a conservation law: once the winning logit is confident enough, its gradient becomes exactly zero while the losing gradients remain positive.

01

The one subtraction that disappears

Let the target logit exceed the log-sum-exp of all other logits by margin m. The target gradient is −exp(−m)/(1+exp(−m)). Standard code instead forms the target probability near one and subtracts one. In fp32, values smaller than roughly 10⁻⁷ cannot change 1.0, so that subtraction returns zero around m = 16.6.

true target-gradient magnitudestandard fp32 target gradient
Illustrative deterministic fp32 simulation from the pure TypeScript core. Values are log10 gradient magnitude; the plotted −40 floor marks an exact numerical zero. The standard target gradient collapses at the paper's fp32 cliff while the algebraically equivalent fixed form continues.
standard fp32 |sum gradient|fixed |sum gradient|
The same core-computed sweep exposes the invariant violation. Exact softmax gradients sum to zero because adding a constant to every logit changes no probability. Standard fp32 leaves a positive residual after the target entry vanishes; the fixed gradient remains zero-sum.

At the paper's three-class example [9, −9, −9], the standard fp32 target gradient is 0.0, but the two non-target entries are still 1.523e-8 each. The true loss is not zero; it is 3.046e-8.

def fixed_gradient(margin, non_targets):
    tail = exp(-margin)
    each = tail / (non_targets * (1.0 + tail))
    others = [each] * non_targets
    target = -sum(others)
    return [target] + others

The running TypeScript uses exactly this rearrangement. Python and C++ are faithful translations: compute the tiny tail first, then make the target gradient the negative sum of all non-target gradients. No higher-precision cast is required.

02

Why the bug becomes an optimizer event

Adam divides a moving average of the gradient by a moving scale plus epsilon. When collapsed gradients make that scale decay, a later non-zero gradient is divided by a tiny denominator and produces the sudden loss spike called Slingshot. Correct cross-entropy makes the gradient decay smoothly instead of switching off at a format boundary.

03

Epsilon becomes a margin scale

At a stationary AdamW point, the normalized scalar step is |g|/(|g|+epsilon). After memorization, |g| is proportional to exp(−m). With weight decay opposing the step, the balance occurs around m* ≈ log(1/epsilon). The learning rate and moment coefficients cancel from this stationary approximation.

epsilon 1e-6epsilon 1e-8epsilon 1e-10
Illustrative core-computed Adam normalization. Each curve bends when exp(−margin) becomes comparable to epsilon; smaller epsilon moves the bend rightward.
Core-computed m* = log(1/epsilon). This is an optimizer–regularizer equilibrium, not a floating-point cliff. Crucially, the derivation needs weight decay; without it nothing balances the normalized gradient.
04

The reported experiment separates the two boundaries

On modular addition, the fixed loss reaches the epsilon-predicted margin across bf16, fp32, and fp64. Standard cross-entropy stalls near each format's cliff. The table below reproduces selected means from the paper's five-seed Table 1.

PrecisionLossepsilonTest accuracyFinal margin
fp32fixed1e-8100.0%17.9
fp32standard1e-894.3%13.0
bf16fixed1e-8100.0%17.9
bf16standard1e-893.3%5.1
fp64fixed1e-8100.0%17.9
fp64standard1e-8100.0%17.9
fp32fixed1e-1699.0%36.8
fp32standard1e-1696.5%12.7
Paper-reported means. The 10⁻⁸ rows cover all three precisions; the 10⁻¹⁶ rows show fp32's higher intended equilibrium.
Paper-reported modular-addition test accuracy at epsilon 10⁻⁸. Fixed cross-entropy reaches 100% in every precision; standard bf16 and fp32 are lower and more variable.
Paper-reported final margins at epsilon 10⁻⁸. Fixed cross-entropy converges near the predicted 18.4; standard bf16 stops at its 5.5 precision cliff and standard fp32 remains below its intended equilibrium.
05

The second bug hides near the teacher

Knowledge distillation trains a student against a teacher's probability distribution. Computing both softmaxes separately and subtracting nearly equal probabilities loses significant digits. The paper instead works with the student–teacher logit difference using expm1 and log1p, then explicitly removes residual zero-sum drift. Starting student and teacher from identical weights, the corrected loss stays at zero KL and 100% accuracy across all tested precisions; standard bf16 drifts.

06

What to probe next

The paper is deliberately strongest in extreme regimes: very large margins and nearly identical teacher–student logits, which the authors note are uncommon in ordinary large-scale training. Next, benchmark wall-clock cost in fused GPU kernels, test label smoothing and huge vocabularies, and separate improvements caused by restored arithmetic from those caused by the changed long-run margin trajectory.

References

  1. Barron, J. T., Gnanapragasam, D., and Tschannen, M. (2026). A Fix for Softmax and Cross-Entropy. arXiv:2610.31642
  2. Kingma, D. P. and Ba, J. (2015). Adam: A Method for Stochastic Optimization. ICLR
  3. Hinton, G., Vinyals, O., and Dean, J. (2015). Distilling the Knowledge in a Neural Network. arXiv:1503.02531