TRL documentation
Integración de PEFT
Integración de PEFT
TRL admite métodos de PEFT (ajuste fino de parámetros eficientes) para el entrenamiento de modelos eficiente en memoria. PEFT permite realizar el ajuste fino de modelos de lenguaje grandes entrenando solo un pequeño número de parámetros adicionales mientras se mantiene el modelo base congelado, lo que reduce significativamente los costos computacionales y los requisitos de memoria.
Esta guía explica cómo usar PEFT con diferentes entrenadores de TRL, incluidas las técnicas de LoRA, QLoRA y prompt tuning.
Para un ejemplo completo y funcional, consulte el cuaderno de SFT con LoRA/QLoRA.
Instalación
Para usar PEFT con TRL, instale las dependencias necesarias:
pip install trl[peft]
Para el soporte de QLoRA (cuantización de 4 bits y 8 bits), instale también:
pip install bitsandbytes
Inicio rápido
Todos los entrenadores de TRL admiten PEFT a través del argumento peft_config. La forma más sencilla de habilitar PEFT es utilizar la interfaz de línea de comandos con la bandera --use_peft:
python trl/scripts/sft.py \
--model_name_or_path Qwen/Qwen2-0.5B \
--dataset_name trl-lib/Capybara \
--use_peft \
--lora_r 32 \
--lora_alpha 16 \
--output_dir Qwen2-0.5B-SFT-LoRAAlternativamente, puede pasar una configuración de PEFT directamente en su código de Python:
from peft import LoraConfig
from trl import SFTTrainer
# Configure LoRA
peft_config = LoraConfig(
r=32,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# Configure training - note the higher learning rate for LoRA (10x base rate)
training_args = SFTConfig(
learning_rate=2.0e-4, # 10x the base rate (2.0e-5) for LoRA
...
)
# Create trainer with PEFT
trainer = SFTTrainer(
model=model,
train_dataset=dataset,
peft_config=peft_config,
)Tres formas de configurar PEFT
TRL ofrece tres métodos diferentes para configurar PEFT, cada uno adecuado para distintos casos de uso:
1. Uso de banderas de CLI (el más simple)
La forma más sencilla de habilitar PEFT es usar la bandera --use_peft con la interfaz de línea de comandos. Este método es ideal para experimentos rápidos y configuraciones estándar:
python trl/scripts/sft.py \
--model_name_or_path Qwen/Qwen2-0.5B \
--dataset_name trl-lib/Capybara \
--use_peft \
--lora_r 32 \
--lora_alpha 16 \
--lora_dropout 0.05 \
--output_dir Qwen2-0.5B-SFT-LoRAVentajas: Configuración rápida, no requiere código
Desventajas: Limitado a LoRA, menos opciones de personalización
2. Pasar peft_config a Trainer (Recomendado)
Para tener más control, pase una configuración de PEFT directamente al entrenador. Este es el enfoque recomendado para la mayoría de los casos de uso:
from peft import LoraConfig
from trl import SFTConfig, SFTTrainer
peft_config = LoraConfig(
r=32,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
)
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=dataset,
peft_config=peft_config, # Pass config here
)Ventajas: Control total, admite todos los métodos de PEFT (LoRA, Prompt Tuning, etc.)
Desventajas: Requiere código de Python
3. Aplicar PEFT directamente al modelo (avanzado)
Para obtener la máxima flexibilidad, puedes aplicar PEFT a tu modelo antes de pasarlo al trainer:
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
from trl import SFTConfig, SFTTrainer
# Load base model
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-0.5B")
# Apply PEFT configuration
peft_config = LoraConfig(
r=32,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
model = get_peft_model(model, peft_config)
# Pass PEFT-wrapped model to trainer
trainer = SFTTrainer(
model=model, # Already has PEFT applied
args=training_args,
train_dataset=dataset,
# Note: no peft_config needed here
)Ventajas: Control máximo, útil para arquitecturas de modelos personalizadas o configuraciones complejas
Desventajas: Más verboso, requiere comprender los detalles internos de PEFT
Consideraciones sobre la tasa de aprendizaje
Al utilizar LoRA u otros métodos PEFT, normalmente se necesita emplear una taxa de aprendizaje más alta (aproximadamente 10 veces) en comparación con el ajuste fino completo. Esto se debe a que los métodos PEFT entrenan solo una pequeña fracción de los parámetros, lo que requiere una tasa de aprendizaje mayor para lograr actualizaciones de parámetros similares.
Tasas de aprendizaje recomendadas:
| Trainer | Ajuste fino completo | Con LoRA (10x) |
|---|---|---|
| SFT | 2.0e-5 | 2.0e-4 |
| DPO | 5.0e-7 | 5.0e-6 |
| GRPO | 1.0e-6 | 1.0e-5 |
| Ajuste de prompts | N/A | de 1.0e-2 a 3.0e-2 |
¿Por qué 10x? Los adaptadores LoRA tienen significativamente menos parámetros entrenables que el modelo completo. Una tasa de aprendizaje más alta compensa esta reducción en el número de parámetros, garantizando un entrenamiento efectivo. Para una explicación detallada, consulte esta publicación de blog.
Para obtener más mejores prácticas sobre el uso efectivo de LoRA, consulte la documentación de LoRA Without Regret.
PEFT con diferentes entrenadores
Los entrenadores de TRL admiten configuraciones de PEFT para diversos paradigmas de entrenamiento. A continuación se muestran ejemplos detallados para cada entrenador principal.
Ajuste fino supervisado (SFT)
El SFTTrainer se utiliza para el ajuste fino supervisado en conjuntos de datos de instrucciones.
Con LoRA
python trl/scripts/sft.py \
--model_name_or_path Qwen/Qwen2-0.5B \
--dataset_name trl-lib/Capybara \
--learning_rate 2.0e-4 \
--num_train_epochs 1 \
--per_device_train_batch_size 2 \
--gradient_accumulation_steps 8 \
--use_peft \
--lora_r 32 \
--lora_alpha 16 \
--output_dir Qwen2-0.5B-SFT-LoRAEjemplo en Python
from peft import LoraConfig
from trl import SFTConfig, SFTTrainer
# Configure LoRA
peft_config = LoraConfig(
r=32,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
target_modules=["q_proj", "v_proj"], # optional: specify target modules
)
# Configure training with higher learning rate for LoRA
training_args = SFTConfig(
learning_rate=2.0e-4, # 10x the base rate for LoRA
...
)
# Create trainer with PEFT config
trainer = SFTTrainer(
model="Qwen/Qwen2-0.5B", # can pass model name or loaded model
args=training_args,
train_dataset=dataset,
peft_config=peft_config, # pass PEFT config here
)
trainer.train()Optimización de Preferencias Directas (DPO)
El DPOTrainer implementa el aprendizaje de preferencias a partir de la retroalimentación humana.
Con LoRA
python trl/scripts/dpo.py \
--model_name_or_path Qwen/Qwen2-0.5B-Instruct \
--dataset_name trl-lib/ultrafeedback_binarized \
--learning_rate 5.0e-6 \
--per_device_train_batch_size 2 \
--gradient_accumulation_steps 8 \
--use_peft \
--lora_r 32 \
--lora_alpha 16 \
--output_dir Qwen2-0.5B-DPO-LoRAEjemplo en Python
from peft import LoraConfig
from trl import DPOConfig, DPOTrainer
# Configure LoRA
peft_config = LoraConfig(
r=32,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# Configure training with higher learning rate for LoRA
training_args = DPOConfig(
learning_rate=5.0e-6, # 10x the base rate for DPO with LoRA
...
)
# Create trainer with PEFT config
trainer = DPOTrainer(
model="Qwen/Qwen2-0.5B", # can pass model name or loaded model
args=training_args,
train_dataset=dataset,
peft_config=peft_config, # pass PEFT config here
)
trainer.train()Nota: Al usar PEFT con DPO, no es necesario proporcionar un modelo de referencia separado (ref_model). El entrenador utiliza automáticamente el modelo base congelado como referencia.
Optimización de Política Relativa por Grupos (GRPO)
El GRPOTrainer optimiza las políticas utilizando recompensas basadas en grupos.
Con LoRA
python trl/scripts/grpo.py \
--model_name_or_path Qwen/Qwen2-0.5B \
--dataset_name trl-lib/math-reasoning \
--learning_rate 1.0e-5 \
--per_device_train_batch_size 2 \
--use_peft \
--lora_r 32 \
--lora_alpha 16 \
--output_dir Qwen2-0.5B-GRPO-LoRAEjemplo en Python
from peft import LoraConfig
from trl import GRPOConfig, GRPOTrainer
# Configure LoRA
peft_config = LoraConfig(
r=32,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# Configure training with higher learning rate for LoRA
training_args = GRPOConfig(
learning_rate=1.0e-5, # 10x the base rate for GRPO with LoRA
...
)
# Create trainer with PEFT config
trainer = GRPOTrainer(
model="Qwen/Qwen2-0.5B", # can pass model name or loaded model
args=training_args,
train_dataset=dataset,
peft_config=peft_config, # pass PEFT config here
)
trainer.train()QLoRA: Adaptación de bajo rango cuantizada
QLoRA combina la cuantización de 4 bits con LoRA para permitir el ajuste fino de modelos muy grandes en hardware de consumo. Esta técnica puede reducir los requisitos de memoria hasta 4 veces en comparación con LoRA estándar.
Cómo funciona QLoRA
- Cuantización de 4 bits: El modelo base se carga en precisión de 4 bits usando
bitsandbytes - Pesos congelados: Los pesos del modelo cuantizado permanecen congelados durante el entrenamiento
- Adaptadores LoRA: Solo los parámetros del adaptador LoRA se entrenan con mayor precisión
- Eficiencia de memoria: Permite el ajuste fino de modelos como Llama-70B en una sola GPU de consumo
Usar QLoRA con TRL
Simplemente combine load_in_4bit=True con la configuración de PEFT:
Línea de comandos
python trl/scripts/sft.py \
--model_name_or_path meta-llama/Llama-2-7b-hf \
--dataset_name trl-lib/Capybara \
--load_in_4bit \
--use_peft \
--lora_r 32 \
--lora_alpha 16 \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 16 \
--output_dir Llama-2-7b-QLoRAEjemplo en Python
Pasa quantization_config directamente al trainer junto con peft_config: el trainer carga y cuantiza el modelo por ti. El mismo argumento quantization_config está disponible en SFTTrainer, DPOTrainer, GRPOTrainer y RLOOTrainer.
import torch
from peft import LoraConfig
from transformers import BitsAndBytesConfig
from trl import SFTConfig, SFTTrainer
# Configure 4-bit quantization
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
)
# Configure LoRA
peft_config = LoraConfig(
r=32,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# Configure training with higher learning rate for LoRA
training_args = SFTConfig(
learning_rate=2.0e-4, # 10x the base rate for QLoRA
...
)
# Create trainer with quantization and PEFT config
trainer = SFTTrainer(
model="meta-llama/Llama-2-7b-hf",
args=training_args,
train_dataset=dataset,
quantization_config=bnb_config,
peft_config=peft_config,
)
trainer.train()Opciones de configuración de QLoRA
La BitsAndBytesConfig ofrece varias opciones para optimizar la memoria y el rendimiento:
import torch
from transformers import BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # or "fp4"
bnb_4bit_compute_dtype=torch.bfloat16, # Compute dtype for 4-bit base models
bnb_4bit_use_double_quant=True, # Nested quantization for additional memory savings
)Parámetros de configuración:
bnb_4bit_quant_type: Tipo de datos de cuantización ("nf4"o"fp4"). Se recomienda NF4.bnb_4bit_compute_dtype: El dtype utilizado para el cálculo. Utilicebfloat16para una mayor estabilidad en el entrenamiento.bnb_4bit_use_double_quant: Habilita la cuantización anidada para ahorrar aproximadamente 0,4 bits adicionales por parámetro.
Cuantización de 8 bits
Para una precisión ligeramente mayor con un ahorro de memoria reducido, puedes usar cuantización de 8 bits:
from transformers import BitsAndBytesConfig, AutoModelForCausalLM
bnb_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
quantization_config=bnb_config,
device_map="auto",
)O mediante la línea de comandos:
python trl/scripts/sft.py \
--model_name_or_path meta-llama/Llama-2-7b-hf \
--load_in_8bit \
--use_peft \
--lora_r 32 \
--lora_alpha 16Puntos de control pre-cuantizados
Algunos puntos de control se publican cuantizados, como gpt-oss en MXFP4 o Mistral Medium 3.5 en FP8. Estos pesos no se pueden entrenar in situ, por lo que, al pasar un punto de control de este tipo por nombre, el entrenador lo carga descuantizado, con o sin peft_config. El modelo ocupa entonces la memoria de sus pesos descuantizados, por ejemplo, unos 42 GB en bfloat16 para gpt-oss-20b, frente a 13 GB de su punto de control en MXFP4. Para cargarlo en bfloat16, como cualquier otro modelo:
from trl import SFTConfig
training_args = SFTConfig(model_init_kwargs={"dtype": "bfloat16"})Los puntos de control FP8 requieren transformers 5.0.0 o posterior.
Prompt Tuning
El ajuste de prompts (prompt tuning) es otra técnica de PEFT que aprende prompts suaves (incrustaciones continuas) que se antepone a la entrada, manteniendo el modelo completo congelado. Esto resulta especialmente eficaz para modelos grandes.
Cómo funciona el ajuste de prompts
- Virtual Tokens: Añade incrustaciones continuas aprendibles (tokens virtuales) a la entrada
- Modelo congelado: Todo el modelo base permanece congelado
- Indicadores específicos de la tarea: Cada tarea aprende sus propios incrustados de indicador
- Eficiencia extrema: solo se entrenan los embeddings del prompt (típicamente 8-20 tokens)
Usar Prompt Tuning con TRL
from peft import PromptTuningConfig, PromptTuningInit, TaskType
from trl import SFTConfig, SFTTrainer
# Configure Prompt Tuning
peft_config = PromptTuningConfig(
task_type=TaskType.CAUSAL_LM,
prompt_tuning_init=PromptTuningInit.TEXT,
num_virtual_tokens=8,
prompt_tuning_init_text="Classify if the tweet is a complaint or not:",
tokenizer_name_or_path="Qwen/Qwen2-0.5B",
)
# Configure training with higher learning rate for Prompt Tuning
training_args = SFTConfig(
learning_rate=2.0e-2, # Prompt Tuning typically uses 1e-2 to 3e-2
...
)
# Create trainer with PEFT config
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=dataset,
peft_config=peft_config, # pass PEFT config here
)
trainer.train()Configuración de Prompt Tuning
from peft import PromptTuningConfig, PromptTuningInit, TaskType
peft_config = PromptTuningConfig(
task_type=TaskType.CAUSAL_LM, # Task type
prompt_tuning_init=PromptTuningInit.TEXT, # Initialize from text
num_virtual_tokens=8, # Number of virtual tokens
prompt_tuning_init_text="Your initialization text here",
tokenizer_name_or_path="model_name",
)Parámetros de configuración:
task_type: El tipo de tarea (TaskType.CAUSAL_LMpara modelado de lenguaje)prompt_tuning_init: Método de inicialización (TEXT,RANDOM)num_virtual_tokens: Número de tokens virtuales que se añadirán al principio (normalmente 8-20)prompt_tuning_init_text: Texto para inicializar los tokens virtuales (cuando se usa la inicializaciónTEXT)tokenizer_name_or_path: Tokenizador para inicializar desde texto
Prompt Tuning frente a LoRA
| Característica | Prompt Tuning | LoRA |
|---|---|---|
| Parámetros entrenados | ~0.001% | ~0.1-1% |
| Uso de memoria | Mínimo | Bajo |
| Velocidad de entrenamiento | Más rápido | Rápido |
| Modificación de modelos | Ninguno | Capas de adaptador |
| Mejor para | Modelos grandes, muchas tareas | Ajuste fino general |
| Tasa de aprendizaje | Más alto (1e-2 a 3e-2) | Estándar (1e-4 a 3e-4) |
Configuraciones avanzadas de PEFT
Parámetros de configuración de LoRA
from peft import LoraConfig
peft_config = LoraConfig(
r=16, # LoRA rank
lora_alpha=32, # LoRA scaling factor
lora_dropout=0.05, # Dropout probability
bias="none", # Bias training strategy
task_type="CAUSAL_LM", # Task type
target_modules=["q_proj", "v_proj"], # Modules to apply LoRA
modules_to_save=None, # Additional modules to train
)Parámetros clave:
r: rango de LoRA (valores típicos: 8, 16, 32, 64). Un rango más alto implica más parámetros, pero puede ofrecer un mejor rendimiento.lora_alpha: Factor de escala (típicamente 2 veces el rango). Controla la magnitud de las actualizaciones de LoRA.lora_dropout: Probabilidad de dropout para las capas de LoRA (típico: 0.05-0.1).target_modules: Módulos a los que se aplicará LoRA. Opciones habituales:["q_proj", "v_proj"]: Consulta y valor de atención (eficiente en memoria)["q_proj", "k_proj", "v_proj", "o_proj"]: Todas las proyecciones de atención["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]: Todas las capas lineales
modules_to_save: Módulos adicionales para entrenar por completo (p. ej.,["embed_tokens", "lm_head"])
Selección del módulo objetivo
Puede especificar a qué módulos se aplica LoRA. Patrones comunes:
# Minimal (most memory efficient)
target_modules=["q_proj", "v_proj"]
# Attention only
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"]
# All linear layers (best performance, more memory)
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]Uso de argumentos de línea de comandos
Los scripts de TRL aceptan parámetros de PEFT a través de la línea de comandos:
python trl/scripts/sft.py \
--model_name_or_path Qwen/Qwen2-0.5B \
--dataset_name trl-lib/Capybara \
--use_peft \
--lora_r 32 \
--lora_alpha 16 \
--lora_dropout 0.05 \
--lora_target_modules q_proj v_proj \
--output_dir outputBanderas disponibles:
--use_peft: Habilitar PEFT--lora_r: rango de LoRA (predeterminado: 16)--lora_alpha: alpha de LoRA (predeterminado: 32)--lora_dropout: dropout de LoRA (predeterminado: 0.05)--lora_target_modules: Módulos objetivo (separados por espacios)--lora_modules_to_save: Módulos adicionales para entrenar--use_rslora: Habilitar LoRA con rango estabilizado--use_dora: Habilita Weight-Decomposed LoRA (DoRA)--load_in_4bit: Habilita la cuantización de 4 bits (QLoRA)--load_in_8bit: Habilita la cuantización de 8 bits
Guardar y cargar modelos PEFT
Guardado
Después del entrenamiento, guarda tus adaptadores PEFT:
# Save the adapters
trainer.save_model("path/to/adapters")
# Or manually
model.save_pretrained("path/to/adapters")Esto guarda solo los pesos del adaptador (unos pocos MB) en lugar del modelo completo (varios GB).
Cargando
Cargue un modelo PEFT para inferencia:
from transformers import AutoModelForCausalLM
from peft import PeftModel
# Load base model
base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-0.5B")
# Load PEFT adapters
model = PeftModel.from_pretrained(base_model, "path/to/adapters")
# Optionally merge adapters into base model for faster inference
model = model.merge_and_unload()Subir al Hub
Puedes compartir fácilmente tus adaptadores PEFT en el Hugging Face Hub:
# Push adapters to Hub
model.push_to_hub("username/model-name-lora")
# Load from Hub
from peft import PeftModel
model = PeftModel.from_pretrained(base_model, "username/model-name-lora")Entrenamiento con múltiples GPU
PEFT funciona a la perfección con la compatibilidad de TRL para múltiples GPU:
torchrun --nproc_per_node 8 trl/scripts/sft.py \
--model_name_or_path Qwen/Qwen2-0.5B \
--dataset_name trl-lib/Capybara \
--use_peft \
--lora_r 32 \
--lora_alpha 16Para QLoRA con varias GPU, el modelo base se fragmenta automáticamente:
torchrun --nproc_per_node 8 trl/scripts/sft.py \
--model_name_or_path meta-llama/Llama-2-70b-hf \
--load_in_4bit \
--use_peft \
--lora_r 32Paralelismo de pipeline ingenuo (NPP) para modelos grandes
Para modelos muy grandes (>60B parámetros), TRL admite Naive Pipeline Parallelism (NPP), que distribuye el modelo y los adaptadores entre varias GPU. Las activaciones y los gradientes se comunican entre las GPU, admitiendo tanto int8 como otros tipos de datos.

