TRL documentation

LoRA Sem Arrependimento

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.18.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

LoRA Sem Arrependimento

Pesquisas recentes da equipe do Thinking Machines Lab (Schulman et al., 2025) mostram que o LoRA pode alcançar o mesmo desempenho do fine-tuning completo quando configurado corretamente, utilizando apenas ~67% do poder de computação. Esses achados são empolgantes para os usuários do TRL, pois são fáceis de implementar e podem melhorar o desempenho do modelo com orçamentos menores.

Este guia fornece instruções simples para reproduzir os resultados do post no blog no TRL.

É recomendável ler o post no blog antes de seguir este guia, ou consultar ambos os recursos em paralelo para obter os melhores resultados.

Vantagens do LoRA em relação ao ajuste fino completo

Primeiramente, vamos relembrar os benefícios do LoRA em relação ao fine-tuning completo.

LoRA adiciona camadas de adaptador sobre o modelo base, que contém significativamente menos parâmetros do que o próprio modelo base. Esse design reduz os requisitos de memória de GPU e permite um treinamento mais eficiente. Conforme descrito no blog, acreditava-se originalmente que essa abordagem envolvia um compromisso de desempenho, embora uma configuração cuidadosa possa superar esse compromisso e igualar o desempenho do ajuste fino completo.

Exemplos com TRL

Vamos implementar e treinar adaptadores LoRA em scripts do TRL com base nas principais conclusões do post no blog. Em seguida, revisitaremos cada conclusão à luz dos resultados do TRL.

Ajuste Fino Supervisionado (SFT)

O post do blog executa SFT em uma variedade de modelos e conjuntos de dados do Hub, que podemos reproduzir no TRL.

ModelConjunto de dados
Llama-3.2-1B-Instructallenai/tulu-3-sft-mixture
Llama-3.2-1B-Instructopen-thoughts/OpenThoughts-114k
Llama-3.1-8B-Instructallenai/tulu-3-sft-mixture
Llama-3.1-8B-Instructopen-thoughts/OpenThoughts-114k
python
jobs
local

Podemos integrar essas descobertas com a API Python do TRL da seguinte forma:


from datasets import load_dataset
from peft import LoraConfig
from trl import SFTTrainer, SFTConfig

dataset = load_dataset("open-thoughts/OpenThoughts-114k", split="train")

peft_config = LoraConfig(r=256, lora_alpha=16, target_modules="all-linear")

training_args = SFTConfig(
    learning_rate=2e-4,
    per_device_train_batch_size=1,
    gradient_accumulation_steps=4,
    num_train_epochs=1,
    report_to=["trackio"],
)

trainer = SFTTrainer(
    model="Qwen/Qwen2.5-3B-Instruct",
    train_dataset=dataset,
    peft_config=peft_config,
    args=training_args,
)

trainer.train()

Quando o treinamento começa, você pode monitorar o progresso no Trackio, que registrará a URL.

Aprendizado por Reforço (GRPO)

O post do blog executa GRPO em uma variedade de modelos e conjuntos de dados do Hub, e, mais uma vez, podemos reproduzir os resultados no TRL.

ModelConjunto de dados
Llama-3.1-8B-BaseGSM8k
Llama-3.1-8B-BaseDeepMath-103K
Qwen3-8b-baseDeepMath-103K

Para o aprendizado por reforço, o blog utiliza uma tarefa de raciocínio matemático que podemos reproduzir como uma função em Python.

python
jobs
local

Podemos implementar essas recomendações com a API Python do TRL da seguinte forma:


from datasets import load_dataset
from peft import LoraConfig
from trl import GRPOConfig, GRPOTrainer
from trl.rewards import reasoning_accuracy_reward

dataset = load_dataset("HuggingFaceH4/OpenR1-Math-220k-default-verified", split="train")

peft_config = LoraConfig(
    r=1,
    lora_alpha=32,
    target_modules="all-linear"
)

training_args = GRPOConfig(
    learning_rate=5e-5,
    per_device_train_batch_size=1,
    gradient_accumulation_steps=4,
    num_train_epochs=1,
    num_generations=8,
    generation_batch_size=8,
    report_to=["trackio"],
)

trainer = GRPOTrainer(
    model="Qwen/Qwen3-0.6B",
    reward_funcs=reasoning_accuracy_reward,
    args=training_args,
    train_dataset=dataset,
    peft_config=peft_config,
)

trainer.train()

Este trecho omite a função de recompensa, definida acima, para manter o exemplo conciso.

O script de aprendizado por reforço com GRPO é implementado como um script personalizado no TRL, que utiliza a função de recompensa mostrada acima. Você pode consultá-lo em grpo.py - Boas práticas de aprendizado por reforço com LoRA

Principais descobertas na otimização do LoRA

Os autores recomendam aplicar LoRA a todas as matrizes de pesos, em vez de limitá-lo às camadas de atenção, pois aumentar o rank não compensa essa restrição. No TRL, isso pode ser configurado usando --lora_target_modules all-linear para aplicar LoRA a todas as matrizes de pesos.

