🐶

Stable Diffusion WebUI で『つくよみちゃん』を召喚する

2022/12/05に公開
6

こちらは創作+機械学習 Advent Calendar 2021 の4日目の記事になります。

この記事は

「うすい」というものが『創作』に寄与するようなツールを機械学習・AI で作りたい気持ちで書いています。

機械学習は初学者です。丸二年やってまだなんも分からんくらいなので、大したことはできません。
去年のアドベントカレンダーでは NLP を投稿しましたが、夏には同人誌を出したりしました。……そして、今の流行はやはりStable Diffusionを中心とした『じぇねれーてぃぶ AI 』!
ということで、私もStable Diffusion の小ネタを投稿します。

対象者

この記事は、機械学習初心者・初学者向けです。理論や難しいことは省略します。
ただし、ある程度の IT 知識、今回のツールを指定したサイトを見ながら自分で環境構築出来るくらいの知識がある人に向けて書きます。
又、何らかの創作に関わるような人に読んでもらいたいかもです。

注:「つくよみちゃんの特徴をDreamArtistで学習させる」の記事については動作しない旨の報告が来ており、私の方でも確認しております。現状は利用できないのでご了承ください。(2023/07/31)

「つくよみちゃん」を応援したい

個人的に「つくよみちゃん」という創作キャラクターを応援しています。
企画者、およびこのキャラ設定的にも、創作したい人に大変寛大で、キャラクターの AI 化にも積極的です。夢前さんのボイスもJVSコーパスとして提供されており、今後 AI で利用可能な選択肢のひとつと言っても過言ではないでしょう。

既に AI に関してはつくよみちゃん運営側も色々な動きをされておりますが、私なりに「つくよみちゃん」の創作に寄与できるような仕組みを作ってみたいと思います。

まずは、環境構築

今回の環境は、AUTOMATIC1111氏の『Stable Diffusion WebUI(以下 SD-WebUI)』を使用します。
ツールを利用する方法としては、

  1. GoogleColabなどGPU利用できるクラウド環境を利用する
  2. ローカル環境にWebUIの環境を構築する
    の二つが一般的です。取り急ぎ今回はローカル環境(Windows環境)での利用を想定します。
    又、利用するモデルとしては今回、Stable-Diffusion-1.5を利用します。

ローカル環境の構築にはDockerを利用するのが一番簡単ではないかと思います。 npaka 氏のこちら の記事を参考にGit, Docker およびDocker版のSD-webuiをインストールしてください。

GPUがない人でも以下のコマンドで実行すればCPUで立ち上げることができると思います(ただし、速度は遅いです)

$ git clone https://github.com/AbdBarho/stable-diffusion-webui-docker.git
$ cd stable-diffusion-webui-docker
$ docker compose --profile download up --build
$ docker compose --profile auto-cpu up --build

これで環境構築は終了です。

SD-WebUI を動かす

では、さっそくつくよみちゃんを召喚してみましょう。こちらをクリックしてください
http://localhost:7860/

以下のような画面が出てくれば成功です。

つくよみちゃんっぽい呪文を考えてみました。これを上のプロンプト欄に入れてどうなるか試してみます。

1girl,white kimono,silver hair,long hair,two pigtails with small pink chuchu,blue eyes

うーん、なかなかいいのが出ませんでした。

良い画像に会うため、品質にこだわるためには、以下のようなことを考えるといいでしょう。

  1. テーマに合わせてモデルを探し、変更する
  2. 呪文詠唱、魔術を極める(最適なプロンプトを探す)

あたりの作業が必要になります。
今回、つくよみちゃんの絵はアニメ系イラストが強いので最適なモデルは別にあるのでしょうが、敢えて今回は 1 はスキップします。

もし、1を試してみたい方は上記の hugging face からmodelsで検索してみてください。anything-v3.0やwaifu-diffusionなどアニメ系イラストに強いモデルは数多くあります。

良い画像を手に入れるための呪文探索

SD-WebUI には様々な機能があります。例えば、画像の精度を調整する設定や何回も繰り返し実行するようなコマンドなど。

