LoginSignup
18
13

Stable Diffusionでの画像生成をPythonとWeb APIで実装してみた記録

Posted at

Supershipの名畑です。ツイステッドワンダーランドの7章のChapter 3がついに公開されたわけなんですが、すぐに読み終わってしまい、続きはよ。はよ。

はじめに

これまでOpenAIで遊ぶ記事を色々と公開してきまして、また今更感ありまくりなのですが、最近はstability.aiAPI群で遊んでおります。テキストからの画像生成モデルであるStable Diffusionがめちゃくちゃ有名ですね。

今回の記事ではアカウントの作成APIを呼び出しての画像生成をPythonで実装した記録を残しておきます。

登場するコードはREST API referenceのv1/generationのままです。

自環境

macOS(Monterey)です。

Pythonはすでにインストール済みです。

$ python --version
Python 3.10.7

また、サンプルコードがHTTPライブラリであるrequestsを用いていたため、入れておきました。

$ pip install requests

今のバージョンは2.30.0でした。

$ pip show requests
Name: requests
Version: 2.30.0
以下略

DreamStudioのアカウント作成

DreamStudioという、Stable DiffusionをWeb上で操作して画像生成する公式サービスがあるのですが、こちらのページの右上にあるLoginをクリックします。

Google、Discord、あるいはメールアドレスでのアカウント作成に対応しています。

API key発行

ログイン後のAccountのページで行えます。おそらくデフォルトで一つAPI keyが発行されているかと思います。追加発行も可能です。
無料クレジットで足りない場合のクレジットの購入もこちらのページで可能です。

取得したAPI keyはハードコーディングを避けるため環境変数に設定しました。
公式に倣いSTABILITY_API_KEYという環境変数名としました。

export STABILITY_API_KEY =ここに取得したAPI keyを書く

価格

Pricing Tableに価格が掲載されています。エンジンとサイズとステップ数(後述)で変わります。

Stable Diffusionの最新版であるStable Diffusion XLSDXL)以外のエンジンであれば現在は下記価格です。

Steps 512 x 512 512 x 768 512 x 1024 768 x 768 768 x 1024 1024 x 1024
15 $0.001 $0.003 $0.004 $0.005 $0.007 $0.01
30 $0.002 $0.005 $0.008 $0.01 $0.014 $0.019
50 $0.004 $0.009 $0.013 $0.016 $0.023 $0.032
100 $0.007 $0.017 $0.026 $0.031 $0.045 $0.064
150 $0.01 $0.025 $0.039 $0.046 $0.067 $0.095

Stable Diffusion XLSDXL)の価格はSDXL Pricing Tableに掲載されています。下記です。大体2.5倍って感じでしょうか。

Steps 512 x 512 640 x 512 768 x 512 896 x 512 512 x 640 512 x 768 512 x 896
15 $0.0025 $0.0045 $0.0065 $0.0084 $0.0045 $0.0065 $0.0084
30 $0.005 $0.009 $0.013 $0.017 $0.009 $0.013 $0.017
50 $0.0083 $0.0149 $0.0215 $0.028 $0.0149 $0.0215 $0.028
100 $0.0167 $0.0298 $0.0431 $0.0563 $0.0298 $0.0431 $0.0563
150 $0.025 $0.045 $0.065 $0.085 $0.045 $0.065 $0.085

engine_id

APIの呼び出し時にengine_idを指定するのですが、現在は下記が選べます。stable-diffusion-xl-beta-v2-2-2 が最新のSDXLです。

id name
stable-diffusion-v1 Stable Diffusion v1.4
stable-diffusion-v1-5 Stable Diffusion v1.5
stable-diffusion-512-v2-0 Stable Diffusion v2.0
stable-diffusion-768-v2-0 Stable Diffusion v2.0-768
stable-diffusion-512-v2-1 Stable Diffusion v2.1
stable-diffusion-768-v2-1 Stable Diffusion v2.1-768
stable-diffusion-xl-beta-v2-2-2 Stable Diffusion v2.2.2-XL Beta
stable-inpainting-v1-0 Stable Inpainting v1.0
stable-inpainting-512-v2-0 Stable Inpainting v2.0
esrgan-v1-x2plus Real-ESRGAN x2
stable-diffusion-x4-latent-upscaler Stable Diffusion x4 Latent Upscaler

指定可能なengine_idのリストはenginesのlist APIで取得可能です。今回は説明は省略します。

generation APIのパラメータ

Deault値 説明
height 512 高さです。768用のengineではheight * widthが589,824以上である必要があります。
width 512 幅です。768用のengineではheight * widthが589,824以上である必要があります。
text_prompts - これのみがrequiredです。どういった画像を生成してほしいかをtextに記載し、その重みをweigthに記載します。重みはoptionalで、マイナス値(いわゆるネガティブプロンプト)も指定可能です。
cfg_scale 7 text_promptsで記載した内容にどれだけ従うかを0〜35で記載します。35に近いほど強く従います。
clip_guidance_preset NONE CLIPガイダンスプリセット。下記から選択可能です。
FAST_BLUE / FAST_GREEN / NONE / SIMPLE / SLOW / SLOWER / SLOWEST
sampler - サンプラー。下記から選択可能です。指定しない場合は適切なものが適用されます。
DDIM / DDPM / K_DPMPP_2M / K_DPMPP_2S_ANCESTRAL / K_DPM_2 / K_DPM_2_ANCESTRAL / K_EULER / K_EULER_ANCESTRAL / K_HEUN / K_LMS
samples 1 生成画像数
seed 0 乱数設定するためのシード値。つまりはこれを違う値にすれば同じプロンプトでも違う画像が生成されます。0指定、もしくは無指定だと自動でランダムになります。
steps 50 生成ステップ数を10〜150で記載します。150に近いほど画像が高精度になります。
style_preset - 画像のスタイル。下記から選べます。
3d-model / analog-film / anime / cinematic / comic-book / digital-art / enhance / fantasy-art / isometric / line-art / low-poly / modeling-compound / neon-punk / origami / photographic / pixel-art / tile-texture
extras - その他のパラメータをengineに渡すためのものです。開発用途などで使われるそうです。

