LoRA e QLoRA são técnicas revolucionárias no campo do ajuste fino (finetuning) de Grandes Modelos de Linguagem (LLMs). Eles permitem que você personalize modelos enormes usando hardware de consumo (como uma única GPU de PC), tornando o fine-tuning acessível a mais pessoas e organizações.
LoRA (Low-Rank Adaptation)
O LoRA é um método que permite adaptar um modelo de aprendizado de máquina a novas tarefas sem a necessidade de retreinar todos os seus parâmetros.
Como funciona:
- Congelamento do Modelo Base: O modelo original (os pesos principais) permanece inalterado e “congelado” durante o treinamento.
- Introdução de Matrizes Pequenas (Adaptadores): Para cada camada do modelo original que você deseja ajustar, o LoRA introduz duas pequenas matrizes adicionais (frequentemente chamadas de “adaptadores”).
- Treinamento Apenas dos Adaptadores: Apenas essas pequenas matrizes são treinadas com seus novos dados.
- Combinação na Inferência: Durante a inferência (uso do modelo após o treinamento), os resultados dessas pequenas matrizes treinadas são combinados com os pesos originais do modelo.
Vantagens do LoRA:
- Eficiência de Memória: Reduz drasticamente o número de parâmetros treináveis, economizando memória da GPU em comparação com o fine-tuning completo.
- Velocidade: O treinamento é mais rápido, pois menos parâmetros estão sendo atualizados.
- Armazenamento Eficiente: Você armazena apenas os adaptadores pequenos (que pesam megabytes), não o modelo inteiro (que pode pesar gigabytes), facilitando a gestão de múltiplos modelos ajustados para tarefas diferentes.
QLoRA (Quantized Low-Rank Adaptation)
O QLoRA é uma evolução do LoRA que leva a eficiência de memória um passo adiante, introduzindo a quantização.
Como funciona:
- Quantização do Modelo Base: Antes do fine-tuning, o modelo base inteiro é comprimido, geralmente para uma precisão de 4 bits (em vez dos 16 bits ou 32 bits padrão). Isso reduz o espaço de memória ocupado pelo modelo base em até 75%.
- Uso do LoRA: O processo de LoRA (introdução e treinamento de adaptadores pequenos) é então aplicado sobre este modelo base quantizado (comprimido).
- Otimizadores Paginados (Paged Optimizers): O QLoRA usa uma técnica especial de gerenciamento de memória que permite mover estados do otimizador entre a RAM da CPU e a VRAM da GPU, lidando com picos de memória de forma eficiente.
Vantagens do QLoRA:
- Eficiência Extrema de Memória: Permite o fine-tuning de modelos gigantescos (30 bilhões de parâmetros ou mais) em hardware de consumidor (como uma única GPU de 12GB ou 24GB), o que seria impossível com LoRA tradicional ou fine-tuning completo.
- Acessibilidade: Democratiza o fine-tuning de modelos de ponta para um público mais amplo.
- Desempenho Competitivo: Apesar da compressão, o QLoRA mantém uma precisão e desempenho muito próximos do fine-tuning completo.
Resumo das Diferenças
| Característica |
|---|
| LoRA | QLoRA | |
|---|---|---|
| Modelo Base | Mantido em precisão normal (16/32 bits) | Quantizado (comprimido, geralmente para 4 bits) |
| Uso de Memória | Eficiente (requer menos VRAM que o fine-tuning completo) | Extremamente eficiente (o que há de mais eficiente hoje) |
| Hardware Necessário | Requer VRAM suficiente para o modelo completo em precisão normal | Permite fine-tuning em GPUs de consumidor com VRAM limitada |
| Velocidade de Treinamento | Rápido | Rápido (ligeiramente mais lento que LoRA devido à quantização) |
Usar QLoRA em Python é facilitado pelas bibliotecas do Hugging Face: transformers, peft (Parameter-Efficient Fine-Tuning) e bitsandbytes (para a quantização).
Abaixo, um exemplo simplificado de como configurar e usar QLoRA para fine-tuning, utilizando o SFTTrainer da biblioteca trl, que simplifica muito o processo.
Pré-requisitos (Instalação de Bibliotecas)
Primeiro, instale as bibliotecas necessárias. Recomenda-se usar um ambiente virtual.
bash
pip install torch transformers datasets accelerate bitsandbytes peft trl
Exemplo de Código Python para QLoRA
Este script demonstra o carregamento de um modelo em 4 bits e a configuração do QLoRA.
python
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments
from datasets import load_dataset
from peft import LoraConfig, prepare_model_for_kbit_training
from trl import SFTTrainer
# 1. Carregar o Modelo Base com Configuração de Quantização (QLoRA)
model_id = "facebook/opt-125m" # Um modelo pequeno para exemplo. Use Mistral/Llama para melhor desempenho.
# Configuração da Quantização (4 bits)
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4", # Normal Float 4 bits, geralmente o melhor para pesos
bnb_4bit_compute_dtype=torch.bfloat16 # Tipo de dado para computação
)
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=bnb_config,
device_map="auto" # Carrega o modelo na GPU automaticamente
)
# Prepara o modelo para treinamento k-bit (necessário para QLoRA)
model = prepare_model_for_kbit_training(model)
# 2. Configurar o LoRA (Adaptadores)
lora_config = LoraConfig(
r=16, # Rank: dimensão das matrizes de adaptação (valor comum: 8, 16, 32)
lora_alpha=32, # Escala: fator de escalonamento para os adaptadores
target_modules=["q_proj", "v_proj"], # Módulos do modelo para aplicar LoRA (específico para a arquitetura do modelo)
lora_dropout=0.05, # Dropout para regularização
bias="none", # Não usar bias para LoRA
task_type="CAUSAL_LM", # Tipo de tarefa (Causal Language Modeling)
)
# 3. Carregar e Preparar o Conjunto de Dados
# Carregando um dataset de exemplo do Hugging Face
# Para um dataset de programação, use um formato de instrução/resposta
dataset = load_dataset("imdb", split="train[:1000]") # Exemplo: dataset de análise de sentimento
# O SFTTrainer espera uma coluna de texto. Você pode formatar seus dados.
# No caso do imdb, a coluna é 'text'.
# Para programação, você criaria uma função para formatar o prompt/resposta em uma única string de texto.
# 4. Configurar os Argumentos de Treinamento
training_args = TrainingArguments(
output_dir="./qlora_results",
per_device_train_batch_size=2,
gradient_accumulation_steps=4, # Acumula gradientes para um batch size efetivo maior
optim="paged_adamw_32bit", # Otimizador paginado para eficiência de memória
save_steps=50,
logging_steps=10,
learning_rate=2e-4,
num_train_epochs=1,
fp16=False, # Definir como True se a sua GPU suportar, bf16 se for Ampere ou superior
bf16=True, # Exemplo para GPUs compatíveis como A100, RTX 30/40 series
)
# 5. Inicializar e Treinar o SFTTrainer
trainer = SFTTrainer(
model=model,
train_dataset=dataset,
peft_config=lora_config,
tokenizer=AutoTokenizer.from_pretrained(model_id, trust_remote_code=True),
args=training_args,
dataset_text_field="text", # Nome da coluna com o texto a ser treinado
max_seq_length=512, # Comprimento máximo da sequência
)
# Iniciar o treinamento
trainer.train()
# 6. Salvar o Adaptador (LoRA)
# O modelo completo não é salvo, apenas os pesos do adaptador QLoRA
trainer.model.save_pretrained("./meu_adaptador_qlora")
Após o treinamento, o arquivo salvo em ./meu_adaptador_qlora conterá apenas os adaptadores LoRA (alguns MB), que podem ser carregados sobre o modelo base original quantizado para uso (inferência).

