Stable DiffusionをWindows 10とAMD GPU上で動作させている記事、Running Stable Diffusion on Windows with an AMD GPUを見つけたので、実践。以下は作成してみたサンプル。
事前準備
まずは実行環境を確認。
・メモリ6GB以上のAMD GPU
・Pythonの3.7、3.8、3.9、3.10がインストールされている
・Gitがインストールされている。
・Hugging Face(Stable Diffusionの学習済みモデルを公開している)のアカウント
・6GBの学習モデルをダウンロード&変換する勇気
と言うわけでPythonのインストール。PythonはMicrosoft StoreからPython 3.10をインストールしてしまうのが手がかからない。
続いてGitのインストール。私はVisual Studioと一緒にインストールされてしまっているが、単独でインストールするならGit for Windowsをインストールするのが良いかと思う。
さらにHugging Faceにユーザー登録する。ユーザー登録自体は無料。
インストール作業
ますはインストール先となるフォルダを作成する。私はD:\stable-diffusionにした。インストールには15GB程度の空き容量が必要になるはずなので、十分に空きのあるドライブを選ぶこと。PowerShellからコマンドプロンプトを開いて、インストール先フォルダに移動します。
Microsoft’s DirectMLに対応したOnnx runtimeをhttps://aiinfra.visualstudio.com/PublicPackages/_artifacts/feed/ORT-Nightlyからonnxruntime-directmlをダウンロードする。ダウンロードするランタイムはPythonのバージョンによって異なる。Python 3.10.xをインストールしているなら、cp310(onnxruntime_directml-1.12.0-cp310-cp310-win_amd64.whl)をダウンロードする。
コマンドプロンプトまたはPowerShellのプロンプトを開いて以下のコマンドを実行。
python -m venv ./virtualenv
./virtualenv/Scripts/Activate.ps1 または virtualenv\Scripts\activate.bat
pip install diffusers==0.3.0
pip install transformers
pip install onnxruntime
pip install protobuf<3.20.x
pip install onnx
pip install pathToYourDownloadedFile/ort_nightly_whatever_version_you_got.whl --force-reinstall
Stable Diffusionの学習済みモデルをダウンロードするには、ライセンス条項に同意する必要があります。ライセンス条項を確認した上で、Hugging Faceのhttps://huggingface.co/CompVis/stable-diffusion-v1-4のページにアクセスして、「 have read the License and agree with its terms」にチェックをして、Access Repositoryをクリック。
Hugging FaceのAccess Tokenを発行する必要があります。Hugging FaceのWEBページ右上のユーザーアイコンから「Settings→Access Tokens」に進み、Access Tokenを発行します。
プロンプトから以下のコマンドを実行します。
huggingface-cli.exe login
Token:とプロンプトが表示されるので、先ほど発行したAccess Tokenを入力します。「Your token has been saved to ~」と表示されれば大丈夫です。
Stable DiffusionをOnnixに変換するためのスクリプトを「https://raw.githubusercontent.com/huggingface/diffusers/main/scripts/convert_stable_diffusion_checkpoint_to_onnx.py」からダウンロードします。
以下のコマンドを実行します。
python convert_stable_diffusion_checkpoint_to_onnx.py --model_path="CompVis/stable-diffusion-v1-4" --output_path="./stable_diffusion_onnx"
学習モデルのダウンロードと変換に数時間かかります。気長に待ってください。
試しに画像を生成してみます。以下の内容をtext2img.pyとして保存して、プロンプトから実行してみてください。output.pngが無事に生成されればインストール成功です。
from diffusers import StableDiffusionOnnxPipeline
pipe = StableDiffusionOnnxPipeline.from_pretrained("./stable_diffusion_onnx", provider="DmlExecutionProvider")
prompt = "A happy celebrating robot on a mountaintop, happy, landscape, dramatic lighting, art by artgerm greg rutkowski alphonse mucha, 4k uhd'"
image = pipe(prompt).images[0]
image.save("output.png")
生成する画像サイズや、反復計算する回数などのパラメータを指定する事もできます。それらを指定する場合には以下のコードを参考に書き換えてください。
from diffusers import StableDiffusionOnnxPipeline
import numpy as np
def get_latents_from_seed(seed: int, width: int, height:int) -> np.ndarray:
# 1 is batch size
latents_shape = (1, 4, height // 8, width // 8)
# Gotta use numpy instead of torch, because torch's randn() doesn't support DML
rng = np.random.default_rng(seed)
image_latents = rng.standard_normal(latents_shape).astype(np.float32)
return image_latents
pipe = StableDiffusionOnnxPipeline.from_pretrained("./stable_diffusion_onnx", provider="DmlExecutionProvider")
"""
prompt: Union[str, List[str]],
height: Optional[int] = 512,
width: Optional[int] = 512,
num_inference_steps: Optional[int] = 50,
guidance_scale: Optional[float] = 7.5, # This is also sometimes called the CFG value
eta: Optional[float] = 0.0,
latents: Optional[np.ndarray] = None,
output_type: Optional[str] = "pil",
"""
seed = 50033
# Generate our own latents so that we can provide a seed.
latents = get_latents_from_seed(seed, 512, 512)
prompt = "A happy celebrating robot on a mountaintop, happy, landscape, dramatic lighting, art by artgerm greg rutkowski alphonse mucha, 4k uhd"
image = pipe(prompt, num_inference_steps=25, guidance_scale=13, latents=latents).images[0]
image.save("output.png")
制限
この時点ではいくつかの制限があります。
生成画像解像度の制約
512×512以上の解像度の画像を生成することが出来ません。これはOnnixの制約です。より高解像度の画像が必要な場合には、waifu2xなどの超解像AIを併用するなどの工夫が必要です。
NSFW(職場閲覧注意)による制約
真っ黒な画像を生成することが頻繁にあります。標準で組み込まれているNSFW(職場閲覧注意)フィルタにブロックされていることが原因です。以下の様に1行追加する事でNSFWを無効に出来るようですが、Stable Diffusionの利用規約上NSFWを無効にして生成した画像の公開は慎重に行いましょう。NSFWを無効にすると相当に高速になるという副次的効果もあるようです。
pipe = StableDiffusionOnnxPipeline.from_pretrained("./stable_diffusion_onnx", device_map="auto", provider="DmlExecutionProvider", max_memory=max_memory_mapping)
pipe.safety_checker = lambda images, **kwargs: (images, [False] * len(images))
その他、細かなHackは続編のStable Diffusion Updatesに・・・・