# LoRA

[LoRA (Low-Rank Adaptation)](https://huggingface.co/papers/2106.09685) menyesuaikan model pretrained ke tugas baru dengan membekukan bobot asli dan melatih seperangkat kecil parameter baru. Adaptasi ini lebih cepat dan lebih murah daripada fine-tuning penuh, sehingga praktis untuk tugas seperti menghasilkan gambar dalam gaya baru.

Checkpoint LoRA biasanya hanya berukuran beberapa ratus MB. Muat dengan `pipeline.load_lora_weights` dan atur `weight_name` ke nama file checkpoint. Lihat [load_lora_weights()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.StableDiffusionLoraLoaderMixin.load_lora_weights) untuk parameter bersama.

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

API pipeline LoRA di halaman ini bekerja dengan cara yang sama di seluruh keluarga model. Modul denoising adalah `pipeline.unet` pada [Stable Diffusion](../api/pipelines/stable_diffusion/overview) dan [SDXL](../api/pipelines/stable_diffusion/stable_diffusion_xl), serta `pipeline.transformer` pada model bergaya DiT seperti [Flux](../api/pipelines/flux), [Stable Diffusion 3](../api/pipelines/stable_diffusion/stable_diffusion_3), [AuraFlow](../api/pipelines/aura_flow), dan [LTX](../api/pipelines/ltx_video). Pola yang sama berlaku untuk model video seperti [CogVideoX](../api/pipelines/cogvideox), [HunyuanVideo](../api/pipelines/hunyuan_video), dan [Wan](../api/pipelines/wan). Metode PEFT tingkat model menggunakan atribut tersebut dan `prefix` yang sesuai (`"unet"` atau `"transformer"`).

`pipeline.load_lora_weights` adalah cara yang disarankan untuk memuat bobot LoRA ke dalam denoiser (UNet atau transformer) dan text encoder. Lihat [load_lora_weights()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.StableDiffusionLoraLoaderMixin.load_lora_weights) untuk parameter bersama. Metode ini dapat menangani kasus di mana:

- checkpoint berbagi kunci di antara denoiser dan text encoder
- checkpoint menggunakan kunci denoiser dan text-encoder yang terpisah

Metode [load_lora_adapter()](/docs/diffusers/v0.43.0/id/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.load_lora_adapter) memuat adapter LoRA pada tingkat *model* di model Diffusers mana pun yang merupakan subclass dari `PeftAdapterMixin`, seperti UNet atau transformer. Metode ini membangun dan menyiapkan konfigurasi adapter, lalu memuat bobot ke dalam modul tersebut.

Gunakan `prefix` untuk memfilter kunci state dict dari modul target (`"unet"` atau `"transformer"`). Nilainya secara default adalah `"transformer"`, sehingga Stable Diffusion dan SDXL harus meneruskan `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) mempercepat inferensi dengan mengompilasi model PyTorch untuk menggunakan kernel yang dioptimalkan. Sebelum kompilasi, bobot LoRA perlu dileburkan ke dalam model dasar dan dimuat keluar terlebih dahulu.

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

Biasanya, kompilasi denoiser karena komponen ini paling intensif dalam penggunaan komputasi di dalam 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]
```

Untuk Flux dan pipeline DiT lainnya, kompilasi `pipeline.transformer` sebagai gantinya.

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

Lihat bagian [hotswapping](#hotswapping) untuk mempelajari cara menghindari kompilasi ulang saat bekerja dengan model terkompilasi dan beberapa LoRA.

## Skala bobot

Gunakan parameter `adapter_weights` pada [set_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) untuk mengontrol seberapa besar LoRA yang diterapkan. Bobot `0` setara dengan hanya menggunakan bobot model dasar, dan bobot `1` setara dengan menggunakan LoRA secara penuh.

Lewatkan skalar ke `adapter_weights` pada [set_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) untuk mengontrol seberapa kuat LoRA diterapkan.

```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` sebagai pola utama, tetapi beberapa pipeline juga menerima `cross_attention_kwargs={"scale": 1.0}` pada pemanggilan sebagai cara sekunder untuk menskalakan perhatian. Pipeline yang tidak menggunakan cross-attention biasanya mengekspos `attention_kwargs` sebagai gantinya (atau `joint_attention_kwargs` pada Flux dan Stable Diffusion 3).

> [!WARNING]
> Metode [set_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.set_adapters) hanya menskalakan bobot perhatian. Jika sebuah LoRA memiliki ResNets atau down dan upsamplers, komponen-komponen ini tetap memiliki nilai skala `1.0`.

Lewatkan dictionary untuk menskalakan setiap blok text encoder atau denoiser. Kunci dictionary mengikuti modul pipeline. Contoh di bawah adalah SDXL (`unet` plus text encoders). Flux menggunakan `transformer` dan `text_encoder`. SD3 menggunakan `transformer` dan beberapa text encoder.

Pada contoh SDXL ini, blok `"down"` di UNet diskalakan dengan 0,9 dan Anda dapat lebih lanjut menentukan skala blok perhatian di `"block_0"` dan `"block_1"` di bawah `"up"`. Jika blok seperti `"mid"` tidak ditentukan, nilai default `1.0` akan digunakan.

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

### Penjadwalan skala

Menyesuaikan skala LoRA secara dinamis selama sampling memberikan Anda kontrol yang lebih baik atas komposisi dan tata letak keseluruhan, karena langkah-langkah tertentu mungkin lebih diuntungkan dari peningkatan atau penurunan skala.

[character LoRA](https://huggingface.co/alvarobartt/ghibli-characters-flux-lora) pada contoh di bawah ini dimulai dengan skala yang lebih tinggi yang secara bertahap meluruh selama 20 langkah pertama untuk membangun generasi karakter. Pada langkah-langkah selanjutnya, hanya skala `0.2` yang diterapkan untuk menghindari penambahan terlalu banyak fitur LoRA ke bagian lain dari gambar yang tidak dilatih oleh LoRA.

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

Hotswapping LoRA adalah cara efisien untuk bekerja dengan beberapa LoRA sambil menghindari akumulasi memori dari beberapa panggilan ke `load_lora_weights` dan, dalam beberapa kasus, kompilasi ulang, jika model dikompilasi. Alur kerja ini memerlukan LoRA yang dimuat karena bobot LoRA baru ditukar di tempat untuk LoRA yang sudah dimuat sebelumnya.

```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]
> Hotswapping tidak didukung untuk LoRA yang menargetkan text encoder.

Set `hotswap=True` pada `load_lora_weights` untuk mengganti LoRA kedua. Gunakan parameter `adapter_name` untuk menunjukkan LoRA mana yang akan diganti. Jika Anda mengabaikan `adapter_name` saat memuat, Diffusers memberi nama adapter sebagai `default_0`, `default_1`, dan seterusnya. Adapter bernama lebih mudah ditargetkan secara eksplisit.

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

### Model yang dikompilasi

Untuk model yang dikompilasi, gunakan [enable_lora_hotswap()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) untuk menghindari kompilasi ulang saat melakukan hotswap LoRA. Metode ini harus dipanggil *sebelum* memuat LoRA pertama dan `torch.compile` harus dipanggil *setelah* memuat LoRA pertama.

> [!TIP]
> Metode [enable_lora_hotswap()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) tidak selalu diperlukan jika LoRA kedua menargetkan rank dan skala LoRA yang identik dengan LoRA pertama.

Di dalam [enable_lora_hotswap()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap), atur `target_rank` ke rank tertinggi di antara adapter yang akan Anda muat (default 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]
> Pindahkan kode Anda ke dalam context manager `with torch._dynamo.config.patch(error_on_recompile=True)` untuk mendeteksi apakah model dikompilasi ulang. Jika model tetap dikompilasi ulang meskipun Anda telah mengikuti semua langkah di atas, silakan buka [issue](https://github.com/huggingface/diffusers/issues) dengan contoh yang dapat direproduksi.

Jika Anda mengharapkan resolusi yang bervariasi selama inferensi dengan fitur ini, pastikan untuk mengatur `dynamic=True` saat kompilasi. Lihat [dynamic shape compilation](../optimization/fp16#dynamic-shape-compilation) untuk detail lebih lanjut.

Masih ada skenario di mana kompilasi ulang tidak dapat dihindari, misalnya ketika LoRA yang di-hotswap menargetkan lebih banyak lapisan daripada adapter awal. Usahakan untuk memuat LoRA yang menargetkan lapisan terbanyak *terlebih dahulu*. Untuk detail lebih lanjut tentang keterbatasan ini, lihat dokumentasi [hotswapping](https://huggingface.co/docs/peft/main/en/package_reference/hotswap#peft.utils.hotswap.hotswap_adapter) PEFT.

Mengapa `target_rank` dan urutan pemuatan penting

Metode [enable_lora_hotswap()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) mengonversi faktor penskalaan LoRA dari float menjadi torch.tensors dan mengisi bentuk bobot hingga bentuk terbesar yang diperlukan untuk menghindari penugasan ulang seluruh atribut ketika data dalam bobot diganti.

Inilah mengapa argumen `target_rank` penting. Hasilnya tidak berubah meskipun nilai diisi dengan nol. Namun, komputasi mungkin lebih lambat tergantung pada ukuran padding.

Karena tidak ada atribut LoRA baru yang ditambahkan, setiap LoRA berikutnya hanya diizinkan menargetkan lapisan yang sama, atau subset dari lapisan, yang ditargetkan oleh LoRA pertama. Memilih urutan pemuatan LoRA penting karena jika LoRA menargetkan lapisan yang tidak tumpang tindih, Anda mungkin berakhir membuat LoRA dummy yang menargetkan gabungan dari semua lapisan target.

Lihat posting blog [LoRA fast](https://huggingface.co/blog/lora-fast) untuk informasi lebih lanjut tentang hotswapping LoRA dengan model yang dikompilasi, dan untuk detail implementasi lebih lanjut, lihat file [`hotswap.py`](https://github.com/huggingface/peft/blob/92d65cafa51c829484ad3d95cf71d09de57ff066/src/peft/utils/hotswap.py).

## Merge

Bobot dari setiap LoRA dapat digabungkan untuk menghasilkan campuran dari beberapa gaya yang sudah ada. Terdapat beberapa metode untuk menggabungkan LoRA, di mana masing-masing berbeda dalam *bagaimana* bobotnya digabungkan (dapat memengaruhi kualitas generasi).

### set_adapters[[merge]]

Metode [set_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) menggabungkan LoRA dengan mengonkatenasi matriks berbobotnya. Sampaikan nama-nama LoRA ke [set_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) dan gunakan parameter `adapter_weights` untuk mengontrol penskalaan setiap LoRA. Sebagai contoh, jika `adapter_weights=[0.5, 0.5]`, hasilnya adalah rata-rata dari kedua LoRA tersebut.

> [!TIP]
> Gunakan `adapter_weights` pada [set_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) untuk mengontrol seberapa besar setiap LoRA yang digabungkan akan diterapkan. Lihat bagian [Weight scale](#weight-scale) untuk detail lebih lanjut.

```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]
> Ini adalah metode eksperimental dan Anda dapat merujuk ke [Model merging](https://huggingface.co/docs/peft/developer_guides/model_merging) PEFT untuk detail lebih lanjut. Lihat [issue](https://github.com/huggingface/diffusers/issues/6892) ini jika Anda tertarik dengan motivasi dan desain di balik integrasi ini.

Metode `add_weighted_adapter` memungkinkan metode penggabungan yang lebih efisien seperti [TIES](https://huggingface.co/papers/2306.01708) atau [DARE](https://huggingface.co/papers/2311.03099). Metode penggabungan ini menghapus parameter yang redundan dan berpotensi saling mengganggu dari model yang digabungkan. Perlu diingat bahwa rank LoRA harus memiliki rank yang identik agar dapat digabungkan. Penjelasan di bawah ini menggunakan UNet dari SDXL.

Pastikan versi stabil terbaru dari Diffusers dan PEFT terpasang.

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

Muat UNet yang sesuai dengan 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"
```

Muat sebuah pipeline, teruskan UNet ke dalamnya, dan muat sebuah 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"
)
```

Buat `PeftModel` dari checkpoint LoRA dengan menggabungkan UNet pertama yang Anda muat dan UNet LoRA dari 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]
> Anda dapat menyimpan dan menggunakan ulang `ikea_peft_model` dengan mendorongnya ke Hub seperti yang ditunjukkan di bawah ini.
> ```py
> ikea_peft_model.push_to_hub("ikea_peft_model", token=TOKEN)
> ```

Ulangi proses ini dan buat `PeftModel` untuk LoRA kedua.

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

Muat model UNet dasar dan muat adapter-nya.

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

Gabungkan LoRA menggunakan `add_weighted_adapter` dan tentukan cara penggabungan dengan `combination_type`. Contoh di bawah menggunakan metode `"dare_linear"` (lihat [artikel blog](https://huggingface.co/blog/peft_merging) ini untuk mempelajari lebih lanjut tentang metode penggabungan ini), yang secara acak memangkas beberapa bobot dan kemudian melakukan penjumlahan berbobot dari tensor berdasarkan bobot yang ditetapkan untuk setiap LoRA di `weights`.

Aktifkan LoRA yang telah digabungkan dengan [set_adapters()](/docs/diffusers/v0.43.0/id/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

Metode [fuse_lora()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.fuse_lora) menggabungkan bobot LoRA secara langsung dengan bobot denoiser asli (UNet atau transformer) dan text encoder dari model dasar. Hal ini mengurangi overhead pemuatan model dasar untuk setiap LoRA karena model hanya dimuat sekali, yang menurunkan penggunaan memori dan meningkatkan kecepatan inferensi.

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

Panggil [fuse_lora()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.fuse_lora) untuk menggabungkannya. Parameter `lora_scale` mengontrol seberapa besar output diskalakan dengan bobot LoRA. Penting untuk melakukan penyesuaian ini sekarang karena meneruskan `scale` ke `cross_attention_kwargs` tidak akan berfungsi di pipeline.

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

Muat turun bobot LoRA karena bobot tersebut sudah dilebur dengan model dasarnya. Simpan pipeline yang telah dilebur menggunakan [save_pretrained()](/docs/diffusers/v0.43.0/id/api/pipelines/overview#diffusers.DiffusionPipeline.save_pretrained) untuk menyimpannya secara lokal atau `~PushToHubMixin.push_to_hub` untuk menyimpannya ke 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")
```

Pipeline yang sudah digabungkan kini dapat dimuat dengan cepat untuk inferensi tanpa perlu memuat setiap LoRA secara terpisah.

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

Gunakan [unfuse_lora()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.unfuse_lora) untuk memulihkan bobot model dasar, misalnya jika Anda ingin menggunakan nilai `lora_scale` yang berbeda. Anda hanya dapat melakukan unfuse jika hanya ada satu LoRA yang ter-fuse. Sebagai contoh, hal ini tidak akan berfungsi pada pipeline di atas karena terdapat beberapa LoRA yang ter-fuse. Dalam kasus seperti ini, Anda perlu memuat ulang seluruh model.

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

## Kelola

Diffusers menyediakan beberapa metode untuk membantu Anda mengelola penggunaan LoRA. Metode-metode ini dapat sangat berguna jika Anda bekerja dengan beberapa LoRA.

### set_adapters[[manage]]

[set_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) juga mengaktifkan LoRA saat ini untuk digunakan jika ada beberapa LoRA yang aktif. Hal ini memungkinkan Anda untuk berpindah antar LoRA yang berbeda dengan menentukan nama mereka.

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

Simpan adapter dengan [save_lora_adapter()](/docs/diffusers/v0.43.0/id/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.save_lora_adapter) pada modul yang sama yang Anda muat ke (`pipeline.unet` atau `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

Metode [unload_lora_weights()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.unload_lora_weights) memuat ulang bobot LoRA apa pun dalam pipeline untuk memulihkan bobot model dasar.

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

### disable_lora

Metode [disable_lora()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.disable_lora) menonaktifkan semua LoRA (namun tetap disimpan pada pipeline) dan memulihkan pipeline ke bobot model dasar.

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

### get_active_adapters

Metode [get_active_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.get_active_adapters) mengembalikan daftar LoRA aktif yang terpasang pada pipeline.

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

### get_list_adapters

Metode [get_list_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.get_list_adapters) mengembalikan semua LoRA yang dimuat untuk setiap komponen dalam pipeline. Kunci kamus cocok dengan modul yang dimuat, seperti `unet` atau `transformer` dan semua text encoder.

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

### delete_adapters

Metode [delete_adapters()](/docs/diffusers/v0.43.0/id/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.delete_adapters) menghapus sepenuhnya LoRA dan lapisan-lapisannya dari model.

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

## Langkah selanjutnya

- Jelajahi [LoRA Studio](https://lorastudio.co/models) untuk berbagai LoRA yang dapat digunakan, atau Anda dapat mengunggah LoRA favorit Anda dari Civitai ke Hub dengan Space di bawah ini.

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

- Anda dapat menemukan LoRA tambahan di Spaces [FLUX LoRA the Explorer](https://huggingface.co/spaces/multimodalart/flux-lora-the-explorer) dan [LoRA the Explorer](https://huggingface.co/spaces/multimodalart/LoraTheExplorer).

- Lihat blog post [Fast LoRA inference for Flux with Diffusers and PEFT](https://huggingface.co/blog/lora-fast) untuk mempelajari cara mengoptimalkan inferensi LoRA dengan metode seperti FlashAttention-3 dan kuantisasi fp8.

