Fine-Tuning Models
From the course Hugging Face & Transformers
Customizing Models for Your Data
When to Fine-Tune
- Model performs well generally but needs domain-specific knowledge
- You have labeled data for your specific task
- Prompt engineering isn't achieving desired quality
- You need consistent output format or style
Using the Trainer API
from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer
from datasets import load_dataset
# Load model and data
model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=2)
dataset = load_dataset("imdb")
training_args = TrainingArguments(
output_dir="./results",
num_train_epochs=3,
per_device_train_batch_size=16,
evaluation_strategy="epoch",
learning_rate=2e-5,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
)
trainer.train()
Parameter-Efficient Fine-Tuning (PEFT)
Full fine-tuning is expensive. PEFT methods train a fraction of parameters:
- LoRA: Add small trainable matrices alongside frozen weights
- QLoRA: LoRA + 4-bit quantization for even lower memory
- Adapter layers: Insert small trainable layers between frozen layers
Dataset Preparation
- Format data consistently (input/output pairs)
- Split into train/validation/test sets
- Balance classes for classification tasks
- Use Hugging Face Datasets library for efficient loading
Common Pitfall: Full Fine-Tuning on Consumer Hardware
Fine-tuning even a 7B model requires ~80GB of VRAM with standard Adam optimizer settings. Attempting full fine-tuning on a consumer GPU (24GB VRAM) will OOM immediately. Always use LoRA or QLoRA for consumer hardware:
from peft import get_peft_model, LoraConfig, TaskType
lora_config = LoraConfig(
r=8, # Low-rank dimension (8 or 16 are common)
lora_alpha=32, # Scaling factor
target_modules=["q_proj", "v_proj"], # Attention layers to adapt
lora_dropout=0.1,
task_type=TaskType.CAUSAL_LM,
)
model = get_peft_model(base_model, lora_config)
model.print_trainable_parameters()
# Trainable params: 4,194,304 (0.06% of total) — runs on 8GB VRAM!
Best Practice: Evaluate on a Hold-Out Set Every Epoch
Without evaluation, you cannot detect overfitting — a model that scores perfectly on training data but fails on new inputs. Configure the Trainer to evaluate at the end of each epoch and monitor the validation loss:
training_args = TrainingArguments(
eval_strategy="epoch",
load_best_model_at_end=True, # Auto-restore best checkpoint
metric_for_best_model="f1",
greater_is_better=True,
)
Named Product Reference: Unsloth for Fast Fine-Tuning
Unsloth is a library that makes LoRA fine-tuning 2–5x faster than standard PEFT with 70% less VRAM. It uses custom CUDA kernels to speed up backward passes. The library supports Llama 3, Mistral, Gemma, and Phi models. For anyone doing frequent fine-tuning experiments, pip install unsloth is one of the highest-ROI changes to make to your workflow.
Key Takeaways
- •Fine-tune when prompt engineering isn't sufficient for your domain
- •The Trainer API simplifies the training loop with built-in features
- •LoRA and QLoRA reduce fine-tuning costs by 10-100x
- •Proper dataset preparation is critical for fine-tuning success
Progress is kept in this browser only.