【2024年最新版】Windowsローカル環境でAIイラストを高速&大量生産 【Web UI Forge / Diffusers】【Stable Diffusion】

技術部@Deep Sky Gate
言語(Language)

こんばんは。
はばふぐって名乗ってるっぽい人です。
XMPP: habafugu@xmpp.deep-sky-gate.net
Mastodon: @Habafugu@vivaldi.net
Twitter: @habafugu

0. この記事でやること

まず前提として、AIイラストは平均品質が低いですよね。ですから、生成を繰り返し、数百枚のイラストの中からごくわずかのあたりを取り出すというのが基本メソッドになると思います。無論、最近は細かい部分を修正してくれる技術も出てきましたが、それでもやはり生成数が鍵です。

ということで、どうやってAIイラストを生成しようか考えたときに、この「生成数」を軸に考えていくといいかと思います。

たとえばWebサイトやスマホアプリでもAIイラストが作れますが、カスタマイズ性がなく、生成数も少ないので、当たりを引くまで作業が面倒です。

今回は、Windowsローカル環境に、AIイラストを大量生産できる技術を築いていきたいと思います。

わたしのパソコンはGPUが6GBくらいしかなく、イラストAI界においては低スペックなPCですが、そんなPCでもできることを書いていきますのでご安心ください。

1. Forge (Stable Diffusion Web UI) をインストール

Forgeは、Windowsローカル環境で構築され、ブラウザ上で動くStable Diffusionです(Web GUI)。

視覚的にわかりやすく、なおかつ1つのプロンプトで一気に何千枚も生成してくれるので、あらゆる面において優れたシステムです。

なお「AUTOMATIC1111」がWindowsローカル環境のStable Diffusionとして大変有名ですが、最近出たその親戚である「Forge」を、今回は使っていこうと思います。「Forge」はスペックが低いパソコンで、AUTOMATIC1111の数倍高速で生成できるので、今回の目的にぴったりです。

とりま、公式はこちら。
https://github.com/lllyasviel/stable-diffusion-webui-forge

(1) Pythonのインストール

どうやら、Pythonのバージョン3.10.6が必要なようです。

https://www.python.org/downloads/release/python-3106/
上記リンクの、一番下「Files」の「Windows installer 64-bit」を選んでダウンロード。
インストーラーを実行する際に、下側の「Add Python 3.10 to PATH」にチェックするのを忘れない。初心者でもベテランでも意外と忘れがち。

こんな記事を読むみなさんなら、別のプロジェクトで使った他のバージョンのPythonが入ってるでしょう。以前使ってたバージョンに戻したい場合は、コントロールパネルのシステム環境設定から環境変数のところに行って、「Path」を編集し、下画像のように使いたいバージョンのPathを上に持っていきます。詳しくは以下の記事で。
https://leez.info/archives/4193

最後に、適当なとこでcmdを開いて、「python -V」でバージョンを確認し、3.10.6になっていることを確認しましょう。

(2) GitでForgeをインストール

Gitはバージョン管理ツールですね。入ってる人も多いと思うけど。
https://git-scm.com/download/win
まだGitが入ってないって人は、上記リンクの「64-bit Git for Windows Setup」からダウンロード・インストールして、(特にこだわりがないなら)何も考えず「Next」をクリックしていきましょう。

もしcmdが開いていたらいったん閉じます。

そして、cmdを開きなおし、Stable Diffusionをインストールする作業用フォルダのディレクトリにします。

そして、「git –version」でgitがインストールされていることを確かめてから、git cloneで、「https://github.com/lllyasviel/stable-diffusion-webui-forge.git」をクローンします。

git --version

git clone https://github.com/lllyasviel/stable-diffusion-webui-forge.git

エラーが出なかったらOK。

ディレクトリに「stable-diffusion-webui-forge」というフォルダがあるはずですからエクスプローラーから開いて、その中の「webui-user.bat」をダブルクリックで実行。

一回目の実行時はなんかいっぱいインストールしてて時間がかかります。

おや。なんか変なエラーが出てきました。ownershipって書いてるのでそこら辺が問題みたい。ひょっとするとDドライブでやったからよくなかったのかな。
とりあえず、「call: git…」と書いてあって、そこに書いてるコマンド実行すればよさそうな気がしたので、とりあえずエラーが消えるまで指示通りコマンドを打ち続けました。

