Single-GPU fine-tuning becomes realistic when you stack the right ingredients. Each piece shrinks a different part of the memory bill.
Rough memory story for a 70B model:
| Setup | Bits / memory story | GPU picture |
|---|---|---|
| Naive full fine-tuning | Heavy weights + gradients + optimizer | Many data-center GPUs |
| LoRA (higher-precision base) | Smaller trainable set, base still bulky | Fewer GPUs, still heavy |
| QLoRA-style stack | About 5.2 bits/param class budget in this sketch | Often 1× data-center GPU class |
The exact numbers depend on hardware and settings. The lesson is the composition: 4-bit weights + small adapters + controlled activations + controlled optimizer spikes.
| Component | Role in the memory budget |
|---|---|
| 4-bit weights (NF4) | Shrink base model storage |
| LoRA adapters | Keep trainable parameters tiny |
| Double quantization | Reduce metadata overhead |
| Gradient checkpointing | Save activation memory |
| Paged optimization | Reduce memory spikes |
from transformers import AutoModelForCausalLM, BitsAndBytesConfig, TrainingArguments
from peft import LoraConfig, get_peft_model
import torch
bnb = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=torch.bfloat16,
)
model = AutoModelForCausalLM.from_pretrained(
base_model, quantization_config=bnb, device_map="auto"
)
model.gradient_checkpointing_enable()
lora = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
)
model = get_peft_model(model, lora)
args = TrainingArguments(
optim="paged_adamw_8bit",
per_device_train_batch_size=1,
gradient_accumulation_steps=16,
)
Read this as a map of ideas, not a copy-paste production recipe:
nf4 + double quant → compress the frozen backboneLoraConfig → tiny trainable updategradient_checkpointing_enable → save activation memorypaged_adamw_8bit → soften optimizer spikesQLoRA works as a stack: compress the frozen base, learn a tiny LoRA update, and control activation and optimizer memory so large models become trainable.