Cómo usar NPP
Carga tu modelo con un device_map personalizado para dividirlo entre varios dispositivos:
from transformers import AutoModelForCausalLM
from peft import LoraConfig
# Create custom device map (see accelerate documentation)
device_map = {
"model.embed_tokens": 0,
"model.layers.0": 0,
# ... distribute layers across GPUs
"lm_head": 0, # Must be on GPU 0
}
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-70b-hf",
device_map=device_map,
peft_config=lora_config,
)
- Mantenga el módulo
lm_headen la primera GPU (dispositivo 0) para evitar errores- Vea este tutorial sobre mapas de dispositivos para una configuración adecuada
- Ejecuta los scripts de entrenamiento directamente (no con
torchrun):python script.py- El paralelismo de datos aún no es compatible con NPP
Recursos
Ejemplos y cuadernos de TRL
- Cuaderno de SFT con LoRA/QLoRA - Ejemplo funcional completo que muestra las implementaciones de LoRA y QLoRA
- Directorio de ejemplos de TRL - Colección de scripts de entrenamiento que demuestran PEFT con diferentes entrenadores
- Recetas del libro de cocina de TRL - Guías paso a paso para escenarios comunes de entrenamiento PEFT
Documentación
- Documentación de PEFT - Documentación oficial de la biblioteca PEFT
- Documentación de TRL - Documentación completa de TRL con guías de entrenadores
- LoRA sin arrepentimientos - Mejores prácticas para usar LoRA de manera efectiva
Artículos de investigación
- Artículo de LoRA - Metodología y resultados originales de LoRA
- Artículo de QLoRA - Ajuste fino eficiente con cuantización de 4 bits
- Artículo sobre Prompt Tuning - El poder de la escala para el ajuste de prompts eficiente en parámetros