skip to content

A segmentation network with 60 MB of weights fails on a 4 GB edge device — why?

level: seniorimportance: should knowfreq 40%

answer

  1. Weights are not the whole footprint
  2. Feature maps live at the same time
  3. Resolution drives the tensor sizes
  4. Skip connections keep big tensors alive
  5. Peak is the maximum live set

basics

~20 s

Peak activation memory, not weight memory, is the binding cost. At high input resolution the intermediate feature maps that must be live at once run to hundreds of megabytes each, and an encoder-decoder holds high-resolution skip tensors alive across the whole decoder.

solid answer

~50 s

Weights are only one of the things resident during a forward pass. The other is the set of intermediate feature maps that must be live simultaneously, and peak memory is the maximum of that live set over the execution order. At dense-prediction resolutions the numbers are brutal: a 1024x2048 input with 64 channels in 32-bit floats is 512 MiB for a single tensor. An encoder-decoder makes it worse, because the high-resolution encoder outputs feeding skip connections stay alive until the matching decoder stage consumes them, so several large tensors coexist. Add scratch buffers some operators allocate and the input and output staging, and a 60 MB model can need several gigabytes to run one image. The fixes act on the tensors, not the weights: reduce input resolution, tile the image and process patches, downsample earlier, narrow the early channel counts, run activations in lower precision, and keep the batch at one.

go deeper

for a junior

Be ready to name the two kinds of memory a running model needs — the stored weights and the intermediate feature maps — and to say that the feature maps grow with input resolution and batch size.

for a middle

Explain peak as the maximum set of tensors live at one moment, and be able to size a tensor on the spot: elements times bytes per element. Know that a skip connection extends a tensor's lifetime.

for a senior

Show that you profile before you optimize: establish which memory is binding, then reach for resolution, tiling, activation precision or graph restructuring, and verify on the device rather than on paper.

for a principal

Own the deployment envelope. Decide what memory headroom a target class of devices must guarantee, and make peak activation memory a first-class requirement in model briefs rather than something discovered at integration.

## The memory a running model needs At inference a model's memory footprint has three parts, and only the first is what people usually quote: 1. **Weights** — parameter count times bytes per parameter. Fixed, easy to compute, and here it is 60 MB. 2. **Activations** — the intermediate feature maps produced by each layer. Their size depends on input resolution, channel counts and batch size, not on the parameter count at all. 3. **Working buffers** — scratch space some operators allocate, plus input and output staging. **Peak** memory is what decides whether the model runs. It is the maximum, over the execution schedule, of the total size of everything that must be live at that moment. A tensor is live from the point it is produced until its last consumer has read it; after that its memory can be reused. So peak is a property of the network's *graph shape and execution order*, not simply the sum of all tensors. ## Why dense prediction at high resolution is the hard case Run the arithmetic. A street-scene image at 1024x2048 has about 2.1 million pixels. A first feature map at full resolution with 64 channels, in 32-bit floats, is `1024 * 2048 * 64 * 4` bytes = **512 MiB** — for one tensor, at batch size one. A convolution needs its input and its output live at the same time, so that stage alone can want a gigabyte. An encoder-decoder with skip connections compounds it. The whole point of a skip is that a high-resolution encoder feature map is handed to the matching decoder stage. That tensor must stay live from the moment the encoder produces it until the decoder consumes it, which is most of the forward pass. With several skip levels, several of the largest tensors in the network are alive simultaneously by design. Concatenation-style merging is worse than addition, because the concatenated result is a new tensor as large as both inputs together, and both inputs must be live to produce it. Meanwhile the weights barely move: convolution kernels are small and reused across every spatial position. That is exactly the regime where **parameter memory and activation memory disagree completely**, and where trusting the 60 MB figure gets a deployment rejected. ## How to diagnose it Walk the graph and compute each tensor's size as `elements * bytes-per-element`, then find the point in the execution order where the live set is largest. That is the number to compare against the device budget — and the budget is not the full 4 GB, since the operating system, other processes and the runtime itself take a share. Confirm on the device: a footprint that fits on paper can still fail because of allocator behaviour or an operator's scratch requirements. ## Levers that actually move peak activation memory - **Lower the input resolution.** Activation memory scales with the spatial product, so halving each dimension cuts it by about four. This is the largest single lever, and it costs accuracy on small structures. - **Tile the input.** Run overlapping patches through the network one at a time and stitch the outputs. Peak memory becomes a function of tile size, which you choose. The price is redundant computation in the overlap and possible seams at tile borders. - **Downsample earlier and narrow the early layers.** The stem, operating at the highest resolution, is usually the most expensive part of the memory profile. Reducing resolution one stage sooner, or holding fewer channels while resolution is high, moves peak substantially. - **Store activations in a lower-precision format.** Halving bytes per element halves activation memory directly, with an accuracy question to validate. - **Restructure so tensors die sooner.** Fewer or shorter skip connections, addition instead of concatenation where the architecture allows, and an execution order that consumes large tensors promptly all shrink the live set. - **Keep batch size at one.** Activation memory scales linearly with batch; on a memory-constrained device, batching is a luxury. Note which levers are absent from that list: quantizing or pruning the *weights* saves at most a fraction of 60 MB, and would not have made a difference to a deficit measured in gigabytes. ## What a strong answer sounds like Separate weight memory from activation memory immediately, define peak as the maximum live set over the execution order, produce one concrete tensor-size calculation to show the scale, explain why encoder-decoder skips keep the largest tensors alive, and then propose levers that act on resolution, tiling, precision and graph shape rather than on the weights. The interviewer is watching for whether you check which memory is binding before optimizing anything.

  • How would you compute the peak figure before you ever touch the device?
    Walk the graph, size each tensor as elements times bytes per element, and mark each one live from its producer to its last consumer. Peak is the largest total live set over the execution order, plus weights and any operator scratch. Then leave headroom — the operating system, the runtime and other processes take a share of the 4 GB — and confirm the estimate with a real run, because allocator behaviour can add more.
  • Why does tiling the input help, and what does it cost?
    Peak activation memory scales with the spatial size of the tensors, so processing one overlapping patch at a time makes peak a function of tile size, which you control. The costs are redundant computation in the overlaps, extra latency from running the network many times, seams where predictions disagree at tile borders, and a loss of context for objects larger than a tile. Overlap width is the tuning knob.
  • Would quantizing the weights to 8-bit have rescued this deployment?
    No. It would take 60 MB of weights down to roughly 15 MB, against a shortfall measured in gigabytes that lives entirely in the activations. Quantizing the activations as well is a different and far more relevant change, since it halves or quarters the bytes per element in the tensors that actually dominate peak. The lesson is to identify the binding resource before choosing a compression method.

saying these in an interview costs you the question

  • Assumes model size equals runtime memory footprint
  • Ignores that activation memory scales with input resolution
  • Forgets skip connections keep high-resolution tensors alive
  • Proposes weight quantization for an activation-memory shortfall
  • Sums all tensor sizes instead of the maximum live set
  • Assumes the full device memory is available to the model

context