git config --global --add safe.directory D:/StableDiffusion/stable-diffusion-webui-forge

git config --global --add safe.directory D:/StableDiffusion/stable-diffusion-webui-forge/repositories/stable-diffusion-webui-assets

git config --global --add safe.directory D:/StableDiffusion/stable-diffusion-webui-forge/repositories/stable-diffusion-stability-ai

git config --global --add safe.directory D:/StableDiffusion/stable-diffusion-webui-forge/repositories/generative-models

git config --global --add safe.directory D:/StableDiffusion/stable-diffusion-webui-forge/repositories/k-diffusion

git config --global --add safe.directory D:/StableDiffusion/stable-diffusion-webui-forge/repositories/BLIP

検索してみたら、こんな記事がありましたので参考までに。
https://stackoverflow.com/questions/71849415/i-cannot-add-the-parent-directory-to-safe-directory-in-git

あれっ先に進まないなぁって思ったら、いったんCtrl+Cで強制終了して、再度「webui-user.bat」を実行してみましょう。

最新の技術にはエラーがつきものです。

うまくいかなかったら、こちらのサイトの方法でやってみてください。
https://soroban.highreso.jp/article/article-081

(3) 起動後

起動時の見た目はマジでAUTOMATIC1111とそっくりです。使い方は適当に調べてください。こういうの↓。
https://note.com/koresugo/n/n5e7445b8e6b9

結構速いです。AUTOMATIC1111の2/3~1/3程度で生成されている実感がします。
注意:生成待ちの間に別タブでYouTubeを見てしまうと、メモリが足りなくて生成が遅くなったり最悪ブラウザがクラッシュしたりします。よくやりがちです。

メモリ関係のエラーが起きたときは、全アプリを閉じたり、再起動したりしてください。

インストールが詰まった場合は、もう一度最初からやり直してください。Pythonをインストールしなおしたり…。エラーは予知しようもないですから...

2. Forge(AUTOMATIC1111)をもっと使いこなしたい!

ForgeもAUTOMATIC1111も機能上はほぼ同じですので、まとめて解説します。

最近はこういうAI生成のコツを販売してお金を儲けようという人がいてよくないですね。「All rights reserved」じゃなくて「All light’s reversed」なら世界は平和になると思います。

(1) Forgeの起動を速くしよう

Forgeを起動する際には、いちいちインストールしたフォルダに行って、「webui-user.bat」を実行しなくてはいけません。めんどいですね。デスクトップから実行できるようにしましょう。

デスクトップにバッチファイル(Forge.batなど.bat拡張子のファイル)を作り、そのファイルをメモ帳やVSCodeで開いて、以下のようなコードを書き込みます。

cd /d D:\StableDiffusion\stable-diffusion-webui-forge
call webui-user.bat

cdでディレクトリを移動して、callでbatファイルを呼び出すだけの簡単な操作。
cdのあとの/dオプションは、ドライブを移すやつですね。ぼくはDドライブで実行してるから。そこは環境に応じてください。

あとはこのbatファイルをダブルクリックすれば、ちゃんと開きます。

(2) プロンプトを改良しよう

AIイラストの出来を決める大きな要素はモデルとプロンプトです。まずはプロンプトについて。

当然、どんなプロンプトがいいのかは求める絵やモデルによっても変わります。
一番いいのは、AIイラストが集まってるサイトに行って、自分の欲しい絵に似てるものを探して、そこのプロンプトを参考にすることです。

とりあえず、わたしが使ってる、二次元の女の子を出したいときの汎用プロンプトを紹介します。

プロンプト
masterpiece, best quality, super fine illustration, loli, an extremely cute and beautiful girl, detailed beautiful face, beautiful hair, beautiful eyes

ネガティブプロンプト
light, shadow, NSFW, worst quality, low quality, medium quality, deleted, lowres, comic,underboob,open_clothes, bad anatomy,strapless,bare_legs, bad hands, text,error, missing fingers, extra digit, fewer digits, cropped , jpeg artifacts, signature, blurry, flat color, flat shading, nsfw, retro style, poor quality, bad face, bad fingers, bad anatomy, missing fingers, low res, cropped, signature, watermark, username, artist name, text

