ノードベースで動くComfyUIを使ってみる(stable diffusion)

2023年5月3日水曜日

stable-diffusion

t f B! P L

ComfyUIとは

主な特徴

  • コードを書くことなくノードベースで自由にUIを設計できて、処理の流れを追いやすい
  • デフォルトでキューに対応
  • 変更があった部分だけを実行する効率的な動作
  • Embedding、Textual inversion、Lora、ControlNetに対応
  • 起動が速い

ComfyUIのインストール

ComfyUIのGitHubページのManual Installを参考にPaperspaceにインストールしてみます。

note:今回は/tmp以下にすべてダウンロードしますが、ストレージに空きがある場合は/storageや/notebooks以下にインストールすると便利です。公式にも書いてありますが、AUTOMATIC1111のwebuiなど他のUIをすでにインストールしている場合、同じvenvを流用できます。

%cd /tmp
!git clone https://github.com/comfyanonymous/ComfyUI
%cd ComfyUI

!pip install virtualenv
!virtualenv venv

!/tmp/ComfyUI/venv/bin/pip install xformers!=0.0.18
!/tmp/ComfyUI/venv/bin/pip install -U torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118

!/tmp/ComfyUI/venv/bin/pip install -r requirements.txt

モデルとVAEをそれぞれ/models以下のcheckpointsとvaeディレクトリにダウンロード。今回はAbyssOrangeMix2_hardとorangemixのVAEを利用します。

!wget https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/Models/AbyssOrangeMix2/Pruned/AbyssOrangeMix2_hard_pruned_fp16_with_VAE.safetensors -O /tmp/ComfyUI/models/checkpoints/AbyssOrangeMix2_hard_pruned_fp16_with_VAE.safetensors
!wget https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt -O /tmp/ComfyUI/models/vae/orangemix.vae.pt

公式にあるipynbをほぼそのまま使ってComfyUIを起動。

%cd /tmp/ComfyUI/
!npm install -g localtunnel

import subprocess
import threading
import time
import socket
def iframe_thread(port):
  while True:
      time.sleep(0.5)
      sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      result = sock.connect_ex(('127.0.0.1', port))
      if result == 0:
        break
      sock.close()
  print("\nComfyUI finished loading, trying to launch localtunnel (if it gets stuck here localtunnel is having issues)")
  p = subprocess.Popen(["lt", "--port", "{}".format(port)], stdout=subprocess.PIPE)
  for line in p.stdout:
    print(line.decode(), end='')


threading.Thread(target=iframe_thread, daemon=True, args=(8188,)).start()

!/tmp/ComfyUI/venv/bin/python main.py

一度止めたComfyUIを再起動する場合。

%cd /tmp/ComfyUI/
threading.Thread(target=iframe_thread, daemon=True, args=(8188,)).start()
!/tmp/ComfyUI/venv/bin/python main.py --use-pytorch-cross-attention

ログのどこかにyour url is: https://(生成された文字列).loca.ltと出てくるのでクリックするなどして開く。なにやら出てきますがClick to Continueをクリック。

ComfyUI起動成功。コードを実行してから起動するまでが速い。

使い方

単純に画像を生成する

Load Checkpointでモデルを選びます。ファイル名が長いと文字がはみ出ますが問題ありません。

VAEが含まれているモデルならそのまま、別途VAEを使う場合は右クリック→Loaders→Load VAEでVAEのloaderを呼び出してVAE Decodeに繋ぎます。

プロンプトを入力します。KSamplerのpositiveとnegativeに繋がっているClip Text Encode (Prompt)にそれぞれプロンプトとネガティブプロンプトを入力し、Queue Promptをクリックすると画像生成が始まり、Save Imageに画像が出力されます。

Save Imageを右クリックしOpen Imageすると別ウィンドウで画像が開き、Save Imageすると画像のダウンロードができます。

ちなみにそれぞれのノードは右下の部分をドラッグしてサイズ変更ができます。

生成したデータの保存場所

Save Imageに送られた画像はComfyUI/outputに保存されます。クラウド上で動かしている場合は以下のようにoutput以下をzipでまとめてからダウンロードすると楽です。

