interviewpath
  • 0day streak
  • 10total XP
  • Level 1
0/5

Unit 8 · AI infrastructure · Lesson 2 of 10

Training memory accounting

Out-of-memory errors, batch-size limits and the choice between sharding, recomputation and offload all follow from one accounting exercise: bytes per parameter for weights, gradients and optimizer state, plus activations that scale with batch and sequence length. Interviewers use it to see whether you can estimate before you run.
About 3 h 30 minFocus mode

Step 1: Learn the ideas

  • Weights, gradients and optimizer state (Adam first and second moments)
  • Mixed precision: 16-bit working copies plus fp32 master weights
  • Activations saved for backward and their dependence on micro-batch, sequence, hidden size and depth
  • Attention-score memory and quadratic growth with sequence length without fused kernels
  • Logits and loss computation as a memory spike for large vocabularies
  • Temporary buffers, library workspaces and gradient communication buckets
  • The caching allocator: allocated versus reserved memory and fragmentation
  • Peak versus steady-state memory within a step
  • Levers: micro-batch size, accumulation, fused attention, checkpointing, ZeRO/FSDP sharding, offload

Why it matters

Whether a run fits in memory is decided before the first step, by arithmetic you can do on paper. Interviewers ask "will this model train on these GPUs, and if not, what would you change?" to check whether you estimate before running and whether you know which lever moves which term.

Core ideas

Model states scale with the parameter count Ψ. Count bytes per parameter:

  • fp32 training with Adam: 4 (weights) + 4 (gradients) + 8 (two moments) = 16 bytes.
  • 16-bit compute with fp32 master weights and Adam, the setup analyzed in the ZeRO paper: 2 (16-bit weights) + 2 (16-bit gradients) + 4 (fp32 master copy) + 8 (two fp32 moments) = 16 bytes.
  • SGD with momentum in fp32: 4 + 4 + 4 = 12 bytes; plain SGD keeps no optimizer state.

So mixed precision with master weights does not shrink model states; its savings are in activations and speed. As simple arithmetic, a 1-billion-parameter model at 16 bytes per parameter needs about 16 GB for model states before any activation is stored. Frameworks differ (some keep fp32 gradients, some train purely in bf16 without a master copy), so check what your setup actually stores.

Activations scale with the micro-batch. The backward pass needs values from the forward pass: inputs to linear layers, attention probabilities, normalization statistics, dropout masks. For a transformer, activation memory grows roughly linearly with micro-batch size b, sequence length s, hidden size h and layer count L, plus a per-layer term proportional to b × heads × s² when attention scores are materialized. That is why runs often fit at short context and fail at long context with the same model.

Everything else. Short-lived temporaries, library workspaces, gradient buckets for all-reduce, the output logits (b × s × vocabulary, plus the softmax for the loss, often a spike with large vocabularies), and fragmentation in the caching allocator. PyTorch reports allocated memory (live tensors) separately from reserved memory (held by the allocator); nvidia-smi shows reserved memory plus the CUDA context, so it overstates live tensors.

Peak, not average. Memory peaks at a specific moment, often early in the backward pass when saved activations and new gradients coexist, or in the first optimizer step when optimizer state is created lazily. Measure the peak.

model_states = params * bytes_per_param(precision, optimizer)
activations  ≈ layers * per_layer_activations(micro_batch, seq_len, hidden, heads)
peak         ≈ model_states + activations + largest_temporary (e.g. logits)
               + communication_buffers + allocator_slack

Then run one step, read the peak allocated memory and a memory snapshot, and explain the gap.

Levers, roughly from cheapest to most invasive: a smaller micro-batch with gradient accumulation (activation memory of one micro-batch, same effective batch); fused attention kernels that never store the s×s matrix; activation checkpointing (store less, recompute in backward); sharding model states across data-parallel ranks (ZeRO stage 1 shards optimizer state, stage 2 adds gradients, stage 3 or FSDP adds parameters); tensor or pipeline parallelism; and CPU or NVMe offload, limited by transfer bandwidth. Lower-precision optimizer states also exist but change numerics.

Common misconceptions

  • "Mixed precision halves training memory." With fp32 master weights and Adam, model states stay near 16 bytes per parameter; the savings are in activations.
  • "Memory grows with the global batch size." It grows with the micro-batch; gradient accumulation keeps the global batch while bounding activation memory.
  • "nvidia-smi tells me what my tensors use." It reports reserved memory and the CUDA context; use allocated and peak-allocated counters and memory snapshots.
  • "Activation checkpointing doubles the step time." Recomputing the whole forward pass costs about one extra forward, roughly a third more compute when backward costs about twice the forward; selective recomputation costs less.
  • "Inference needs training memory minus gradients." Inference drops optimizer state and most activations but adds the KV cache, which can dominate at long contexts and high concurrency.

