# LoRA

[LoRA (Low-Rank Adaptation)](https://huggingface.co/papers/2106.09685)は、元の重みを凍結し、新しいパラメータの小さなセットを学習させることで、事前学習済みモデルを新しいタスクに適応させます。適応はフルファインチューニングよりも高速かつ低コストであるため、新しいスタイルでの画像生成のようなタスクに実用的です。

LoRAのチェックポイントは通常、数百MB程度です。`pipeline.load_lora_weights`で読み込み、`weight_name`にチェックポイントのファイル名を指定します。共通のパラメータについては、[load_lora_weights()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.StableDiffusionLoraLoaderMixin.load_lora_weights)を参照してください。

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

このページの pipeline LoRA API は、モデルファミリーを問わず同じように動作します。デノイジングモジュールは、[Stable Diffusion](../api/pipelines/stable_diffusion/overview)および[SDXL](../api/pipelines/stable_diffusion/stable_diffusion_xl)では`pipeline.unet`、[Flux](../api/pipelines/flux)、[Stable Diffusion 3](../api/pipelines/stable_diffusion/stable_diffusion_3)、[AuraFlow](../api/pipelines/aura_flow)、[LTX](../api/pipelines/ltx_video)などの DiT 系モデルでは`pipeline.transformer`です。[CogVideoX](../api/pipelines/cogvideox)、[HunyuanVideo](../api/pipelines/hunyuan_video)、[Wan](../api/pipelines/wan)などの動画モデルにも同じパターンが適用されます。モデルレベルの PEFT メソッドでは、この属性と対応する`prefix`（`"unet"`または`"transformer"`）を使用します。

`pipeline.load_lora_weights` は、LoRA 重みをデノイザー（UNet または transformer）およびテキストエンコーダーに読み込むための推奨方法です。共通のパラメータについては [load_lora_weights()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.StableDiffusionLoraLoaderMixin.load_lora_weights) を参照してください。以下のケースに対応できます。

- チェックポイントは、デノイザーとテキストエンコーダー間でキーを共有します
- チェックポイントは、個別のデノイザーとテキストエンコーダーのキーを使用しています。

[load_lora_adapter()](/docs/diffusers/v0.43.0/ja/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.load_lora_adapter) メソッドは、UNet や transformer など、`PeftAdapterMixin` をサブクラス化する任意の Diffusers モデルにおいて、*モデルレベル*で LoRA アダプターを読み込みます。アダプターの設定を構築・準備し、そのモジュールに重みをロードします。

`prefix` を使用して、対象モジュール（`"unet"` または `"transformer"`）の state dict キーをフィルタリングします。デフォルトは `"transformer"` であるため、Stable Diffusion および SDXL では `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) は、PyTorch モデルをコンパイルして最適化されたカーネルを使用することで、推論を高速化します。コンパイルの前に、LoRA 重みをベースモデルに融合し、その後アンロードする必要があります。

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

通常、パイプラインの中で最も計算負荷が高いコンポーネントであるため、デノイザーをコンパイルします。

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

Fluxおよびその他のDiTパイプラインでは、代わりに`pipeline.transformer`をコンパイルしてください。

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

コンパイル済みモデルと複数のLoRAを扱う際に再コンパイルを回避する方法については、[hotswapping](#hotswapping)セクションを参照してください。

## 重みスケール

[set_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) の `adapter_weights` パラメータを使用して、適用する LoRA の量を制御します。重みが `0` の場合はベースモデルの重みのみを使用する場合に相当し、`1` の場合は LoRA を完全に使用する場合に相当します。

`adapter_weights` にスカラーを渡し、[set_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) で 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` を主要なパターンとして使用しますが、一部の pipeline は呼び出し時に `cross_attention_kwargs={"scale": 1.0}` を受け入れ、アテンションのスケーリングを行う副次的な方法として機能します。クロスアテンションを使用しない pipeline は、代わりに `attention_kwargs` を公開している場合が多いです（Flux と Stable Diffusion 3 では `joint_attention_kwargs` ）。

> [!WARNING]
> [set_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.set_adapters) メソッドはアテンションの重みのスケーリングのみを行います。LoRA に ResNet やダウンサンプラー、アップサンプラーが含まれている場合、これらのコンポーネントのスケーリング値は `1.0` のままになります。

各テキストエンコーダーまたはデノイザーブロックをスケーリングするには、辞書を渡します。辞書のキーはパイプラインのモジュールに従います。以下の例はSDXL（`unet`とテキストエンコーダー）です。Fluxは`transformer`と`text_encoder`を使用します。SD3は`transformer`と複数のテキストエンコーダーを使用します。

この SDXL の例では、UNet の `"down"` ブロックは 0.9 倍にスケーリングされ、`"up"` 配下の `"block_0"` と `"block_1"` でアテンションブロックのスケーリングをさらに指定できます。`"mid"` のようなブロックが指定されていない場合、デフォルト値の `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]
```

### スケジューリングのスケーリング

サンプリング中にLoRAスケールを動的に調整することで、特定のステップではスケールの増加または減少がより効果的になるため、全体の構成やレイアウトをより適切に制御できます。

以下の例では、[character LoRA](https://huggingface.co/alvarobartt/ghibli-characters-flux-lora)は、キャラクター生成を確立するために、最初の20ステップで徐々に減衰する高いスケールから始まります。後半のステップでは、LoRAが学習されていない画像の他の部分にLoRAの特徴を過度に追加しないよう、スケールは`0.2`のみが適用されます。

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

## ホットスワップ

LoRAのホットスワップは、`load_lora_weights`を複数回呼び出すことによるメモリ蓄積を回避し、モデルがコンパイルされている場合によっては再コンパイルも回避できるため、複数のLoRAを扱う効率的な方法です。このワークフローには、既存のロード済みLoRAの重みがその場で新しいLoRAの重みと置き換えられるため、ロード済みのLoRAが必要です。

```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]
> テキストエンコーダーを対象とするLoRAでは、ホットスワップはサポートされていません。

`load_lora_weights` で `hotswap=True` を設定すると、2番目の LoRA をスワップできます。スワップする LoRA を指定するには `adapter_name` パラメータを使用します。`adapter_name` を省略して読み込む場合、Diffusers はアダプターに `default_0`、`default_1` のような名前を付けます。名前付きアダプターの方が明示的にターゲットを指定しやすくなります。

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

### コンパイル済みモデル

コンパイル済みモデルでは、LoRA のホットスワップ時に再コンパイルを回避するために [enable_lora_hotswap()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) を使用します。このメソッドは最初の LoRA をロードする*前に*呼び出す必要があり、`torch.compile` は最初の LoRA をロードする*後に*呼び出します。

> [!TIP]
> 2番目のLoRAが1番目のLoRAと同一のLoRAランクとスケールを対象とする場合、[enable_lora_hotswap()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap)メソッドは必ずしも必要ではありません。

[enable_lora_hotswap()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) 内で、読み込む予定のアダプターの中で最も高いランクを `target_rank` に設定します（デフォルトは 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]
> `with torch._dynamo.config.patch(error_on_recompile=True)` コンテキストマネージャー内にコードを移動し、モデルが再コンパイルされたかどうかを検出してください。上記の手順をすべて実行したにもかかわらずモデルが再コンパイルされる場合は、再現可能な例を添えて[issue](https://github.com/huggingface/diffusers/issues)を作成してください。

この機能を使用する際に、推論中に解像度が変化する可能性がある場合は、コンパイル時に`dynamic=True`を設定してください。詳細については、[動的な形状のコンパイル](../optimization/fp16#dynamic-shape-compilation)を参照してください。

再コンパイルが避けられないシナリオがまだ存在します。例えば、ホットスワップされた LoRA が初期アダプターよりも多くのレイヤーを対象としている場合です。最も多くのレイヤーを対象とする LoRA を*最初に*読み込むようにしてください。この制約の詳細については、PEFT の[hotswapping](https://huggingface.co/docs/peft/main/en/package_reference/hotswap#peft.utils.hotswap.hotswap_adapter)ドキュメントを参照してください。

`target_rank` とロード順序が重要である理由

[enable_lora_hotswap()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.enable_lora_hotswap) メソッドは、LoRA のスケーリング係数を float から torch.tensors に変換し、重みのデータが置き換えられた際に属性全体を再割り当てすることを避けるため、重みの形状を必要な最大形状にパディングします。

これが`target_rank`引数が重要である理由です。値をゼロでパディングしても、結果は変わりません。ただし、パディングサイズによっては計算が遅くなる場合があります。

新しい LoRA 属性が追加されないため、後続の各 LoRA は、最初の LoRA が対象とするレイヤー、またはその部分集合のみを対象とすることが許可されます。LoRA の読み込み順序の選択は重要であり、LoRA が互いに異なるレイヤーを対象としている場合、すべての対象レイヤーの和集合を対象とするダミーの LoRA が作成されてしまう可能性があります。

コンパイル済みモデルでの LoRA ホットスワップの詳細については、[LoRA fast](https://huggingface.co/blog/lora-fast) のブログ記事をご参照ください。また、実装の詳細については、[`hotswap.py`](https://github.com/huggingface/peft/blob/92d65cafa51c829484ad3d95cf71d09de57ff066/src/peft/utils/hotswap.py) ファイルをご覧ください。

## マージ

各LoRAの重みをマージすることで、複数の既存スタイルのブレンドを生成できます。LoRAのマージにはいくつかの方法があり、それぞれが重みをマージする*方法*が異なります（生成品質に影響する可能性があります）。

### set_adapters[[merge]]

[set_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) メソッドは、重み付き行列を連結することにより LoRA をマージします。[set_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) に LoRA の名前を渡し、`adapter_weights` パラメータを使用して各 LoRA のスケーリングを制御します。例えば、`adapter_weights=[0.5, 0.5]` の場合、出力は両方の LoRA の平均になります。

> [!TIP]
> 各マージ済み LoRA を適用する量を制御するには、[set_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) で `adapter_weights` を優先的に使用してください。詳細は [Weight scale](#weight-scale) セクションを参照してください。

```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]
> これは実験的なメソッドであり、詳細についてはPEFTの[Model merging](https://huggingface.co/docs/peft/developer_guides/model_merging)を参照してください。この統合の動機や設計について興味がある場合は、この[issue](https://github.com/huggingface/diffusers/issues/6892)をご覧ください。

`add_weighted_adapter` メソッドにより、[TIES](https://huggingface.co/papers/2306.01708) や [DARE](https://huggingface.co/papers/2311.03099) のようなより効率的なマージ手法を有効にできます。これらのマージ手法は、マージされたモデルから冗長なパラメータや、干渉を引き起こす可能性のあるパラメータを除去します。マージするには、LoRA のランクが同一である必要がある点にご注意ください。以下の解説では、SDXL の UNet を使用します。

Diffusers と PEFT の最新の安定版がインストールされていることを確認してください。

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

LoRA UNetに対応するUNetを読み込みます。

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

パイプラインを読み込み、UNetを渡して、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"
)
```

最初に読み込んだ UNet と、パイプラインからの LoRA UNet を組み合わせることで、LoRA チェックポイントから`PeftModel`を作成します。

```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]
> `ikea_peft_model`を以下に示すようにHubにプッシュすることで、保存して再利用できます。
> ```py
> ikea_peft_model.push_to_hub("ikea_peft_model", token=TOKEN)
> ```

このプロセスを繰り返し、2番目のLoRA用の`PeftModel`を作成します。

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

ベースのUNetモデルを読み込み、アダプターを読み込みます。

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

`add_weighted_adapter` を使用して LoRA をマージし、`combination_type` でマージ方法を指定します。以下の例では、`"dare_linear"` メソッド（これらのマージ方法の詳細については、この[ブログ記事](https://huggingface.co/blog/peft_merging)を参照してください）を使用しています。このメソッドは、一部の重みをランダムにプルーニングした上で、`weights` に設定された各 LoRA の重みに基づいてテンソルの加重和を計算します。

[set_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.set_adapters) を呼び出して、マージされた LoRA を有効にします。

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

[fuse_lora()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.fuse_lora) メソッドは、LoRA の重みを、基盤モデルの元のデノイザー（UNet または transformer）およびテキストエンコーダーの重みに直接融合します。これにより、各 LoRA ごとに基盤モデルを読み込むオーバーヘッドが削減され、モデルが一度だけ読み込まれるため、メモリ使用量が低減し、推論速度が向上します。

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

[fuse_lora()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.fuse_lora) を呼び出して、それらを融合します。`lora_scale` パラメータは、LoRA 重みによって出力をどの程度スケーリングするかを制御します。パイプラインでは `cross_attention_kwargs` に `scale` を渡しても動作しないため、ここでこの調整を行うことが重要です。

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

LoRA の重みは基盤モデルにすでに融合されているため、アンロードします。融合されたパイプラインは、ローカルに保存するには [save_pretrained()](/docs/diffusers/v0.43.0/ja/api/pipelines/overview#diffusers.DiffusionPipeline.save_pretrained) を、Hub に保存するには `~PushToHubMixin.push_to_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")
```

融合されたパイプラインは、各 LoRA を個別に読み込む必要なく、推論用にすばやく読み込むことができます。

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

`lora_scale` の値を変更したい場合など、元のモデルの重みを復元するには [unfuse_lora()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.unfuse_lora) を使用します。アンフュージョンは、フュージョンされた LoRA が 1 つしかない場合のみ可能です。例えば、上記のパイプラインでは複数の LoRA がフュージョンされているため、この操作は機能しません。このような場合は、モデル全体を再読み込みする必要があります。

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

## 管理

Diffusersには、LoRAの取り扱いを管理するためのいくつかのメソッドが用意されています。複数のLoRAを扱う場合、これらのメソッドが特に役立ちます。

### set_adapters[[manage]]

[set_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.set_adapters) は、複数の LoRA が有効な場合、使用する現在の LoRA を有効にします。これにより、名前を指定して異なる LoRA の間を切り替えることができます。

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

`pipeline.unet` または `pipeline.transformer` に読み込んだのと同じモジュールで、[save_lora_adapter()](/docs/diffusers/v0.43.0/ja/api/loaders/peft#diffusers.loaders.PeftAdapterMixin.save_lora_adapter) を使用してアダプターを保存します。

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

[unload_lora_weights()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.unload_lora_weights) メソッドは、パイプライン内の LoRA 重みをアンロードして、元のモデルの重みを復元します。

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

### disable_lora

[disable_lora()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.disable_lora) メソッドは、すべての LoRA を無効にし（パイプライン上には保持されます）、パイプラインを元のモデルの重みに復元します。

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

### get_active_adapters

[get_active_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.get_active_adapters) メソッドは、パイプラインにアタッチされているアクティブな LoRA のリストを返します。

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

### get_list_adapters

[get_list_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.get_list_adapters) メソッドは、パイプラインの各コンポーネントに対して読み込まれたすべての LoRA を返します。辞書のキーは、`unet` や `transformer`、およびテキストエンコーダーなど、読み込まれたモジュールと一致します。

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

### delete_adapters

[delete_adapters()](/docs/diffusers/v0.43.0/ja/api/loaders/lora#diffusers.loaders.lora_base.LoraBaseMixin.delete_adapters) メソッドは、LoRAとそのレイヤーをモデルから完全に削除します。

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

## 次のステップ

- [LoRA Studio](https://lorastudio.co/models)で利用可能なさまざまなLoRAを閲覧するか、以下のSpaceからCivitaiの好きなLoRAをHubにアップロードできます。

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

- You can find additional LoRAs in the [FLUX LoRA the Explorer](https://huggingface.co/spaces/multimodalart/flux-lora-the-explorer) and [LoRA the Explorer](https://huggingface.co/spaces/multimodalart/LoraTheExplorer) Spaces.

- [DiffusersとPEFTによるFluxの高速LoRA推論](https://huggingface.co/blog/lora-fast)のブログ記事をご覧ください。FlashAttention-3やfp8量子化などの手法を用いてLoRA推論を最適化する方法を学ぶことができます。

