Skip to content

Memory Optimization

One of the most common errors when working with large models is the CUDA out of memory error. This guide provides several strategies to reduce the VRAM footprint of your training and inference jobs.

1. Gradient Accumulation

The Problem

Large models require a sufficiently large batch size for stable training, but fitting a large batch into GPU memory is often impossible.

How to Optimize

Gradient accumulation allows you to simulate a larger batch size. It works by accumulating gradients over several smaller batches (micro-batches) before performing a weight update. The effective batch size becomes batch_size * gradient_accumulation_steps.

This technique trades a small amount of computation for a massive reduction in memory, as only one micro-batch needs to fit in VRAM at a time.

Configuration (config.yaml):

training_args:
  per_device_train_batch_size: 4 # A small batch size that fits in memory
  gradient_accumulation_steps: 8 # Accumulate gradients over 8 steps
  # Effective batch size = 4 * 8 = 32

CLI Argument:

dnallm finetune --per_device_train_batch_size 4 --gradient_accumulation_steps 8 ...

2. Gradient Checkpointing

The Problem

During the forward pass, all intermediate activations are stored in memory to be used for gradient calculation in the backward pass. For very long sequences or deep models, these activations can consume a huge amount of VRAM.

How to Optimize

Gradient checkpointing (also known as activation checkpointing) saves memory by not storing all intermediate activations. Instead, it re-computes them during the backward pass where needed.

This is another trade-off: it saves a significant amount of memory at the cost of increased computation time (typically around 20-30% slower). It is extremely effective for models with very long sequences.

Configuration (config.yaml):

training_args:
  gradient_checkpointing: true

CLI Argument:

dnallm finetune --gradient_checkpointing ...