[Amazon Bedrock] Stable Diffusion XLを使用して、我が家のワンコをイラスト化してみました
1 はじめに
CX 事業本部 delivery部の平内(SIN)です。
Amazon Bedrockを使用することで、生成AIを軽易に利用することが可能です。 今回は、カテゴリ「Image」に分類される、Stability AI の Stable Diffusion XL(Preview) を使用して、写真を元にしたイラストの作成を試してみました。
2 出力画像
最初に、入力とした画像と、出力を御覧ください。入力画像の構成を活かして、コミック風の画像が生成されていること確認できると思います。
入力画像
出力画像
3 Playgrounds
AWSコンソールで提供されているPlaygroundsでは、軽易にモデルを試すことが出来ますが、設定できるパラメータが制限されるため、できることに限りがあります。
今回試したような、Image to Imageは利用出来ません。
4 boto3
パラメータを自由に設定するためには、API requestで利用する必要がありますが、最新のboto3から、これを利用可能です。
下記が、今回の作業で使用したコードです。
image_2_images.py
import base64 import io import json import datetime import random import boto3 from PIL import Image def image_to_base64(image): buffer = io.BytesIO() image.save(buffer, format="PNG") return base64.b64encode(buffer.getvalue()).decode("utf-8") def base64_to_image(base64_str): return Image.open(io.BytesIO(base64.decodebytes(bytes(base64_str, "utf-8")))) boto3_bedrock = boto3.client("bedrock-runtime", region_name="us-east-1") model_id = "stability.stable-diffusion-xl" data_path = "./data" basename = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") # 日時文字列をファイル名に使用する seed = random.randint(0, 1000) steps = 50 cfg_scale = 30 start_schedule = 0.6 change_prompt = "a dog, light smile,cute,character, room" negative_prompts = ["", "", ""] style_preset = "comic-book" size = 512 input_image = "{}/input.png".format(data_path) output_image = "{}/{}.png".format(data_path, basename) # 設定値 config = { "filename": basename + ".png", "seed": seed, "change_prompt": change_prompt, "steps": steps, "cfg_scale": cfg_scale, "start_schedule": start_schedule, "style_preset": style_preset, "size": size, "input_image": input_image, } # 入力パラメータ input_image_b64 = image_to_base64(Image.open(input_image).resize((size, size))) body = json.dumps( { "text_prompts": [{"text": config["change_prompt"], "weight": 1.0}], "cfg_scale": config["cfg_scale"], "seed": config["seed"], "start_schedule": config["start_schedule"], "steps": config["steps"], "style_preset": config["style_preset"], "init_image": input_image_b64, } ) # 推論 response = boto3_bedrock.invoke_model(body=body, modelId=model_id) # 推論結果の画像取得 response_body = json.loads(response.get("body").read()) response_image = base64_to_image(response_body["artifacts"][0].get("base64")) # レスポンス画像の保存 response_image.save("{}/{}.png".format(data_path, basename)) # 設定値の保存 with open("{}/{}.json".format(data_path, basename), "w") as f: json.dump(config, f, ensure_ascii=False)
5 invoke_model()
推論の本体である invoke_model() のリクエストは、下記のようなパラメータで使用されます。
response = client.invoke_model( accept='string', body=b'bytes'|file, contentType='string', modelId='string' )
name | type | description | default | requird |
---|---|---|---|---|
accept | string | 推論結果のMIMEタイプ | application/json | |
body | bytes orfile | 推論パラメーター | ◯ | |
contentType | string | 入力データのMIMEタイプ | application/json | |
modelId | string | モデルの識別子 | ◯ |
レスポンスは、以下です。
{ 'body': StreamingBody(), 'contentType': 'string' }
body の中のartifactsで、レスポンス画像を受け取れます。
response_body = json.loads(response.get("body").read()) response_image = base64_to_image(response_body["artifacts"][0].get("base64"))
6 推論パラメータ
invoke_model()のbodyに指定されるパラメータについては、下記にドキュメントがあります。
参考:Inference parameters for foundation models
参考のため、主なパラメータについて、列挙しておきます。
text_prompts: テキストプロンプト weightがマイナスの場合は、ネガティブプロンプトになる
"text_prompts" = [ {"text": "positive prompt", "weight": 1.0}, {"text": "negative prompt", "weight": -1.0} ]
cfg_scale: text_promptsで記載した内容にどれだけ従うかを0〜30で指定 大きいほど強く従う)
seed: シード値(0は、ランダム)
steps: 生成ステップ数(大きいほど高精度)※ 50以上で、オンデマンド料金が変わります
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
7 同じような画像の生成
コードを実行すると、下記のような「画像ファイル」と「jsonファイル」が出力されます。 入力パラメータのseed値をランダムに指定しているため、毎回、出力画像は変化します。
20231006_073000.png
20231006_073000.json
{ "filename": "20231006_073000.png", "seed": 535, "change_prompt": "a dog, light smile,cute,character, room", "steps": 50, "cfg_scale": 30, "start_schedule": 0.6, "style_preset": "comic-book", "size": 512, "model_id": "stability.stable-diffusion-xl", "input_image": "./data/input.png" }
使用されたseed値等のパラメータをjsonファイルに出力しているため、もう一度、同じような画像(完全に固定されていないため、微妙に変わります)を出力することは可能です。
8 最後に
今回は、Stable Diffusion XL(Preview) で写真を元にしたイラストの作成を試してみました。
画像生成AIでは、テキストプロンプトだけで、イメージした出力を得ることは、結構、難しいと思います。そういう意味で、Image to Imageは、画像でテキストプロンプトを補完できるため、うまく使いこなせば、高確率で思った通りの画像が生成ができるようになるのでは?と妄想しています。