Skip to content
ml-recall

Topic notes

Deep Learning Frameworks

What deep learning frameworks such as PyTorch, Keras and JAX provide; autograd rules, eager vs compiled code, train/eval modes, saving models, GPUs, mixed precision and multi-GPU training.

6-min read AI-checked

Practise 36 questions Take a test

Key ideas

Formulas

Gradient accumulation over kk micro-batches equals one large batch only if each micro-batch's mean loss is divided by kk:

∇θ1kb∑i=1kbℓi=∑j=1k∇θ(1k⋅1b∑i∈micro-batch jℓi)\nabla_\theta \frac{1}{kb}\sum_{i=1}^{kb} \ell_i = \sum_{j=1}^{k} \nabla_\theta\left(\frac{1}{k}\cdot\frac{1}{b}\sum_{i \in \text{micro-batch } j} \ell_i\right)

Loss scaling: ∇θ(S⋅L)=S⋅∇θL\nabla_\theta (S \cdot L) = S \cdot \nabla_\theta L, so the unscaled step is θ←θ−η⋅1S∇θ(S⋅L)\theta \leftarrow \theta - \eta \cdot \tfrac{1}{S}\nabla_\theta(S \cdot L).

Training memory with Adam in float32: about 4×44 \times 4 bytes per parameter (weights, gradients, two moments) plus activations.

Worked example

w=2w = 2, data x=(1,3,2,4)x = (1, 3, 2, 4), loss = mean of (wxi)2(w x_i)^2, whose gradient is 2w⋅mean(xi2)2w \cdot \text{mean}(x_i^2).

In code

import torch
w = torch.tensor(2.0, requires_grad=True)
x = torch.tensor([1.0, 3.0, 2.0, 4.0])
for chunk in x.split(2):                           # two micro-batches of 2
    (((w * chunk) ** 2).mean() / 2).backward()     # divide by the number of micro-batches
print(w.grad)                                      # tensor(30.)  same as one batch of 4
with torch.no_grad():
    w -= 0.01 * w.grad                             # manual SGD step, not recorded
w.grad.zero_()
y = w.detach() ** 2 + 3 * w                        # detached term is a constant
y.backward()
print(w.grad)                                      # tensor(3.)

Common pitfalls

References

  1. PyTorch documentation: Autograd mechanics — How autograd encodes the history; Locally disabling gradient computation (Setting requires_grad, No-grad Mode, Evaluation Mode (nn.Module.eval()))
  2. JAX documentation: Just-in-time compilation — What compilation buys you; What the compiled function captures; Why can't we just jit everything?; JIT and caching
  3. JAX documentation: Pseudorandom numbers — Why not a global generator?; Keys are values; Deriving new keys
  4. PyTorch tutorials: Performance Tuning Guide — Enable asynchronous data loading and augmentation; Disable gradient calculation for validation or inference; Checkpoint intermediate buffers; Avoid unnecessary CPU-GPU synchronization
  5. PyTorch tutorial: Saving and Loading Models — What is a state_dict?; Save/Load state_dict (Recommended); Save/Load Entire Model
  6. PyTorch documentation: Distributed Data Parallel — Internal Design
  7. PyTorch documentation: Automatic Mixed Precision package (torch.amp) — Introduction; Gradient Scaling
  8. PyTorch documentation: Reproducibility — PyTorch random number generator; CUDA convolution benchmarking; Avoiding nondeterministic algorithms (CUDA Scaled Dot Product Attention)