久しぶりにDiffusersライブラリを触る

## 始めに

初めてDiffusersライブラリで画像生成してから2年ぐらい経ちました。
残っているもので最初に生成した画像はこちらです。
![output37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238748/302c8827-9fb8-ccec-677b-6bf46a612832.png)

しばらくして[Stable diffusion WEBUI AUTOMATIC1111](https://github.com/AUTOMATIC1111/stable-diffusion-webui)が話題になって、遠巻きに見ていましたがとんでもなく便利らしいということで使ってみたらたしかにとんでもなく便利でずっとWEBUIを使っていました。ホーチミン天才。
最近は[reforge](https://github.com/Panchovix/stable-diffusion-webui-reForge)を専ら使っていますが、久しぶりにDiffusersライブラリを触ってみようと思い、せっかくなら記事にしようかと思いました。
さらに、せっかくならアドベントカレンダーに参加してみようかと思いました。

WEBUIもreforgeも比較的ﾎﾟﾁﾎﾟﾁで入れられるので考えることが少ない（特に[Stability Matrix](https://github.com/LykosAI/StabilityMatrix?tab=readme-ov-file)を使うと何もすることなくはじめられます）のですが、Diffusersライブラリはそう言うわけにいきません。

Hugging Faceのドキュメントに従って導入をします。
[Hugging Face Diffusersライブラリ](https://huggingface.co/docs/diffusers/ja/index)

## 前提

以下の環境で導入しました。
* 使用GPU:Nvidia Geforce RTX3060（12GB）（12GBのVRAMあったほうがいいです）
* CUDA11.8
* Python3.10.6

## 導入

### 準備

事前にPythonとCUDAをインストールしておきます。
* [Python Documentation 4. Windows で Python を使う](https://docs.python.org/ja/3/using/windows.html#windows-full)
* [CUDA](https://developer.nvidia.com/cuda-downloads)

始めに、作業用ディレクトリを作って、そのディレクトリをカレントディレクトリにしてコマンドプロンプトを開きます。("G:\StableDiffusion\Diffusers"とします。)
Pythonの仮想環境を作り、仮想環境に入ります。

```winbatch
(Diffusers_venv) G:\StableDiffusion\Diffusers>python -m venv Diffusers_venv
(Diffusers_venv) G:\StableDiffusion\Diffusers>Diffusers_venv\Scripts\activate
```

なぜかpipのバージョンが古いと怒られたので、先にpipのアップデートをします。

```winbatch
(Diffusers_venv) G:\StableDiffusion\Diffusers>python.exe -m pip install --upgrade pip
```

### Transformersライブラリインストール

NLP(Neuro Linguistic Programming)をするためのTransformersライブラリをインストールします。
torchを使います。

```winbatch
(Diffusers_venv) G:\StableDiffusion\Diffusers>pip install diffusers["torch"] transformers
```

### Pytorchインストール

[Pytorch](https://pytorch.org/get-started/locally/#start-locally)をインストールします。
ページに飛んだら環境を選択するとコマンドが出てきますので、コピペします。
また、DiffusersライブラリからPytorchを扱うためにaccelerateをインストールします。

```winbatch
(Diffusers_venv) G:\StableDiffusion\Diffusers>pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
(Diffusers_venv) G:\StableDiffusion\Diffusers>pip install accelerate
```

### Diffusersライブラリをインストール

```winbatch
(Diffusers_venv) G:\StableDiffusion\Diffusers>pip install git+https://github.com/huggingface/diffusers
```

### スクリプト作成

[ドキュメント](https://huggingface.co/docs/diffusers/main/en/api/pipelines/auto_pipeline)を参考に書いていきます。モデルはお好みで。
私は[BloodOrangeMix](https://huggingface.co/WarriorMama777/OrangeMixs/blob/main/Models/BloodOrangeMix/BloodOrangeMix_half.ckpt)をダウンロードしてDiffusersディレクトリ内にmodelディレクトリを作成して入れました。

「うさみみつけた赤目の女の子」を生成します。
main.pyとしてPythonのスクリプトを保存します。

#### スクリプト例

```python
## ライブラリのインポート
from diffusers import StableDiffusionPipeline
import torch

## モデルの設定とパイプラインの読み込み
model_file = 'model\BloodOrangeMix_half.ckpt'
pipe = StableDiffusionPipeline.from_single_file(
    model_file, torch_dtype=torch.float16, use_safetensors=True
    )
## 生成に使うデバイスをCUDAに設定します。"cpu"にするとCPUで生成してくれますが、おすすめしません。
pipe.to("cuda")

## プロンプトの設定
prompt = 'sfw, rabbit ears, 1girl, kawaii, red eyes, long skirt'
negative_prompt = 'lowres, bad anatomy, bad hands, text, error, missing fingers, ugly, deformed, disfigured, poor details'

## おまじない
if pipe.safety_checker is not None:
    pipe.safety_checker = lambda images, **kwargs: (images, False)

## パイプラインの実行
image = pipe(
    prompt, 
    negative_prompt=negative_prompt, 
    width=512,
    height=512,
    num_inference_steps=30
    ).images[0]
## 画像の保存
image.save('usamimigirl.jpg')
```

### 実行します

```winbatch
(Diffusers_venv) G:\StableDiffusion\Diffusers>python main.py
Fetching 11 files: 100%|███████████████████████████████████████████████████████████████████████| 11/11 [00:00<?, ?it/s]
Loading pipeline components...:   0%|                                                            | 0/6 [00:00<?, ?it/s]Some weights of the model checkpoint were not used when initializing CLIPTextModel:
 ['text_model.embeddings.position_ids']
Loading pipeline components...:  50%|██████████████████████████                          | 3/6 [00:00<00:00, 11.80it/s]In this conversion only the non-EMA weights are extracted. If you want to instead extract the EMA weights (usually better for inference), please make sure to add the `--extract_ema` flag.
Loading pipeline components...: 100%|████████████████████████████████████████████████████| 6/6 [00:01<00:00,  4.86it/s]
You have disabled the safety checker for <class 'diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline'> by passing `safety_checker=None`. Ensure that you abide to the conditions of the Stable Diffusion license and do not expose unfiltered results in services or applications open to the public. Both the diffusers team and Hugging Face strongly recommend to keep the safety filter enabled in all public facing circumstances, disabling it only for use-cases that involve analyzing network behavior or auditing its results. For more information, please have a look at https://github.com/huggingface/diffusers/pull/254 .
100%|██████████████████████████████████████████████████████████████████████████████████| 30/30 [00:04<00:00,  6.99it/s]
```

なんか色々出ましたが、生成されました。生成時間は4秒ぐらいでした。
![usamimigirl.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238748/3ce5af90-3147-eaf5-6566-dc8a571c1443.jpeg)

## 導入した感想

以前よりも情報は多いのでかなり入れやすくなっている印象でした。ただ、やはりオプションといいますか、パイプラインのパラメーターは分かりづらいもので、ドキュメント通りにしてもエラーになることがありました。
個人的に大きな変更に感じたのは、safetensorsが標準で扱えることかなと思いました。当時はckptだったかbinしか扱えなかった気がするので、いちいちsafetensorsから変換するスクリプトを使っていました。
削除したい場合は作業ディレクトリのDiffusersごと削除すればまっさらに出来ます。

ファイル保存部分を工夫すれば通し番号をつけられますし、プロンプトの保存も頑張れば出来ます。頑張れば。
自由度しかないDiffusersライブラリなので、人によってはとても良いものかと思います。

以上です。