Chapter 2: Math foundations
Build the linear algebra, probability, and calculus intuition AI Infra needs: the math behind GEMM tiling, Softmax, backpropagation, and mixed-precision training
AI Infra does not ask you to derive hard theorems every day. It does ask that, when you see a formula, you can answer three engineering questions right away: what shape the tensors have, how much compute and memory they need, and how to implement them stably.
This chapter builds that intuition around those three questions. We start from vectors and matrices and connect them to GEMM and tiling; from probability distributions to Softmax, cross-entropy, and sampling; from the chain rule to backpropagation; and finally floating-point numbers, error, and mixed precision. The goal is not to prove every result. It is to get to the point where you can read a formula, push dimensions through it, estimate the order of magnitude, and judge numerical risk.
📑 Contents
- 1. Learning goals, notation, and three questions
- 2. Linear algebra: tensors, transforms, and decompositions
- 3. Block matrices and GEMM engineering intuition
- 4. Probability: from random variables to model distributions
- 5. Softmax, cross-entropy, and KL divergence
- 6. Calculus and backpropagation
- 7. Optimization, gradient stability, and normalization
- 8. Numerical computing and mixed precision
- 9. Worked AI Infra examples
- Summary
- Self-check list
- Exercises
- References
1. Learning goals, notation, and three questions
After this chapter you should be able to:
- Tell scalars, vectors, matrices, and higher-order tensors apart, and confidently derive shapes after each operation;
- Explain the intuition behind dot products, norms, matrix multiplication, rank, eigendecomposition, and SVD;
- Split a matrix multiply into blocks and see why GEMM tiling is mathematically equivalent;
- Compute expectation, variance, and covariance, and understand common distributions and conditional probability;
- Get a stable Softmax from logits, and understand temperature, cross-entropy, entropy, and KL divergence;
- Read a computation graph with the chain rule, and hand-derive gradients for a linear layer and Softmax cross-entropy;
- Explain how vanishing/exploding gradients, residual connections, and normalization affect training;
- Tell apart the precision and dynamic range of FP32, TF32, FP16, BF16, and FP8;
- Spot overflow, underflow, catastrophic cancellation, non-associativity, and other numerical risks;
- Estimate an operator’s parameter count, activation size, FLOPs, memory traffic, and arithmetic intensity.
1.1 Notation in this chapter
| Symbol | Meaning |
|---|---|
| Scalar, or a variable when the context is clear | |
| Vector | |
| Matrix or higher-order tensor | |
| Element at row , column of a matrix | |
| Set of real matrices with rows and columns | |
| Transpose | |
| Inverse (when it exists) | |
| L2 norm of a vector | |
| Expectation | |
| Variance | |
| Gradient of w.r.t. | |
| Partial derivative | |
| Element-wise multiplication |
Deep learning code usually uses batch-first notation:
- : batch size;
- : sequence length;
- : hidden size;
- : vocabulary size;
- : number of attention heads;
- : dimension per head.
1.2 Three questions to ask when you read a formula
Take a language-model output projection:
First: do the shapes match? The inner dimension is the same, so the output is .
Second: what does it cost? Each output element does multiply-adds, so the total is about:
Here one multiply and one add each count as one floating-point operation.
Third: what can go wrong in the implementation? The weights are large and the output logits are large. You have to think about dtype, memory layout, tiling, parallel strategy, and Softmax numerical stability.
Those three questions show up across the whole AI Infra stack.
2. Linear algebra: tensors, transforms, and decompositions
2.1 Scalars, vectors, matrices, and tensors
- A scalar is a single number, like a learning rate ;
- A vector is a 1-D ordered array, like a token’s hidden state ;
- A matrix is a 2-D array, like a linear-layer weight ;
- A tensor is a multi-dimensional array, like a batch of sequence hidden states .
In engineering, a “tensor” also carries information beyond its mathematical shape:
data address + shape + stride + dtype + device + layout
Two tensors with the same shape need not share the same memory layout. Equal values need not share the same dtype or error behavior.
2.2 Shape, indexing, and stride
Take a row-major matrix with shape :
Contiguous storage underneath is [1, 2, 3, 4, 5, 6], and the element-wise stride is . The linear offset of element is:
A transpose view has shape and stride , usually without copying data. Scanning along the last dimension after the transpose is no longer contiguous.
Whether reshape copies depends on whether the original layout can be expressed with the new shape/stride. When you see view, reshape, transpose, or contiguous, think about both logical dimensions and physical layout.
2.3 Element-wise ops and broadcasting
Element-wise addition needs corresponding elements to pair up:
Broadcasting lets some dimensions of length 1, or missing dimensions, expand logically. For example:
reuses the same bias across the batch and sequence dimensions, and the result shape is still .
Aligning from the trailing dimensions forward, each pair of dimensions must satisfy:
- Both sizes are equal; or
- At least one size is 1; or
- One side does not have that dimension.
Broadcasting is usually a logical view; it does not first materialize a full copy. Later kernel memory access and reduction patterns still feel the effect. The more dangerous case is a wrong shape that “happens to broadcast”: the code does not error, but the semantics are wrong.
2.4 Dot product: similarity and weighted sums
The dot product of two -dimensional vectors:
Two common intuitions:
Weighted sum: is the weights, is the values.
Directional similarity:
So cosine similarity is:
Attention uses the Query–Key dot product to measure how well they match. Embedding retrieval often uses a normalized dot product as an approximation to cosine similarity.
If a vector’s norm is near 0, the denominator is unstable. Implementations usually add a small .
2.5 Norms: length, error, and constraints
Common vector norms:
The Frobenius norm of a matrix treats every element as one long vector:
In practice norms are used to:
- Measure the scale of parameters, activations, or gradients;
- Clip gradients;
- Compare error between a reference and an optimized implementation;
- Regularize;
- Normalize vectors.
When comparing floating-point results, absolute and relative error each matter:
When the reference is near 0, relative error blows up, so test libraries usually combine absolute tolerance atol and relative tolerance rtol:
2.6 Matrix multiplication is a set of dot products
If:
then:
Each element is:
Treat shapes as an interface check:
(M, K) @ (K, N) -> (M, N)
The middle is reduced; the outer stay. Standard GEMM is often written:
Matrix multiplication generally does not commute: and may differ in shape or in values. It does associate:
Mathematical equality does not mean bit-identical floating-point results, or equal compute cost. Different association orders can change intermediate tensor sizes and FLOPs a lot.
2.7 Batched matrix multiplication
In multi-head Attention you often see:
After transposing the last two dimensions:
Batched matrix multiply:
The leading dimensions are batch dims; each (batch, head) runs its own matrix multiply. Higher-order tensor multiplication is usually just matrix multiplication on the last two dims, with the leading dims handling batching and broadcast.
2.8 Linear and affine transforms
A strict linear transform satisfies:
Matrix multiplication is linear. The “Linear” layer in a neural net usually also has a bias:
Mathematically that is an affine transform. Several linear/affine layers with no activation can be fused into one, so nonlinear activations are what let deep nets express complex functions.
2.9 Transpose, identity, and inverse
Transpose swaps rows and columns:
A useful identity:
The identity satisfies:
If a square matrix has an inverse:
To solve you can write , but numerical code usually does not form the inverse explicitly. It uses LU, QR, Cholesky, or similar factorizations and solves directly. Explicit inversion usually costs more and accumulates more error.
2.10 Linear dependence, span, and rank
If one vector in a set can be written as a linear combination of the others, they are linearly dependent. The rank of a matrix is the number of independent directions:
Low rank means the matrix has redundant information and can be approximated by two smaller matrices:
That drops parameter count from to , and it is the math behind low-rank adapters and model compression.
2.11 Eigenvalues and eigenvectors
For a square matrix , if a nonzero vector and scalar satisfy:
then is an eigenvector and is the matching eigenvalue. Intuitively, along that direction the transform only scales; it does not change direction.
Eigenvalues help you reason about:
- Whether a linear dynamical system amplifies or damps;
- Hessian curvature along different directions;
- Why gradients explode or vanish when many Jacobians multiply;
- Principal directions of change in a covariance matrix (PCA).
Not every matrix has a nice eigendecomposition over the reals. In practice pick an algorithm that fits the matrix structure; do not treat eig as a universal tool.
2.12 Singular value decomposition (SVD)
Any real matrix can be written:
where:
- Columns of are left singular vectors;
- Columns of are right singular vectors;
- The diagonal of holds singular values .
Keeping the top singular values:
is an optimal rank- approximation (in the usual 2-norm and Frobenius sense). Small singular values correspond to weak directions you can drop for compression.
SVD itself has compute and memory cost. Compressing large model weights usually uses truncation, randomized algorithms, or training low-rank factors directly, not a full SVD on every huge matrix.
2.13 LoRA’s low-rank update
For a pretrained weight , LoRA freezes and only trains a low-rank update:
where:
New parameters drop from a full update’s to:
For example , :
Low rank only cuts trainable parameters and the matching optimizer state. It does not automatically remove base-weight, activation, or forward-compute cost. At deploy time you can merge the weights, or keep adapters and switch them dynamically; the two choices trade off memory, latency, and flexibility differently.
3. Block matrices and GEMM engineering intuition
3.1 Why block computation works
Cut the matrices along , , and the reduction dimension . For a block example:
then:
Other blocks work the same way. Each output block accumulates several local products along . So a GPU kernel can:
- Take a small block of and a small block of ;
- Move them into on-chip shared memory / registers;
- Reuse that data to compute many output elements;
- Iterate along and accumulate;
- Write the output block back to HBM.
That is the mathematical basis of tiling. It changes compute order and data movement, not the target formula.
3.2 Compute and memory traffic for naive GEMM
For :
- Number of output elements: ;
- Each element does multiply-adds;
- FLOPs are about .
A naive implementation that loads and from global memory on every multiply-add re-reads the same elements many times. High-performance GEMM comes from reuse:
- One element of is reused across many columns of the same output row;
- One element of is reused across many rows of the same output column;
- Accumulators in registers reuse data times.
3.3 A simplified arithmetic-intensity estimate
Arithmetic intensity is:
Ideally an FP16 GEMM reads each input matrix from HBM once and writes the output once, so a rough byte count is:
Then:
In reality you also have cache, alignment, read-modify-write, temporaries, and fused ops. This estimate is not a precise performance model, but it helps you decide whether an operator is more likely compute-bound or bandwidth-bound.
3.4 Bigger tiles are not always better
Larger tiles improve data reuse, but they also consume more:
- Shared memory;
- Registers;
- Threads and synchronization per block;
- Boundary-handling cost.
Too much resource use lowers how many blocks/warps an SM can keep resident, which hurts latency hiding. Choosing a tile size trades off data reuse, occupancy, instruction efficiency, and shape fit.
3.5 Tail blocks and padding
When are not integer multiples of the tile size, the last block crosses the valid boundary. Common approaches:
- Add boundary checks / masks;
- Pad inputs to an aligned size;
- Keep a fast path for common aligned shapes and a generic path for the rest.
Padding adds compute and storage; branches add control overhead. Which is faster depends on shape and hardware.
3.6 Why floating-point tiled results can differ
Real addition associates, but floating-point addition does not strictly:
Different tiles, thread reduction trees, and Tensor Core paths change accumulation order, so optimized and reference results may not match bit for bit. Correctness checks should use error tolerances that fit the dtype and problem size, and watch whether error grows systematically with reduction length.
4. Probability: from random variables to model distributions
4.1 Random variables and probability distributions
A random variable maps random outcomes to numbers. Discrete random variables use a probability mass function:
Continuous random variables use a probability density function:
The probability of a continuous variable at a single point is usually 0; interval probabilities come from integrating the density. Distributions you see in models:
| Distribution | Values | Typical use |
|---|---|---|
| Bernoulli | Binary classification, Dropout masks | |
| Categorical | Next-token distribution | |
| Uniform | Interval / finite set | Initialization, random sampling |
| Gaussian | Reals | Initialization, noise, approximate analysis |
4.2 Joint, marginal, and conditional probability
Joint probability describes several events happening together:
Summing or integrating out the other variable gives the marginal:
Conditional probability:
Autoregressive language models factor sequence probability with the chain rule:
That is why next-token prediction at train time and token-by-token generation at inference are two processes of the same probability model.
4.3 Independence and conditional independence
If:
then are independent. Independence is stronger than “uncorrelated”; zero covariance does not imply independence.
Conditional independence given is written:
Distributed sampling, data parallelism, and statistical estimation often assume i.i.d. Real data can break that with duplicate samples, shard bias, or sequence correlation.
4.4 Bayes’ rule
Here is the prior, the likelihood, and the posterior. Ordinary LLM training does not hand-compute Bayes’ rule, but it is still the foundation of probabilistic inference, parameter estimation, and uncertainty modeling.
4.5 Expectation: a probability-weighted average
Discrete:
Continuous:
Expectation is linear; the variables need not be independent:
Training objectives are usually expected loss under the data distribution:
You cannot walk the true distribution, so you approximate with a mini-batch sample mean.
4.6 Variance and standard deviation
Variance measures spread around the mean:
Standard deviation has the same units as the original variable:
If are independent:
Gradient noise in training, initialization scale, normalization, and quantization error all connect to variance.
4.7 Covariance and correlation
Covariance measures how two variables move together:
Normalize to get the correlation coefficient:
For a vector random variable, the covariance matrix is:
It is symmetric positive semidefinite. PCA eigendecomposes the covariance matrix to find orthogonal directions of largest variance.
4.8 Sample mean, variance, and mini-batches
Given samples , the sample mean is:
A common unbiased sample variance is:
Whether a deep-learning operator’s “variance” divides by or depends on the definition. LayerNorm usually uses the population form (divide by the element count); stats libraries may default differently. When you reimplement an operator, check the API semantics; do not trust the name alone.
4.9 Maximum likelihood and negative log-likelihood
Given data , maximum likelihood picks parameters that make the observed data most probable:
Products underflow easily and are awkward to differentiate. Taking the log turns the product into a sum:
Equivalently, minimize the negative log-likelihood (NLL):
The logarithm is an important bridge between numerical computing and probabilistic modeling.
5. Softmax, cross-entropy, and KL divergence
5.1 Logits are not probabilities
The last layer of a model outputs arbitrary reals:
These values are called logits. They can be negative and need not sum to 1. Softmax turns them into a categorical distribution:
Clearly and .
Softmax is invariant to a uniform shift:
because numerator and denominator both multiply by . That property is exactly what the stable implementation relies on.
5.2 Numerically stable Softmax
Directly computing overflows finite-precision floats. Let:
The stable form is:
The largest exponent input is 0, so the largest exponential is 1; everything else is at most 1. Pseudocode:
def stable_softmax(x):
maximum = max(x)
exps = [exp(value - maximum) for value in x]
denominator = sum(exps)
return [value / denominator for value in exps]
Subtracting the max prevents overflow in the forward direction, but tiny terms can still underflow to 0. That usually means they are negligible relative to the max; if you still need a logarithm afterward, use a stable log_softmax directly instead of going through 0 and then log(0).
5.3 LogSumExp
Define:
Stable form:
Then:
Cross-entropy implementations usually fuse log_softmax + NLLLoss, which cuts intermediate tensors and memory traffic and avoids the unstable path of Softmax then log.
5.4 Temperature
Softmax with temperature :
- : amplifies logit differences, sharper distribution;
- : shrinks differences, flatter distribution;
- : approaches picking only the max logit;
- : approaches the uniform distribution.
Temperature changes the sampling distribution; it does not change model weights. Implementations should scale logits first, then apply stable Softmax, and be careful with very small temperatures.
5.5 Cross-entropy
Cross-entropy between a true distribution and a model distribution :
If the true label is one-hot with correct class :
then:
Higher probability on the correct class means lower loss. If , loss is 0; if is near 0, loss is large.
5.6 Information entropy
Entropy of a distribution itself:
Entropy measures uncertainty:
- When all mass sits on one class, entropy is minimal;
- With classes uniform, entropy is maximal: .
The log base sets the unit: natural log gives nats, base 2 gives bits. Machine-learning losses usually use the natural log.
5.7 KL divergence
KL divergence from distribution to :
It satisfies:
and is 0 when the two distributions match. It is usually not symmetric:
so KL divergence is not a distance in the strict sense.
Cross-entropy decomposes as:
During training the true distribution is fixed, so does not depend on model parameters, and minimizing cross-entropy is equivalent to minimizing the matching KL.
KL shows up in knowledge distillation, distribution matching, RLHF/PPO constraints, and speculative-decoding analysis. When you implement it, be clear whether the API takes probabilities, log probabilities, or logits, and which direction of KL it uses.
5.8 Perplexity
If the average token negative log-likelihood is , perplexity is:
Intuitively it is the model’s “effective number of candidates” at each step. Different tokenizers, preprocessing, context lengths, and whether special tokens are ignored all change PPL, so you cannot compare numbers across eval setups blindly.
5.9 Top-k and Top-p sampling
After the model outputs a distribution, the decoding strategy decides how to pick a token:
- Greedy: pick the highest-probability token;
- Top-k: sample only among the highest-probability tokens;
- Top-p (nucleus): take the smallest candidate set whose cumulative probability is at least , renormalize, then sample.
The Top-p set size changes with how sharp the distribution is. Implementations usually filter logits first, set excluded entries to negative infinity, then run stable Softmax and sample.
In distributed inference, if the vocabulary is sharded by tensor parallelism, global top-k/top-p needs cross-device aggregation of local candidates, or an equivalent distributed algorithm.
6. Calculus and backpropagation
6.1 Derivatives: local rate of change
Derivative of a univariate function:
Near , a small input change affects the output as:
Common derivatives:
6.2 Partial derivatives and gradients
For a multivariate scalar , the rate of change w.r.t. one variable is a partial. Stacking all partials gives the gradient:
The gradient points in the direction of steepest ascent, so gradient descent updates along the negative gradient:
is the learning rate.
6.3 Jacobian and Hessian
For a vector-valued function , the Jacobian is:
It describes each input component’s local effect on each output component.
The Hessian of a scalar function is the matrix of second partials:
The Hessian describes local curvature. Deep-learning parameter counts are too large to build a full Hessian explicitly, but Hessian-vector products, curvature approximations, and eigenvalue analysis still show up in optimization and stability work.
6.4 Chain rule
If:
then:
A multi-layer network is a composition. For:
gradients flow from the loss backward:
Conceptually that is a product of Jacobians. Real automatic differentiation does not materialize huge Jacobians; it efficiently computes vector-Jacobian products (reverse mode).
6.5 Computation graphs and reverse-mode autodiff
Let:
The forward pass saves needed intermediates. Reverse starts from:
then:
Because :
affects along two paths, so the gradients add:
That is why a tensor used in more than one place on the graph accumulates gradient.
6.6 Backprop through a linear layer
Using the batch-as-rows convention:
where:
Given upstream gradient:
then:
Shapes alone are a fast check on the formulas:
dX: (B, dout) @ (dout, din) -> (B, din)
dW: (din, B) @ (B, dout) -> (din, dout)
db: reduce over batch dim -> (dout,)
A linear layer’s backward pass usually has two GEMMs and one reduction, which is one reason training compute is much higher than a single forward pass.
6.7 Softmax Jacobian
Softmax:
Its partials:
In matrix form:
Every Softmax output depends on every input, so the Jacobian is not diagonal. The backward pass can still run in time without materializing a matrix.
6.8 The clean gradient of Softmax + cross-entropy
One-hot label , loss:
Differentiating jointly with Softmax yields:
This is one of the most important simplifications in deep learning. For the correct class the gradient is ; for other classes it is . The farther the prediction is off, the harder the push to correct the logits.
A fused cross-entropy kernel can share the max and reduction results, skip intermediate probability tensors, and emit the needed gradients directly.
6.9 Gradient checking
Automatic-differentiation implementations can spot-check with finite differences at small scale:
Central differences are usually more accurate than one-sided ones, but must not be too large or too small: too large brings truncation error; too small is drowned by floating-point rounding. Gradient checks fit small sizes, double precision, and deterministic functions. They are a poor fit for checking full training jobs with randomness or huge tensors.
7. Optimization, gradient stability, and normalization
7.1 Full-batch gradients, SGD, and mini-batches
Empirical risk:
A full-batch gradient uses every sample each step and is expensive. A mini-batch gradient:
is a stochastic estimate of the full gradient. Basic SGD update:
Larger batches often cut gradient-estimate variance and raise hardware utilization, but they need more activation memory, and optimizer hyperparameters may need matching adjustments.
7.2 Momentum
A common momentum form:
Momentum exponentially averages past gradients, damps short-term noise, and accelerates along directions that stay consistent.
7.3 Adam’s scale-adaptive intuition
Adam keeps exponential moving averages of first and second moments:
After bias correction:
Squaring and square roots are element-wise. Adam stores extra state per parameter; if that state is FP32, the memory cost is often a large share of large-model training, which is why techniques like ZeRO sharding exist.
7.4 Vanishing and exploding gradients
Gradients of a deep composition include many Jacobian products:
If those transforms stay below scale 1 along the relevant directions for long, gradients decay exponentially; if they stay above 1, gradients grow exponentially.
Engineering symptoms include:
- Gradient norms near 0, early layers barely updating;
- Sudden huge gradient norms, loss becoming
inf/nan; - Mixed precision triggering underflow or overflow earlier.
Mitigations include careful initialization, residual connections, normalization, gradient clipping, a sensible learning rate, and stable dtypes.
7.5 Why residual connections help gradient flow
A residual block:
has Jacobian:
The identity path gives a gradient route that does not fully depend on . It does not guarantee you never explode or vanish, but it improves the optimization landscape for deep nets a lot.
7.6 Initialization and variance propagation
Consider:
If are independent with mean 0:
To keep activation variance roughly stable across layers, set on the order of . Xavier and Kaiming initialization pick scales from fan-in, fan-out, and the activation.
Smaller is not always more stable: too small damps signals and gradients; too large saturates or explodes.
7.7 LayerNorm
For one token’s hidden vector :
LayerNorm reduces over the hidden dimension and does not depend on other samples in the batch, so it fits variable-length sequences and autoregressive models.
From a kernel view it at least involves a mean reduction, a variance reduction, and an element-wise transform. A naive implementation reads and writes HBM multiple times; an optimized one fuses the reductions with the affine transform and handles parallel reduction over long vectors.
7.8 RMSNorm
RMSNorm skips subtracting the mean and only scales by the root mean square:
It drops the mean-related work, but “fewer formulas” does not automatically translate into matching end-to-end speedups. Real gains depend on fusion, memory traffic, and the model’s overall bottleneck.
7.9 Gradient clipping
Global L2-norm clipping:
When the gradient norm exceeds threshold , the whole vector is scaled down while keeping direction. In distributed training, if gradients are sharded, computing the global norm needs an AllReduce of local squared sums across ranks:
So even a simple-looking math op can introduce collective communication.
8. Numerical computing and mixed precision
8.1 Floating-point numbers are a finite set
A typical binary float looks like:
Bits are split among sign, exponent, and significand (mantissa). Exponent bits set dynamic range; significand bits set how finely nearby representable numbers are spaced.
| Format | Total bits | Exponent bits | Significand field bits | Main traits |
|---|---|---|---|---|
| FP32 | 32 | 8 | 23 | Balanced range and precision |
| TF32 | 19 (multiply-input semantics) | 8 | 10 | Keeps FP32 range, lowers multiply precision, often accumulates in FP32 |
| FP16 | 16 | 5 | 10 | Decent precision, smaller dynamic range |
| BF16 | 16 | 8 | 7 | Near-FP32 dynamic range, less precision than FP16 |
| FP8 E4M3 | 8 | 4 | 3 | Precision-first, smaller range; exact encoding depends on the spec |
| FP8 E5M2 | 8 | 5 | 2 | Range-first, even less precision; exact encoding depends on the spec |
The table does not count the implicit leading bit in the significand field. TF32 is usually an NVIDIA Tensor Core compute mode, not a normal in-memory storage dtype.
8.2 Precision and dynamic range are different things
FP16 has a wider significand field than BF16, so at the same magnitude it can usually represent finer differences. But FP16 has fewer exponent bits: its largest finite value is only 65504, and the range of nonzero values is much narrower.
BF16 trades some precision for the same exponent-bit count as FP32, so training is usually less prone to overflow/underflow. It still has clear rounding error, especially when adding a tiny increment onto a large number.
8.3 Rounding and machine precision
Many decimal fractions cannot be represented exactly in binary floating point:
>>> 0.1 + 0.2 == 0.3
False
Spacing between floats grows with absolute magnitude. If is far smaller than the representable spacing near the current :
That is why optimizers often keep FP32 master weights: updates that are too small on low-precision weights can be rounded away entirely.
8.4 Non-associativity and reduction order
Because every step rounds:
Parallel reductions use tree-shaped addition; different thread counts, block partitions, and atomics can yield slightly different results. Nondeterminism is not automatically a bug, but the error must stay acceptable and match the task’s reproducibility needs.
Ways to improve reduction accuracy include:
- Accumulate in higher precision;
- Pairwise / tree summation to avoid adding extreme scales for long stretches;
- Compensated summation such as Kahan (extra instruction cost);
- Local reduce first, then merge partial sums.
8.5 Overflow, underflow, and non-finite values
- overflow: absolute value exceeds the largest finite value, often becoming ;
- underflow: result too close to 0, entering subnormals or rounding to 0;
NaN: e.g. , , or other illegal ops;infin later ops can quickly spread intoNaN.
When loss becomes NaN, find the first non-finite tensor; do not only stare at the final loss. Common sources include oversized logits, division by zero, square root of a negative, bad masks, gradient overflow, and wrong custom-kernel boundaries.
8.6 Catastrophic cancellation
Subtracting two nearly equal large numbers cancels leading significant digits, and the relative error of what remains can be huge. For example, computing variance with:
both terms can be large and close, so subtraction loses a lot of precision.
More stable options include two-pass variance or Welford’s online algorithm. The latter updates mean and squared deviation step by step:
Population variance is . Welford can also merge statistics from different chunks, which fits parallel reduction.
8.7 Condition number: how much input error is amplified
A problem’s condition number describes how a tiny input perturbation affects the output. For an invertible matrix, in a consistent norm:
A large condition number means an ill-conditioned problem: even with a correct algorithm and tiny rounding in the input, the output can change a lot.
Separate:
- whether the problem itself is ill-conditioned;
- whether the chosen algorithm is numerically stable.
More bits ease rounding error; they do not remove sensitivity that comes from ill-conditioning.
8.8 Basic patterns for mixed-precision training
Mixed precision is not “cast everything to FP16”. Common patterns:
- Large matrix multiplies use FP16/BF16 inputs and Tensor Core acceleration;
- Multiply-adds finish in FP32 or another specified higher accumulation precision;
- Sensitive ops such as reductions, normalization, and Softmax stay in or promote internally to FP32;
- Optimizer state and/or master weights stay FP32;
- Output dtype is chosen per hardware and operator.
Exact strategies differ by framework and hardware. Read the real operator docs and the profiler; do not guess the internal path from the input dtype alone.
8.9 Why loss scaling helps
Small FP16 gradients in the backward pass can underflow to 0. With scale factor :
then:
Gradients are first amplified into the FP16 representable range; after the backward pass they are divided by :
Dynamic loss scaling:
- Runs backward with the current scale;
- Checks whether gradients contain
inf/NaN; - On overflow, skips the update and shrinks the scale;
- After several stable steps, tries growing the scale.
Loss scaling mainly fights underflow of small gradients; too large a scale causes overflow instead. BF16’s larger dynamic range usually does not need loss scaling, but the model can still produce non-finite values from its own instability.
8.10 Stable algorithms often fuse better too
Numerical stability and performance optimization are not always in conflict:
- Stable Softmax does a max reduction first, then exp/sum; Online Softmax can merge block states;
- Fusing
log_softmax + NLLavoids writing intermediate probabilities; - Welford keeps statistics that fit LayerNorm’s block reductions;
- GEMM with low-precision inputs and high-precision accumulation balances throughput and error.
The key is choosing a mathematical form with composable state so kernels can process tiles in limited on-chip storage.
9. Worked AI Infra examples
9.1 Example 1: Transformer linear-layer shape and cost
Input:
Weight:
Flatten the first two dims:
Output:
then reshape to . FLOPs:
If :
That is only one forward linear projection, which shows why large models lean so hard on Tensor Core GEMM.
9.2 Example 2: Full multi-head Attention dimensions
From:
after producing Q/K/V, reshape and transpose:
with .
Score matrix:
Apply causal mask and Softmax:
where future positions are masked as so their Softmax probability is 0.
Output:
Merge heads and return to .
If you explicitly materialize FP16 , that alone needs:
When :
and that still ignores probabilities, backward intermediates, and other layers. FlashAttention’s key idea is not writing the full intermediate back to HBM, but finishing stable Softmax and accumulation in on-chip tiles.
9.3 Example 3: Why divide by
Assume independent, mean 0, variance 1:
Each has expectation about 0 and variance about 1, so the sum has variance about and standard deviation about .
After dividing by , score variance returns to about 1:
That keeps logits from over-expanding as dimension grows and Softmax from entering extreme saturation.
9.4 Example 4: Merging Online Softmax blocks
A row of logits is split into blocks. The processed part has max and exp-sum :
The new block’s state is . Merge the max:
Rescale to a common baseline and merge the exp-sums:
That lets Softmax run tiled, streaming, and numerically stable. If you also keep a weighted Value accumulator, you can avoid storing the full attention matrix—one of FlashAttention’s mathematical cores.
9.5 Example 5: LoRA parameters and compute
Full linear layer:
LoRA:
Shapes:
x: (..., din)
A^T: (din, r) -> (..., r)
B^T: (r, dout) -> (..., dout)
An online adapter adds two small GEMMs. If you merge into the base weight ahead of time, inference is still one large GEMM, but you lose cheap dynamic adapter switching.
9.6 Example 6: Why distributed means must be weighted
Two ranks have local sample counts and local means . The global mean is not simply unless . The correct value:
More generally each rank first aggregates local sum and count, AllReduces, then divides. Distributed loss, metrics, and throughput stats all need a clear denominator, especially with a trailing incomplete batch or differing sequence masks.
9.7 Example 7: Memory estimate
For a tensor of shape with bytes per element, contiguous storage size is:
For BF16 :
Peak training memory also includes parameters, gradients, optimizer state, saved activations, temporary workspace, communication buffers, fragmentation, and framework context. A single-tensor estimate is only the starting point.
9.8 A fixed checklist from formula to kernel
When you see a new operator, break it down in this order:
- What are the shapes of inputs, outputs, and intermediates?
- Which dimensions are kept, and which are reduced?
- Can it be tiled? How do tile states merge?
- What are the FLOPs and the theoretical minimum memory traffic?
- Are there broadcasts, transposes, or non-contiguous strides?
- Which ops are precision-sensitive and need high-precision accumulation?
- Can you hit exp overflow, division by zero, cancellation, or long-reduction error?
- Can intermediate tensors be fused away?
- How are boundary shapes and tail blocks handled?
- What reference implementation, dtype tolerances, and extreme inputs do you use to validate?
That checklist turns abstract math into an executable Infra workflow.
Summary
This chapter built four linked threads:
- Linear algebra describes how tensors transform: shape decides legality, rank and decompositions decide compression options, and blocking decides how data is reused;
- Probability describes what model outputs mean: logits become a distribution through Softmax, cross-entropy matches negative log-likelihood, and KL measures distribution difference;
- Calculus describes how parameters learn: the chain rule backpropagates along the computation graph, and a linear layer’s backward pass is still GEMMs plus a reduction;
- Numerical computing decides whether a formula is trustworthy on hardware: finite precision rounds, overflows, and underflows, so stable formulas and mixed-precision strategy matter as much as the algebra.
For an AI Infra engineer, “knowing the math” ends up meaning: you can turn a formula into shapes, reductions, tiles, data movement, precision choices, and validation criteria.
Self-check list
- Seeing
(B, S, H) @ (H, V)you can write the output shape immediately - You can tell element-wise multiply, dot product, matrix multiply, and batched matmul apart
- From shape/stride you can tell whether a transpose view is contiguous
- You can explain the intuition of norms, rank, eigenvalues, and singular values
- You can compute parameter savings for low-rank factorization and LoRA
- You can explain GEMM tiling correctness from block matrix multiplication
- You can estimate GEMM FLOPs, minimum memory traffic, and arithmetic intensity
- You can compute expectation, variance, covariance, and conditional probability
- You can write stable Softmax and LogSumExp
- You can state how cross-entropy, entropy, and KL relate
- You can derive gradients on a small computation graph with the chain rule
- You can write the gradient shapes of a linear layer w.r.t. input, weight, and bias
- You know Softmax + cross-entropy’s gradient w.r.t. logits is
p - y - You can explain why residual connections improve gradient pathways
- You can distinguish precision, dynamic range, overflow, and underflow
- You can explain why FP16 often needs Loss Scaling while BF16 usually does not
- You can explain why parallel reductions may not be bit-identical
- From Attention shapes you can derive intermediates and their memory cost
Exercises
- Derive the output shape of
(B, Nh, Sq, Dh) @ (B, Nh, Dh, Sk), and mark the batch dims and reduction dims. - For an FP16 GEMM with , estimate FLOPs and the ideal minimum input/output byte count.
- Write a program that verifies , and compare naive vs stable Softmax on large logits.
- Starting from the Softmax Jacobian and cross-entropy, hand-derive .
- Derive the backward shapes for
Y = GELU(XW + b); you do not need to expand GELU’s exact derivative. - Compare FP16, BF16, and FP32 error when summing the sequence
[1, 1e-3, 1e-3, ...], and try changing the summation order. - Implement Welford variance and compare it with
E[x²] - E[x]²on data with a large mean and small variance. - For a weight, compute parameter ratios and extra forward FLOPs for rank-8, 16, and 64 LoRA.
- Compute the size of an explicit FP16 Attention score matrix when .
- Two ranks process 7 and 5 valid tokens with local mean losses 2.0 and 3.0; compute the correct global mean and explain why a simple average is wrong.
- Finite-difference-check a small handwritten linear-layer backward; try different and look at the error curve.
- Pick a PyTorch operator and write a one-page analysis covering shape, reduction, FLOPs, memory traffic, numerical risk, and validation method.
References
- Deep Learning Book:Linear Algebra
- Deep Learning Book:Probability and Information Theory
- Deep Learning Book:Numerical Computation
- Matrix Calculus for Deep Learning
- Automatic Differentiation in Machine Learning: a Survey
- LoRA: Low-Rank Adaptation of Large Language Models
- Attention Is All You Need
- FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness
- NVIDIA Mixed Precision Training
- NVIDIA TensorFloat-32
- PyTorch Numerical Accuracy
- PyTorch Broadcasting Semantics