advanced32 min studyLesson 595 in Engineering

Peak activation memory depends on overlapping lifetimes and allocator scope

Attribute live storage and transient workspaces at the actual peak rather than summing per-operator allocations or equating allocator statistics with total device use.

On this page

What you’ll understand

  • Compute a peak from unique storage lifetimes with a stated counting scope.
  • Distinguish live tensor allocation, reserved allocator capacity, and external device allocations.
  • Evaluate recomputation or offloading against both memory and completed time.

The largest allocation is not necessarily the cause of a training run's memory peak. Several saved activations may remain live together while backward work creates a transient workspace. Views can share storage, the allocator may retain freed capacity, and communication libraries may allocate outside the framework's tracker. A useful explanation identifies which unique storages overlap at the actual peak and which measurement reports them. Adding each operator's allocation total ignores lifetimes and can count the same memory repeatedly.

Count unique storage across live intervals

For a defined memory scope, assign each unique allocation a size and an interval from allocation until it can actually be reused. A tensor view usually shares an existing storage rather than creating another full allocation, so counting logical tensor sizes alone can double count. Conversely, a small view can retain a much larger underlying storage. Saved forward values, retained graph references, and asynchronous stream use can extend lifetimes beyond the Python variable's apparent last use. Use the allocator and execution semantics rather than source indentation to establish release.

Peak live memory is the maximum simultaneous sum of the counted storage sizes. Define endpoint conventions so a free followed by a same-time allocation is handled consistently. Separate persistent parameter, gradient, and optimizer-state storage from activations and transient workspaces, but combine their lifetimes when computing the actual total. The maximum of category totals taken at different times is not the same as the maximum of their sum. A peak snapshot should therefore include time or operation identity and the relevant live allocations, not only a ranked list of allocation sizes.

Mlive(t)=∑jbj 1[aj,fj)(t),Mpeak=max⁡tMlive(t)M_{\rm live}(t)=\sum_j b_j\,\mathbf1_{[a_j,f_j)}(t),\qquad M_{\rm peak}=\max_t M_{\rm live}(t)
Each j is one unique counted allocation of b_j bytes, live on the half-open interval from a_j to f_j. Shared views do not create duplicate entries. Actual reuse may depend on asynchronous completion. This model counts a defined allocator scope and does not automatically include external allocations or cached free blocks.↔ Scroll wide equations horizontally.

Separate allocated, reserved, and total device memory

A caching allocator can keep blocks reserved after individual tensors are freed so later allocations can reuse them efficiently. Reserved capacity is therefore different from bytes currently allocated to live tensors. Fragmentation can prevent an allocation even when some free space exists inside the reserved pool. Resetting a peak statistic changes the observation window, not the allocator's physical state. A measurement that begins after warmup should state which persistent allocations already exist and whether the reported peak is a current amount, a maximum since reset, or an allocation-volume counter.

Framework allocation history may omit device memory acquired directly by another library. Communication buffers are a practical example; a framework snapshot can be internally accurate while explaining only part of total device usage. Compare measurements with documented scopes instead of assuming their difference is automatically a leak. Context overhead, workspaces, graph pools, and driver-visible external allocations can contribute. APIs and allocator backends evolve, so verify the deployed version's definitions and support before treating a particular counter or snapshot field as universally complete.

max⁡t[A(t)+W(t)]≤max⁡tA(t)+max⁡tW(t)\max_t[A(t)+W(t)]\le\max_t A(t)+\max_t W(t)
A and W are nonnegative counted activation and workspace bytes in the same scope. Equality requires their maxima to coincide or another equally large combined point. This inequality explains why adding separate category peaks can overestimate the combined live peak; persistent and external memory still require their own explicitly timed accounting.↔ Scroll wide equations horizontally.

Optimize the lifetime that actually crosses the limit

Activation checkpointing trades retained values for later recomputation, which can reduce a particular peak but add arithmetic and change timing. Offloading trades device residency for transfers and synchronization; it can introduce another peak if staging buffers overlap. Compare the complete live-memory trace and completed training time rather than subtracting every removed activation from one static number. Check saved-tensor semantics and numerical equivalence as well. A configuration that fits memory by changing the batch or effective update count needs a separate quality and throughput comparison.