以上の汎用プロンプトに、髪・目の色や姿勢、カメラアングル、背景などを状況に応じて加えてください。

少し汎用プロンプトを解説しますと

  • masterpiece, best quality, super fine illustration, an extremely cute and beautiful girl:必須。
  • loli:顔が丸っこくなって、基本的に10代の雰囲気になります。個人の好みに合わせてください。
    年齢を指定したいなら、プロンプトに「15-year-old」などと書いてあげてもいいですよ。
  • detailed beautiful face, beautiful hair, beautiful eyes:髪と目は一応beautifulとかdetailedとかで修飾しておきましょう。やっぱり弱いですからね。
  • ネガティブプロンプトは(モデルによりますが)多ければ多いほどいいです。

(3) モデルを選ぼう

AIイラストの出来栄えを決めるもう一つの要素がモデルです。どんなモデルを使うかによって、画風がことなってきます。結局Stable Diffusion系列ってことには変わりないんですが。

とりあえず、Stable Diffusionで使える二次元系のモデルをいっぱい挙げておきますね。
以下の生成画像はさっきの汎用プロンプトを用いています。また、VAEやLoRAなどの補正機能は一切使っていません

モデルのダウンロード方法の詳細は調べてください。「.safetensors」とか「.ckpt」拡張子のファイルがモデルです。ダウンロードしたモデルは、stable-diffusion-webui-forge\models\Stable-diffusion のディレクトリに入れておきます。

7th Anime
syaimu/7th_Layer · Hugging Face
We’re on a journey to advance and democratize artificial intelligence through open source and open science.

初期からあるモデルですね。たぶんVAEがいります。

Ambient Mix

https://civitai.com/models/26622

すごくアニメっぽい。そのせいで「AIイラスト」感があんまりない。

AnyLoRA
AnyLoRA - Checkpoint - bakedVae (blessed) fp16 NOT-PRUNED | Stable Diffusion Checkpoint | Civitai
AnyLoRA Add a ❤️ to receive future updates. Do you like what I do? Consider supporting me on Patreon 🅿️ or feel free to ...

王道を行くAIイラストっぽさ。ちょっと立体的。

Anything V4.5
Airic/Anything-V4.5 · Hugging Face
We’re on a journey to advance and democratize artificial intelligence through open source and open science.

細かい。

Anything V5
万象熔炉 | Anything XL - ink_base | Stable Diffusion Checkpoint | Civitai
下载模型之前,请仔细查看模型介绍 Please review the model introduction carefully before downloading the model モデルをダウンロードする前に、モデル紹介をよく見てくだ...

どこかで見たよなぁって思うレベルで、AIイラストでかなり多用されてます。

Abyss Orange Mix
WarriorMama777/OrangeMixs · Hugging Face
We’re on a journey to advance and democratize artificial intelligence through open source and open science.

暗いですね。VAEいりますね。

Counterfeit
Counterfeit-V3.0 - v3.0 | Stable Diffusion Checkpoint | Civitai
high quality anime style model. Support☕ more info. Verson2.5

プロンプト変えてませんよ。細かく見ればさすがに変だけど遠くから見るとすごく背景が綺麗。

Eleet Model
Eleet Model - v2.0 | Stable Diffusion Checkpoint | Civitai
Eleet model is a block-weighted merged stable diffusion model aiming at generating good quality 2D anime style images th...

こちらもAIっぽいなぁっていうAIイラスト感。

Himawari Mix
HimawariMix - v11 | Stable Diffusion Checkpoint | Civitai
様々なモデルをマージした背景や細部の表現力が強いVAE内蔵型モデル VAEの内臓はないぞ!と言わせないぞ!!!! Models with built-in VAE with strong expression of backgrounds ...

あれですね。すごくロリになってますね。
「loli」って入れたら10代後半の少女が出てくることが多いのですが、どうやらこのモデルではホントのロリになっちゃうようです。このモデルを生成した人はロリコンに違いありません。

Meina Mix
MeinaMix - Meina V11 | Stable Diffusion Checkpoint | Civitai
MeinaMix objective is to be able to do good art with little prompting. I have a discord where you can share images , dis...

こっちは逆にloli効果をほぼ無効化してますね。

Momiji Mix
MomijiMix - v4.0 | Stable Diffusion Checkpoint | Civitai

VAEつけなきゃいけないやつです。全般的に整っています。


