🍣

【Diffusers】MacでStableDiffusionのImg2Imgのpython環境を整える

2022/09/14に公開
2

はじめに

この記事ではDiffusersを使ったMacのStableDiffusionでimg2imgを実行するまでの手順を紹介します。

対象読者

・M1/M2シリーズのMacユーザ
・stable-diffusionとその発展型のモデルを気軽に試せる環境がほしい人
・stable-diffusion環境メンテと最新化に稼働を割く暇がない人

Diffusersとは?

推論・学習に必要なツールが機械学習周りの機能一式が揃ったツールボックスです。
モデルの切り替えや追加学習などのツールが1コマンドですべて入るので、AIイラストの環境がライトに構築可能です。

Diffusersのインストール方法

以前にこちらの記事で紹介しました。初心者の人でも分かりやすいよう、1から解説してあるので未導入の方はこちらからまずはインストールをお願いします。

https://zenn.dev/michy/articles/102a0558096199

実行方法

diffusersのpython環境で以下のコードを実行してください。
セクションごとの細かいコードの説明は後述しますが、元画像のパスとプロンプトに対して指定した枚数の画像を出力するような動きになっています。

from io import BytesIO
from itertools import count
import requests
import torch
from diffusers import StableDiffusionImg2ImgPipeline
from PIL import Image, ImageFilter

## カスタマイズ部分
device =  "mps" #デバイス名(macの場合はmpsを使う)
model_name = "CompVis/stable-diffusion-v1-4" #モデル名
file_path ="./input.jpg" #元画像のファイルパス
prompt = "A fantasy landscape, trending on artstation" #呪文部分
image_size = (768,512) #横幅と高さ。2の倍数の値で入力。

data_len = 100 #実行回数

## 画像作成
def createImage(output_name:str,count:int):

    pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
        model_name,
        use_auth_token=True
    ).to(device)

    init_image =  Image.open(file_path).convert("RGB").resize(image_size)
    images = pipe(prompt=prompt, image=init_image, strength=0.75, guidance_scale=7.5).images
    images[0].save(output_name + '_' +str(count).zfill(4) +'.jpg')


## 実行部分
for i in range(data_len):
    print(str(i).zfill(4) + "枚目の画像を出力中です。")
    createImage("output",i)

各コードの説明

必要なライブラリのインポート

実行に必要なライブラリをインポートします。一部現時点では必要ないものが入っていますが、今後のMac対応の拡充によって利用できるようになる可能性があるものも合わせてインポートしています。

from io import BytesIO
from itertools import count
import requests
import torch
from diffusers import StableDiffusionImg2ImgPipeline
from PIL import Image, ImageFilter

各パラメータの事前設定

実行に必要な各種パラメータを入力します。
device以外は好みのものを設定してください。image_sizeはPCのスペックが低い場合に下げるなどで品質を犠牲にして処理が早く終る可能性があります。

device =  "mps" #デバイス名(macの場合はmpsを使う)
model_name = "CompVis/stable-diffusion-v1-4" #モデル名
file_path ="./input.jpg" #元画像のファイルパス
prompt = "A fantasy landscape, trending on artstation" #呪文部分
image_size = (768,512) #横幅と高さ。2の倍数の値で入力。

data_len = 100 #実行回数

画像の生成

複数回実行することを前提にするため、実行部分は関数化しています。
ファイル名とインクリメントを引数にし、保存する際のファイル名に使用しています。

def createImage(output_name:str,count:int):

    pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
        model_name,
        use_auth_token=True
    ).to(device)

    init_image =  Image.open(file_path).convert("RGB").resize(image_size)
    images = pipe(prompt=prompt, image=init_image, strength=0.75, guidance_scale=7.5).images
    images[0].save(output_name + '_' +str(count).zfill(4) +'.jpg')

細かいチューニング

strength=0.75の部分と、guidance_scale=7.5は必要に応じてチューニングする部分です。
それぞれ値を変えることで以下の通りに出力が変わります。

変数名 説明
strength 元画像をどの程度意識しないか決める値(0.5~0.9くらいが使いやすい)。 大きいほど元の画像の形を無視する
guidance_scale プロンプト(呪文)をどの程度残すかを決める値(0.5~0.9くらいが使いやすい)。 大きいほどプロンプトを無視する

実行部分

data_lenで決めた回数だけ画像を生成する。

for i in range(data_len):
    print(str(i).zfill(4) + "枚目の画像を出力中です。")
    createImage("output",i)

まとめ

この記事ではdiffusersを使ってimg2imgを行う方法を解説しました。

diffusersのmac対応は今後も進んでくることが予想されますので、ぜひ利用できる環境を構築しキャッチアップしていくことをおすすめします。

不明な点や間違いがありましたら、是非コメント欄で教えていただけると幸いです。

Discussion

Naoya_proNaoya_pro

記事めちゃめちゃ参考になりました!
ありがとうございます!
一つだけ
pipeの引数の、init_imageが現在はimageになっているようです

zaiwazaiwa

コメントありがとうございます!

引数変わっているの気づいていませんでした!ありがとございます。