How to approach it

Write the estimate before running anything, then measure and explain every difference. In interviews, lay out the per-parameter accounting, then activation scaling, then the levers in order of cost. Senior candidates are expected to add communication buffers and fragmentation, and to discuss how sharding, recomputation and throughput interact.

Suggested order

  1. 1Review the CS336 lecture on PyTorch and resource accounting (FLOPs, memory, arithmetic intensity) and reproduce its memory arithmetic for a small transformer.
  2. 2Read the memory-consumption analysis in the ZeRO paper (model states versus residual states) and rebuild the bytes-per-parameter accounting from memory.
  3. 3Read the activation-memory derivation in "Reducing Activation Recomputation in Large Transformer Models" and mark which terms grow with the square of sequence length.
  4. 4Use "All the Transformer Math You Need to Know" in How to Scale Your Model to check parameter counts for a configuration you choose.
  5. 5Read PyTorch "Understanding CUDA Memory Usage" and capture a memory snapshot of one training step.
  6. 6Do the memory-estimate project: write the estimate, run one step, and reconcile the two in a short table.

Step 2: Check off what you can do

Tap each one you can genuinely do or explain. Each earns 10 XP.

Step 3: Go deeper

  • ZeRO: Memory Optimizations Toward Training Trillion Parameter ModelsStart here

    arXiv

    Model-state accounting (parameters, gradients, optimizer state) for mixed-precision Adam, residual states, and what each sharding stage removes.

    Open(opens in a new tab)Link responded, 5 Oct 2026
  • Reducing Activation Recomputation in Large Transformer ModelsStart here

    arXiv

    Term-by-term activation memory of a transformer layer and how selective recomputation and sequence parallelism reduce it.

    Open(opens in a new tab)Link responded, 5 Oct 2026
  • How to Scale Your Model: A Systems View of LLMs on TPUs

    Google DeepMind (online book)

    Section: All the Transformer Math You Need to Know

    Parameter, FLOP and memory formulas for transformer configurations to anchor your estimates.

    Open(opens in a new tab)Link responded, 5 Oct 2026
  • PyTorch: CUDA semantics

    PyTorch documentation

    Section: Understanding CUDA Memory Usage (memory snapshots)

    Allocated versus reserved memory, the caching allocator and memory snapshots for reconciling estimates with measurements.

    Open(opens in a new tab)Link responded, 5 Oct 2026
  • Stanford CS336 Language Modeling from Scratch

    Stanford University

    Section: Lecture 2: PyTorch (einops), resource accounting (Spring 2026 schedule)

    Course-level treatment of FLOP and memory accounting for language-model training.

    Open(opens in a new tab)Link responded, 5 Oct 2026

Step 4: Practice

Pick a small transformer configuration, write the memory estimate component by component, and only then run one training step. Record peak allocated memory, take a snapshot, and explain every sizable difference (allocator slack, logits, temporaries, communication buffers). Repeat with twice the sequence length and predict the change first. The CS336 systems assignment asks for memory-efficient training in a larger setting.

Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).

Step 5: Test yourself

Answer each one out loud or on paper before you finish the lesson.

  1. Question 1Which parts of training memory scale with parameters, and which with micro-batch and sequence length?
  2. Question 2Why does mixed precision with fp32 master weights not reduce model-state memory?
  3. Question 3Where in a training step does memory usually peak, and why?
  4. Question 4What does ZeRO stage 2 shard that stage 1 does not?
  5. Question 5Why can logits be a memory spike for models with large vocabularies?
  6. Question 6What does activation checkpointing not reduce?

You’re done when you can

  • State bytes per parameter for fp32 Adam and for mixed-precision Adam with fp32 master weights, and explain each component.
  • Estimate peak training memory for a model configuration you choose and explain the difference from the measured peak term by term.
  • Name and justify the first lever you would use for an out-of-memory error that appears only at long context.
  • Explain the difference between allocated and reserved GPU memory and why nvidia-smi differs from both.

Finish the lesson

How confident do you feel?

Lesson complete!

+50 XP

Reviews will come up on the Practice tab so it sticks.

Unlocks next: Data, tensor and pipeline parallelism and collectives, Mixed precision, accumulation and activation checkpointing

Your notes and study time

Log study time