さらに「良い画像を手に入れる」には呪文、魔術に精通する必要があります。
しかし、いかにUIの機能が充実していると言っても、毎回手動で生成するのは大変です。
今、Prompt ならぬ、魔術詠唱は様々なところで研究が進められております。
『元素法典 日本語版』や『Stable Diffusion 呪文』などで調べてもらえば色々な呪文を探すことができます。
まずは『品質向上』ができるようなワードを入れていくといいでしょう。

今回、呪文に関する話はしませんが、大量の呪文を試すための方法を考えます。
いかに SD-WebUI が機能が豊富だと言っても、調査した呪文をコマンドプロンプトで逐一試すのはちょっと大変です。

そこで、ある程度プロンプトをランダムで組み合わせて一括登録、あるいはリモートで自動実行することができればなと考えました。

実は、SD-WebUI は『API』の機能があります。そのAPI越しに出来合いのコマンドを自動実行することができるんです。

APIの設定

デフォルトでは利用できませんので、webUI を起動する際に、「--api」というオプションをつけて起動させることで、API の機能が利用できます。

  1. (Dockerを配置したフォルダ)\docker-compose.yml をテキストエディタなどで開く
  2. text のprofileが"auto","auto-cpu"となっている設定の -CLI_ARGSと書かれている一番右に --api という文字を追加
name: webui-docker

services:
  download:
    build: ./services/download/
    profiles: ["download"]
    volumes:
      - *v1

  auto: &automatic
    <<: *base_service
    profiles: ["auto"]
    build: ./services/AUTOMATIC1111
    image: sd-auto:16
    environment:
      - CLI_ARGS=--allow-code --medvram --xformers --api <-- "--api"をここに追加

  auto-cpu:
    <<: *automatic
    profiles: ["auto-cpu"]
    deploy: {}
    environment:
      - CLI_ARGS=--no-half --precision full --api <-- "--api"をここに追加

中略
  1. docker compose --profile auto-cpu up --build コマンドでdockerを起動

これで、SD-WebUI 起動と同時にWeb の API が利用可能となります。

バッチの実行

こちらの記事を参考に、API経由で様々なコマンドをたたくバッチを作成してみました。
こちらを実行するにはpython3の実行環境とrequests,random,pillow,click などいくつかのモジュールが必要になるので都度pip install などでモジュールをインストールして下さい。

import json
import requests
import io
import base64
import random
from PIL import Image, PngImagePlugin
import click


@click.command()
@click.option("--input_url", help="input url",default="")


def sdwebapi_get(input_url):

  while True:
    try:
      payload = {
        "prompt":{
          "default_prompt": "1girl,white kimono,silver hair,long hair,two pigtails with small pink chuchu,blue,eyes",
          "random_prompt":[
            "hyper paint,anime,colored pencil medium,marker medium,painting medium,ballpoint pen medium,anime screencap,anime coloring,game cg,sketch,flat color,watercolor,watercolor medium,pastel color,photorealistic",
            "ultra high detail,realistic photorealistic,realistic,raytrace,cinematic lighting,8k wallpaper",
            "masterpiece,masterwork,high quality,best quality,exquisite,by famous artist,idolmaster,blue archive,hdr,highres,illustration,stylish,detail,great,amazinig,best,highest,100-layer"
          ]
        },
        "negative_prompt":{
          "default_negative_prompt": "bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry",
          "random_negative_prompt": [
            "lowres"
          ]
        },
        "height": 768,
      }

      payload['prompt'] = payload['prompt']['default_prompt'] + ''.join([' ,'+_.split(",")[random.randrange(len(_.split(",")))] for _ in payload['prompt']['random_prompt']])
      payload['negative_prompt'] = payload['negative_prompt']['default_negative_prompt'] + ''.join([' ,'+_.split(",")[random.randrange(len(_.split(",")))] for _ in payload['negative_prompt']['random_negative_prompt']])
	        
      response = requests.post(url=f'{input_url}/sdapi/v1/txt2img', json=payload)
      response_models = requests.get(url=f'{input_url}/sdapi/v1/sd-models')

      r = response.json()
      r_model = response_models.json()

      load_r = json.loads(r['info'])
      meta = load_r["infotexts"][0]

      i=0
      for x in r['images']:
        i=i+1
        image = Image.open(io.BytesIO(base64.b64decode(x)))
        pnginfo = PngImagePlugin.PngInfo()
        pnginfo.add_text("parameters", meta)
        image.save(str(r_model[0]["model_name"])+"_" + str(load_r["all_seeds"][0])+"_" + str(i) + ".png", pnginfo=pnginfo)

        print( 'Prompt:' + r['info'].split(':')[1].replace(', "all_prompts"','').replace('"','') + ' で生成しました。' )
	            
    except Exception as e:
      print(e)