The cache lab illustrates bounded residency in a much smaller, different model. Reset, set both cache capacity C=4 and request stride s=4, predict four misses and twelve hits in the initial sixteen requests, then inspect or Play. Reset and set both C=2 and s=4 for sixteen initial misses. The fully associative LRU model requests address (i×s) mod16 from an empty cache, adds two requests per playback second, and caps simulation at 4096 requests. It tracks toy entries, not activation bytes, tensor aliases, lifetimes, a GPU allocator, or a memory benchmark.

The peak occurs when saved activations meet a workspace

Within one defined allocator scope, persistent storage is 6 GiB throughout. Activation A is 3 GiB live on [0,8) ms; B is 4 GiB live on [4,10) ms. A 2 GiB workspace is live on [7,9) ms. Assume all four storages are distinct and include no external allocations.

  1. From 4 to 7 ms, both activations are live with persistent storage, totaling 6+3+4=13 GiB. Before 4 ms the activation contribution is smaller.

  2. From 7 to 8 ms, the workspace overlaps both activations, giving 6+3+4+2=15 GiB. At 8 ms A is released under the half-open interval convention, so the total drops to 12 GiB.

  3. The counted peak is 15 GiB. If recomputation removes B entirely from this schedule while every other lifetime stays fixed, the modeled peak becomes 6+3+2=11 GiB; real recomputation may introduce new workspaces or timing and needs remeasurement.

The result

The attribution is a simultaneous lifetime calculation. It does not claim that the framework's reserved memory or total device usage equals the counted live peak.

Explore the model

Interactive lab

Interactive lab · cache

Residency depends on both capacity and the request stream

Reset, set both C=4 and stride s=4, predict initial N=16 results of four misses and twelve hits, then inspect or Play. Reset and re-enter both C=2 and s=4 for sixteen misses. The empty fully associative LRU model uses address (i×s) mod16 and N=16+floor(2t), capped at 4096. It counts toy entries, not tensor bytes, live activation intervals, allocator capacity, or total device memory.

Residency depends on both capacity and the request streamA fully associative LRU cache starts empty and requests address (i·s) mod 16. Hits move an address to the newest position; misses evict the oldest when full. Playback starts with 16 requests and adds two per second, capped at 4096 explicitly simulated requests. This toy stream is not a processor-cache benchmark. Current readings: Hits / requests: 0 / 16; Hit rate: 0%; Address-stream period: 16 addresses. All parameters are adjustable with the labeled controls below.Fully associative LRU cache after 16 deterministic requests: 0 hits and 16 misses.Most recent 16 requestsaddress = i × 3 mod 160M3M6M9M12M15M2M5M8M11M14M1M4M7M10M13MCurrent cache order · oldest → newest471013Latest address 13 · miss: inserted as newestToy address stream · period 16 · starts empty
Cached addressMiss / evictionMost recent request
Hits / requests
0 / 16
Hit rate
0%
Address-stream period
16 addresses
t = 0 s

A fully associative LRU cache starts empty and requests address (i·s) mod 16. Hits move an address to the newest position; misses evict the oldest when full. Playback starts with 16 requests and adds two per second, capped at 4096 explicitly simulated requests. This toy stream is not a processor-cache benchmark. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forDefine the counted residency model and inspect the overlapping state that creates its peak.

Check your understanding

A framework memory snapshot explains fewer bytes than total device usage. Which conclusion is best supported before further investigation?

Try it yourself

Activation bytes peak at 7 GiB at one instant and workspace bytes at 5 GiB at another. At the first instant workspace is 1 GiB; at the second, activations are 2 GiB. If these are the only candidate maxima and persistent counted memory is 4 GiB, compute the combined peak and compare with adding category peaks.

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Evaluate simultaneous sums at each candidate instant before taking their maximum.

Compare with the solution

The candidate totals are 4+7+1=12 GiB and 4+2+5=11 GiB, so the combined peak is 12 GiB under the stated candidate assumption. Adding separate peaks gives 4+7+5=16 GiB, an overestimate because the category maxima do not coincide. An actual trace must also check all other times and its allocation scope.

Take it with you

  • Peak live memory is a simultaneous sum of unique storage lifetimes.
  • Allocated, reserved, and total device usage have different scopes and meanings.
  • Remeasure memory and completed time after recomputation, offloading, or lifetime changes.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.