Amazon Bedrock(Stable Diffusion) の workshop をやってみた~Text to Image編~

記事タイトルとURLをコピーする

こんにちは!引き続きIE課にて修行中の荒井です。

今回は最近話題の Amazon Bedrock(Stable Diffusion) の workshop を触ってきたので、そちらについて書こうと思います。

手順通りにやるとエラーが出たり上手くいかない点があったので、そちらの備忘録でもあります。

はじめに

今回の workshop は Amazon が公式に公開しているものを利用しています。

workshop は日々更新されているため、将来的には違った内容になっている可能性があります。

前提

この記事で取り扱うこと

  • Bedrock(Stable Diffusion) の Text to Image のワークショップ

この記事で取り扱わないこと

  • Bedrock(Stable Diffusion) の Image to Image のワークショップ
  • Bedrock(Stable Diffusion) 以外のワークショップ
  • awscli の初期設定

以下の記事にて awscli の設定方法について紹介しておりますので、必要に応じてご参照ください。

blog.serverworks.co.jp

環境

OS: windows11 + Ubuntu 22.04

Python: 3.11.6

事前準備

github.com

まずはローカルの環境で公式のリポジトリのクローンを行います。

git clone https://github.com/aws-samples/amazon-bedrock-workshop

次に AWS コンソールを開き、リージョンをバージニア北部に変更します。

Amazon Bedrockのページを開き、左メニューから Model access を選択し、[Manage model access] をクリックします。

今回利用したいモデルは Stable Diffusion XL なので、チェックを入れて [Request model access] をクリックします。

早ければ直ぐにでも状態が Access granted に変更になり、利用可能な状態となります。

最後に以下のポリシーを作成し、今回利用するユーザに割り当てます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "BedrockFullAccess",
            "Effect": "Allow",
            "Action": [
                "bedrock:*"
            ],
            "Resource": "*"
        }
    ]
}

その後、ユーザの認証情報を awscli に設定すれば準備は完了です。

パッケージのインストール

github.com

以下のコマンドを実行し、必要なパッケージをインストールします。

%pip install --no-build-isolation --force-reinstall \
    "boto3>=1.28.57" \
    "awscli>=1.29.57" \
    "botocore>=1.31.57"

今回は画像生成の手順を行うため、追加で pillow もインストールします。

%pip install --quiet "pillow>=9.5,<10"

画像生成

github.com

サンプルコードを繋げて保存し、実行してみます。

# Python Built-Ins:
import base64
import io
import json
import os
import sys
import random

# External Dependencies:
import boto3
from PIL import Image

module_path = ".."
sys.path.append(os.path.abspath(module_path))
from utils import bedrock, print_ww

# ---- ⚠️ Un-comment and edit the below lines as needed for your AWS setup ⚠️ ----

os.environ["AWS_DEFAULT_REGION"] = "us-east-1"  
os.environ["AWS_PROFILE"] = "default" # ここは設定したプロファイル名を指定

boto3_bedrock = bedrock.get_bedrock_client(
    assumed_role=os.environ.get("BEDROCK_ASSUME_ROLE", None),
    region=os.environ.get("AWS_DEFAULT_REGION", None),
    runtime=False
)

prompt = "a beautiful mountain landscape"
negative_prompts = [
    "poorly rendered",
    "poor background details",
    "poorly drawn mountains",
    "disfigured mountain features",
]
style_preset = "photographic"  # (e.g. photographic, digital-art, cinematic, ...)
clip_guidance_preset = "FAST_GREEN" # (e.g. FAST_BLUE FAST_GREEN NONE SIMPLE SLOW SLOWER SLOWEST)
sampler = "K_DPMPP_2S_ANCESTRAL" # (e.g. DDIM, DDPM, K_DPMPP_SDE, K_DPMPP_2M, K_DPMPP_2S_ANCESTRAL, K_DPM_2, K_DPM_2_ANCESTRAL, K_EULER, K_EULER_ANCESTRAL, K_HEUN, K_LMS)
width = 768

request = json.dumps({
    "text_prompts": (
        [{"text": prompt, "weight": 1.0}]
        + [{"text": negprompt, "weight": -1.0} for negprompt in negative_prompts]
    ),
    "cfg_scale": 5,
    "seed": 452345,
    "steps": 60,
    "style_preset": style_preset,
    "clip_guidance_preset": clip_guidance_preset,
    "sampler": sampler,
    "width": width,
})
modelId = "stability.stable-diffusion-xl"

response = boto3_bedrock.invoke_model(body=request, modelId=modelId)
response_body = json.loads(response.get("body").read())

print(response_body["result"])
base_64_img_str = response_body["artifacts"][0].get("base64")
print(f"{base_64_img_str[0:80]}...")

os.makedirs("data", exist_ok=True)
image_1 = Image.open(io.BytesIO(base64.decodebytes(bytes(base_64_img_str, "utf-8"))))
image_1.save("./data/image_1.png") # ここだけちょっとだけ変更
image_1

しかし以下の通りエラーが出てしまいました。

どうやら invoke_model という属性が存在しないというエラーのようです。

Create new client
  Using region: us-east-1
  Using profile: default
boto3 Bedrock client successfully created!
bedrock(https://bedrock.us-east-1.amazonaws.com)
Traceback (most recent call last):
  File "/home/arai/venv/python3.11/test2.py", line 55, in <module>
    response = boto3_bedrock.invoke_model(body=request, modelId=modelId)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/arai/venv/python3.11/bedrock/lib/python3.11/site-packages/botocore/client.py", line 888, in __getattr__
    raise AttributeError(
AttributeError: 'Bedrock' object has no attribute 'invoke_model'

公式の boto3 ドキュメントを見ると、クライアント生成は以下で出来そうなので、 クライアント生成を行っている箇所を修正してみます。

boto3.amazonaws.com

client = boto3.client('bedrock-runtime')

修正箇所

# boto3_bedrock = bedrock.get_bedrock_client(
#    assumed_role=os.environ.get("BEDROCK_ASSUME_ROLE", None),
#    region=os.environ.get("AWS_DEFAULT_REGION", None),
#    runtime=False
# )

boto3_bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")

上記の修正を行い、コードを再度実行すると・・・無事に成功しました!

生成された画像は以下となります。

今回は固定シードで行っているため、モデルの更新等が無ければ同じ画像が生成されるかと思われます。

おわりに

後半はだいぶ駆け足になってしまいましたが、無事に画像を生成することが出来ました。

次回は画像から画像を生成すること(Image to Image)を試してみようと思います。

本記事を最後までお読みくださりありがとうございました。

どなかたのお役に立てれば幸いです。