if __name__ == "__main__":
  sdwebapi_get() # pylint: disable=no-value-for-parameter

オプションとして--input_url という文字列を引数で渡すようにしてあります。ローカル起動なので基本的に http://localhost:7860/ の文字列を渡せば大丈夫です。
以下のコマンドを例えば testapi.py というファイルで保存したとすると、コマンドは

python testapi.py --input_url=http://localhost:7860/

とすることで、バッチファイルの置いてある場所に画像が無限に湧いてきます。

これで、様々な呪文をランダムで組み合わせて出力ができます。同一のプロンプトではなく、ランダムに組み合わせるので、たまたま良い組み合わせになったらそれを使う、ということもできるのが良い感じです。

こちらなんかは大分つくよみちゃんっぽい感じになっているのではないかと。
ちなみに、画像は作りっぱなしてはなく、どんなプロンプトが「つくよみちゃん」を作るのに役立ったか、など調べることができます。

SD-WebUIのPNGInfoというタブに画像をドラッグ&ドロップすると、画像がアップロードされ、なんのプロンプトだったかを調べることもできます。
そのままプロンプトをtxt2imgで使ったり、img2imgのインプット画像などに使うこともできます。
SD-WebUI、かなり優秀ですね!

(2022/12/8追加)つくよみちゃんの特徴をDreamArtistで学習させる

大したことは結局してないので記事追加します。StableDiffusion WebUI 上で、1枚の画像から特徴を学習させる手法を利用してみました。

まずは、こちらを元にextensionフォルダ内に以下のgit内容をコピーしてください。そして、SD-webuiを再起動します。

cd stable-diffusion-webui
git clone https://github.com/7eu7d7/DreamArtist-sd-webui-extension.git extensions/DreamArtist

再起動してwebuiの画面に移り、以下のように「Dream Artist」タブが表示されていれば成功です。

次に左側の「DreamArtist Create embedding」タブで名前を付け、initialization text に今回は「1girl」という文字を入力して「Create embedding」ボタンを押します。

次は右側の「DreamArtist Train」タブでつくよみちゃんの画像を1枚指定して学習を行わせます。

Embedding には先ほど設定したnameを設定
Embedding Learning rate には0.003を設定

Dataset directoryにはつくよみちゃん画像を配置し、そのディレクトリのパスを設定
Max steps には学習させる最大回数を設定。1万step以上回さないとしっかり学習はできないかもしれないので、1万回ずつくらい分割して学習させました。

その下の
Save an image to log directory every N steps, 0 to disable
Save a copy of embedding to log directory every N steps, 0 to disable
はデフォルトの500でもいいですが、1000などでもいいかもしれません。

最後に「Train Embedding」ボタンを押します。

終われば、つくよみちゃん画像のチューニングは終わりです。

検索で「1girl ,by (Embeddingで設定した名前)」と入力して検索することで、つくよみちゃんの絵のスタイルを学習して画像が生成されます。
今回は、8万回ほど学習させています。

1girl,by tsukuyomichan

検索に更に条件を付けくわえることで様々なつくよみちゃんを出すことができます。

1girl,by tsukuyomichan,white kimono,silver hair,long hair,two pigtails,blue eyes

結構つくよみちゃん率上がってますね。
良い絵を一枚選んだわけではなく、全体見ても同様の雰囲気で出ているのが分かると思います。