Pythonでのコード

サンプルコードを基本としていますが「requiredではないパラメータの削除」「コメントの追加」「ファイル保存先とファイル名を変更」をしています。

プロンプトには「A cute fairy on top of a white laptop」というtextを渡しています。「白いノートパソコンの上のかわいい妖精」ですね。

import base64
import os
import requests
import time

engine_id = "stable-diffusion-v1-5"
api_host = os.getenv('API_HOST', 'https://api.stability.ai')
api_key = os.getenv("STABILITY_API_KEY")

# API Keyの取得確認
if api_key is None:
    raise Exception("Missing Stability API key.")

# API呼び出し
response = requests.post(
    f"{api_host}/v1/generation/{engine_id}/text-to-image",
    headers={
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authorization": f"Bearer {api_key}"
    },
    json={
        "text_prompts": [
            {
                "text": "A cute fairy on top of a white laptop"
            }
        ],
    },
)

# レスポンス確認
if response.status_code != 200:
    raise Exception("Non-200 response: " + str(response.text))

# レスポンス取得
data = response.json()

# 画像保存
# ファイル名にはタイムスタンプとengine_id、通番を含めています
# 通番は0〜samplesの値 - 1
for i, image in enumerate(data["artifacts"]):
    with open(f"./{engine_id}_{int(time.time())}_{i}.png", "wb") as f:
        f.write(base64.b64decode(image["base64"]))

生成結果

engine_id別で2枚ずつ結果を添付します。
こうやって並べてみると最新のSDXLの生成画像の品質向上が目で見てわかるレベルですね。主観ではありますが。

Stable Diffusion v1.4

engine_id = "stable-diffusion-v1"
stable-diffusion-v1_1684075967_0.png stable-diffusion-v1_1684076096_0.png

Stable Diffusion v1.5

engine_id = "stable-diffusion-v1-5"
stable-diffusion-v1-5_1684075976_0.png stable-diffusion-v1-5_1684076102_0.png

Stable Diffusion v2.0

engine_id = "stable-diffusion-512-v2-0"
stable-diffusion-512-v2-0_1684076018_0.png stable-diffusion-512-v2-0_1684076113_0.png

Stable Diffusion v2.1

engine_id = "stable-diffusion-512-v2-1"
stable-diffusion-512-v2-1_1684075987_0.png stable-diffusion-512-v2-1_1684076118_0.png

Stable Diffusion v2.2.2-XL Beta

engine_id = "stable-diffusion-xl-beta-v2-2-2"
stable-diffusion-xl-beta-v2-2-2_1684075996_0.png stable-diffusion-xl-beta-v2-2-2_1684076124_0.png

生成結果(anime指定)

style_presetanimeを指定した絵も生成してみました。
こちらもSDXLでかなり質が高まったと感じます。

    json={
        "text_prompts": [
            {
                "text": "A cute fairy on top of a white laptop"
            }
        ],
        "style_preset": "anime",
    },

Stable Diffusion v1.4(anime指定)

engine_id = "stable-diffusion-v1"
stable-diffusion-v1_1684075613_0.png stable-diffusion-v1_1684076193_0.png

Stable Diffusion v1.5(anime指定)

engine_id = "stable-diffusion-v1-5"
stable-diffusion-v1-5_1684075678_0.png stable-diffusion-v1-5_1684076197_0.png

Stable Diffusion v2.0(anime指定)

engine_id = "stable-diffusion-512-v2-0"
stable-diffusion-512-v2-0_1684075686_0.png stable-diffusion-512-v2-0_1684076202_0.png

Stable Diffusion v2.1(anime指定)

engine_id = "stable-diffusion-512-v2-1"
stable-diffusion-512-v2-1_1684075692_0.png stable-diffusion-512-v2-1_1684076206_0.png

Stable Diffusion v2.2.2-XL Beta(anime指定)

engine_id = "stable-diffusion-xl-beta-v2-2-2"
stable-diffusion-xl-beta-v2-2-2_1684075552_0.png stable-diffusion-xl-beta-v2-2-2_1684075701_0.png

最後に

次回はプロンプトをもう少し色々といじって遊んでみようかと思います。同一人物における表情変化を記事にする予定です。

宣伝

SupershipのQiita Organizationを合わせてご覧いただけますと嬉しいです。他のメンバーの記事も多数あります。

Supershipではプロダクト開発やサービス開発に関わる方を絶賛募集しております。
興味がある方はSupership株式会社 採用サイトよりご確認ください。

18
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
13