AI Model Wiki

    Skip to main content
    50 min
    Lesson 3 of 5

    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
    0 of 5 lessons marked complete

    Progress is kept in this browser only.