# Ajuste fino eficiente en parámetros

Los métodos de [ajuste fino eficiente en parámetros (PEFT)](https://huggingface.co/docs/peft/index) solo ajustan un número pequeño de parámetros adicionales del modelo (adaptadores) sobre un modelo preentrenado. Dado que solo se actualizan los parámetros de los adaptadores, el optimizador rastrea muchas menos gradiente y estados, lo que reduce significativamente el uso de memoria. Los adaptadores son ligeros, lo que facilita su intercambio, almacenamiento y carga.

Transformers se integra directamente con la biblioteca PEFT a través de [PeftAdapterMixin](/docs/transformers/main/es/main_classes/peft#transformers.integrations.PeftAdapterMixin), que se ha añadido a todas las clases [PreTrainedModel](/docs/transformers/main/es/main_classes/model#transformers.PreTrainedModel). Puedes cargar, añadir, entrenar, cambiar y eliminar adaptadores sin envolver tu modelo en un [PeftModel](https://huggingface.co/docs/peft/main/en/package_reference/peft_model#peft.PeftModel) separado. Se admiten todos los métodos de PEFT que no se basan en el aprendizaje de prompts (LoRA, IA3, AdaLoRA). Los métodos basados en prompts, como prompt tuning y prefix tuning, requieren el uso directo de la [biblioteca PEFT](https://huggingface.co/docs/peft/index).

Instala PEFT para comenzar. La integración requiere `peft >= 0.20.0`.

```shell
pip install -U peft
```

## Agregar un adaptador

Cree una configuración de PEFT, por ejemplo [LoraConfig](https://huggingface.co/docs/peft/main/en/package_reference/lora#peft.LoraConfig), y asígnela a un modelo con [add_adapter()](/docs/transformers/main/es/main_classes/peft#transformers.integrations.PeftAdapterMixin.add_adapter).

```py
from peft import LoraConfig, TaskType
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("google/gemma-2-2b")

lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    inference_mode=False,
    r=8,
    lora_alpha=32,
    lora_dropout=0.1,
)

model.add_adapter(lora_config, adapter_name="my_adapter")
```

### Ajuste fino completo de capas específicas

Para entrenar módulos adicionales junto con un adaptador (por ejemplo, la cabeza del modelo de lenguaje), especifíquelos en `modules_to_save`. `modules_to_save` especifica las capas que se ajustan por completo junto con el adaptador, por lo que *todos* sus parámetros se actualizan. Esto es útil cuando ciertas capas necesitan actualizaciones, por ejemplo la cabeza del modelo de lenguaje (`lm_head`), al adaptar un LM causal para la clasificación de secuencias.

```py
lora_config = LoraConfig(
    modules_to_save=["lm_head"],
    ...
)
model.add_adapter(lora_config)
```

### Elegir qué capas adaptar

Para las arquitecturas comunes (Llama, Gemma, Qwen, etc.), PEFT tiene objetivos predeterminados (como `q_proj` y `v_proj`), por lo que no es necesario especificar `target_modules`. Si deseas apuntar a capas diferentes, o si el modelo no tiene objetivos predeterminados, pasa `target_modules` explícitamente como una lista de nombres de módulos o un patrón de expresión regular.

```py
lora_config = LoraConfig(
    target_modules=["q_proj", "k_proj"],
    ...
)
model.add_adapter(lora_config)
```

## Entrenamiento

Pase el modelo con un adaptador adjunto a [Trainer](/docs/transformers/main/es/main_classes/trainer#transformers.Trainer) y llame a [train()](/docs/transformers/main/es/main_classes/trainer#transformers.Trainer.train). [Trainer](/docs/transformers/main/es/main_classes/trainer#transformers.Trainer) solo actualiza los parámetros del adaptador (aquellos con `requires_grad=True`) porque el modelo base está congelado.

```py
from transformers import Trainer, TrainingArguments

training_args = TrainingArguments(
    output_dir="./output",
    num_train_epochs=3,
    per_device_train_batch_size=4,
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=dataset,
)

trainer.train()
```

Durante el entrenamiento, los puntos de control de [Trainer](/docs/transformers/main/es/main_classes/trainer#transformers.Trainer) contienen solo los pesos del adaptador (`adapter_model.safetensors`) y la configuración (`adapter_config.json`), lo que mantiene los puntos de control pequeños. El modelo base no se incluye.

Después del entrenamiento, guarda el adaptador final con [save_pretrained()](/docs/transformers/main/es/main_classes/model#transformers.PreTrainedModel.save_pretrained).

```py
model.save_pretrained("./my_adapter")
```

### Reanudar desde un punto de control

[Trainer](/docs/transformers/main/es/main_classes/trainer#transformers.Trainer) detecta automáticamente los puntos de control de adaptadores al reanudar. [Trainer](/docs/transformers/main/es/main_classes/trainer#transformers.Trainer) examina el directorio del punto de control en busca de subdirectorios que contengan pesos de adaptadores y recarga cada adaptador con el estado entrenable correcto.

```py
trainer.train(resume_from_checkpoint="./output/checkpoint-1000")
```

### Entrenamiento distribuido

Los adaptadores de PEFT funcionan con el entrenamiento distribuido sin necesidad de configuración adicional.

Para ZeRO-3, [Trainer](/docs/transformers/main/es/main_classes/trainer#transformers.Trainer) pasa `exclude_frozen_parameters=True` al guardar puntos de control con un modelo PEFT. Se omiten los pesos del modelo base congelado. Solo se guardan los parámetros del adaptador entrenable, lo que reduce el tamaño del punto de control y el tiempo de guardado.

Para FSDP, [Trainer](/docs/transformers/main/es/main_classes/trainer#transformers.Trainer) actualiza la política de auto-envoltura de FSDP para manejar correctamente las capas de LoRA. Para QLoRA (modelo base cuantizado + LoRA), [Trainer](/docs/transformers/main/es/main_classes/trainer#transformers.Trainer) también ajusta la política de precisión mixta para que coincida con el dtype de almacenamiento de la cuantización.

Puedes cargar adaptadores de PEFT en un modelo base con paralelismo de tensores y dejar que PEFT gestione la partición de los pesos del adaptador. Cargar un adaptador requiere `peft >= 0.21.1`. Consulta [Paralelismo de tensores](./tensor_parallelism) para el entrenamiento con TP.

## Carga de un adaptador

Para cargar un adaptador, el repositorio de Hub o el directorio local debe contener un archivo `adapter_config.json` y los pesos del adaptador.

[from_pretrained()](/docs/transformers/main/es/main_classes/model#transformers.PreTrainedModel.from_pretrained) detecta los adaptadores automáticamente. Cuando encuentra un `adapter_config.json`, lee el campo `base_model_name_or_path` para cargar el modelo base correcto y, a continuación, carga el adaptador sobre él.

```py
from transformers import AutoModelForCausalLM

# Automatically loads the base model and attaches the adapter
model = AutoModelForCausalLM.from_pretrained("klcsp/gemma7b-lora-alpaca-11-v1")
```

Para cargar un adaptador en un modelo existente, use [load_adapter()](/docs/transformers/main/es/main_classes/peft#transformers.integrations.PeftAdapterMixin.load_adapter).

```py
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("google/gemma-7b")
model.load_adapter("klcsp/gemma7b-lora-alpaca-11-v1")
```

Para modelos grandes, carga una versión cuantizada en precisión de 8 bits o 4 bits con [bitsandbytes](./quantization/bitsandbytes) para ahorrar memoria. Añade `device_map="auto"` para distribuir el modelo entre el hardware disponible.

```py
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

model = AutoModelForCausalLM.from_pretrained(
    "klcsp/gemma7b-lora-alpaca-11-v1",
    quantization_config=BitsAndBytesConfig(load_in_8bit=True),
    device_map="auto",
)
```

## Gestión de varios adaptadores

Un modelo puede contener varios adaptadores a la vez. Añade adaptadores con nombres únicos y cambia entre ellos según sea necesario.

```py
from peft import LoraConfig

model.add_adapter(LoraConfig(r=8, lora_alpha=32), adapter_name="adapter_1")
model.add_adapter(LoraConfig(r=16, lora_alpha=64), adapter_name="adapter_2")
```

Use [set_adapter()](/docs/transformers/main/es/main_classes/peft#transformers.integrations.PeftAdapterMixin.set_adapter) para activar un adaptador específico. Los demás adaptadores se desactivan pero permanecen en memoria.

```py
model.set_adapter("adapter_2")
```

[enable_adapters()](/docs/transformers/main/es/main_classes/peft#transformers.integrations.PeftAdapterMixin.enable_adapters) habilita todos los adaptadores adjuntos, y [disable_adapters()](/docs/transformers/main/es/main_classes/peft#transformers.integrations.PeftAdapterMixin.disable_adapters) los deshabilita.

```py
# Disable all adapters for base model inference
model.disable_adapters()

# Re-enable all adapters
model.enable_adapters()
```

Use [active_adapters()](/docs/transformers/main/es/main_classes/peft#transformers.integrations.PeftAdapterMixin.active_adapters) para ver qué adaptadores están activos actualmente.

```py
model.active_adapters()
# ["adapter_1"]
```

Elimina los adaptadores que ya no necesites con [delete_adapter()](/docs/transformers/main/es/main_classes/peft#transformers.integrations.PeftAdapterMixin.delete_adapter) para liberar memoria.

```py
model.delete_adapter("adapter_1")
```

## Intercambio de adaptadores

Cargar un nuevo adaptador cada vez que se atiende una solicitud asigna nueva memoria. Si el modelo se compila con `torch.compile`, cada nuevo adaptador provoca una recompilación. El intercambio en caliente (hotswapping) reemplaza los pesos del adaptador in situ, evitando ambos problemas. Solo se admiten adaptadores LoRA.

Pasa `hotswap=True` al cargar un adaptador LoRA para intercambiar sus pesos en un slot de adaptador existente. Establece `adapter_name` con el nombre del adaptador que se va a reemplazar (`"default"` es el nombre de adaptador predeterminado).

```py
model = AutoModel.from_pretrained(...)
# Load the first adapter normally
model.load_adapter(adapter_path_1)
# Generate outputs with adapter 1
...
# Hotswap the second adapter in-place
model.load_adapter(adapter_path_2, hotswap=True, adapter_name="default")
# Generate outputs with adapter 2
```

### torch.compile

Para los modelos compilados, llama a [enable_peft_hotswap()](/docs/transformers/main/es/main_classes/peft#transformers.integrations.PeftAdapterMixin.enable_peft_hotswap) *antes* de cargar el primer adaptador y antes de compilar.

```py
model = AutoModel.from_pretrained(...)
max_rank = ...  # highest rank among all LoRAs you'll load
model.enable_peft_hotswap(target_rank=max_rank)
model.load_adapter(adapter_path_1, adapter_name="default")
model = torch.compile(model, ...)
output_1 = model(...)

# Hotswap without recompilation
model.load_adapter(adapter_path_2, adapter_name="default")
output_2 = model(...)
```

El argumento `target_rank` establece el rango máximo entre todos los adaptadores LoRA que se cargarán. Si tiene adaptadores con rango 8 y rango 16, pase `target_rank=16`. El valor predeterminado es 128.

Después de llamar a `enable_peft_hotswap`, todas las llamadas posteriores a `load_adapter` realizan hotswap de forma predeterminada. Pasa `hotswap=False` explícitamente para desactivar el hotswap.

Es posible que se produzca una recompilación si el adaptador intercambiado en caliente apunta a más capas que el adaptador inicial. Cargue primero el adaptador que apunta a más capas para evitar la recompilación.

> [!TIP]
> Envuelve tu código en `with torch._dynamo.config.patch(error_on_recompile=True)` para detectar recompilaciones inesperadas. Si detectas recompilaciones a pesar de seguir los pasos anteriores, abre un issue con [PEFT](https://github.com/huggingface/peft/issues) incluyendo un ejemplo reproducible.

## Próximos pasos

- La [documentación](https://huggingface.co/docs/peft/index) de PEFT abarca todo el rango de métodos y opciones de PEFT.
- La [referencia de intercambio en caliente](https://huggingface.co/docs/peft/main/en/package_reference/hotswap#peft.utils.hotswap.hotswap_adapter) de PEFT detalla las limitaciones y los casos límite.
- Una [entrada de blog](https://huggingface.co/blog/lora-fast) realiza una prueba de rendimiento sobre cómo `torch.compile` con hotswapping mejora el tiempo de ejecución.

