Gradient Accumulation › The Mathematical Foundation

Michael BrenndoerferJanuary 27, 20262 min read
Language AI HandbookAll chapters
Part 32 of 67Training Optimization
Chapter 236Gradient Accumulation › The Mathematical Foundation
Reading section 2 of 14 · The Mathematical Foundation · 2 minSection 2 of 14 · 2 min

Book contents

Section 2 of 14 · 2 min read

Gradient Accumulation › The Mathematical FoundationOne section · Sections in this chapter2 / 14 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

The insight behind gradient accumulation predates deep learning. It is a direct consequence of the linearity of differentiation: the gradient of a sum is the sum of the gradients, and the gradient of a mean is the mean of the gradients. This property means you can split a batch into any number of smaller chunks, compute gradients independently on each chunk, add the results together, and obtain the same answer as if you had processed the entire batch at once.

To see why this works, consider a dataset D\mathcal{D} and a model with parameters θ\theta. The standard training objective is to minimize the empirical loss over a batch BB:

L(θ;B)=1∣B∣∑i∈Bℓ(θ;xi,yi)\mathcal{L}(\theta; B) = \frac{1}{|B|} \sum_{i \in B} \ell(\theta; x_i, y_i)

where:

  • ℓ(θ;xi,yi)\ell(\theta; x_i, y_i): the per-sample loss for input xix_i and label yiy_i
  • ∣B∣|B|: the number of samples in the batch
  • θ\theta: the model parameters

The gradient of this loss is:

∇θL(θ;B)=1∣B∣∑i∈B∇θℓ(θ;xi,yi)\nabla_\theta \mathcal{L}(\theta; B) = \frac{1}{|B|} \sum_{i \in B} \nabla_\theta \ell(\theta; x_i, y_i)

Now suppose we partition BB into KK non-overlapping micro-batches B1,B2,…,BKB_1, B_2, \ldots, B_K of equal size m=∣B∣/Km = |B|/K. The gradient of the loss on micro-batch BkB_k is:

∇θL(θ;Bk)=1m∑i∈Bk∇θℓ(θ;xi,yi)\nabla_\theta \mathcal{L}(\theta; B_k) = \frac{1}{m} \sum_{i \in B_k} \nabla_\theta \ell(\theta; x_i, y_i)

If we compute the average of these per-micro-batch gradients:

1K∑k=1K∇θL(θ;Bk)=1K∑k=1K1m∑i∈Bk∇θℓ(θ;xi,yi)\frac{1}{K} \sum_{k=1}^{K} \nabla_\theta \mathcal{L}(\theta; B_k) = \frac{1}{K} \sum_{k=1}^{K} \frac{1}{m} \sum_{i \in B_k} \nabla_\theta \ell(\theta; x_i, y_i)

Since the micro-batches partition BB and each has size m=∣B∣/Km = |B|/K:

=1K⋅m∑i∈B∇θℓ(θ;xi,yi)=1∣B∣∑i∈B∇θℓ(θ;xi,yi)=∇θL(θ;B)= \frac{1}{K \cdot m} \sum_{i \in B} \nabla_\theta \ell(\theta; x_i, y_i) = \frac{1}{|B|} \sum_{i \in B} \nabla_\theta \ell(\theta; x_i, y_i) = \nabla_\theta \mathcal{L}(\theta; B)

The average of the micro-batch gradients equals the full-batch gradient exactly. This identity is not an approximation or a statistical trick. It is an algebraic consequence of the distributive property of addition over summation.

Deep learning frameworks make this easy to exploit. In PyTorch, each call to .backward() adds gradients into the parameter's .grad attribute rather than overwriting it. Gradient accumulation is simply using this additive behavior intentionally: you call .backward() multiple times without calling optimizer.zero_grad() between calls, allowing gradients to accumulate. The only thing you need to get right is the scaling factor, which ensures the accumulated sum equals the mean rather than the sum of the micro-batch gradients.