こだわりがある人は、モデルをMixしてもいいかもしれません。ぼくはメモリが足りなかったので諦めました。半年前やったときはできたんですがね…
https://romptn.com/article/7837#toc3

ともあれ、モデルは適当な二次元モデルを使い、sampling stepsを30、大きさを512×512にして、とくにLoRAなども設定せずに50枚ほど生成した中の一枚がこちら。

AIイラストっぽさはすごいありますね。それにボタンとか細部がおかしいけど、突き詰めていったところでAIイラストは人間の絵を超えられませんし、これくらいでぼくは妥協しています。

(3) LoRA・VAEを使おう

VAEは、光とか陰影を補正してくれる補正機能です。ほぼ必須。だいたい、モデルごとに「このVAEを使ってください」ということが説明に書いてますので各モデルを読んでください。

LoRAというのは、生成する絵に特定の傾向をつけてくれる機能です。特定のキャラの絵を出したいときによく使ったりしますね。 

3. Web UIを使わずにPythonコードから実行しよう!

いわゆる「CLI」(コマンドラインインターフェイス)からの実行です。
古典的技法なので機能は少ないですが、プロンプトやLoRA、モデルを変えて何種類もの画像を一気に大量生産するときに向いています。

Forge(AUTOMATIC1111)は多機能ですが、基本的にプロンプトやLoRAを入れ替えるのは手動です。だからたとえば、100人のキャラの画像をそれぞれ500枚ずつ生産したいなぁっていうときには、100回入れ替える必要があります。
ふつう、イラスト生成は仕事に行ってる間や寝てる間にパソコンに自動でやってもらいますよね。その点、Web UIでプロンプトを入れ替える作業が発生すると面倒です。CLIなら、超自動化コーディングをすれば、一回コマンドを打つだけであとは自動でプロンプト入れ替えもやってくれるんです。

公式はこちらhttps://huggingface.co/docs/diffusers/en/installation

参考はこちらhttps://self-development.info/%E6%9C%80%E5%85%88%E7%AB%AF%E3%81%AE%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E5%88%A9%E7%94%A8%E3%81%A7%E3%81%8D%E3%82%8Bdiffusers%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9/

(1) Pythonバージョン確認と仮想環境の準備

Pythonのバージョンは3.8~3.11が必要です。3.12は2024/3の段階ではまだ対応していないみたい。
今回は、3.10.6(AUTOMATIC、Forgeと同じ)で行きます。

まずは適当なディレクトリをつくり、そこでコマンドプロンプト(cmd)を開きます。

そして以下の詠唱を行います。「difenv」の部分は適当でOK。

python -m venv difenv

これで仮想環境が構築されたので、「\Scripts\activate.bat」を以下のように実行してアクティベートします(2回目以降はここから)。

difenv\Scripts\activate.bat

(difenv) D:\StableDiffusion\automatic1111> 
みたいな文字が出てくるはずです。これでOK。

仮想環境を解除するときは「deactivate」とだけ打ち込みます。

deactivate

(2) CUDAのインストール

NVIDIAのGPUを利用していることが前提になるのかな?とは思いますが…。

CUDA Toolkit - Free Tools and Training
Get access to SDKs, trainings, and connect with developers.

上記リンクからCUDAをインストールします。

nvcc -V

というコマンドを打って、ちゃんとインストールできているか確認しましょう。

参考
https://self-development.info/tensorflow-1%E7%B3%BBgpu%E7%89%88%E3%81%AE%E3%81%9F%E3%82%81%E3%81%ABcuda-10-0%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/

(3) PyTorchのインストール

Start Locally
Start Locally

上の公式サイトに行って、以下の画像のような画面のところで、Windows, pip, python, CUDAのバージョンを選びます。

一番下の「Run this Command」と書いてるところのコマンドを実行します。

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

上のような画面になったら(Successfully…)成功です。

参考
https://self-development.info/%E3%80%90windows%E3%80%91gpu%E7%89%88pytorch-1-12%E7%B3%BB%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/

(4) Flaxのインストール

公式:https://flax.readthedocs.io/en/latest/

pip install flax

