In this article
Before you start
This page belongs to the deep learning path and uses ideas from probability and statistics.
Why interviewers ask this
A model whose loss turns into garbage after a few epochs can waste a training run, and a naive softmax is a known cause. The DeepStability study (2022) reports that weights, biases and loss all became NaN after a couple of training epochs with a numerically unstable softmax in the last layer. NaN (not a number) is the floating-point value that marks an undefined result, such as infinity divided by infinity.
The question tests whether a candidate sees that correct math can still fail on a real machine. A weak answer says "to avoid big numbers" and stops. A strong answer names overflow and underflow, shows why subtracting the max leaves the result unchanged, and says what goes wrong with the log. A Staff-level answer adds that the fix is stable but not exact, and that the loss should be computed from logits.
Softmax stabilization from first principles
- Numerical stabilization
- Numerical stabilization is a rewrite of a formula that gives the same answer in exact arithmetic but keeps every intermediate value inside the range a floating-point format can hold, so the computation does not produce infinity or NaN.
- Underflow
- Underflow is the error that occurs when a result is closer to zero than the smallest number a floating-point format can store, so the computer rounds it to exactly zero.
In plain words
Picture a scoreboard with a counter that stops at a fixed maximum. If a score is too big for the counter, it shows "error". Softmax turns scores into shares of a total. You can write each score as its gap behind the leader, so the numbers stay small.
The analogy breaks in one place. Ordinary shares change when you subtract a constant from every score. Softmax shares do not, because exp turns subtraction into a common divisor that cancels.
In one precise sentence: softmax computes exp of each score divided by the sum of those exps, and stabilization rewrites it so no intermediate value leaves the range the number format can hold.
A logit is the raw output score of a network before softmax is applied.
Step 1: Naive softmax overflows and underflows
Naive softmax fails because exp of a large score exceeds the largest number the format holds, and exp of a very negative score rounds to zero. In 32-bit floating point (FP32) the largest finite value is about 3.4028e38, so exp(88) fits and exp(89) becomes infinity.1 The lecture slides of Goodfellow (2017) give the same threshold. For scores [10, 100, 1000], exp(10) is 22,026.5, while exp(100) and exp(1000) overflow, so the sum is infinity and the outputs are 0, NaN, NaN.1
The low end fails too. For scores [-1000, -10000, -1000000] every exp rounds to zero, the sum is zero, and the division is zero over zero, which is NaN.1 Equal scores [1000, 1000, 1000] should give one third each, but the naive version returns NaN (Goodfellow et al., 2016, constant-input case).1
Input: scores. Output: NaN, though the true answer is fine. You now know the failure happens at both ends of the range.
Why half precision breaks sooner
The 16-bit half-precision format (FP16) overflows exp at a much smaller score than FP32 does, while brain floating point 16 (BF16) keeps the FP32 range.
Text description of the diagram
- The largest exp argument that fits is 11.09 in FP16.
- The largest exp argument that fits is 88.72 in BF16 and 88.72 in FP32.
The largest exp argument that fits is 11.09 in FP16, 88.72 in BF16 and 88.72 in FP32.1 A score of 12 is therefore harmless in FP32 and fatal in FP16.
Step 2: Subtract the max, and the result does not change
Softmax is shift-invariant, meaning adding the same constant to every score leaves the output unchanged. Choosing the constant as minus the largest score makes every exponent at most zero:
With c set to the maximum, every numerator is at most one, and the largest term is exactly one. The denominator then lies between one and the number of classes, so overflow cannot happen (Zhang et al., section 4.5). A practical softmax relies on this shift (2025 error analysis).
Check on scores [2, 1, 0] (illustrative): the shifted scores are [0, -1, -2], the denominator is 1.5032, and the outputs are 0.6652, 0.2447 and 0.0900, identical to the unshifted result.1 The failing cases now work: [10, 100, 1000] gives [0, 0, 1], [1000, 1000, 1000] gives one third each, and the very negative scores give [1, 0, 0].1
Input: scores minus their max. Output: valid probabilities. You now know the probabilities are safe; the logarithm is not yet.
Step 3: Compute the log from the logits, not from the probabilities
Cross-entropy needs the log of the softmax, and taking a log of a stabilized softmax output can still hit log(0), because a tiny probability may round to zero. Zhang et al. note that trouble when computing log of a zero; the cure is to combine the two steps. With m as the maximum score:
The sum inside the log is at least one, so the log is always finite. This is log-sum-exp, and the lecture slides advise computing the loss from the logits, using a fused cross-entropy function.
Take logits [1000, 0]. Naive log of softmax gives NaN for class one and minus infinity for class two. The stable formula gives 0 and -1000, both finite.1
Input: logits. Output: log-probabilities that never hit log(0). That is the follow-up trap: a stable softmax is not enough if the loss takes a log of its output.
Step-by-step description
- Large scores overflow, very negative ones underflow.
- Every exponent is at most zero.
- The log is computed from the logits.
- Naive softmax gives infinity or zero, then NaN.
- Subtracting the max makes every exponent at most zero.
- Log-sum-exp computes the log from the logits.
Naive softmax gives infinity or zero, then NaN. Subtracting the max makes every exponent at most zero. Log-sum-exp computes the log from the logits.
Knowing it is half the job. Saying it is the other half.
Interview Clozo is an AI interview copilot for real interview rounds: it hears the question and puts a strong answer on your screen, and you say it in your own words. See the features or how it works.
Start Free Trial →The Staff-level answer
Why does softmax need numerical stabilization?
Softmax divides the exponential of each score by the sum of all the exponentials. In floating point that breaks at both ends: a large score overflows to infinity, a very negative one underflows to zero, and infinity over infinity or zero over zero is not a number. Softmax is shift-invariant, so I subtract the maximum score first. Every exponent is then at most zero and the denominator lies between one and the class count. For the loss I never take a log of the probabilities; I compute log-sum-exp from the logits, as a fused cross-entropy does. It is stable, not exact: tiny terms can still flush to zero.
What makes it Staff-level: it names both failure directions, justifies the fix with shift invariance, protects the log, and states the limit of the fix.
The rubric
| Dimension | Weak answer | Strong answer | Staff answer |
|---|---|---|---|
| Correctness | "Numbers get too big." | Exp overflows to infinity, giving infinity over infinity. | Names overflow, underflow and the zero denominator. |
| Depth | Says "subtract the max" with no reason. | Explains shift invariance and that the output is unchanged. | Shows the denominator lies in one to n, every exponent at most zero. |
| Trade-offs | Claims the fix is perfect. | Notes tiny terms can underflow harmlessly. | Adds that the shift prevents overflow but can raise sensitivity to rounding up to fourfold. |
| Communication | Jargon without a number. | Gives one concrete failing input. | Walks one input before and after, in under a minute. |
| Follow-up readiness | Stuck on "what about the log?" | Mentions log-softmax. | Explains log-sum-exp and why losses take logits. |
Three variants of this question
Why do we subtract the max in softmax?
Subtracting the max keeps every exponent at most zero, so exp cannot overflow, and the largest term is exactly one, so the denominator cannot be zero. Shift invariance ensures the probabilities are unchanged.
Why do loss functions take logits instead of probabilities?
A loss computed from logits can use log-sum-exp, which never evaluates log(0). Starting from probabilities, a tiny value that rounded to zero already lost the information (Goodfellow, 2017).
What goes wrong with softmax in half precision?
FP16 overflows exp near an argument of 11, against about 89 in FP32, so moderate logits can already break a naive softmax.1 The max shift matters even more there; see FP16 vs BF16 for the formats.
Common mistakes
- "Subtracting the max changes the probabilities." (wrong) It does not; the shift cancels in the ratio. (right) "Softmax is shift-invariant, so the output is mathematically identical."
- "Only huge scores are a problem." (wrong) Very negative scores underflow to zero, so the denominator is zero and the result is NaN. (right) "Both ends break, and the shift fixes both."
- "I'll take the log of the softmax output." (wrong) A tiny probability may be zero and log(0) is minus infinity. (right) "I compute log-softmax from logits with log-sum-exp."
- "I'll add a small epsilon." (wrong) An epsilon added to a denominator does not stop exp from overflowing. (right) "I shift by the max before exp."
- "After the shift, softmax is exact." (wrong) Tiny terms can still flush to zero (Zhang et al.), and the shift, while preventing overflow, can at most quadruple the sensitivity to rounding perturbations (2025 error analysis). (right) "It is stable, not exact: small terms can round to zero, and the shift trades a little sensitivity for no overflow."
Follow-up questions
Does subtracting the max change the output?
No. The factor exp(-c) appears in the numerator and in the denominator and cancels, so the probabilities are mathematically identical.
What happens if all the scores are equal and large?
The true answer is one over n for each class. Naive softmax overflows to infinity over infinity, but after the shift every exponent is exp(0) = 1 and the result is exactly one over n.1
Is log-softmax the same as the log of softmax?
Mathematically yes, numerically no. Log-softmax is computed with log-sum-exp from the logits and stays finite, while the log of a softmax output can be log(0).
Is a NaN loss always an exploding gradient?
No. An unstable softmax or log can produce NaN with small gradients, so check the forward pass first; exploding gradients are a separate cause. More practice questions are in deep learning interview questions.
- Naive softmax overflows on large scores and underflows on very negative ones, giving NaN either way.
- Subtracting the maximum score leaves the probabilities unchanged and keeps the denominator between one and n.
- Compute the loss from logits with log-sum-exp, never from a log of the probabilities.
- FP16 overflows exp near an argument of 11, so the shift matters even more there.
- The shifted softmax is stable, not exact: tiny terms can still round to zero.
Sources
- Dive into Deep Learning, section 4.5: Concise Implementation of Softmax Regression, Softmax Revisited (arXiv 2106.11342, v1 read) — arXiv (Zhang, Lipton, Li, Smola), 21 Jun 2021
- Deep Learning, chapter 4: Numerical Computation — MIT Press (Goodfellow, Bengio, Courville), 18 Nov 2016
- Lecture slides for Deep Learning chapter 4: Numerical Computation — deeplearningbook.org (Goodfellow), 1 Jan 2017
- DeepStability: A Study of Unstable Numerical Methods and Their Solutions in Deep Learning (arXiv 2202.03493) — arXiv / ICSE 2022, 7 Feb 2022
- Numerical Error Analysis of Large Language Models (arXiv 2503.10251) — arXiv (Budzinskiy et al.), 13 Mar 2025