import datetime
dt_now = datetime.datetime.now()
timestamp = dt_now.strftime('%Y%m%d%H%M%S')
!zip -r /notebooks/{timestamp}.zip /tmp/ComfyUI/output/*

よく使うノードやパラメータなど

他のUIを使ったことがあるなら読まなくても勘でわかると思います。

  • Empty Latent Image
    • width, height: 出力される画像のサイズ。細かいサイズ指定はデフォルトだとできなかった
  • KSampler
    • seed: 生成時に使用する乱数
    • control_after_generate: randomizeだと毎回乱数を変え、fixedだと固定
    • steps: ステップ数。高いときれいな画像が生成されやすいがその分時間がかかる
    • cfg: cfgスケール。プロンプトの効かせ具合のようなもの。高すぎると崩れるので8前後あたりから調整する
    • sampler_name: どのように生成するか。euler_ancestralやdpmpp_sdeがよさそう
    • scheduler: samplerと同様に生成に影響する。normalやkarrasがよさそう
    • denoise: text2imageなら1、image2imageなら0.5あたりから調整
  • Queue Promptがあるところ
    • Queue Prompt: キューに追加。生成してる間に次のプロンプトを予約できて便利
    • Save: 今のレイアウトを保存。json形式のファイルをダウンロードする
    • Load: 保存したレイアウトを呼び出す。jsonファイルをアップロードする
    • Refresh:
    • Clear: すべてのノードが消えてまっさらになる
    • Load Default: 初回起動時と同じレイアウトになる

モデルにもよりますが、AOM2の場合はKSamplerのsampler_nameをeuler_ancestralかdpmpp_sde、schedulerをkarrasにするときれい目に出力できました。Loraを使ったりするとまた変わったりするのでいろいろと試す必要があります。

Loraの適用

まずComfyUI/models/lorasにLoraを保存します(ComfyUIの再起動が必要)。ComfyUI上でLoad LoRAを出し、Load Checkpointの次に挿入するようにMODELとCLIPをノードを繋ぎます。

複数Loraをつなぐときは直列に繋ぎます。(公式の説明)

Hires fix(高画質化)

Upscale Latent、KSampler、VAE Decode、Save Imageを追加します。最初のKSamplerの出力を2つに分岐させることで処理前と処理後の両方を表示させることができて便利。

note: 画質を上げる方のKSamplerのdenoiseをデフォルトの1から0.5ぐらいに下げる。

t2i部分のKSamplerでseedをfixedにしてHires fixの部分を調整しながら生成を繰り返すとき、変更点であるHires fixのKSamplerから処理が始まるので効率的に動いているのがわかります。

カスタムノード

ComfyUIはユーザーが定義したノードを追加することができます。例えばごちゃごちゃしたノードをスッキリとまとめたEfficiency Nodes for ComfyUIを使ってみます。

ComfyUI/custom_nodes以下にカスタムノードをフォルダごと置くと適用できます。custom_nodesディレクトリ内でgit cloneするのが簡単。

%cd /tmp/ComfyUI/custom_nodes
!git clone https://github.com/LucianoCirino/efficiency-nodes-comfyui

右クリックしてAdd Nodeを選択するとEfficicency Nodesが追加されているのでEffcient LoaderとKsampler (Efficient)を選択。

それぞれ繋ぐ。見た目がスッキリとまとまり、preview_imageをEnabledにすることで出力もできました。

note: このカスタムノードの画像の保存先はComfyUI/temp/

まとめてダウンロードするときの例。(IMAGEから伸ばしてSave Image繋ぎoutputにまとめてもいい)

import datetime
dt_now = datetime.datetime.now()
timestamp = dt_now.strftime('%Y%m%d%H%M%S')
!zip -r /notebooks/{timestamp}.zip /tmp/ComfyUI/temp/*

おわり

Stable DiffusionでAI画像生成するときのwebuiといえばAUTOMATIC1111のwebUIだと思いますが、代替というよりは便利な部分が違うといった印象です。処理を分岐できるので複数の設定で実行して比べるというのがやりやすかったです。

QooQ