PEFT documentation

Tour rápido

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

and get access to the augmented documentation experience

to get started

Tour rápido

PEFT ofrece métodos eficientes en parámetros para el ajuste fino de modelos preentrenados de gran tamaño. El paradigma tradicional consiste en ajustar todos los parámetros de un modelo para cada tarea descendente, pero esto se está volviendo extremadamente costoso e impráctico debido al enorme número de parámetros en los modelos actuales. En su lugar, es más eficiente entrenar un número menor de parámetros de indicación o utilizar un método de reparametrización, como la adaptación de bajo rango (LoRA), para reducir la cantidad de parámetros entrenables.

PEFT puede considerarse un marco de trabajo para añadir parámetros entrenables en lugares arbitrarios de modelos existentes ("modelos base"). Los métodos específicos de PEFT organizan los parámetros entrenables de ciertas maneras o modifican el proceso de entrenamiento para lograr un rendimiento de ajuste fino comparable al de entrenar todos los parámetros del modelo base.

En esta introducción rápida se muestran las funciones principales de PEFT y cómo puedes entrenar o ejecutar inferencia en modelos grandes que normalmente serían inaccesibles en dispositivos de consumo.

Configuración de PEFT y modelo

Para cualquier método de PEFT, es necesario crear una configuración que contenga todos los parámetros que especifican cómo debe aplicarse el método de PEFT, y sobre todo, qué capas del modelo existente se deben seleccionar para los parámetros entrenables. Una vez configurada, pásala a la función get_peft_model() junto con el modelo base para crear un PeftModel entrenable.

Usaremos LoRA como ejemplo, pero solo discutiremos los parámetros comunes; es posible que desees utilizar uno de los muchos otros métodos PEFT. La configuración generalmente implica lo siguiente:

  • target_modules: qué módulos del modelo base adaptar
  • task_type (por defecto: None, ver TaskType disponibles): la naturaleza de la tarea entrenada; si se proporciona, puede ayudar a guardar automáticamente las capas relevantes junto con los pesos del adaptador o advertirte sobre incompatibilidades
  • inference_mode (predeterminado: False): si estás usando el modelo para inferencia o no

Según el método de PEFT que elijas, añadirás parámetros específicos que, por ejemplo, determinan el tamaño de las matrices de actualización. Aquí tienes un ejemplo de una configuración que podrías encontrar en la práctica:

from peft import LoraConfig, TaskType

peft_config = LoraConfig(target_modules=["q_proj"], task_type=TaskType.CAUSAL_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1)

Consulte la guía de configuración para obtener más detalles sobre cómo funciona la configuración de PEFT por debajo.

Una vez que se configura el LoraConfig, cree un PeftModel con la función get_peft_model(). Esta toma un modelo base, que puede (pero no es obligatorio) cargar desde la biblioteca Transformers, y el LoraConfig que contiene los parámetros para configurar un modelo para el entrenamiento con LoRA.

Cargue el modelo base que desea ajustar.

from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")

Ahora envuelve el modelo base y peft_config con la función get_peft_model() para crear un PeftModel.

Wrapping significa que PEFT reemplaza las capas objetivo (en este caso: todas las capas q_proj) con la capa específica del adaptador para el tipo de capa objetivo. Dado que estamos tratando con capas lineales, en este caso será una capa lora.Linear. Tenga en cuenta que estos cambios se realizan in-place para ahorrar memoria, por lo que su modelo base queda modificado.

Tenga en cuenta que solo hemos especificado q_proj, pero en realidad estamos dirigiéndonos a todas las capas model.layers[:].self_attn.q_proj. Esto se debe a que PEFT busca prefijos coincidentes de forma predeterminada. Pase una cadena con una expresión regular si desea dirigirse a patrones de capas más complejos.

La capa del modelo base se envolverá, se conservará y no se entrenará, mientras se añaden y combinan nuevos pesos entrenables. La forma en que se estructuran estos nuevos pesos y se combinan con los pesos del modelo base es una parte importante de lo que distingue a los diferentes métodos de PEFT.

Antes de iniciar el entrenamiento, ejecute una comprobación de estado para confirmar el estado del adaptador e inspeccionar el número de parámetros entrenables.

from peft import get_peft_model, LoraConfig

peft_config = LoraConfig()  # or your other PEFT method of choice
peft_model = get_peft_model(model, peft_config)
peft_model.print_healthcheck()

El healthcheck incluye la fracción de parámetros entrenables junto con el estado del adaptador, la configuración del modelo y el entorno.

Ejecutar una comprobación de estado

Use print_healthcheck() para identificar estados sospechosos, como adaptadores fusionados o inconsistentes, y para crear un informe compacto para un informe de error.

peft_model.print_healthcheck()

Esto debería mostrar algo como:

PEFT healthcheck
Model:
  ID: meta-llama/Llama-3.2-1B, type: LlamaForCausalLM, adapters: default (LORA)
Environment:
  peft: 0.21.0, transformers: 5.18.0.dev0, torch: 2.14.0+cu130, Python: 3.13.9
Runtime:
  training: True, devices: cpu, dtypes: bfloat16=1,235,814,400, float32=851,968, gradient checkpointing: False
Parameters:
  trainable: 851,968, total: 1,236,666,368, percent trainable: 0.0689%, adapter layers: 32
State:
  adapter is enabled: True, active: default, merged: none
Layer types:
  default:
    lora.Linear=32

La salida de impresión está sujeta a cambios, no intente analizarla. Para uso programático, llame a healthcheck() en su lugar, que devuelve la misma información como un diccionario serializable en JSON.