Conseguimos reproduzir os resultados do post no blog usando o TRL e o modelo SmolLM3. Treinamos o modelo por 500 passos no conjunto de dados Math 220k com a função de recompensa e a configuração acima. Como você pode ver na figura abaixo, a curva média de recompensa de treinamento do modelo LoRA corresponde à curva de ajuste fino completo.

train reward

E, o mais importante, o modelo LoRA usa significativamente menos memória do que o modelo de ajuste fino completo, como podemos ver na figura abaixo.

memory usage

Aqui estão os parâmetros que usamos para treinar os modelos acima

ParâmetroLoRAFT completo
--model_name_or_pathHuggingFaceTB/SmolLM3-3BHuggingFaceTB/SmolLM3-3B
--dataset_nameHuggingFaceH4/OpenR1-Math-220k-default-verifiedHuggingFaceH4/OpenR1-Math-220k-default-verified
--learning_rate1.0e-51.0e-6
--max_completion_length40964096
--lora_r1-
--lora_alpha32-
--lora_dropout0.0-
--lora_target_modulesall-linear-

Vamos detalhar as principais conclusões do post no blog e como conseguimos reproduzi-las.

1. O LoRA apresenta melhor desempenho quando aplicado a todas as matrizes de pesos

Os autores recomendam aplicar o LoRA a todas as matrizes de pesos, em vez de limitá-lo às camadas de atenção, pois aumentar o rank não compensa essa restrição.

all layers

LoRA apenas em camadas de atenção apresenta desempenho inferior mesmo ao usar um rank maior para igualar a contagem de parâmetros. No TRL, isso pode ser configurado usando --lora_target_modules all-linear para aplicar LoRA a todas as matrizes de pesos. Em Python, podemos fazer isso da seguinte forma:

from peft import LoraConfig  

peft_config = LoraConfig(target_modules="all-linear")  

2. O adaptador precisa de capacidade suficiente para aprender a partir do conjunto de dados

O post no blog recomenda usar um rank de LoRA suficiente para aprender a partir do conjunto de dados. O rank determina o número de parâmetros treináveis no adaptador LoRA. Portanto, “Para conjuntos de dados que excedem a capacidade do LoRA, o LoRA tem desempenho inferior ao FullFT”.

learning rate

No script do TRL, podemos usar --lora_r para definir o rank e ajustá-lo com base na tarefa e no conjunto de dados em que estamos treinando. O post no blog recomenda os seguintes ranks com base na tarefa e no tamanho do conjunto de dados:

Tarefas de aprendizado por reforço geralmente exigem menor capacidade, portanto, é possível usar ranks de LoRA menores. Isso ocorre porque os algoritmos de gradiente de política extraem aproximadamente ~1 bit de informação por episódio, exigindo uma capacidade de parâmetros mínima.

O post no blog define o tamanho ideal do conjunto de dados para o LoRA, para corresponder ao fine-tuning completo, como “Escala de pós-treino”. O que podemos usar para determinar o rank recomendado para LoRAs de SFT e RL como:

Tipo de TarefaTamanho do Conjunto de DadosRank Recomendado
SFTEscala de pós-treino256
RLQualquer tamanho1-32

3. “FullFT e LoRAs de alta ordem têm curvas de aprendizado semelhantes”

Contraintuitivamente, o post do blog recomenda usar uma taxa de aprendizado maior do que a utilizada no fine-tuning completo. Na tabela acima, usamos 1.0e-5 para LoRA e 1.0e-6 para fine-tuning completo. No script do TRL, poderíamos usar --learning_rate para definir a taxa de aprendizado. O 1r \frac{1}{r} escalonamento no LoRA torna a taxa de aprendizado ótima aproximadamente independente do rank.

learning rate

4. “Em alguns cenários, o LoRA é menos tolerante a tamanhos de lote grandes do que o ajuste fino completo.”

O post no blog recomenda o uso de um tamanho de lote efetivo < 32, pois os autores constataram que o LoRA é menos tolerante a tamanhos de lote grandes. Isso não pôde ser mitigado aumentando o rank do LoRA. No script do TRL, podemos usar --per_device_train_batch_size e --gradient_accumulation_steps para definir o tamanho do lote.

learning rate

Principais pontos

Usando o TRL, você pode implementar adaptadores LoRA de forma eficiente para corresponder ao desempenho do fine-tuning completo, aplicando os principais insights (direcionar todas as matrizes de pesos, escolher o rank adequado e gerenciar o tamanho do lote e a taxa de aprendizado) sem o alto custo computacional do FullFT.

Citação

@article{schulman2025lora,  
    title        = {{LoRA Without Regret}},  
    author       = {John Schulman and Thinking Machines Lab},  
    year         = 2025,  
    journal      = {Thinking Machines Lab: Connectionism},  
    doi          = {10.64434/tml.20250929},  
    note         = {https://thinkingmachines.ai/blog/lora/}  
}  
Update on GitHub