やはり、素晴らしいですね。
これからもつくよみちゃん道を極めるべく精進していきたいと思います。

最後までお読みいただき、ありがとうございました!

つくよみちゃん

上記はフリー素材キャラクター「つくよみちゃん」のファンアートになります。
公式サイトはこちら!⇒https://tyc.rei-yumesaki.net/

紹介したURL参考にしたURL

StableDiffusionV1.5
https://huggingface.co/runwayml/stable-diffusion-v1-5

AUTOMATIC1111氏のStable Diffusion WebUI
https://github.com/AUTOMATIC1111/stable-diffusion-webui

npaka氏 の Note
https://note.com/npaka/n/nc8b0e9a91d97

StableDiffusion-WebUIでAPIを利用するためのQiita記事
https://qiita.com/odu_beyond/items/7870dd99e9225b9af5f0

DreamArtist(webui extension)
https://github.com/7eu7d7/DreamArtist-sd-webui-extension

DreamArtistを試してみる
https://koubou-rei.com/entry/dreamartist

Discussion

ヒカルヒカル

初めまして。こちらの記事を参考にDream Artistのインストールと使い方を参考にさせていただきました。

最後に「Train Embedding」ボタンを押します。
ここまでは進めましたが、ボタンを押しても何か変化がありません。(読み込み中とか学習中とかそういう表示がない)
どこかに何かそういう表示が出るのでしょうか?
また、学習する絵は複数枚でもよかったのでしょうか?
ご回答よろしくお願いいたします。

ヒカルヒカル

すみません、何度か試してみてコマンドプロンプトのエラーに気づきました。
RuntimeError: Expected tensor for argument #1 'indices' to have one of the following scalar types: Long, Int; but got torch.cuda.FloatTensor instead (while checking arguments for embedding)
検索してみて似たような答えを見つけたのですが、どうすればいいのかわかりません。
https://stackoverflow.com/questions/56360644/pytorch-runtimeerror-expected-tensor-for-argument-1-indices-to-have-scalar-t
どうかご指導お願いいたします。

エラーコード全文 https://5.gigafile.nu/0804-b45bcbd6a101fdbd0fa7e2bad98057ccf
WEB UI Ver:1.3.0
Windows11 64BIT
CPU:Intel Core i5-13400
メモリ:16GB
HDD:8TB
graphic board:Ge Force RTX 3060Ti 8GB

うすいうすい

記事を見ていただき、ありがとうございます。

この記事の内容はこの発展著しい画像生成AIでは比較的過去の記事になってしまっており、Dream Artistのメンテナンスも止まっているようです。
私も現状のSDやDockerで試してみましたが、動きません。おそらくtorch か依存するライブラリのバージョンの不整合で動かないように見えます。

エラーが違うのでお問い合わせの方は、Dockerではなく自環境での直接の生成を試しているのだと思いますが、自環境でも当時の状況を再現できるかは分かりませんし、できてもそちらの環境と完全に合致させられるかは分かりません。
(念のため記事冒頭にも注記を入れさせていただきます)

もう少し試してみますが、現状ですと、DreamArtistは動作しないのではないかと思います。
お役に立てず申し訳ありません。

ヒカルヒカル

こんばんは、ご回答ありがとうございます。確かに日付を見ると少々古いですね…申し訳ありません。
では、せめて現在どうやってスタイル学習させるのかだけでも教えてもらえませんか?(拡張機能名)
あとは調べてみますので。

うすいうすい

現時点でStyleを学習するのはやはりLoRAかLyCORISではないかと思います。
上記のようにwebui でやるのであれば、「sd-webui-train-tools」でLoRAでスタイル学習させるのはいかがでしょうか。
DreamArtistは1枚からでもできましたが、LoRAなどですと10-20枚くらいは必要で時間もそこそこかかるとは思います。
これも試したのは少し前なので、利用できるかは少しやってみないと分かりませんが……。

ヒカルヒカル

おはようございます、ご回答ありがとうございます。
ざっと検索してみるとDreamArtistは3番目の使いやすさみたいですね。
でもこのおかげでどんな拡張機能があるかわかりました、ありがとうございました!