PyTorch's Hidden Memory Hog: Why Your 200MB Tensor Needs 3GB During Training
Curated by the Inblix editorial team
That CUDA out of memory error isn’t just frustrating—it’s a lie of omission. It tells you the GPU is full, but not why your 7.93 GiB card choked on a 20 MiB allocation. PyTorch has shipped a built-in memory profiler that finally makes the difference between allocated and reserved memory visible, and using it reveals a counterintuitive truth about how deep learning frameworks horde VRAM.
The tool works by recording a snapshot of every allocation and free event. You wrap your code with torch.cuda.memory._record_memory_history(), run a few iterations, and dump a pickle file. Dragging that into the visualizer at pytorch.org/memory_viz shows a timeline that reads like an EKG for your GPU. A simple nn.Linear(10_000, 50_000) model immediately grabs 2 GB just for its parameters—that’s the blue block that never budges. Then things get interesting.
In a loop, creating a 200 MB input tensor spikes memory, but the forward pass adds another 1 GB for the output and activations. The real shocker is what doesn’t happen: that first input tensor isn’t freed after the second iteration starts. The model hangs onto it because the activation is still referenced for a backward pass that may never come. This is the silent killer in inference scripts. PyTorch’s caching allocator also plays a role—the 6.00 GiB reserved in total message in the error means the framework is holding onto memory it’s already freed, waiting to reuse it, but the OS sees it as gone.
Scaling up to a real model like Qwen2.5-1.5B with an AdamW optimizer, the profile shows three distinct spikes per training step. The forward pass balloons memory with activations, loss.backward() pushes it even higher as it computes gradients, and optimizer.step() adds optimizer state tensors before zero_grad() finally lets it all collapse. If you’re running validation or inference and still seeing OOMs, wrapping the forward call in torch.no_grad() is the single most impactful line you can add—it tells PyTorch to stop hoarding those activations immediately. The profiler file itself will bloat to 8 MB for just three training steps, so keep your captured iterations brutally short.
💡 Key Takeaways
- A 200 MB input tensor can consume over 1 GB of GPU memory during a forward pass because PyTorch retains activations for the backward pass even when you're not training.
- The `6.00 GiB reserved` message in CUDA OOM errors does not mean memory is actively in use; it's a cache held by PyTorch's allocator that the OS can't reclaim, misleading users about what's actually consuming VRAM.
- Profiling a real LLM like Qwen2.5-1.5B reveals that `loss.backward()` and `optimizer.step()` create distinct memory spikes beyond the forward pass, with optimizer states consuming memory that persists across all training steps.
Keep reading: See related articles below for more coverage on this topic.
Get smarter about AI
The sharpest AI news, curated daily. Delivered free to your inbox.