← Back to DevBytes

How to Fine-Tune Llama 3 with QLoRA on a Single GPU

Introduction to Fine-Tuning Llama 3 with QLoRA

Llama 3 is Meta's latest and most powerful open-source large language model, offering state-of-the-art performance across a variety of natural language processing tasks. However, fine-tuning a model with 8 billion or 70 billion parameters requires immense computational resources. This is where QLoRA (Quantized Low-Rank Adaptation) comes in.

QLoRA is an efficient fine-tuning technique that reduces the memory footprint of large language models. It works by loading the pre-trained base model in a 4-bit quantized format (freezing its weights) and attaching small, trainable adapter layers (LoRA) on top. By only updating these adapter weights during training, QLoRA allows developers to fine-tune massive models on consumer-grade hardware.

Fine-tuning Llama 3 with QLoRA on a single GPU matters because it democratizes AI development. Instead of needing a multi-GPU cluster, you can customize Llama 3 for your specific domain—such as medical text analysis, customer support, or code generation—using a single 24GB GPU (like an RTX 3090 or 4090).

Prerequisites and Environment Setup

Before we begin, ensure you have access to a machine with an NVIDIA GPU (at least 16GB VRAM is recommended for the 8B model) and the necessary CUDA drivers installed. You will also need to create a Hugging Face account and accept the Llama 3 license terms to access the model weights.

First, install the required Python libraries. We will use transformers for model loading, peft for LoRA adapters, bitsandbytes for 4-bit quantization, and trl for the supervised fine-tuning trainer.

pip install -U transformers peft bitsandbytes datasets trl accelerate torch

Next, log into your Hugging Face account via the CLI so the script can download the gated Llama 3 model.

huggingface-cli login

Step-by-Step Implementation

1. Loading the Model and Tokenizer with 4-bit Quantization

To fit Llama 3 on a single GPU, we will load it using a BitsAndBytesConfig configured for 4-bit NF4 (NormalFloat4) quantization. We will also set the computation dtype to bfloat16 to maintain training stability and speed.

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

model_id = "meta-llama/Meta-Llama-3-8B"

# Configure 4-bit quantization
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_use_double_quant=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16
)

# Load the tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_id)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"

# Load the model with quantization
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    quantization_config=bnb_config,
    device_map="auto"
)

2. Preparing the Dataset

For this tutorial, we will use a subset of the Databricks Dolly 15k dataset, which contains instruction-response pairs. We need to format the data into a single text string that the model can learn from.

from datasets import load_dataset

# Load a small subset of the dataset for demonstration
dataset = load_dataset("databricks/databricks-dolly-15k", split="train[:1000]")

def format_instruction(sample):
    return f"### Instruction:\n{sample['instruction']}\n\n### Response:\n{sample['response']}"

# Map the formatting function to the dataset
dataset = dataset.map(lambda x: {"text": format_instruction(x)})

3. Configuring the QLoRA Adapter

Now we configure the LoRA adapter. The r parameter dictates the rank of the adapter matrices, and lora_alpha scales the adapter weights. For Llama 3, it is highly recommended to target all linear layers in the transformer blocks to maximize learning capacity.

from peft import LoraConfig, get_peft_model

peft_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
    target_modules=[
        "q_proj", "k_proj", "v_proj", "o_proj",
        "gate_proj", "up_proj", "down_proj"
    ]
)

# Apply the LoRA adapter to the quantized model
model = get_peft_model(model, peft_config)
model.print_trainable_parameters()

4. Setting up the Trainer

We will use the SFTTrainer (Supervised Fine-Tuning Trainer) from the trl library. It simplifies the training loop and handles the dataset text field automatically. We will configure the training arguments to use paged 8-bit AdamW optimizer to further reduce memory usage.

from trl import SFTTrainer
from transformers import TrainingArguments

training_args = TrainingArguments(
    output_dir="./llama-3-qlora-output",
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    learning_rate=2e-4,
    logging_steps=10,
    max_steps=50, # Keep short for tutorial purposes
    optim="paged_adamw_8bit",
    save_steps=50,
    warmup_steps=10,
    fp16=True,
)

trainer = SFTTrainer(
    model=model,
    train_dataset=dataset,
    peft_config=peft_config,
    dataset_text_field="text",
    max_seq_length=512,
    tokenizer=tokenizer,
    args=training_args,
)

5. Training and Saving the Model

Finally, initiate the training process. Once training is complete, we save the adapter weights. Note that we only save the adapter, not the full model, as the base model remains unchanged.

# Start training
trainer.train()

# Save the fine-tuned adapter
trainer.model.save_pretrained("./llama-3-qlora-adapter")
tokenizer.save_pretrained("./llama-3-qlora-adapter")

print("Training complete and adapter saved successfully!")

Best Practices for QLoRA Fine-Tuning

Conclusion

Fine-tuning Llama 3 with QLoRA on a single GPU bridges the gap between cutting-edge AI research and practical, accessible development. By leveraging 4-bit quantization and low-rank adapters, you can transform a general-purpose large language model into a highly specialized tool for your specific use case without requiring enterprise-level hardware. By following the steps and best practices outlined in this tutorial, you are now equipped to build, train, and deploy your own custom Llama 3 models efficiently and cost-effectively.

— Ad —

Google AdSense will appear here after approval

← Back to all articles