【Stable-diffusionローカル実行】モデルを簡単に切り替えられるDiscordBOTを作ってみた

実行環境はもうできてて、Botだけ使いたいんよって人は【本論】Botを起動するまで流し見で

Botでは、--model | -mでモデルの指定ができたり、--times | -tで生成回数を指定できる。また、設定をいじることでファイル出力もできるので保存も可能。(./generate.pyに同じように引数を渡すと保存だけできる)

何かをインストールした後にうまくいかなかったら再起動すると動くことが多い。

コマンドプロンプトの開き方(わかる人は飛ばす)

以降の$から始まるコマンドはすべてコマンドプロンプト/ターミナルで実行する必要があります。
開き方はいくつかあるが、

  • Windowsボタンを押して「cmd」と検索
  • `Windowsキー+Rで、「ファイル名を指定して実行」にcmdと入力して起動

あたりが楽かな?と、、、

CUDAをインストール

まず、前提としてMacOSでの実行は検証してません。というか、GeForce系のグラボ以外で動くかもわからないので、悪しからず。
現在PyTorch(後述)が対応しているのが、おそらく最新でも11.8なので11.8をインストール。
developer.nvidia.com

Pythonとライブラリのインストール

Pythonとライブラリのインストール

特にこだわりなければ最新でよし
どこからインストールするのかわからない人は、ターミナルにwinget install pythonって入れるとおそらくインストールできる。
www.python.org

画像生成に必要なパッケージをインストール

コマンドでPythonのパッケージをインストールする。

$ pip install <ライブラリ名>
  • diffusers
  • discord
  • PyTorch類(下記詳細)
  • transformers
  • accelerate
  • omegaconf

PyTorchはCUDA対応のものをインストールする必要があるので、公式ページからインストールコマンドを持ってくる。(pip3をpipにしないといけないかもしれない)

torchのバージョンにcudaが書いてるか確認する

$ python
Python 3.10.11
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> print(torch.__version__)

Windows環境でCUDA11.8をインストール、途中でわからなくなったらとりあえずPythonをアンインストール、インストールし直して下のコマンド2つを実行してみる。

terminal
$ pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
$ pip install diffusers discord transformers accelerate omegaconf

【本論】Discordボットを起動する

ファイルのダウンロードとBotの準備

GithubからBOTプログラム本体をダウンロードして展開(Download ZIPから)

次に、Discordのボット作成イントロダクションに従ってBotの設定をする。コピーしたトークンは設定しなければならないのでメモっといてください。
Bot permissionはTEXT PERMISSIONSをすべてチェックつける。
discordpy.readthedocs.io

設定の説明(settings.ini)

フォルダ内のsettings.iniにはボットに必要な情報や、変更可能なオプションがある。
基本的に内容はコメントに書いてるので見てくれたらわかると思う。
ただし、以下の内容は設定しないと動きません。
- discord_token : さっきコピーしたトークン(ID) - on_ready_channel_id :Botの起動・終了を知らせるチャンネルID

モデル追加の説明(models.json)

models.jsonにモデルのリストを記述することで、モデルの指定をしています。

[
  {"model":"stable-diffusion-v1", "path":"runwayml/stable-diffusion-v1-5"},
  {"model":"stable-diffusion-v2", "path":"stabilityai/stable-diffusion-2-1"}
]

追加するときは
{"model":"モデル名", "path":"モデルのパス"}を追加する。
, を忘れるとエラーが出るので、追加するときは注意。
モデル名はコマンドでモデルを指定するときに使う名前なので、わかりやすい名前をつけてください。パスは違うと動きません。
Hugging Faceで公開されているモデルはタイトルの横のコピーマークでコピーできるパスを入れると動くものも多いです。

下記の方法でモデルを自分でダウンロードしたときは、そのフォルダパスを記述する。
例えば、7th_anime_v3_Cなどは上のコピーするだけの方法では実行できない。
そのときは、ダウンロードからckptファイルをダウンロード、下の方法でフォルダに展開する
./models/7th_anime_v3_Cに展開したとすると、
{"model":"7th-anime", "path":"./models/7th_anime_v3_C"}を追加する。

Botの起動

ターミナルでbot_start.pyディレクトリに移動(できる人は)。
わからなかったらbot_start.pyの存在するフォルダで右クリックからターミナルで開く。

python ./bot_start.pyというコマンドを実行することで、BOTが起動します。
We have logged in as "bot名"と表示されたらBOTの設定は成功。

Botのコマンド説明

基本は
/gen "プロンプト" [--model モデル名] [--times 実行回数] [--negative "ネガティブプロンプト"]
プロンプトはスペースを含む場合は””で囲って入力。
[]は省略可能、--model-m--times-t--negative-nに省略可能。
/gen --show-modelsで指定できるモデル一覧を表示できる。

nsfw無効化

stable-diffusion-v2以降はプログラム内からの解除ができないのでdiffusersをいじる必要がある。

$ python
>>> import diffusers
>>> print(diffusers.__file__)

でフォルダの場所を見つけて、diffusers/pipelines/stable_diffusion/safety_check.py内の記述をコメントアウト。(#を各行頭につける)

safety_check.py
for idx, has_nsfw_concept in enumerate(has_nsfw_concepts):
    if has_nsfw_concept:
        if torch.is_tensor(images) or torch.is_tensor(images[0]):
            images[idx] = torch.zeros_like(images[idx])  # black image
        else:
            images[idx] = np.zeros(images[idx].shape)  # black image

if any(has_nsfw_concepts):
    logger.warning(
        "Potential NSFW content was detected in one or more images. A black image will be returned instead."
        " Try again with a different prompt and/or seed."
    )

モデルがファイルで配布されてるときの変換方法

ckptからstable-diffusionモデルを作る

convert_original_stable_diffusion_to_diffusers.pyを使う

$ python .\convert_original_stable_diffusion_to_diffusers.py --checkpoint_path /path/to/ckpt --dump_path /path/to/models/<output>

github.com

例) bot_start.pyのフォルダにckptフォルダを作ってその中にexample.ckptを配置、modelsフォルダに出力する
python .\convert_original_stable_diffusion_to_diffusers.py --checkpoint_path ./ckpt/example.ckpt --dump_path ./models/example

safetensorsをckptに変換する

有志の方の変換ツールを使用。
safetensors → ckpt → diffusersフォルダの順に変更して使ってる。
ここはまだ最適法じゃない気がする。(一旦の間に合わせでckptに変換)
もっと楽な方法があったら教えて欲しい。(safetensors->diffusers)

VAEを入れ替える

なんか出てくる画像がザラザラしてたり、ぼやけているってときはVAEを入れ替えるときれいになる事が多い。おすすめはvae-ft-mse-840000-ema。アニメ系だとkl-f8-anime2とかが人気っぽいけど、stable-diffusionのファインチューニングだとバグることが多いイメージ。
merge_vae.pyを使わせてもらう。
ここもまだ、簡単な方法がありそう。ただvae内binファイルを変えただけだと効果がなさそう?

$ python merge_vae.py <挿入先ckpt> <入れ替えるVAE> <出力先>

例) bot_start.pyのフォルダにckptフォルダを作ってその中にexample.ckptvae-ft-mse-840000-ema-pruned.ckptを配置、example.ckptにvaeを挿入してexample-new.ckptとして出力
python merge_vae.py ./ckpt/example.ckpt ./ckpt/vae-ft-mse-840000-ema-pruned.ckpt ./ckpt/example-new.ckpt

有識者に向けて

これだと特殊な状況しか実行できない!だったり、もっと簡単な方法があったら教えていただけると幸いです。また、この表現は初めての人には伝わんないよってところもあったらできるだけ修正するので、ぜひ伝えてほしいです。