A shape audit of the backward pass, with a batch
shape▲▲△Exact shapes; no arithmetic beyond integer dimensions.
STATEMENT
Tabulate the shape of every tensor in both directions through a batched MLP, and say where the batch dimension goes. One of the two gradients in (I.6.4) sums over the batch and the other does not; the shapes say which, before any calculus is done.
GIVEN
The network of I.5.B03 — widths , four affine layers, ReLU after the first three, no activation on the head — now run on a batch of examples, so the input is . The loss is a scalar: a mean over the batch.
FIND
For every layer : the shapes of , , and . Then the total activation memory kept for the backward pass, in fp32.
STRATEGY
Two rules settle every row. A gradient has the shape of the thing it differentiates, so parameter gradients cannot carry a batch dimension — the parameters do not have one. An adjoint has the shape of the value it belongs to, so activation adjoints must carry it. Where those two rules disagree, a sum appears, and that is the only place a sum can appear.
SOLUTION
Step 1 — forward shapes. The batch dimension is untouched by every layer:
| 1 | |||
| 2 | |||
| 3 | |||
| 4 |
Step 2 — adjoints. has the shape of , so it carries the batch: , , , .
Step 3 — the weight gradient absorbs the batch. Per example the gradient is the outer product of (I.6.4). Over a batch it is the sum of those outer products, which is a single matrix product:
with shapes . The 32 is contracted away — it is the inner dimension of the product. The summation over the batch is not an extra step anybody writes; it is what the matrix product already does.
| 1 | ||
| 2 | ||
| 3 | ||
| 4 |
Step 4 — the bias gradient needs an explicit sum. Per example , of shape . Over a batch there is no matrix product to hide the contraction in, so it is written out:
This is the asymmetry the Statement promised. Both gradients sum over the batch; the weight gradient’s sum is the inner dimension of a matrix product and the bias gradient’s is a reduction along an axis. Forgetting the second is a common implementation error and it is caught immediately by a shape check — where was required.
Step 5 — what must be kept. The backward pass consumes for (I.6.4) and for . For ReLU the mask suffices, but counting stored floats:
At 4 bytes each that is bytes, about MB.
Step 6 — compare with the parameters. I.5.B03 counted parameters, MB in fp32. At the activations are a tenth of the parameters. At they are floats, MB — three times the parameters. Activation memory is linear in the batch and parameter memory is constant in it, so which term dominates is a property of the batch size and not of the model.
Answer
Adjoints carry the batch: at every layer. Parameter gradients do not: is and is . The weight gradient’s batch sum is the inner dimension of ; the bias gradient’s is an explicit reduction over rows.
Stored activations at : floats, bytes, MB — against MB of parameters. At : MB, three times the parameters.
Check — sanity
No parameter gradient carries a batch dimension. It cannot: the parameter does not have one, and a gradient has the shape of what it differentiates. Any implementation returning a weight gradient has computed per-example gradients and not yet reduced them — sometimes deliberately, which is what per-sample gradient methods want, but never by accident.
Every adjoint does carry it. Different examples have different activations and therefore different adjoints, and they stay separate until a parameter is reached. The batch dimension survives exactly as far as the parameters and no further.
The two contractions are the same contraction. Both gradients sum terms; only the notation differs. Writing the bias as a row of ones times makes them identical in form, which is a good way to remember that the missing sum is missing rather than unnecessary.
Where this breaks
The audit counts the activations this architecture stores, and that count is a floor rather than an estimate. A real framework also holds the gradient buffer for every parameter, the optimiser state — two more copies for Adam — and workspace for the matrix products. It may also keep both and where one would do, since whether can be inverted from its output is a per-operation question the memory planner may not answer.
The larger omission is that the numbers here are for an MLP, where activations are . For a convolutional network they are and for a transformer the attention matrices are , quadratic in sequence length. The shape of the bill changes completely with the architecture even though the rule producing it — keep what the backward pass will read — does not.
Variation
Run the same audit with the batch dimension last, so activations are . Every shape transposes and every product reverses. Which of the two batch contractions is now the explicit one, and which is hidden inside a matrix product?