¡Eso es todo 🎉! Ahora puedes entrenar el modelo con el Trainer de Transformers, Accelerate o cualquier bucle de entrenamiento personalizado de PyTorch.

Por ejemplo, para entrenar con la clase Trainer, configure una clase TrainingArguments con algunos hiperparámetros de entrenamiento.

training_args = TrainingArguments(
    output_dir="your-name/meta-llama/my-llama3.2-adapter",
    learning_rate=1e-3,
    per_device_train_batch_size=32,
    per_device_eval_batch_size=32,
    num_train_epochs=2,
    weight_decay=0.01,
    eval_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
)

Pasa el modelo, los argumentos de entrenamiento, el conjunto de datos, el tokenizador y cualquier otro componente necesario al Trainer y llama a train para iniciar el entrenamiento.

trainer = Trainer(
    model=peft_model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["test"],
    data_collator=data_collator,
    compute_metrics=compute_metrics,
)

trainer.train()

Guardar modelo

Cuando tu modelo termina de entrenarse, puedes guardarlo en un directorio usando la función save_pretrained().

peft_model.save_pretrained("output_dir")

También puedes guardar tu modelo en el Hub (asegúrate de haber iniciado sesión en tu cuenta de Hugging Face primero) con la función push_to_hub.

from huggingface_hub import notebook_login

notebook_login()
peft_model.push_to_hub("your-name/my-llama3.2-adapter")

Ambos métodos solo guardan los pesos adicionales de PEFT que se entrenaron, lo que los hace muy eficientes de almacenar, transferir y cargar. Por ejemplo, este modelo facebook/opt-350m entrenado con LoRA solo contiene dos archivos: adapter_config.json y adapter_model.safetensors. ¡El archivo adapter_model.safetensors solo tiene 6,3 MB!

Los pesos del adaptador para un modelo opt-350m almacenado en el Hub son de solo ~6MB en comparación con el tamaño completo de los pesos del modelo, que puede ser de ~700MB.

Inferencia

Consulte la referencia de la API de AutoPeftModel para obtener una lista completa de las clases AutoPeftModel disponibles.

Carga fácilmente cualquier modelo entrenado con PEFT para inferencia con la clase AutoPeftModel y el método from_pretrained:

from peft import AutoPeftModelForCausalLM
from transformers import AutoTokenizer
import torch

device = torch.accelerator.current_accelerator().type if hasattr(torch, "accelerator") else "cuda"

peft_model = AutoPeftModelForCausalLM.from_pretrained("ybelkada/opt-350m-lora")
tokenizer = AutoTokenizer.from_pretrained("facebook/opt-350m")

peft_model = peft_model.to(device)
peft_model.eval()
inputs = tokenizer("Preheat the oven to 350 degrees and place the cookie dough", return_tensors="pt")

outputs = peft_model.generate(input_ids=inputs["input_ids"].to(peft_model.device), max_new_tokens=50)
print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0])

"Preheat the oven to 350 degrees and place the cookie dough in the center of the oven. In a large bowl, combine the flour, baking powder, baking soda, salt, and cinnamon. In a separate bowl, combine the egg yolks, sugar, and vanilla."

Para otras tareas que no se admiten explícitamente con una clase AutoPeftModelFor, como el reconocimiento automático de voz, aún puedes usar la clase base AutoPeftModel para cargar un modelo para la tarea.

from peft import AutoPeftModel

peft_model = AutoPeftModel.from_pretrained("smangrul/openai-whisper-large-v2-LORA-colab")

La forma más general de cargar un adaptador PEFT entrenado en un modelo es usar from_pretrained():

from transformers import AutoPeftModelForCausalLM
from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained("meta-llama/llama3.2-1B")
peft_model = PeftModel.from_pretrained(base_model, "my-user/my-llama-adapter")  # you can also pass a directory instead of a hub path

Varios adaptadores

PEFT permite instalar varios adaptadores (del mismo tipo, en este documento se trata de LoRA) sobre un modelo base. Al llamar a get_peft_model, solo hay un adaptador llamado "default", pero puedes añadir tantos adaptadores adicionales como quieras llamando a peft_model.add_adapter(adapter_name=...).

Esto funciona porque la capa envuelta tiene en realidad un conjunto único de pesos entrenables para cada nombre de adaptador. No todos los adaptadores están activos y entrenables de forma predeterminada. Debes habilitar explícitamente los adaptadores por nombre antes de que estén activos. Esto te permite cambiar rápidamente entre adaptadores cuando se necesita conocimiento específico de la tarea o servir diferentes casos de uso sobre un mismo modelo.

Recuerda llamar primero a peft_model.set_adapter(<adapter_name>) para habilitar el adaptador.

Ejemplo rápido:

peft_model.add_adapter(adapter_name='new_adapter')
peft_model.set_adapter('new_adapter')

Próximos pasos

Ahora que has visto cómo entrenar un modelo con uno de los métodos de PEFT, te animamos a probar algunos de los otros métodos, como prompt tuning. Los pasos son muy similares a los mostrados en el quicktour:

  1. prepara un PeftConfig para un método PEFT, por ejemplo, un LoraConfig u otra configuración (consulta el resumen de métodos)
  2. usa el método get_peft_model() para crear un PeftModel a partir de la configuración y el modelo base

¡Entonces puedes entrenarlo como prefieras! Para cargar un modelo PEFT para inferencia, puedes usar la clase AutoPeftModel.

Siéntase libre de consultar también las guías de tareas si le interesa entrenar un modelo con otro método PEFT para una tarea específica, como segmentación semántica, reconocimiento automático de voz multilingüe, DreamBooth, clasificación de tokens, entre otras.

Update on GitHub