gtzhost logo

NORTH AMERICA

EUROPE

ASIA

How to Fix "CUDA Out of Memory" Error on GPU Servers

If you've trained or fine-tuned a deep learning model, you've almost certainly hit this wall:

plaintext
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:

bash
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:

bash
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.

python
# 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:

python
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.

python
# 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.

python
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.

python
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 size

  • Set 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-smi during long training runs to catch gradual memory creep before it causes a crash

  • Version-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.