Bedrock APIを使用して画像から画像を作成してみました

2023.10.04

3ヶ月ほど前にオンラインイベントで初めてAmazon Bedrockのことを知り、それから試してみたいと思いました。ついに先週リリースされたので、私が最初の試みでやったことを書いたと聞いてください。

https://aws.amazon.com/jp/blogs/news/amazon-bedrock-is-now-generally-available-build-and-scale-generative-ai-applications-with-foundation-models/

最初にBedrock Workshopを参照したので、試してみたい場合は、非常に優れたステップバイステップガイドがあります

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

前提条件

SDK を使用して Bedrock にアクセスするには、次のポリシーを使用して Iam ロールを作成する必要があります IAM Policy

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

次のライブラリまたはパッケージのリストをインポートする必要があります

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

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

画像生成を容易にするため また, リポジトリから Utils ディレクトリを複製またはコピーする必要があります。 https://github.com/aws-samples/amazon-bedrock-workshop/tree/main/utils

ライブラリは venv にインストールすることを好みますが、どこにでもインストールできます

また、us-east-1 リージョンからの安定した拡散のためのアクセスを許可する必要があります。

Python スクリプト

コード内のBedrock Iam ARNを変更してください CLI で aws プロファイルが設定されている場合、 をそのままにしていない場合は置き換える必要があります 拡張子が .py のフォルダーにファイルを保存します 例:app.py

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

# 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"  # E.g. "us-east-1"
# os.environ["AWS_PROFILE"] = "<YOUR_PROFILE>"
os.environ["BEDROCK_ASSUME_ROLE"] = # E.g. "arn:aws:iam::xxxxxxxxxxxx:role/xxxxxx"  # E.g. 

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

print("1 if the image is generated using a prompt, 2 if the image is generated using an image and a prompt.")
choice = int(input("Enter Choice :"))
print(choice)

if (choice == 1):
    print("please enter the Prompt"),
    prompt = str(input())
    print("Please enter 3 negative Prompt eg:poorly rendered,poor background details,poorly drawn face")
    negative_prompts = []
    n = 3
    for i in range(0, n):
        # ele = [input(), str(input()),]
        ele = str(input())
        negative_prompts.append(ele)
    print(negative_prompts)
    style_preset = "photographic" 
    request = json.dumps({
        "text_prompts": (
            [{"text": prompt, "weight": 1.0}]
            + [{"text": negprompt, "weight": -1.0} for negprompt in negative_prompts]
        ),
        "cfg_scale": 5,
        "seed": 5450,
        "steps": 70,
        "style_preset": style_preset,
    })
    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

if (choice == 2):
    print("please enter the image file path"),
    image_path = str(input())
    print("please enter the Prompt"),
    change_prompt = str(input())
    print("Please enter 3 negative Prompt eg:poorly rendered,poor background details,poorly drawn face")
    negative_prompts = []
    n = 3
    for i in range(0, n):
        # ele = [input(), str(input()),]
        ele = str(input())
        negative_prompts.append(ele)
    print(negative_prompts)
    style_preset = "photographic" 

    def image_to_base64(img) -> str:
        """Convert a PIL Image or local image file path to a base64 string for Amazon Bedrock"""
        if isinstance(img, str):
            if os.path.isfile(img):
                print(f"Reading image from file: {img}")
                with open(img, "rb") as f:
                    return base64.b64encode(f.read()).decode("utf-8")
            else:
                raise FileNotFoundError(f"File {img} does not exist")
        elif isinstance(img, Image.Image):
            print("Converting PIL Image to base64 string")
            buffer = io.BytesIO()
            img.save(buffer, format="PNG")
            return base64.b64encode(buffer.getvalue()).decode("utf-8")
        else:
            raise ValueError(f"Expected str (filename) or PIL Image. Got {type(img)}")

    original_image = Image.open(image_path)
    image_1 = original_image.resize((512,512))
    init_image_b64 = image_to_base64(image_1)
    print(init_image_b64[:80] + "...")

    request = json.dumps({
        "text_prompts": (
            [{"text": change_prompt, "weight": 1.0}]
            + [{"text": negprompt, "weight": -1.0} for negprompt in negative_prompts]
        ),
        "cfg_scale": 10,
        "init_image": init_image_b64,
        "seed": 321,
        "start_schedule": 0.6,
        "steps": 50,
        "style_preset": style_preset,
    })
    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"])
    image_2_b64_str = response_body["artifacts"][0].get("base64")
    print(f"{image_2_b64_str[0:80]}...")

    image_2 = Image.open(io.BytesIO(base64.decodebytes(bytes(image_2_b64_str, "utf-8"))))
    image_2.save("data/image.png")

以下のコマンドを使用してコードを実行できます。

python app.py

独自の画像を指定するための 2 つの選択肢が求められますので、オプション 2 を選択してください 次に、画像をどのように変更したいかを通常の英語で書きます 次にネガティブプロンプトに画像を表示させたくない方法を書きます

終わりました:データフォルダー内で画像を見つけることができます

私の画像と私の画像出力

入力:

出力

結論

Bedrockにより、大規模な組織が提供する基礎となるモデルを非常に簡単に使用できるようになります。 さまざまな AWS サービスとのシームレスな統合を通じて API を制御、監視、保護できるのは素晴らしいことです。