(もしくは pip install –upgrade git+https://github.com/google/flax.git )

こちらでFlaxをインストール。

(5) Transformersのインストール

公式:https://huggingface.co/docs/transformers/en/installation

pip install transformers

同じくこちらでTransformersをインストールします。Warningが出てくるかもしれませんがErrorではないので無理矢理次に行きましょう。

(6) Diffusersのインストール

先ほどの公式ガイドに従って、以下のようにコマンドを打ちます。

pip install diffusers["torch"] transformers

ふつうに pip install diffusers でもいいかもしれませんが。

(7) テスト(飛ばしてもOK)

以上のセットアップが完了したら、Pythonファイルにコードを打って実行するだけです。

Waifu Diffusionという古典的なモデルが、コードを公開しているのでそれを参考にしながらやっていきます。
https://huggingface.co/hakurei/waifu-diffusion

cmdを開いているディレクトリに画像を入れる「save」フォルダと、Pythonファイル(generator-net.pyとしておきます)を新しく作り、以下のようにPythonのテストコードを入力しましょう。プロンプトはさっきの汎用プロンプトです。

from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler

pipe = StableDiffusionPipeline.from_pretrained('hakurei/waifu-diffusion')
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
pipe.enable_attention_slicing()     
pipe=pipe.to("cuda")

#プロンプト
prompt = "masterpiece, best quality, super fine illustration, loli, an extremely cute and beautiful girl, detailed beautiful face, beautiful hair, beautiful eyes"

#ネガティブプロンプト
n_prompt="light, shadow, NSFW, worst quality, low quality, medium quality, deleted, lowres, comic,underboob,open_clothes, bad anatomy,strapless,bare_legs, bad hands, text,error,  missing fingers, extra digit, fewer digits, cropped , jpeg artifacts, signature, blurry, flat color, flat shading, nsfw, retro style, poor quality, bad face, bad fingers, bad anatomy, missing fingers, low res, cropped, signature, watermark, username, artist name, text"

# 処理の実行
image = pipe(
    prompt=prompt,
    negative_prompt=n_prompt,
    height=512,
    width=512,
    num_inference_steps=20, # =sample steps=何回処理を繰り返すか(多いほど精彩になる)
    guidance_scale=9 #=CFG Scale=どれほどプロンプトに従うか
).images[0]
    
image.save("save/test.png")

現在のフォルダはこんな感じになってると思います。

そして、cmdからこのPythonファイルを実行しましょう。

python generator-net.py

ひどく時間がかかりますし、Waifu Diffusionは旧世代なのでそんなにかわいくないです。
わたしの環境では1枚で3分。笑うしかありません。あと、気付いたらいつの間にかパソコンの容量が0GBになってます。

(8) ローカルモデル読み込み

それもこれも、ネット上からモデルを読み込んでるからですね。ちゃんとローカルでモデルを読み込みましょう。

上の画像のようにディレクトリを構築します。Diffusersフォルダ直下に、既にdifenvフォルダ(仮想環境)はあると思うので、モデルを入れるmodelsフォルダと画像を入れるsaveフォルダを作り、実行コードを書き込む「generator.py」をつくります。

modelsフォルダの中には、モデル・VAE・LoRAを入れます。

generator.pyには以下を書き込みます。今回は試しに咲夜さんをつくってみましょう。プロンプトには咲夜さんの要素を入れておきます(下記コードでeach_promptのところ)。
モデルはアニメ調のambientmixです。

#generator.py

from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler

import datetime

model_path = "models/main/ambientmixAnAnime_v10.safetensors" #モデルが入ってるパス

pipe = StableDiffusionPipeline.from_single_file(model_path, load_safety_checker=False, extract_ema=True) 
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
pipe.enable_attention_slicing()


prompt = "masterpiece, best quality, super fine illustration, loli, an extremely cute and beautiful girl, detailed beautiful face, beautiful hair, beautiful eyes"
each_prompt="navy maid clothes,maid_headdress,silver hair, upper body, solo" #さくやさん
n_prompt="light, shadow, NSFW, worst quality, low quality, medium quality, deleted, lowres, comic,underboob, open_clothes, bad anatomy,strapless,bare_legs, bad hands, text,error,  missing fingers, extra digit, fewer digits, cropped , jpeg artifacts, signature, blurry, flat color, flat shading, nsfw, retro style, poor quality, bad face, bad fingers, bad anatomy, missing fingers, low res, cropped, signature, watermark, username, artist name, text"

pipe=pipe.to("cuda")

for i in range(5): #rangeのカッコ内は生成枚数 
    image = pipe(
        prompt=prompt+","+each_prompt,
        negative_prompt=n_prompt,
        height=512,
        width=512,
        num_inference_steps=25,  #=sampling steps
        guidance_scale=9 #=CFG Scale
    ).images[0]

    image.save("save/"+datetime.datetime.now().strftime('%Y_%m_%d__%H_%M_%S')+".png") #日付・時刻をファイル名につける

数枚生成した結果がこちら。

咲夜さんっぽいけど、服が若干違ったりしますね。というか全体的に暗いし薄い。

(8) VAE読み込み

暗いので、VAEで補正します。ambientmixの説明を読むと、VAEは「orangemix.vae.pt」がよさそうなのでそれにします。

ただし、Diffusersでは.vae.pt形式のVAEを直接使うことはできません。.safetensorsか.bin拡張子に変換しなければいけません。

自分で変換する方法もあるのですが、世の中は広くて、既に変換して公開してくださってる方が多いので、「orangemix vae bin」などと検索してみましょう。

uf/orangemix.vae.pt at main
We’re on a journey to advance and democratize artificial intelligence through open source and open science.

ほら、ありました。ここから、.binファイルとconfig.jsonファイルの2種類(.binだけじゃダメ)をダウンロードして、新規フォルダに入れましょう。

VAEを使った場合の全体のコードは以下のようになります(さっきのから4,10,11,12,13,15行目に変更有り)。.safetensorsファイルのVAEかbinのVAEかでは、リンクだけでなく読み込み方もちょっと違うので気をつけましょう。

#generator.py

from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
from diffusers.models import AutoencoderKL #VAEを使わなければこの行は不要

import datetime

model_path = "models/main/ambientmixAnAnime_v10.safetensors" #モデルのパス

#.safetensorsファイルのVAEを使うときは以下
#vae = AutoencoderKL.from_single_file("models/vae/diffusion_pytorch_model.safetensors") #VAEファイルのパス(VAEを使わなければこの行は不要)
#.binとconfig.jsonのVAEを使うときは以下
vae = AutoencoderKL.from_pretrained("models/vae/orangemixVAE") #VAEが入ってるフォルダのパス(VAEを使わなければこの行は不要)

pipe = StableDiffusionPipeline.from_single_file(model_path, load_safety_checker=False, extract_ema=True, vae=vae) #最後のvaeのところだけは、vaeを使わなければ不要。
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
pipe.enable_attention_slicing()


prompt = "masterpiece, best quality, super fine illustration, loli, an extremely cute and beautiful girl, detailed beautiful face, beautiful hair, beautiful eyes"
each_prompt="navy maid clothes,maid_headdress,silver hair, upper body, solo" #さくやさん
n_prompt="light, shadow, NSFW, worst quality, low quality, medium quality, deleted, lowres, comic,underboob, open_clothes, bad anatomy,strapless,bare_legs, bad hands, text,error,  missing fingers, extra digit, fewer digits, cropped , jpeg artifacts, signature, blurry, flat color, flat shading, nsfw, retro style, poor quality, bad face, bad fingers, bad anatomy, missing fingers, low res, cropped, signature, watermark, username, artist name, text"

pipe=pipe.to("cuda")

for i in range(5): #rangeのカッコ内は生成枚数 
    image = pipe(
        prompt=prompt+","+each_prompt,
        negative_prompt=n_prompt,
        height=512,
        width=512,
        num_inference_steps=25,  #=sampling steps
        guidance_scale=9 #=CFG Scale
    ).images[0]

    image.save("save/"+datetime.datetime.now().strftime('%Y_%m_%d__%H_%M_%S')+".png") #日付・時刻をファイル名につける

以上のコードで生成すると上のようになります。だいぶましですね。これくらいなら使えそうです。

補記 .vae.ptを手動変換(必要なら読んで)

参考:https://self-development.info/pt%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AEvae%E3%82%92diffusers%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/

以下のリンクのPythonファイルをダウンロード(上記リンクを名前を付けて保存)します。

https://github.com/huggingface/diffusers/blob/main/scripts/convert_vae_pt_to_diffusers.py

そして、これをgenerator.pyと同じディレクトリに入れておきます。

そこからcmdを開きます。

python convert_pt_to_bin.py -h

上のように打って、動作確認をします。このときに「Please install it with “pip install OmegaConf”」と出てきたら、その通りに「pip install OmegaConf」をしてあげてもう一回実行しましょう。

上記のような出力になったら正常です。上記のヘルプ(usage)に従って進めます。

python convert_pt_to_bin.py –vae_pt_path (.vae.ptファイルのパス) –dump_path (出力されるものが入るフォルダのパス)

という構造ですね。–dump_pathのあとにつづくのは出力されるフォルダのパスだということに気をつけましょう。

python convert_pt_to_bin.py --vae_pt_path models\vae\orangemix.vae.pt --dump_path models\vae\orangemixVAE

というように打ちます。

すると、そのフォルダ内に.safetensorsファイルと、config.jsonファイルが出てきます。
この.safetensorsファイルは.binファイルに相当しますので、それに気を付けて、フォルダごと指定して生成してください(.safetensors単独で指定してもエラーが出ます)。

(9) LoRA読み込み

咲夜さんにさらに近づけるため、LoRAを使いましょう。LoRAを使えば特徴が出てきます。civitAIとかのサイトで咲夜さんのLoRAをダウンロードします。

generator.pyと同じディレクトリに、「convert_lora_safetensor_to_diffusers.py」ファイルを作ります。

convert_lora_safetensor_to_diffusers.pyには以下を書き込みます。これはぼくのコードじゃなくて、どっかで配布されてたコードです。

# coding=utf-8
# Copyright 2023, Haofan Wang, Qixun Wang, All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

""" Conversion script for the LoRA's safetensors checkpoints. """

import argparse

import torch
from safetensors.torch import load_file

from diffusers import StableDiffusionPipeline

torch.set_default_tensor_type('torch.cuda.FloatTensor')
 
def load_safetensors_lora(pipeline, checkpoint_path, LORA_PREFIX_UNET="lora_unet", LORA_PREFIX_TEXT_ENCODER="lora_te", alpha=1):

    # load LoRA weight from .safetensors
    state_dict = load_file(checkpoint_path)

    visited = []

    # directly update weight in diffusers model
    for key in state_dict:
        # it is suggested to print out the key, it usually will be something like below
        # "lora_te_text_model_encoder_layers_0_self_attn_k_proj.lora_down.weight"

        # as we have set the alpha beforehand, so just skip
        if ".alpha" in key or key in visited:
            continue

        if "text" in key:
            layer_infos = key.split(".")[0].split(LORA_PREFIX_TEXT_ENCODER + "_")[-1].split("_")
            curr_layer = pipeline.text_encoder
        else:
            layer_infos = key.split(".")[0].split(LORA_PREFIX_UNET + "_")[-1].split("_")
            curr_layer = pipeline.unet

        # find the target layer
        temp_name = layer_infos.pop(0)
        while len(layer_infos) > -1:
            try:
                curr_layer = curr_layer.__getattr__(temp_name)
                if len(layer_infos) > 0:
                    temp_name = layer_infos.pop(0)
                elif len(layer_infos) == 0:
                    break
            except Exception:
                if len(temp_name) > 0:
                    temp_name += "_" + layer_infos.pop(0)
                else:
                    temp_name = layer_infos.pop(0)

        pair_keys = []
        if "lora_down" in key:
            pair_keys.append(key.replace("lora_down", "lora_up"))
            pair_keys.append(key)
        else:
            pair_keys.append(key)
            pair_keys.append(key.replace("lora_up", "lora_down"))

        # update weight
        if len(state_dict[pair_keys[0]].shape) == 4:
            weight_up = state_dict[pair_keys[0]].squeeze(3).squeeze(2).to(torch.float32)
            weight_down = state_dict[pair_keys[1]].squeeze(3).squeeze(2).to(torch.float32)
            curr_layer.weight.data += alpha * torch.mm(weight_up, weight_down).unsqueeze(2).unsqueeze(3)
        else:
            weight_up = state_dict[pair_keys[0]].to(torch.float32)
            weight_down = state_dict[pair_keys[1]].to(torch.float32)
            curr_layer.weight.data += alpha * torch.mm(weight_up, weight_down)            

        # update visited list
        for item in pair_keys:
            visited.append(item)

    return pipeline

そして、generator.pyの方を以下のように書き換えます。5, 14, 20行目あたりが変更点。

#generator.py

from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
from diffusers.models import AutoencoderKL #VAEを使わなければこの行は不要
import convert_lora_safetensor_to_diffusers #LoRAを使わなければこの行は不要

import datetime

model_path = "models/main/ambientmixAnAnime_v10.safetensors" #モデルのパス
#.safetensorsファイルのVAEを使うときは以下
#vae = AutoencoderKL.from_single_file("models/vae/diffusion_pytorch_model.safetensors") #VAEファイルのパス(VAEを使わなければこの行は不要)
#.binとconfig.jsonのVAEを使うときは以下
vae = AutoencoderKL.from_pretrained("models/vae/orangemixVAE") #VAEが入ってるフォルダのパス(VAEを使わなければこの行は不要)
lora_path="models/lora/sakuya.safetensors" #LoRAが入ってるパス(LoRAを使わなければこの行は不要)

pipe = StableDiffusionPipeline.from_single_file(model_path, load_safety_checker=False, extract_ema=True, vae=vae) #最後のvaeのところだけは、vaeを使わなければ不要。
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
pipe.enable_attention_slicing()

pipe = convert_lora_safetensor_to_diffusers.load_safetensors_lora(pipe, lora_path, alpha=0.7) #LoRAを使わなければこの行は不要

pipe=pipe.to("cuda")

prompt = "masterpiece, best quality, super fine illustration, loli, an extremely cute and beautiful girl, detailed beautiful face, beautiful hair, beautiful eyes"
each_prompt="navy maid clothes,maid_headdress,silver hair, upper body, solo" #さくやさん
n_prompt="light, shadow, NSFW, worst quality, low quality, medium quality, deleted, lowres, comic,underboob, open_clothes, bad anatomy,strapless,bare_legs, bad hands, text,error,  missing fingers, extra digit, fewer digits, cropped , jpeg artifacts, signature, blurry, flat color, flat shading, nsfw, retro style, poor quality, bad face, bad fingers, bad anatomy, missing fingers, low res, cropped, signature, watermark, username, artist name, text"

for i in range(5): #rangeのカッコ内は生成枚数 
    image = pipe(
        prompt=prompt+","+each_prompt,
        negative_prompt=n_prompt,
        height=512,
        width=512,
        num_inference_steps=25,  #=sampling steps
        guidance_scale=9 #=CFG Scale
    ).images[0]

    image.save("save/"+datetime.datetime.now().strftime('%Y_%m_%d__%H_%M_%S')+".png") #日付・時刻をファイル名につける

cmdから実行。

python generator.py

さて、たぶんエラーが出ます。

エラーの基本はメッセージを読むこと。TypeError: can’t convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to…というあたりが重要そうです。

このエラーをネットで検索すると、以下のようなサイトがヒット。

TypeError: can’t convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first
I am using a modified predict.py for testing a pruned SqueezeNet Model $ python predict.py --image 3_100.jpg --model mod...

「Change ” index = output.data.numpy().argmax() ” to ” index = output.cpu().data.numpy().argmax() “」と書いてますから、どうやらエラーは「.cpu()」を書き足してやれば解決しそうです。

エラーが起きているファイルをエラーメッセージから特定し、「.numpy()」の場所を「.cpu().numpy()」と書き換えます。数か所あります。

書き換えたら動くはずです。それでもだめならエラーと戦ってください。

LoRAの重み(どれだけ影響するか)は、上記コード20行目の「alpha=0.7」のところの数字を調整するかで変わります。0だと影響なし、1なら最大限影響します。うまく加減してください。

ということで、alphaを調整したりして、VAEもLoRAも付けて生成したのが上画像です。かなりいい感じですね。

(10) 大量生産体制を整える

あとはPythonコードをいじるだけなので簡単です。配列などを活用してうまくやっていきましょう。

4. 最後に

だいたいこういう記事の最後って、「イラスト生成はGPUのスペックに依存します。ぜひ新しいのを買ってください」っていうアフェリエイト広告が貼ってますよねw あれで買う人いるんだろうかw

わたしは金はなくても、二次元の女の子がゆりゆりしてれば幸せなのでOKです。

コメント

タイトルとURLをコピーしました