advanced28 min studyLesson 508 in Engineering

Checkpointing trades saved activations for compatible recomputation

Budget a simple segmented reverse schedule, preserve forward semantics across RNG and device behavior, and distinguish ideal memory counts from measured peak cost.

On this page

What you’ll understand

  • Calculate an ideal segmented activation-memory budget and recomputation work.
  • Explain why replayed activations must match the original derivative dependencies.
  • Identify RNG, device movement, state mutation, and schedule limits in checkpoint implementations.

Reverse mode needs forward information, but it need not keep every activation until backward reaches it. Activation checkpointing saves selected boundaries and recomputes missing intermediates when needed. This moves cost from retained memory into extra execution and possibly transfers. A correct schedule must reproduce the required forward values; a memory saving is not an optimization if replay changes randomness, state, or the function being differentiated.

Choose boundaries and account for local replay

Consider a chain of L similar layers divided into segments of s layers. A simple schedule keeps segment boundaries and, during reverse work on one segment, recomputes that segment's internal activations. An idealized payload budget has about L/s boundary slots plus s local slots rather than L saved layer outputs. This gives a useful square-root-style tradeoff for a uniform chain, not a universal optimal policy. Real graphs have branches, nonuniform activation sizes, different recomputation costs, and kernels whose workspaces can dominate the activation payload.

The original sublinear-memory research analyzes and demonstrates particular checkpoint schedules; its asymptotic result depends on the model and implementation assumptions. Saving more boundaries can reduce replay while retaining more memory. Nested or optimized schedules make different tradeoffs, and offloading introduces bandwidth and synchronization costs. Include parameters, gradients, allocator reserves, input/output storage, communication buffers, and temporary workspaces when measuring total peak. A theoretical count of activation slots should be labeled as such rather than advertised as an exact accelerator-memory guarantee.

Btoy≲m(Ls+s)B_{\rm toy}\lesssim m\left(\frac Ls+s\right)
For an ideal uniform chain with L divisible by positive segment length s, m is bytes per activation slot. The expression budgets boundary and local replay slots only; it excludes endpoints, parameters, gradients, workspaces, aliases, and implementation overhead and is not a universal peak-memory bound.↔ Scroll wide equations horizontally.

Recomputation must reproduce the needed function evaluation

Random operations require a compatible RNG-state policy if replayed activations must match. PyTorch 2.9 documents checkpoint RNG preservation for CPU and one additional device type inferred from the tensor arguments, with limitations when several device types or movement to a new device are involved. It cannot anticipate arbitrary device changes inside the function. PyTorch 2.9 documents that torch.compile preserves RNG regardless of the preserve_rng_state flag; on execution paths that honor disabling it, the reproducibility assumption changes. Other random generators or external state also need a contract; a fixed global seed alone does not establish the exact same draw sequence after a different execution schedule.

A checkpointed function that updates a global counter, appends output, performs an external side effect, or changes mutable model state can behave differently when recomputed. Some implementations stop replay once needed residuals are reconstructed, while others rerun a whole region; PyTorch 2.9 distinguishes reentrant and non-reentrant variants and their transform restrictions. Select and test the documented variant explicitly. Do not rely on replay executing an exact number of side effects. The safe teaching model is a compatible computation whose necessary values can be regenerated without changing its intended semantics.

rreplay=rrequired forwardunder the chosen numerical and state contractr_{\rm replay}=r_{\rm required\ forward}\quad\text{under the chosen numerical and state contract}
r denotes residual values required by reverse rules, not necessarily object identity or bitwise equality under every permitted numerical contract. RNG, mutable state, device behavior, and supported runtime transforms determine whether this equality claim is justified.↔ Scroll wide equations horizontally.

Measure the schedule that actually runs

Compare gradients with a trusted non-checkpointed reference at fixed inputs and state, then measure peak allocated and reserved memory, step time, extra kernels, transfers, and variation. Include higher-order or custom-rule paths if the application needs them. A partial replay can make simple layer-count estimates inaccurate in either direction. Verify that a saved boundary stays live only as long as intended and that the chosen checkpoint policy does not retain another reference to the supposedly discarded activation. The goal is a correct computation under a useful resource budget, not merely a lower number in one memory category.

The cache lab illustrates finite remembrance for a hypothetical pure-value lookup, not an AD schedule. Reset, set BOTH C=4 and s=2, predict zero hits among the N=16 requests at t=0, then Play or Step. Reset and re-set BOTH C=8 and s=2; predict eight hits. N=min(4096,16+floor(2t)); edits retain t/recompute from empty. A miss would require a separately assumed fetch or recomputation in an application, but the lab does neither. It has no activation graph, checkpoint boundaries, RNG, device memory, or measured replay time.

A uniform segmented schedule's payload and work

A fictional sixteen-layer chain uses eight MB per saved activation. Budget four segment-boundary slots and at most four local replay slots for a four-layer-segment schedule. Ignore endpoints and all other allocations; assume replay recomputes each layer once.

  1. Saving all sixteen layer activations would use 16×8=128 MB of this payload category.

  2. The illustrative segmented budget is (4+4)×8=64 MB. Some slots may overlap or have shorter lifetimes; this is the stated slot budget, not a measured total peak.

  3. Replay adds sixteen forward-layer evaluations to the original sixteen. If backward costs another sixteen equal work units in this toy, total work rises from 32 to 48 units, a 50-percent increase under these deliberately uniform assumptions.

The result

The example halves the chosen activation-slot budget while adding work. Real memory and time depend on the complete graph and checkpoint implementation.

Explore the model

Interactive lab

Interactive lab · cache

Remembered values and missing values have different costs

For EACH run Reset, set BOTH C and s, predict, then Play or Step. At N=16/t=0 compare (4,2), zero hits, with (8,2), eight hits. N=min(4096,16+floor(2t)); edits retain t/recompute from empty. This LRU trace does not execute activation rematerialization, time recomputation, preserve RNG, or measure device memory.

Remembered values and missing values have different costsA 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 forReducing retained values requires a correct plan for obtaining them later; memory-slot counts alone do not establish replay correctness or speed.

Check your understanding

Why can a checkpointed function that moves tensors to an unanticipated device and uses randomness violate a naive replay assumption?

Try it yourself

For the ideal slot model with L=36 equal layers and segment length s=6, calculate boundary-plus-local slot count. If each slot is two MB, compare this category with saving all 36 activations.

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

Give me a hint

Use L/s+s, keeping the model's excluded allocations and uniform-size assumptions visible.

Compare with the solution

The slot count is 36/6+6=12, giving 24 MB versus 72 MB for all 36 slots. This comparison excludes endpoints, gradients, workspaces, reserves, and replay costs; it does not prove a particular framework implementation has exactly that measured peak.

Take it with you

  • Rematerialization trades a selected saved-state budget for extra compatible execution.
  • RNG, device, mutable-state, and transform contracts determine replay correctness.
  • Uniform-chain slot formulas need measured whole-step memory and time validation.

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.