# LoRA

[LoRA (Low-Rank Adaptation)](https://huggingface.co/papers/2106.09685) adapta um modelo pré-treinado a uma nova tarefa congelando os pesos originais e treinando um pequeno conjunto de novos parâmetros. A adaptação é mais rápida e barata do que o fine-tuning completo, o que a torna prática para tarefas como gerar imagens em um novo estilo.

Os checkpoints de LoRA geralmente têm apenas algumas centenas de MBs. Carregue-os com `pipeline.load_lora_weights` e defina `weight_name` como o nome do arquivo do checkpoint. Consulte [load_lora_weights()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.StableDiffusionLoraLoaderMixin.load_lora_weights) para os parâmetros compartilhados.

```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)
```

As APIs de pipeline LoRA desta página funcionam da mesma forma entre as famílias de modelos. O módulo de desruidamento é `pipeline.unet` em [Stable Diffusion](../api/pipelines/stable_diffusion/overview) e [SDXL](../api/pipelines/stable_diffusion/stable_diffusion_xl), e `pipeline.transformer` em modelos no estilo DiT, como [Flux](../api/pipelines/flux), [Stable Diffusion 3](../api/pipelines/stable_diffusion/stable_diffusion_3), [AuraFlow](../api/pipelines/aura_flow) e [LTX](../api/pipelines/ltx_video). O mesmo padrão se aplica a modelos de vídeo, como [CogVideoX](../api/pipelines/cogvideox), [HunyuanVideo](../api/pipelines/hunyuan_video) e [Wan](../api/pipelines/wan). Os métodos PEFT em nível de modelo usam esse atributo e um `prefix` correspondente (`"unet"` ou `"transformer"`).

`pipeline.load_lora_weights` é a maneira preferida de carregar pesos LoRA no denoiser (UNet ou transformer) e nos codificadores de texto. Consulte [load_lora_weights()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.StableDiffusionLoraLoaderMixin.load_lora_weights) para os parâmetros compartilhados. Ele pode lidar com casos em que:

- o checkpoint compartilha chaves entre o denoiser e os codificadores de texto
- o checkpoint usa chaves separadas para o denoiser e o text-encoder

O método [load_lora_adapter()](/docs/diffusers/v0.43.0/pt/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.load_lora_adapter) carrega um adaptador LoRA no *nível do modelo* em qualquer modelo do Diffusers que subclasse `PeftAdapterMixin`, como um UNet ou transformer. Ele constrói e prepara a configuração do adaptador e carrega os pesos nesse módulo.

Use `prefix` para filtrar as chaves do state dict do módulo de destino (`"unet"` ou `"transformer"`). O padrão é `"transformer"`, portanto, o Stable Diffusion e o SDXL devem passar `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 a inferência compilando o modelo PyTorch para usar kernels otimizados. Antes de compilar, os pesos LoRA precisam ser fundidos no modelo base e descarregados primeiro.

```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()
```

Normalmente, compile o denoiser, pois é o componente mais intensivo em computação do 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 o Flux e outros pipelines DiT, compile `pipeline.transformer` em vez disso.

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

Consulte a seção [hotswapping](#hotswapping) para aprender a evitar a recompilação ao trabalhar com modelos compilados e múltiplos LoRAs.

## Escala de pesos

Use o parâmetro `adapter_weights` em [set_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) para controlar a quantidade de LoRA a ser aplicada. Um peso de `0` é equivalente a usar apenas os pesos do modelo base e um peso de `1` é equivalente a usar totalmente o LoRA.

Passe um escalar para `adapter_weights` em [set_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) para controlar a intensidade com que o LoRA é aplicado.

```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 o padrão principal, mas alguns pipelines também aceitam `cross_attention_kwargs={"scale": 1.0}` na chamada como uma forma secundária de escalar a atenção. Pipelines que não usam cross-attention geralmente expõem `attention_kwargs` em vez disso (ou `joint_attention_kwargs` no Flux e no Stable Diffusion 3).

> [!WARNING]
> O método [set_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.set_adapters) escala apenas os pesos de atenção. Se um LoRA tiver ResNets ou down e upsamplers, esses componentes mantêm um valor de escala de `1.0`.

Passe um dicionário para escalar cada bloco de codificador de texto ou desruidor. As chaves do dicionário seguem os módulos do pipeline. O exemplo abaixo é do SDXL (`unet` mais codificadores de texto). O Flux usa `transformer` e `text_encoder`. O SD3 usa `transformer` e múltiplos codificadores de texto.

Neste exemplo de SDXL, o bloco `"down"` na UNet é escalado por 0,9 e você pode especificar ainda as escalas dos blocos de atenção em `"block_0"` e `"block_1"` sob `"up"`. Se um bloco como `"mid"` não for especificado, o valor padrão `1.0` é usado.

```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]
```

### Escala de agendamento

Ajustar dinamicamente a escala do LoRA durante a amostragem oferece um melhor controle sobre a composição e o layout gerais, pois certas etapas podem se beneficiar mais de uma escala aumentada ou reduzida.

O [LoRA de personagem](https://huggingface.co/alvarobartt/ghibli-characters-flux-lora) no exemplo abaixo começa com uma escala mais alta que decai gradualmente nos primeiros 20 passos para estabelecer a geração do personagem. Nos passos posteriores, apenas uma escala de `0.2` é aplicada para evitar adicionar muitas das características do LoRA a outras partes da imagem em que o LoRA não foi treinado.

```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

O hotswap de LoRAs é uma maneira eficiente de trabalhar com múltiplos LoRAs, evitando o acúmulo de memória proveniente de múltiplas chamadas para `load_lora_weights` e, em alguns casos, a recompilação, se o modelo estiver compilado. Este fluxo de trabalho requer um LoRA carregado, pois os novos pesos do LoRA são substituídos no local do LoRA já carregado.

```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]
> O hotswapping não é suportado para LoRAs que têm como alvo o text encoder.

Defina `hotswap=True` em `load_lora_weights` para substituir o segundo LoRA. Use o parâmetro `adapter_name` para indicar qual LoRA substituir. Se você omitir `adapter_name` ao carregar, o Diffusers nomeia os adaptadores como `default_0`, `default_1` e assim por diante. Adaptadores nomeados são mais fáceis de direcionar explicitamente.

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

### Modelos compilados

Para modelos compilados, use [enable_lora_hotswap()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) para evitar recompilação ao fazer hotswap de LoRAs. Este método deve ser chamado *antes* de carregar o primeiro LoRA e `torch.compile` deve ser chamado *depois* de carregar o primeiro LoRA.

> [!TIP]
> O método [enable_lora_hotswap()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) nem sempre é necessário se o segundo LoRA tiver os mesmos ranks e scales de LoRA que o primeiro.

Dentro de [enable_lora_hotswap()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap), defina `target_rank` como o maior rank entre os adaptadores que você planeja carregar (padrão 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]
> Mova seu código para dentro do gerenciador de contexto `with torch._dynamo.config.patch(error_on_recompile=True)` para detectar se um modelo foi recompilado. Se um modelo for recompilado apesar de seguir todas as etapas acima, abra um [issue](https://github.com/huggingface/diffusers/issues) com um exemplo reproduzível.

Se você espera resoluções variadas durante a inferência com este recurso, certifique-se de definir `dynamic=True` durante a compilação. Consulte [compilação de formas dinâmicas](../optimization/fp16#dynamic-shape-compilation) para mais detalhes.

Ainda existem cenários em que a recompilação é inevitável, como quando o LoRA trocado em tempo de execução (hotswapped) visa mais camadas do que o adaptador inicial. Tente carregar o LoRA que visa o maior número de camadas *primeiro*. Para mais detalhes sobre essa limitação, consulte a documentação de [hotswapping](https://huggingface.co/docs/peft/main/en/package_reference/hotswap#peft.utils.hotswap.hotswap_adapter) do PEFT.

Por que `target_rank` e a ordem de carregamento importam

O método [enable_lora_hotswap()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) converte o fator de escala do LoRA de floats para torch.tensors e ajusta a forma dos pesos para a maior forma necessária, a fim de evitar a reatribuição de todo o atributo quando os dados nos pesos são substituídos.

É por isso que o argumento `target_rank` é importante. Os resultados permanecem inalterados mesmo quando os valores são preenchidos com zeros. No entanto, o cálculo pode ser mais lento, dependendo do tamanho do preenchimento.

Como nenhum novo atributo de LoRA é adicionado, cada LoRA subsequente só pode visar as mesmas camadas, ou um subconjunto das camadas, que o primeiro LoRA visa. A escolha da ordem de carregamento dos LoRAs é importante, pois, se os LoRAs visarem camadas disjuntas, você pode acabar criando um LoRA fictício que vise a união de todas as camadas-alvo.

Veja o post no blog [LoRA fast](https://huggingface.co/blog/lora-fast) para mais informações sobre hotswapping de LoRA com modelos compilados e, para mais detalhes de implementação, confira o arquivo [`hotswap.py`](https://github.com/huggingface/peft/blob/92d65cafa51c829484ad3d95cf71d09de57ff066/src/peft/utils/hotswap.py).

## Mesclar

Os pesos de cada LoRA podem ser mesclados para produzir uma combinação de vários estilos existentes. Existem vários métodos para mesclar LoRAs, cada um dos quais difere em *como* os pesos são mesclados (o que pode afetar a qualidade da geração).

### set_adapters[[merge]]

O método [set_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) mescla LoRAs concatenando suas matrizes ponderadas. Passe os nomes dos LoRAs para [set_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) e use o parâmetro `adapter_weights` para controlar a escala de cada LoRA. Por exemplo, se `adapter_weights=[0.5, 0.5]`, a saída é a média dos dois LoRAs.

> [!TIP]
> Prefira `adapter_weights` em [set_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) para controlar a quantidade de cada LoRA mesclado a ser aplicada. Consulte a seção [Escala de pesos](#weight-scale) para mais detalhes.

```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 é um método experimental e você pode consultar a [Model merging](https://huggingface.co/docs/peft/developer_guides/model_merging) do PEFT para mais detalhes. Dê uma olhada nesta [issue](https://github.com/huggingface/diffusers/issues/6892) se você estiver interessado na motivação e no design por trás desta integração.

O método `add_weighted_adapter` permite métodos de mesclagem mais eficientes, como [TIES](https://huggingface.co/papers/2306.01708) ou [DARE](https://huggingface.co/papers/2311.03099). Esses métodos de mesclagem removem parâmetros redundantes e potencialmente interferentes dos modelos mesclados. Lembre-se de que os ranks LoRA precisam ter ranks idênticos para serem mesclados. O passo a passo abaixo usa o UNet do SDXL.

Certifique-se de que a versão estável mais recente do Diffusers e do PEFT esteja instalada.

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

Carregue um UNet que corresponda ao UNet 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"
```

Carregue um pipeline, passe o UNet para ele e carregue um 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"
)
```

Crie um `PeftModel` a partir do checkpoint do LoRA combinando o primeiro UNet que você carregou e o UNet do LoRA do 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]
> Você pode salvar e reutilizar o `ikea_peft_model` enviando-o para o Hub, conforme mostrado abaixo.
> ```py
> ikea_peft_model.push_to_hub("ikea_peft_model", token=TOKEN)
> ```

Repita esse processo e crie um `PeftModel` para o 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)
```

Carregue um modelo base UNet e carregue os 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"
)
```

Mescle os LoRAs com `add_weighted_adapter` e especifique como deseja mesclá-los com `combination_type`. O exemplo abaixo usa o método `"dare_linear"` (consulte este [post de blog](https://huggingface.co/blog/peft_merging) para saber mais sobre esses métodos de mesclagem), que poda aleatoriamente alguns pesos e, em seguida, realiza uma soma ponderada dos tensors com base na ponderação definida de cada LoRA em `weights`.

Ative os LoRAs mesclados com [set_adapters()](/docs/diffusers/v0.43.0/pt/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

O método [fuse_lora()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.fuse_lora) funde os pesos do LoRA diretamente com os pesos originais do denoiser (UNet ou transformer) e do codificador de texto do modelo subjacente. Isso reduz o sobrecusto de carregar o modelo subjacente para cada LoRA, pois carrega o modelo apenas uma vez, o que diminui o uso de memória e aumenta a velocidade de inferência.

```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])
```

Chame [fuse_lora()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.fuse_lora) para fundi-los. O parâmetro `lora_scale` controla em quanto a saída deve ser escalada pelos pesos do LoRA. É importante fazer esse ajuste agora, pois passar `scale` para `cross_attention_kwargs` não funcionará no pipeline.

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

Descarregue os pesos do LoRA, pois eles já foram fundidos com o modelo subjacente. Salve o pipeline fundido usando [save_pretrained()](/docs/diffusers/v0.43.0/pt/api/pipelines/overview#diffusers.DiffusionPipeline.save_pretrained) para salvá-lo localmente ou `~PushToHubMixin.push_to_hub` para salvá-lo no 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")
```

O pipeline fundido agora pode ser carregado rapidamente para inferência, sem a necessidade de carregar cada LoRA separadamente.

```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]
```

Use [unfuse_lora()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.unfuse_lora) para restaurar os pesos do modelo subjacente, por exemplo, se você quiser usar um valor diferente para `lora_scale`. Você só pode desfazer a fusão se houver um único LoRA fundido. Por exemplo, não funcionará com o pipeline acima, pois há múltiplos LoRAs fundidos. Nesses casos, você precisará recarregar o modelo inteiro.

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

## Gerenciar

O Diffusers oferece vários métodos para ajudar você a gerenciar o trabalho com LoRAs. Esses métodos podem ser especialmente úteis se você estiver trabalhando com vários LoRAs.

### set_adapters[[manage]]

[set_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) também ativa o LoRA atual para uso quando há múltiplos LoRAs ativos. Isso permite alternar entre diferentes LoRAs especificando seus nomes.

```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

Salve um adaptador com [save_lora_adapter()](/docs/diffusers/v0.43.0/pt/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.save_lora_adapter) no mesmo módulo que você carregou em (`pipeline.unet` ou `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

O método [unload_lora_weights()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.unload_lora_weights) descarrega os pesos LoRA no pipeline para restaurar os pesos do modelo subjacente.

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

### disable_lora

O método [disable_lora()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.disable_lora) desativa todos os LoRAs (mas eles ainda são mantidos no pipeline) e restaura o pipeline para os pesos do modelo subjacente.

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

### get_active_adapters

O método [get_active_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.get_active_adapters) retorna uma lista de LoRAs ativos anexados a um pipeline.

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

### get_list_adapters

O método [get_list_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.get_list_adapters) retorna todos os LoRAs carregados para cada componente no pipeline. As chaves do dicionário correspondem aos módulos carregados, como `unet` ou `transformer` e quaisquer codificadores de texto.

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

### delete_adapters

O método [delete_adapters()](/docs/diffusers/v0.43.0/pt/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.delete_adapters) remove completamente um LoRA e suas camadas de um modelo.

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

## Próximas etapas

- Navegue pelo [LoRA Studio](https://lorastudio.co/models) para diferentes LoRAs para usar ou você pode enviar seus LoRAs favoritos da Civitai para o Hub com o Space abaixo.

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

- Você pode encontrar LoRAs adicionais nos Spaces [FLUX LoRA the Explorer](https://huggingface.co/spaces/multimodalart/flux-lora-the-explorer) e [LoRA the Explorer](https://huggingface.co/spaces/multimodalart/LoraTheExplorer).

- Confira o post no blog [Fast LoRA inference for Flux with Diffusers and PEFT](https://huggingface.co/blog/lora-fast) para aprender a otimizar a inferência de LoRA com métodos como FlashAttention-3 e quantização fp8.

