If you've trained or fine-tuned a deep learning model, you've almost certainly hit this wall:
RuntimeError: CUDA out of memory. Tried to allocate X GiB (GPU 0; Y GiB total capacity; ...)
The CUDA Out of Memory (OOM) error means your GPU's VRAM has run out of space to store the model weights, activations, gradients, and optimizer states your job needs. It's one of the most common blockers in AI training and inference — and thankfully, one of the most fixable, once you understand what's actually consuming memory.
Quick Answer
CUDA OOM errors are almost always caused by batch size, model size, or memory fragmentation exceeding available VRAM. Start by reducing batch size and enabling mixed precision (FP16/BF16) — this resolves the majority of cases immediately. If the model itself is too large for your GPU's VRAM even at a minimal batch size, the fix is architectural: gradient checkpointing, model parallelism, or moving to a GPU tier with more VRAM (such as an A100 80GB or H100).
What Actually Causes CUDA Out of Memory
GPU VRAM is consumed by several things simultaneously during training:
Model weights — fixed size based on parameter count
Activations — grows with batch size, sequence length, and image resolution
Gradients — roughly the same size as the model weights
Optimizer states — Adam-style optimizers store two extra values per parameter, often doubling or tripling memory use beyond the model weights alone
CUDA context and framework overhead — a fixed baseline reserved by PyTorch/TensorFlow and the CUDA driver itself
Memory fragmentation — repeated allocation/deallocation cycles can leave VRAM fragmented, causing OOM errors even when total free memory looks sufficient
Understanding which of these is your actual bottleneck determines which fix below will work.
Step-by-Step Fixes
Step 1: Check Current GPU Memory Usage
Before changing anything, confirm what's actually happening on the GPU:
nvidia-smi
This shows total VRAM, memory currently in use, and which processes are holding it. If a previous process crashed without releasing memory, you may need to kill it manually:
kill -9 <PID>
Step 2: Reduce Batch Size
This is the fastest and most reliable fix. Activations scale linearly with batch size, so halving your batch size roughly halves activation memory usage.
# Before
batch_size = 64
# After
batch_size = 16
If reducing batch size hurts training stability or convergence, use gradient accumulation to simulate a larger effective batch size without the memory cost:
accumulation_steps = 4
for i, batch in enumerate(dataloader):
loss = model(batch) / accumulation_steps
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
Step 3: Enable Mixed Precision Training
Switching from FP32 to FP16 or BF16 roughly halves memory usage for weights, activations, and gradients, often with minimal or no accuracy loss.
# PyTorch example using Automatic Mixed Precision
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
output = model(input)
loss = criterion(output, target)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
Step 4: Use Gradient Checkpointing
For deep models where activations are the dominant memory cost, gradient checkpointing trades compute for memory by recomputing activations during the backward pass instead of storing them all.
from torch.utils.checkpoint import checkpoint
output = checkpoint(model_segment, input)
This can cut activation memory usage significantly at the cost of roughly 20-30% more training time — a worthwhile trade when the alternative is not being able to fit the model at all.
Step 5: Clear Cache Between Runs
PyTorch caches allocated memory for reuse, which can look like a memory leak between training runs or experiments in the same session.
import torch
torch.cuda.empty_cache()
Note this doesn't reduce your model's actual memory requirement — it only releases cached memory PyTorch isn't currently using, which helps when running multiple experiments sequentially in one process.
Step 6: Reduce Sequence Length or Image Resolution
For transformer and vision models specifically, memory scales with input size — often quadratically for attention layers relative to sequence length. Shortening sequence length or lowering input resolution during initial development and debugging can avoid OOM errors while you validate your pipeline, before scaling back up on adequate hardware.
Step 7: Use Model or Tensor Parallelism
When the model itself — not the batch size or activations — is too large for a single GPU's VRAM, splitting the model across multiple GPUs is the correct fix rather than continuing to shrink batch size:
Data parallelism splits batches across GPUs (doesn't reduce per-GPU model memory)
Model/tensor parallelism splits the model's layers or tensors across GPUs, directly reducing per-GPU memory requirements
Frameworks like DeepSpeed, FSDP (Fully Sharded Data Parallel), and Megatron-LM handle this automatically for large-scale training.
Step 8: Move to a Higher-VRAM GPU Tier
If you've applied the software-level fixes above and still hit OOM, the model or dataset genuinely exceeds your current GPU's VRAM capacity. At this point, scaling to a GPU with more memory headroom is the practical solution rather than continuing to compromise batch size or precision:
NVIDIA T4 (16GB) — suited to smaller models, inference, and lightweight fine-tuning
NVIDIA A40 (48GB) — a solid step up for mid-size model training and rendering-adjacent workloads
NVIDIA A100 (40GB/80GB) — designed for large-scale training and fine-tuning of billion-parameter models
NVIDIA H100 (80GB HBM3) — the highest-throughput option, suited to the largest transformer training jobs where both VRAM capacity and memory bandwidth matter
GTZHost's GPU dedicated servers offer this full range on bare metal hardware, so you can size VRAM to your model rather than re-engineering your training pipeline around a memory ceiling.
Preventing Future CUDA OOM Errors
Profile memory before scaling up — use
torch.cuda.memory_summary()to understand exactly where memory is going before increasing batch size or model sizeSet a memory fraction limit during development to catch issues early rather than crashing mid-run on shared or production hardware
Monitor VRAM in real time with
watch -n 1 nvidia-smiduring long training runs to catch gradual memory creep before it causes a crashVersion-lock your CUDA/cuDNN/framework versions — memory management behavior can change between releases, and an unexpected inconsistency is a common source of "it worked yesterday" OOM errors
Right-size your GPU tier from the start for expected model scale, rather than discovering the ceiling mid-project
Final Thoughts
Most CUDA Out of Memory errors are solvable at the software level batch size, mixed precision, and gradient checkpointing resolve the majority of cases without touching your infrastructure. But when a model's genuine memory footprint exceeds what your current GPU can hold, no amount of tuning will fix it — that's a hardware ceiling, not a configuration problem. Matching your model size to the right VRAM tier from the start saves both debugging time and unnecessary architecture compromises.
Need more VRAM headroom for your next training run? Explore GTZHost's GPU dedicated servers, ranging from the T4 for lightweight workloads up to the A100 and H100 for large-scale AI training.