# Textual Inversion

[Textual Inversion](https://hf.co/papers/2208.01618)は、学習させたい対象の例示画像を数枚だけ用意するだけで、画像生成モデルをパーソナライズするための学習手法です。この手法は、提供した例示画像に一致するようにテキスト埋め込みを学習・更新することで機能します（新しい埋め込みは、プロンプト内で必ず使用しなければならない特別な単語に紐付けられます）。

学習済み埋め込みを用いた推論については、[Textual inversionの推論](../using-diffusers/legacy_adapters#textual-inversion)を参照してください。

vRAM が限られた GPU で学習を行う場合は、学習コマンドで `gradient_checkpointing` と `mixed_precision` パラメータを有効にすることを推奨します。また、[xFormers](../optimization/attention_backends) を使用したメモリ効率の高いアテンションにより、メモリ使用量を削減することもできます。

このガイドでは、[textual_inversion.py](https://github.com/huggingface/diffusers/blob/main/examples/textual_inversion/textual_inversion.py) スクリプトを詳しく見ていき、その仕組みをより深く理解したうえで、ご自身のユースケースに合わせてどのようにカスタマイズできるかを解説します。

スクリプトを実行する前に、ソースからライブラリをインストールしていることを確認してください。

```bash
git clone https://github.com/huggingface/diffusers
cd diffusers
pip install .
```

トレーニングスクリプトを含むサンプルフォルダに移動し、使用しているスクリプトに必要な依存関係をインストールします:

```bash
cd examples/textual_inversion
pip install -r requirements.txt
```
> [!TIP]
> 🤗 Accelerate は、複数 GPU/TPU での学習や混合精度学習を支援するためのライブラリです。ハードウェアと環境に基づいて、学習設定を自動的に構成します。詳細については、🤗 Accelerate の [クイックツアー](https://huggingface.co/docs/accelerate/quicktour) をご覧ください。

🤗 Accelerate の環境を初期化します:

```bash
accelerate config
```

設定を選択せずにデフォルトの🤗 Accelerate環境を設定するには:

```bash
accelerate config default
```

または、ノートブックのように対話型シェルをサポートしていない環境では、以下を使用できます:

```py
from accelerate.utils import write_basic_config

write_basic_config()
```

最後に、独自のデータセットでモデルをトレーニングしたい場合は、[トレーニング用のデータセットを作成する](create_dataset)ガイドを参照して、トレーニングスクリプトと互換性のあるデータセットの作成方法を確認してください。

> [!TIP]
> 以下のセクションでは、スクリプトの修正方法を理解するために重要な部分に焦点を当てていますが、スクリプトのすべての側面を詳細に説明するものではありません。さらに詳しく知りたい場合は、[スクリプト](https://github.com/huggingface/diffusers/blob/main/examples/textual_inversion/textual_inversion.py)をぜひお読みいただき、ご質問やご懸念事項があればお知らせください。

## スクリプトのパラメータ

学習スクリプトには、学習の実行をニーズに合わせて調整するための多くのパラメータがあります。すべてのパラメータとその説明は、[`parse_args()`](https://github.com/huggingface/diffusers/blob/839c2a5ece0af4e75530cb520d77bc7ed8acf474/examples/textual_inversion/textual_inversion.py#L176) 関数にリストされています。適用可能な場合、Diffusers は学習バッチサイズや学習率などの各パラメータにデフォルト値を提供しますが、必要に応じて学習コマンド内でこれらの値を変更して構いません。

例えば、デフォルト値である1より多くの勾配蓄積ステップ数を増加させるには:

```bash
accelerate launch textual_inversion.py \
  --gradient_accumulation_steps=4
```

その他、指定すべき基本的かつ重要なパラメータには、以下が含まれます。

- `--pretrained_model_name_or_path`: Hub 上のモデル名、または事前学習済みモデルへのローカルパス
- `--train_data_dir`: 学習データセット（サンプル画像）を含むフォルダへのパス
- `--output_dir`: 学習済みモデルを保存する場所
- `--push_to_hub`: 学習したモデルを Hub にプッシュするかどうか
- `--checkpointing_steps`: モデルの学習中にチェックポイントを保存する頻度です。学習が何らかの理由で中断された場合、学習コマンドに`--resume_from_checkpoint`を追加することで、そのチェックポイントから学習を再開できます。
- `--num_vectors`: 埋め込みを学習するためのベクトルの数。このパラメータを大きくするとモデルの学習精度が向上しますが、学習コストも増加します
- `--placeholder_token`: 学習された埋め込みを紐付けるための特別な単語（推論時のプロンプトでこの単語を使用する必要があります）
- `--initializer_token`: 学習対象のオブジェクトやスタイルを大まかに表す1語
- `--learnable_property`: モデルを学習して新しい「スタイル」（例: ヴァン・ゴッホの絵画スタイル）や「オブジェクト」（例: 飼い犬）を学習させるかどうか

## 学習スクリプト

他の一部の学習スクリプトとは異なり、[`TextualInversionDataset`](https://github.com/huggingface/diffusers/blob/b81c69e489aad3a0ba73798c459a33990dc4379c/examples/textual_inversion/textual_inversion.py#L487) は、データセットの作成に使用される独自のデータセットクラスです。画像サイズ、プレースホルダートークン、補間方法、画像のクロップの有無などをカスタマイズできます。データセットの作成方法を変更する必要がある場合は、`TextualInversionDataset` を修正できます。

次に、[`main()`](https://github.com/huggingface/diffusers/blob/839c2a5ece0af4e75530cb520d77bc7ed8acf474/examples/textual_inversion/textual_inversion.py#L573) 関数に、データセットの前処理コードと学習ループが含まれています。

スクリプトは、[tokenizer](https://github.com/huggingface/diffusers/blob/b81c69e489aad3a0ba73798c459a33990dc4379c/examples/textual_inversion/textual_inversion.py#L616)、[schedulerとモデル](https://github.com/huggingface/diffusers/blob/b81c69e489aad3a0ba73798c459a33990dc4379c/examples/textual_inversion/textual_inversion.py#L622)を読み込むことから始まります:

```py
# Load tokenizer
if args.tokenizer_name:
    tokenizer = CLIPTokenizer.from_pretrained(args.tokenizer_name)
elif args.pretrained_model_name_or_path:
    tokenizer = CLIPTokenizer.from_pretrained(args.pretrained_model_name_or_path, subfolder="tokenizer")

# Load scheduler and models
noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler")
text_encoder = CLIPTextModel.from_pretrained(
    args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision
)
vae = AutoencoderKL.from_pretrained(args.pretrained_model_name_or_path, subfolder="vae", revision=args.revision)
unet = UNet2DConditionModel.from_pretrained(
    args.pretrained_model_name_or_path, subfolder="unet", revision=args.revision
)
```

特殊な[プレースホルダトークン](https://github.com/huggingface/diffusers/blob/b81c69e489aad3a0ba73798c459a33990dc4379c/examples/textual_inversion/textual_inversion.py#L632)がトークナイザに追加され、新しいトークンを考慮するために埋め込みが再調整されます。

次に、スクリプトは`TextualInversionDataset`から[データセットを作成します](https://github.com/huggingface/diffusers/blob/b81c69e489aad3a0ba73798c459a33990dc4379c/examples/textual_inversion/textual_inversion.py#L716)。

```py
train_dataset = TextualInversionDataset(
    data_root=args.train_data_dir,
    tokenizer=tokenizer,
    size=args.resolution,
    placeholder_token=(" ".join(tokenizer.convert_ids_to_tokens(placeholder_token_ids))),
    repeats=args.repeats,
    learnable_property=args.learnable_property,
    center_crop=args.center_crop,
    set="train",
)
train_dataloader = torch.utils.data.DataLoader(
    train_dataset, batch_size=args.train_batch_size, shuffle=True, num_workers=args.dataloader_num_workers
)
```

最後に、[training loop](https://github.com/huggingface/diffusers/blob/b81c69e489aad3a0ba73798c459a33990dc4379c/examples/textual_inversion/textual_inversion.py#L784)は、ノイズ付き残差の予測から、特別なプレースホルダートークンの埋め込み重みの更新まで、それ以外のすべての処理を担当します。

トレーニングループの仕組みについてさらに詳しく知りたい場合は、デノイジングプロセスの基本的なパターンを解説している[パイプライン、モデル、スケジューラーの理解](../using-diffusers/write_own_pipeline)チュートリアルをご覧ください。

## スクリプトを実行します

すべての変更が完了したか、デフォルトの設定で問題ない場合は、トレーニングスクリプトの起動準備が整いました！🚀

このガイドでは、[猫のおもちゃ](https://huggingface.co/datasets/diffusers/cat_toy_example)の画像をダウンロードしてディレクトリに保存します。ただし、必要に応じて独自のデータセットを作成して使用することもできます（[学習用データセットの作成](create_dataset)ガイドを参照）。

```py
from huggingface_hub import snapshot_download

local_dir = "./cat"
snapshot_download(
    "diffusers/cat_toy_example", local_dir=local_dir, repo_type="dataset", ignore_patterns=".gitattributes"
)
```

環境変数`MODEL_NAME`に Hub 上のモデル ID またはローカルモデルへのパスを、`DATA_DIR` に先ほど猫の画像をダウンロードしたパスを設定します。このスクリプトは、リポジトリに以下のファイルを作成して保存します。

- `learned_embeds.bin`: サンプル画像に対応する学習済み埋め込みベクトル
- `token_identifier.txt`: 特別なプレースホルダトークン
- `type_of_concept.txt`: 学習対象の概念の種類（"object"または"style"）

> [!WARNING]
> 完全なトレーニングの実行には、単一のV100 GPUで約1時間かかります。

スクリプトを実行する前に、もう1点だけ。トレーニングの進捗を追いかけたい場合は、トレーニングが進むにつれて生成された画像を定期的に保存できます。トレーニングコマンドに次のパラメータを追加してください。

```bash
--validation_prompt="A <cat-toy> train"
--num_validation_images=4
--validation_steps=100
```

```bash
export MODEL_NAME="stable-diffusion-v1-5/stable-diffusion-v1-5"
export DATA_DIR="./cat"

accelerate launch textual_inversion.py \
  --pretrained_model_name_or_path=$MODEL_NAME \
  --train_data_dir=$DATA_DIR \
  --learnable_property="object" \
  --placeholder_token="<cat-toy>" \
  --initializer_token="toy" \
  --resolution=512 \
  --train_batch_size=1 \
  --gradient_accumulation_steps=4 \
  --max_train_steps=3000 \
  --learning_rate=5.0e-04 \
  --scale_lr \
  --lr_scheduler="constant" \
  --lr_warmup_steps=0 \
  --output_dir="textual_inversion_cat" \
  --push_to_hub
```

トレーニングが完了すると、新しくトレーニングしたモデルを次のようにして推論に使用できます。

```py
from diffusers import StableDiffusionPipeline
import torch

pipeline = StableDiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_textual_inversion("sd-concepts-library/cat-toy")
image = pipeline("A <cat-toy> train", num_inference_steps=50).images[0]
image.save("cat-train.png")
```

## 次のステップ

ご自身のTextual Inversionモデルの学習が完了したことをお祝いします！🎉 新しいモデルの使用方法について詳しく知るために、以下のガイドが役立つ可能性があります：

- [Textual Inversion埋め込み](../using-diffusers/legacy_adapters#textual-inversion)の読み込み方法と、ネガティブ埋め込みとして使用する方法を学びましょう。

