# LoRA

[LoRA (Low-Rank Adaptation)](https://huggingface.co/papers/2106.09685) adapta un modelo preentrenado a una nueva tarea congelando los pesos originales y entrenando un pequeño conjunto de nuevos parámetros. La adaptación es más rápida y económica que el ajuste fino completo, lo que la hace práctica para tareas como generar imágenes en un nuevo estilo.

Los puntos de control de LoRA suelen ser de solo unos cientos de MB. Cargalos con `pipeline.load_lora_weights` y establece `weight_name` como el nombre del archivo del punto de control. Consulta [load_lora_weights()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.StableDiffusionLoraLoaderMixin.load_lora_weights) para los parámetros compartidos.

```py
import torch
from diffusers import AutoPipelineForText2Image

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
    "ostris/super-cereal-sdxl-lora",
    weight_name="cereal_box_sdxl_v1.safetensors",
    adapter_name="cereal"
)
pipeline("bears, pizza bites").images[0]
```

```py
import torch
from diffusers import LTXConditionPipeline
from diffusers.utils import export_to_video, load_image

pipeline = LTXConditionPipeline.from_pretrained(
    "Lightricks/LTX-Video-0.9.5", dtype=torch.bfloat16
).to("cuda")  # or "mps", "xpu", "cpu"

pipeline.load_lora_weights(
    "Lightricks/LTX-Video-Cakeify-LoRA",
    weight_name="ltxv_095_cakeify_lora.safetensors",
    adapter_name="cakeify"
)
pipeline.set_adapters("cakeify")

# use "CAKEIFY" to trigger the LoRA
prompt = "CAKEIFY a person using a knife to cut a cake shaped like a Pikachu plushie"
image = load_image("https://huggingface.co/Lightricks/LTX-Video-Cakeify-LoRA/resolve/main/assets/images/pikachu.png")

video = pipeline(
    prompt=prompt,
    image=image,
    width=576,
    height=576,
    num_frames=161,
    decode_timestep=0.03,
    decode_noise_scale=0.025,
    num_inference_steps=50,
).frames[0]
export_to_video(video, "output.mp4", fps=26)
```

Las APIs de pipeline LoRA de esta página funcionan de la misma manera en todas las familias de modelos. El módulo de desruido es `pipeline.unet` en [Stable Diffusion](../api/pipelines/stable_diffusion/overview) y [SDXL](../api/pipelines/stable_diffusion/stable_diffusion_xl), y `pipeline.transformer` en modelos de estilo DiT como [Flux](../api/pipelines/flux), [Stable Diffusion 3](../api/pipelines/stable_diffusion/stable_diffusion_3), [AuraFlow](../api/pipelines/aura_flow) y [LTX](../api/pipelines/ltx_video). El mismo patrón se aplica a modelos de video como [CogVideoX](../api/pipelines/cogvideox), [HunyuanVideo](../api/pipelines/hunyuan_video) y [Wan](../api/pipelines/wan). Los métodos PEFT a nivel de modelo utilizan ese atributo y un `prefix` correspondiente (`"unet"` o `"transformer"`).

`pipeline.load_lora_weights` es la forma preferida para cargar los pesos de LoRA en el denoiser (UNet o transformer) y en los codificadores de texto. Consulte [load_lora_weights()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.StableDiffusionLoraLoaderMixin.load_lora_weights) para los parámetros compartidos. Puede manejar casos en los que:

- el checkpoint comparte claves entre el denoiser y los codificadores de texto
- el checkpoint utiliza claves separadas para el denoiser y el text-encoder

El método [load_lora_adapter()](/docs/diffusers/main/es/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.load_lora_adapter) carga un adaptador LoRA a *nivel de modelo* en cualquier modelo de Diffusers que herede de `PeftAdapterMixin`, como un UNet o un transformer. Construye y prepara la configuración del adaptador y carga los pesos en ese módulo.

Use `prefix` para filtrar las claves del state dict del módulo objetivo (`"unet"` o `"transformer"`). El valor predeterminado es `"transformer"`, por lo que Stable Diffusion y SDXL deben pasar `prefix="unet"`.

```py
import torch
from diffusers import AutoPipelineForText2Image

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.unet.load_lora_adapter(
    "jbilcke-hf/sdxl-cinematic-1",
    weight_name="pytorch_lora_weights.safetensors",
    adapter_name="cinematic",
    prefix="unet"
)
# use cnmt in the prompt to trigger the LoRA
pipeline("A cute cnmt eating a slice of pizza, stunning color scheme, masterpiece, illustration").images[0]
```

```py
import torch
from diffusers import FluxPipeline

pipeline = FluxPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev", dtype=torch.bfloat16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.transformer.load_lora_adapter(
    "alvarobartt/ghibli-characters-flux-lora",
    adapter_name="lora",
    prefix="transformer",
)
```

## torch.compile

[torch.compile](../optimization/fp16#torchcompile) acelera la inferencia al compilar el modelo de PyTorch para usar kernels optimizados. Antes de compilar, es necesario fusionar los pesos de LoRA en el modelo base y descargarlos primero.

```py
import torch
from diffusers import DiffusionPipeline

# load base model and LoRA
pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
    "ostris/ikea-instructions-lora-sdxl",
    weight_name="ikea_instructions_xl_v1_5.safetensors",
    adapter_name="ikea"
)

# activate LoRA and set adapter weight
pipeline.set_adapters("ikea", adapter_weights=0.7)

# fuse LoRAs and unload weights
pipeline.fuse_lora(adapter_names=["ikea"], lora_scale=1.0)
pipeline.unload_lora_weights()
```

Por lo general, compile el denoiser, ya que es el componente más intensivo en cómputo del pipeline.

```py
pipeline.unet.to(memory_format=torch.channels_last)
pipeline.unet = torch.compile(pipeline.unet, mode="reduce-overhead", fullgraph=True)

pipeline("A bowl of ramen shaped like a cute kawaii bear").images[0]
```

Para Flux y otros pipelines de DiT, compile `pipeline.transformer` en su lugar.

```py
pipeline.transformer = torch.compile(pipeline.transformer, mode="reduce-overhead", fullgraph=True)
```

Consulte la sección [hotswapping](#hotswapping) para aprender a evitar la recompilación al trabajar con modelos compilados y múltiples LoRAs.

## Escala de pesos

Use the parameter `adapter_weights` en [set_adapters()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) para controlar cuánto de un LoRA se aplica. Un peso de `0` equivale a usar únicamente los pesos del modelo base y un peso de `1` equivale a usar completamente el LoRA.

Pasa un escalar a `adapter_weights` en [set_adapters()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) para controlar la intensidad con la que se aplica LoRA.

```py
import torch
from diffusers import AutoPipelineForText2Image

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
    "ostris/super-cereal-sdxl-lora",
    weight_name="cereal_box_sdxl_v1.safetensors",
    adapter_name="cereal"
)
pipeline.set_adapters("cereal", adapter_weights=1.0)
pipeline("bears, pizza bites").images[0]
```

`set_adapters` como patrón principal, aunque algunas tuberías también aceptan `cross_attention_kwargs={"scale": 1.0}` en la llamada como forma secundaria de escalar la atención. Las tuberías que no utilizan atención cruzada suelen exponer `attention_kwargs` en su lugar (o `joint_attention_kwargs` en Flux y Stable Diffusion 3).

> [!WARNING]
> El método [set_adapters()](/docs/diffusers/main/es/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.set_adapters) solo escala los pesos de atención. Si un LoRA tiene ResNets o down y upsamplers, estos componentes mantienen un valor de escala de `1.0`.

Pase un diccionario para escalar cada bloque de codificador de texto o desruidador. Las claves del diccionario siguen los módulos de la pipeline. El ejemplo de abajo es SDXL (`unet` más codificadores de texto). Flux usa `transformer` y `text_encoder`. SD3 usa `transformer` y múltiples codificadores de texto.

En este ejemplo de SDXL, el bloque `"down"` del UNet se escala por 0.9 y puedes especificar además las escalas de los bloques de atención en `"block_0"` y `"block_1"` bajo `"up"`. Si un bloque como `"mid"` no se especifica, se utiliza el valor predeterminado `1.0`.

```py
import torch
from diffusers import AutoPipelineForText2Image

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
    "ostris/super-cereal-sdxl-lora",
    weight_name="cereal_box_sdxl_v1.safetensors",
    adapter_name="cereal"
)
scales = {
    "text_encoder": 0.5,
    "text_encoder_2": 0.5,
    "unet": {
        "down": 0.9,
        "up": {
            "block_0": 0.6,
            "block_1": [0.4, 0.8, 1.0],
        }
    }
}
pipeline.set_adapters("cereal", scales)
pipeline("bears, pizza bites").images[0]
```

### Escalar la programación

Ajustar dinámicamente la escala de LoRA durante el muestreo te da un mejor control sobre la composición y el diseño generales, ya que ciertos pasos pueden beneficiarse más de una escala aumentada o reducida.

El [LoRA de personaje](https://huggingface.co/alvarobartt/ghibli-characters-flux-lora) en el ejemplo siguiente comienza con una escala más alta que decae gradualmente durante los primeros 20 pasos para establecer la generación del personaje. En los pasos posteriores, solo se aplica una escala de `0.2` para evitar añadir demasiadas características del LoRA a otras partes de la imagen en las que el LoRA no fue entrenado.

```py
import torch
from diffusers import FluxPipeline

pipeline = FluxPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev", dtype=torch.bfloat16
).to("cuda")  # or "mps", "xpu", "cpu"

pipeline.load_lora_weights("alvarobartt/ghibli-characters-flux-lora", adapter_name="lora")

num_inference_steps = 30
lora_steps = 20
lora_scales = torch.linspace(1.5, 0.7, lora_steps).tolist()
lora_scales += [0.2] * (num_inference_steps - lora_steps + 1)

pipeline.set_adapters("lora", lora_scales[0])

def callback(pipeline: FluxPipeline, step: int, timestep: torch.LongTensor, callback_kwargs: dict):
    pipeline.set_adapters("lora", lora_scales[step + 1])
    return callback_kwargs

prompt = """
Ghibli style The Grinch, a mischievous green creature with a sly grin, peeking out from behind a snow-covered tree while plotting his antics, 
in a quaint snowy village decorated for the holidays, warm light glowing from cozy homes, with playful snowflakes dancing in the air
"""
pipeline(
    prompt=prompt,
    guidance_scale=3.0,
    num_inference_steps=num_inference_steps,
    generator=torch.Generator().manual_seed(42),
    callback_on_step_end=callback,
).images[0]
```

## Hotswapping

El intercambio de LoRAs (hotswapping) es una forma eficiente de trabajar con varios LoRAs mientras se evita la acumulación de memoria derivada de múltiples llamadas a `load_lora_weights` y, en algunos casos, la recompilación, si el modelo está compilado. Este flujo de trabajo requiere un LoRA cargado, ya que los nuevos pesos del LoRA se intercambian en el lugar del LoRA existente que ya está cargado.

```py
import torch
from diffusers import DiffusionPipeline

# load base model and LoRAs
pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
    "ostris/ikea-instructions-lora-sdxl",
    weight_name="ikea_instructions_xl_v1_5.safetensors",
    adapter_name="ikea"
)
```

> [!WARNING]
> El intercambio en caliente no es compatible con los LoRA que apuntan al codificador de texto.

Establezca `hotswap=True` en `load_lora_weights` para intercambiar el segundo LoRA. Use el parámetro `adapter_name` para indicar qué LoRA intercambiar. Si omite `adapter_name` al cargar, Diffusers nombra los adaptadores como `default_0`, `default_1`, y así sucesivamente. Los adaptadores con nombre son más fáciles de especificar explícitamente.

```py
pipeline.load_lora_weights(
    "lordjia/by-feng-zikai",
    hotswap=True,
    adapter_name="ikea"
)
```

### Modelos compilados

Para los modelos compilados, use [enable_lora_hotswap()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) para evitar la recompilación al intercambiar LoRAs en caliente. Este método debe llamarse *antes* de cargar el primer LoRA y `torch.compile` debe llamarse *después* de cargar el primer LoRA.

> [!TIP]
> El método [enable_lora_hotswap()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) no siempre es necesario si el segundo LoRA apunta a los mismos rangos y escalas de LoRA que el primero.

Dentro de [enable_lora_hotswap()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap), establece `target_rank` en el rango más alto entre los adaptadores que planeas cargar (predeterminado 128).

```py
import torch
from diffusers import DiffusionPipeline

# load base model and LoRAs
pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
# 1. enable_lora_hotswap
pipeline.enable_lora_hotswap(target_rank=128)
pipeline.load_lora_weights(
    "ostris/ikea-instructions-lora-sdxl",
    weight_name="ikea_instructions_xl_v1_5.safetensors",
    adapter_name="ikea"
)
# 2. torch.compile
pipeline.unet = torch.compile(pipeline.unet, mode="reduce-overhead", fullgraph=True)

# 3. hotswap
pipeline.load_lora_weights(
    "lordjia/by-feng-zikai",
    hotswap=True,
    adapter_name="ikea"
)
```

> [!TIP]
> Mueve tu código dentro del gestor de contexto `with torch._dynamo.config.patch(error_on_recompile=True)` para detectar si un modelo se recompiló. Si un modelo se recompila a pesar de seguir todos los pasos anteriores, abre un [issue](https://github.com/huggingface/diffusers/issues) con un ejemplo reproducible.

Si espera resoluciones variadas durante la inferencia con esta función, asegúrese de establecer `dynamic=True` durante la compilación. Consulte [compilación de formas dinámicas](../optimization/fp16#dynamic-shape-compilation) para más detalles.

Aún existen escenarios en los que la recompilación es inevitable, como cuando el LoRA intercambiado en caliente apunta a más capas que el adaptador inicial. Intente cargar *primero* el LoRA que apunta a la mayor cantidad de capas. Para más detalles sobre esta limitación, consulte la documentación de [hotswapping](https://huggingface.co/docs/peft/main/en/package_reference/hotswap#peft.utils.hotswap.hotswap_adapter) de PEFT.

Por qué `target_rank` y el orden de carga importan

El método [enable_lora_hotswap()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) convierte el factor de escalado de LoRA de flotantes a torch.tensors y rellena la forma de los pesos hasta la forma más grande requerida para evitar reasignar todo el atributo cuando se reemplaza los datos en los pesos.

Por eso el argumento `target_rank` es importante. Los resultados no cambian incluso cuando los valores se rellenan con ceros. Sin embargo, el cálculo puede ser más lento dependiendo del tamaño del relleno.

Dado que no se añaden nuevos atributos de LoRA, cada LoRA posterior solo puede apuntar a las mismas capas, o a un subconjunto de las capas, a las que apunta el primer LoRA. La elección del orden de carga de los LoRA es importante, ya que si los LoRA apuntan a capas disjuntas, es posible que termine creando un LoRA ficticio que apunte a la unión de todas las capas objetivo.

Consulte la publicación de blog [LoRA fast](https://huggingface.co/blog/lora-fast) para obtener más información sobre el intercambio de LoRA con modelos compilados, y para más detalles de implementación, eche un vistazo al archivo [`hotswap.py`](https://github.com/huggingface/peft/blob/92d65cafa51c829484ad3d95cf71d09de57ff066/src/peft/utils/hotswap.py).

## Fusionar

Los pesos de cada LoRA pueden combinarse para producir una mezcla de varios estilos existentes. Existen varios métodos para combinar LoRAs, cada uno de los cuales difiere en *cómo* se combinan los pesos (lo cual puede afectar la calidad de la generación).

### set_adapters[[merge]]

El método [set_adapters()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) fusiona LoRAs concatenando sus matrices ponderadas. Pasa los nombres de los LoRA a [set_adapters()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) y usa el parámetro `adapter_weights` para controlar la escala de cada LoRA. Por ejemplo, si `adapter_weights=[0.5, 0.5]`, la salida es un promedio de ambos LoRAs.

> [!TIP]
> Prefer `adapter_weights` en [set_adapters()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) para controlar cuánto de cada LoRA fusionado se aplica. Consulte la sección [Escala de pesos](#weight-scale) para más detalles.

```py
import torch
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
    "ostris/ikea-instructions-lora-sdxl",
    weight_name="ikea_instructions_xl_v1_5.safetensors",
    adapter_name="ikea"
)
pipeline.load_lora_weights(
    "lordjia/by-feng-zikai",
    weight_name="fengzikai_v1.0_XL.safetensors",
    adapter_name="feng"
)
pipeline.set_adapters(["ikea", "feng"], adapter_weights=[0.7, 0.8])
# use by Feng Zikai to activate the lordjia/by-feng-zikai LoRA
pipeline("A bowl of ramen shaped like a cute kawaii bear, by Feng Zikai").images[0]
```

### add_weighted_adapter

> [!TIP]
> Este es un método experimental y puedes consultar la [fusión de modelos](https://huggingface.co/docs/peft/developer_guides/model_merging) de PEFT para obtener más detalles. Echa un vistazo a esta [incidencia](https://github.com/huggingface/diffusers/issues/6892) si te interesa la motivación y el diseño detrás de esta integración.

El método [add_weighted_adapter](https://huggingface.co/docs/peft/main/en/package_reference/lora#peft.LoraModel.add_weighted_adapter) permite métodos de fusión más eficientes como [TIES](https://huggingface.co/papers/2306.01708) o [DARE](https://huggingface.co/papers/2311.03099). Estos métodos de fusión eliminan parámetros redundantes y potencialmente interferentes de los modelos fusionados. Tenga en cuenta que los rangos de LoRA deben tener rangos idénticos para poder fusionarse. El recorrido a continuación utiliza el UNet de SDXL.

Asegúrate de que la última versión estable de Diffusers y PEFT esté instalada.

```bash
pip install -U -q diffusers peft
```

Cargue un UNet que corresponda al UNet de LoRA.

```py
import copy
import torch
from diffusers import AutoModel, DiffusionPipeline
from peft import get_peft_model, LoraConfig, PeftModel

unet = AutoModel.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16,
    use_safetensors=True,
    variant="fp16",
    subfolder="unet",
).to("cuda")  # or "mps", "xpu", "cpu"
```

Carga un pipeline, pásale el UNet y carga un LoRA.

```py
pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    variant="fp16",
    dtype=torch.float16,
    unet=unet
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
    "ostris/ikea-instructions-lora-sdxl",
    weight_name="ikea_instructions_xl_v1_5.safetensors",
    adapter_name="ikea"
)
```

Cree un [PeftModel](https://huggingface.co/docs/peft/main/en/package_reference/peft_model#peft.PeftModel) a partir del checkpoint de LoRA combinando el primer UNet que cargó con el UNet de LoRA del pipeline.

```py
sdxl_unet = copy.deepcopy(unet)
ikea_peft_model = get_peft_model(
    sdxl_unet,
    pipeline.unet.peft_config["ikea"],
    adapter_name="ikea"
)

original_state_dict = {f"base_model.model.{k}": v for k, v in pipeline.unet.state_dict().items()}
ikea_peft_model.load_state_dict(original_state_dict, strict=True)
```

> [!TIP]
> Puedes guardar y reutilizar el `ikea_peft_model` subiéndolo al Hub, como se muestra a continuación.
> ```py
> ikea_peft_model.push_to_hub("ikea_peft_model", token=TOKEN)
> ```

Repite este proceso y crea un [PeftModel](https://huggingface.co/docs/peft/main/en/package_reference/peft_model#peft.PeftModel) para el segundo LoRA.

```py
pipeline.delete_adapters("ikea")
sdxl_unet.delete_adapters("ikea")

pipeline.load_lora_weights(
    "lordjia/by-feng-zikai",
    weight_name="fengzikai_v1.0_XL.safetensors",
    adapter_name="feng"
)
pipeline.set_adapters(adapter_names="feng")

feng_peft_model = get_peft_model(
    sdxl_unet,
    pipeline.unet.peft_config["feng"],
    adapter_name="feng"
)

original_state_dict = {f"base_model.model.{k}": v for k, v in pipeline.unet.state_dict().items()}
feng_peft_model.load_state_dict(original_state_dict, strict=True)
```

Carga un modelo UNet base y carga los adaptadores.

```py
base_unet = AutoModel.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16,
    use_safetensors=True,
    variant="fp16",
    subfolder="unet",
).to("cuda")  # or "mps", "xpu", "cpu"

model = PeftModel.from_pretrained(
    base_unet,
    "stevhliu/ikea_peft_model",
    use_safetensors=True,
    subfolder="ikea",
    adapter_name="ikea"
)
model.load_adapter(
    "stevhliu/feng_peft_model",
    use_safetensors=True,
    subfolder="feng",
    adapter_name="feng"
)
```

Fusiona los LoRAs con [add_weighted_adapter](https://huggingface.co/docs/peft/main/en/package_reference/lora#peft.LoraModel.add_weighted_adapter) y especifica cómo deseas fusionarlos con `combination_type`. El ejemplo de abajo utiliza el método `"dare_linear"` (consulta esta [publicación en el blog](https://huggingface.co/blog/peft_merging) para obtener más información sobre estos métodos de fusión), que recorta aleatoriamente algunos pesos y luego realiza una suma ponderada de los tensores en función del peso asignado a cada LoRA en `weights`.

Active los LoRAs fusionados con [set_adapters()](/docs/diffusers/main/es/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.set_adapters).

```py
model.add_weighted_adapter(
    adapters=["ikea", "feng"],
    combination_type="dare_linear",
    weights=[1.0, 1.0],
    adapter_name="ikea-feng"
)
model.set_adapters("ikea-feng")

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    unet=model,
    variant="fp16",
    dtype=torch.float16,
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline("A bowl of ramen shaped like a cute kawaii bear, by Feng Zikai").images[0]
```

### fuse_lora

El método [fuse_lora()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.fuse_lora) fusiona los pesos de LoRA directamente con los pesos del denoiser original (UNet o transformer) y del codificador de texto del modelo subyacente. Esto reduce la sobrecarga de cargar el modelo subyacente para cada LoRA, ya que solo carga el modelo una vez, lo que disminuye el uso de memoria y aumenta la velocidad de inferencia.

```py
import torch
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
    "ostris/ikea-instructions-lora-sdxl",
    weight_name="ikea_instructions_xl_v1_5.safetensors",
    adapter_name="ikea"
)
pipeline.load_lora_weights(
    "lordjia/by-feng-zikai",
    weight_name="fengzikai_v1.0_XL.safetensors",
    adapter_name="feng"
)
pipeline.set_adapters(["ikea", "feng"], adapter_weights=[0.7, 0.8])
```

Llama a [fuse_lora()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.fuse_lora) para fusionarlos. El parámetro `lora_scale` controla cuánto se escala la salida con los pesos de LoRA. Es importante realizar este ajuste ahora porque pasar `scale` a `cross_attention_kwargs` no funcionará en el pipeline.

```py
pipeline.fuse_lora(adapter_names=["ikea", "feng"], lora_scale=1.0)
```

Descarga los pesos de LoRA, ya que ya están fusionados con el modelo subyacente. Guarda el pipeline fusionado con [save_pretrained()](/docs/diffusers/main/es/api/pipelines/overview#diffusers.DiffusionPipeline.save_pretrained) para guardarlo localmente o con `~PushToHubMixin.push_to_hub` para guardarlo en el Hub.

```py
pipeline.unload_lora_weights()
pipeline.save_pretrained("path/to/fused-pipeline")
```

```py
pipeline.unload_lora_weights()
pipeline.push_to_hub("fused-ikea-feng")
```

Ahora, el pipeline fusionado se puede cargar rápidamente para inferencia sin necesidad de cargar cada LoRA por separado.

```py
pipeline = DiffusionPipeline.from_pretrained(
    "username/fused-ikea-feng", dtype=torch.float16,
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline("A bowl of ramen shaped like a cute kawaii bear, by Feng Zikai").images[0]
```

Usa [unfuse_lora()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.unfuse_lora) para restaurar los pesos del modelo subyacente, por ejemplo, si deseas usar un valor diferente de `lora_scale`. Solo puedes desfusionar si hay un único LoRA fusionado. Por ejemplo, no funcionará con el pipeline de arriba porque hay múltiples LoRAs fusionados. En estos casos, necesitarás recargar el modelo completo.

```py
pipeline.unfuse_lora()
```

## Gestionar

Diffusers ofrece varios métodos para ayudarte a gestionar el trabajo con LoRAs. Estos métodos pueden ser especialmente útiles si trabajas con varios LoRAs.

### set_adapters[[manage]]

[set_adapters()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) también activa el LoRA actual para usarlo si hay varios LoRAs activos. Esto permite cambiar entre diferentes LoRAs especificando su nombre.

```py
import torch
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights(
    "ostris/ikea-instructions-lora-sdxl",
    weight_name="ikea_instructions_xl_v1_5.safetensors",
    adapter_name="ikea"
)
pipeline.load_lora_weights(
    "lordjia/by-feng-zikai",
    weight_name="fengzikai_v1.0_XL.safetensors",
    adapter_name="feng"
)
# activates the feng LoRA instead of the ikea LoRA
pipeline.set_adapters("feng")
```

### save_lora_adapter

Guarda un adaptador con [save_lora_adapter()](/docs/diffusers/main/es/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.save_lora_adapter) en el mismo módulo que cargaste en (`pipeline.unet` o `pipeline.transformer`).

```py
import torch
from diffusers import AutoPipelineForText2Image

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.unet.load_lora_adapter(
    "jbilcke-hf/sdxl-cinematic-1",
    weight_name="pytorch_lora_weights.safetensors",
    adapter_name="cinematic",
    prefix="unet"
)
pipeline.unet.save_lora_adapter("path/to/save", adapter_name="cinematic")
```

### unload_lora_weights

El método [unload_lora_weights()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.unload_lora_weights) descarga los pesos de LoRA en el pipeline para restaurar los pesos del modelo subyacente.

```py
pipeline.unload_lora_weights()
```

### disable_lora

El método [disable_lora()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.disable_lora) desactiva todos los LoRA (aunque se mantienen en el pipeline) y restaura el pipeline a los pesos del modelo subyacente.

```py
pipeline.disable_lora()
```

### get_active_adapters

El método [get_active_adapters()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.get_active_adapters) devuelve una lista de los LoRAs activos adjuntos a un pipeline.

```py
pipeline.get_active_adapters()
# ["cereal", "ikea"]
```

### get_list_adapters

El método [get_list_adapters()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.get_list_adapters) devuelve todos los LoRAs cargados para cada componente del pipeline. Las claves del diccionario coinciden con los módulos cargados, como `unet` o `transformer` y cualquier codificador de texto.

```py
pipeline.get_list_adapters()
# {"unet": ["cereal", "ikea"], "text_encoder_2": ["cereal"]}
```

### delete_adapters

El método [delete_adapters()](/docs/diffusers/main/es/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.delete_adapters) elimina por completo un LoRA y sus capas de un modelo.

```py
pipeline.delete_adapters("ikea")
```

## Próximos pasos

- Explora el [LoRA Studio](https://lorastudio.co/models) para ver los diferentes LoRAs disponibles o puedes subir tus LoRAs favoritos de Civitai al Hub con el Space de abajo.

<iframe src="https://multimodalart-civitai-to-hf.hf.space" frameborder="0" width="850" height="450"
>

- Puedes encontrar más LoRAs en los Spaces [FLUX LoRA the Explorer](https://huggingface.co/spaces/multimodalart/flux-lora-the-explorer) y [LoRA the Explorer](https://huggingface.co/spaces/multimodalart/LoraTheExplorer).

- Consulta la publicación de blog [Fast LoRA inference for Flux with Diffusers and PEFT](https://huggingface.co/blog/lora-fast) para aprender a optimizar la inferencia de LoRA con métodos como FlashAttention-3 y cuantización fp8.

