メインコンテンツに移動
How to be a Developer

Amazon Bedrock を利用して、画像生成アプリケーションを開発してみた!

2024-02-01 | Author : 青木 克臣

はじめに

こんにちは!テクニカルインストラクターの青木です。

突然ですが、Amazon Bedrock というサービスをご存知でしょうか ? 2023 年の 9 月に一般提供された生成 AI アプリケーションの開発を支援するサービスです !

この記事では、Amazon Bedrock の初学者や興味がある方を対象に、Amazon Bedrock を用いた画像生成アプリケーション開発の流れを解説します。


X ポスト » | Facebook シェア » | はてブ »

ご注意

本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。

*ハンズオン記事およびソースコードにおける免責事項 »

builders.flash メールメンバー登録

毎月提供されるクラウドレシピのアップデート情報とともに、クレジットコードを受け取ることができます。 
今すぐ特典を受け取る »

1. 今回開発するアプリケーションについて

今回開発するアプリケーションでは、ユーザーの任意の入力に対して画像を出力します。これを実現するために、Amazon Bedrock、AWS Lambda、Amazon S3、Amazon API Gateway というサービスを利用し、最終的に以下のアーキテクチャを設計します。(このアーキテクチャの解説は、後ほど行います。)

今回のアプリケーションを構築すると、使用したサービスごとに料金が発生するので、builders.flash のメールメンバー登録 の上、クレジットコードの当選にチャレンジしていただくのも良いと思います。

Architecture diagram showing a serverless solution using Amazon API Gateway, AWS Lambda, Amazon Simple Storage Service (S3), and Amazon Bedrock, illustrating the flow from a user through API Gateway and Lambda to S3 and Bedrock.

2. 利用するサービスについて

まずは、今回利用するサービスについて簡単に解説します。

2-1. Amazon Bedrock とは

Amazon Bedrock は、API を通じて主要な基盤モデル (FM) を利用できるようにするフルマネージドサービスです。Amazon Bedrock によって、API を通じて AI21 Labs、Anthropic、Cohere、Meta、Stability AI、Amazon などの提供する様々な FM を簡単に利用することができます。

また、Amazon Bedrock はサーバーレスであるため、インフラストラクチャを管理する必要もありません ! 詳細は こちら をご参照ください。

2-2. AWS Lambda とは

AWS Lambda は、サーバーレスなコンピューティングサービスです。
Python や Java などのプログラミング言語のコードを書くだけで、簡単に関数を実行できます ! 詳細は  こちら をご参照ください。

2-3. Amazon API Gateway とは

Amazon API Gateway は、簡単に API の作成、公開、保守、モニタリング、保護が行えるサーバーレスなサービスです。
詳細は こちらをご参照ください。

2-4. Amazon Simple Storage Service (Amazon S3) とは

Amazon S3 は、可用性やスケーラビリティに優れたサーバーレスなオブジェクトストレージサービスです。
HTTPS リクエストによって、オブジェクトの保存や取得が簡単に行えます。詳細は  こちら をご参照ください。

2-5. AWS Identity and Access Management (IAM) とは

IAM は、AWS リソースへのアクセスを安全に管理するためのサービスで、認証・認可を担っているサービスです。
詳細は  こちら をご参照ください。

3. 開発の流れ

それでは早速、開発の流れを手順に沿って解説していきます !

3-1. Amazon Bedrock で、画像生成用の基盤モデルを利用可能にする

Screenshot of the Amazon Bedrock 'Request model access' interface from 2024, displaying a list of base models available to request access in AWS Bedrock, including providers, modalities, and EULA links.

まずは、Amazon Bedrock で、画像生成用の基盤モデルを利用可能にしましょう。

Amazon Bedrock では、選択されたリージョンによって使える基盤モデルが異なる場合があります。今回は、us-east-1 (バージニア北部) リージョンを選択して、リソースを構築していきます。

それでは、Amazon Bedrock のコンソール画面の「Model Access」から、今回利用する Stability AI 社の「SDXL 1.0」を選択し、アクセスリクエストを送ります。

その後、すぐに利用可能になります。なんと、Amazon Bedrock についての操作はこれだけです !!

また、Playgrounds セクションから、基盤モデルのテストが可能です。
このセクションで、画像生成をちょっと遊んでみる、なんてことが簡単にできます !

3-2. S3 バケットの作成

次に、生成した画像を保存するための S3 バケットを作成しましょう。

S3 のコンソール画面から、「バケットを作成」を押下し、汎用タイプのバケットを作成します。

バケット名を入力し、その他の項目はデフォルトのままで OK です !

3-3. Lambda 関数の作成

Screenshot of the AWS Lambda function creation interface in Japanese, displaying options for function name, runtime environment, architecture, and permissions.

次に、Lambda 関数を作成しましょう。今回作成する Lambda 関数では、以下のことを行います。

  • Amazon Bedrock によって用意された API にリクエストを送り、レスポンスとして、生成された画像を受け取る

  • S3 バケットに画像をアップロードする

  • その画像の署名付き URL を取得する

    • 署名付き URL とは、S3 内のオブジェクトへの時間制限付きのアクセス権を付与できる仕組みのことです。

    • この仕組みを用いることで、ポリシーを修正することなくオブジェクトの共有が可能です。

では、AWS Lambda のコンソール画面から、「関数の作成」より、Lambda 関数を作成しましょう。

一から作成」より、適当な関数名を入力し、ランタイムに「Python 3.12」を選択しました。

その他の設定項目は、デフォルトのままで OK です !

Screenshot of the AWS Lambda console displaying demo function role settings in Japanese, showing execution role details and permissions configuration.

次に、この Lambda 関数の IAM ロールを修正していきます。ここでは、大きく二つの権限を追加します。

  • Amazon Bedrock によって用意された 基盤モデルを実行するための権限

  • S3 バケットにオブジェクトを保存・署名付き URL を取得する権限

設定」タブの「アクセス権限」から、実行ロール名のリンクをクリックし、ロールの修正をしていきましょう。

Screenshot of the AWS IAM (Identity and Access Management) console in Japanese, displaying the Lambda Basic Execution Role policy details and interface elements.

許可」タブから、許可ポリシーのリンクをクリックします。

Screenshot of the AWS Identity and Access Management (IAM) policy permissions screen in Japanese, with the 'Edit' button highlighted. The interface displays permissions for CloudWatch Logs and related details.

編集」ボタンを押下し、ロールの修正を行います。

ポリシーの修正

新しいステートメントを追加」から、ポリシーを修正していきます。
以下の権限を追加します。

  • Amazon Bedrock によって用意された 基盤モデルを実行するための権限

    • Stability AI 社の SDXL 1.0 に対して、 bedrock: InvokeModel アクションを許可

  • S3 バケットにオブジェクトを保存・取得する権限

    • 作成した S3 バケットに対して、GetObject、PutObject アクションを許可

修正されたポリシー

最終的に、以下のようなポリシーになっていれば OK です !

json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "bedrock:InvokeModel"
            ],
            "Resource": [
                "arn:aws:bedrock:us-east-1::foundation-model/stability.stable-diffusion-xl-v1"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::{作成したバケット名}/*"
            ]
        }
    ]
}

Lambda 関数を記述

それでは、 Lambda 関数の中身を記述していきましょう ! 今回、AWS SDK for Python (Boto3) を使って、コードを記述します。最終的なコードは以下の通りです。それぞれのコードで何をやっているのか、コメントを添えておきましたので、ご確認ください。

python
# 必要なライブラリを読み込み
import json
import boto3
import base64
import uuid
from botocore.config import Config

bedrock_runtime = boto3.client('bedrock-runtime')
# 署名プロセスには、署名バージョン4(SigV4)を指定
my_config = Config(region_name="us-east-1", signature_version="s3v4")
s3 = boto3.client("s3", config=my_config)
bucket_name = '作成したS3バケット名'

def lambda_handler(event, context):
    # S3に保存するためのランダムなオブジェクト名を生成
    random_uuid = uuid.uuid4().hex 
    # 入力を受け取る
    input_text = event['input_text'] 
    
    # Amazon Bedrockで用意した基盤モデルへAPIリクエストし、画像を生成する
    response = bedrock_runtime.invoke_model(
        body='{"text_prompts": [{"text":"'+input_text+'"}]}',
        contentType='application/json',
        accept='image/png',
        modelId='stability.stable-diffusion-xl-v1'
    )
    
    s3_key = random_uuid + '.png'
    
    # 生成された画像をS3にアップロード    
    s3.upload_fileobj(response['body'], bucket_name, s3_key, ExtraArgs={'ContentType': 'image/png'})
    # 署名付きURLを取得
    presigned_url = s3.generate_presigned_url('get_object',Params={'Bucket': bucket_name,'Key': s3_key},ExpiresIn=3600) 
    
    # 署名付きURLを返す
    return {
        'statusCode': 200,
        'body': {'presigned_url': presigned_url}
    }

ドキュメント

Boto3 について、詳しくは こちら をご参照ください。
Amazon Bedrock の API の操作方法について、詳しくは こちら をご参照ください。

Lambda 関数のタイムアウト値を変更

Screenshot showing the AWS Lambda console's general settings edit screen in Japanese language interface, highlighting the edit button.

次に、Lambda 関数のタイムアウト値を変更しましょう。

Lambda 関数のデフォルトのタイムアウト制限は 3 秒に設定されており、 実際の処理に 3 秒以上時間がかかってしまう場合、エラーが発生してしまいます。

設定」タブの「一般設定」の「編集」ボタンを押下し、タイムアウト値を長めに変更しましょう。今回は 15 分に変更しました。

Screenshot of the AWS Lambda console showing Python code in the code editor. The 'Test' button is highlighted, and a lambda_handler function is visible in the script, demonstrating code that invokes a Bedrock runtime model and uploads results to Amazon S3. The interface is displayed in Japanese.

それでは、この関数をテストしてみましょう。

Test」ボタンを押下してください。

Screenshot of the AWS Lambda test event setup screen in Japanese, showing configuration options such as event name, sharing settings, template options, and an example JSON event with input_text field.

テストイベントを設定します。

適当なイベント名を入力し、イベント JSON を修正します。

今回、 input_text というパラメータを受け付けているので、イベント JSON の修正が必要です。こちらのように設定し、「保存」ボタンを押下してください。

関数を手動実行

「Test」ボタンを押下し、関数を手動実行してみましょう ! すると、関数のレスポンス結果として、以下のように S3 の署名付き URL が返ってくることが確認できました。

json
{
  "statusCode": 200,
  "body": {
    "presigned_url": "https://作成したS3バケット名.s3.amazonaws.com/951daf~.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASsaf~&X-Amz-Date=20240~&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQ2Bu~&X-Amz-Signature=a9~"
  }
}

ブラウザで確認

この URL をコピぺし、ブラウザで確認してみましょう !

このように、画像が生成されているのが確認できました !! 🎉
実際に、該当の S3 バケットを見ても、オブジェクトが保存されていることが確認できるかと思います。

A watercolor illustration of a tabby cat with green eyes, set against a soft pink and blue abstract background.

3-4. Amazon API Gateway で API を作成

Screenshot of the AWS API Gateway interface for creating a REST API, displayed in Japanese. The interface shows options for creating a new API, cloning an existing API, importing an API, or using a sample API, as well as fields for API name, description, and endpoint type selection.

では、先ほど作成した Lambda 関数と Amazon API Gateway を組み合わせて、API を作成しましょう。

Amazon API Gateway のコンソール画面から、「API を作成」ボタンを押下し、REST API の「構築」ボタンを押下してください。

新しい API」から、API 名を入力し、「API を作成」ボタンを押下しましょう。

Screenshot of the AWS API Gateway console in Japanese, showing the interface for creating a new method within a resource, with the 'Create Method' button highlighted.

API の作成が完了しました !

次に、「メソッドを作成」ボタンを押下し、POST メソッドによって渡ってくるデータ (input_text) を Lambda 関数に渡す処理を実装します。

Screenshot of the AWS API Gateway interface in Japanese, showing the creation of a method with "POST" selected and integration type set to "Lambda Function."

メソッドタイプで「POST」を選択し、統合タイプに「Lambda 関数」を選択しましょう。そして、Lambda 関数に、先ほど作成したLambda 関数を指定してください。

その後、「メソッドを作成」ボタンを押下し、メソッドを作成しましょう。

Screenshot of the AWS API Gateway Deploy API Stage dialog box in Japanese, showing options to select or create a new stage for API deployment. The interface includes stage selection, stage name input, a description field, and deployment instructions.

メソッドの作成が完了しました !

次に、「API をデプロイ」ボタンを押下し、API のデプロイを行いましょう。
New Stage」を選択し、適当なステージ名を入力し、「デプロイ」ボタンを押下します。

Screenshot of the AWS API Gateway console showing the details for the 'dev' stage in Japanese, including the invoke URL and deployment information.

これで、デプロイが完了しました !

URL を呼び出す」に表示の URL が API のエンドポイントです。

Screenshot of AWS API Gateway console in Japanese, highlighting the 'Enable CORS' button for a demo API resource configuration.

フロントエンドからこの API にリクエストを送ることで、画像の生成を行いますが、一点注意点があります。それが、クロスオリジンリソース共有 (CORS) の設定です。CORS について、詳しくは こちら をご参照ください。

この設定に対応するために、サイドバーの「リソース」から、「CORS を有効にする」ボタンを押下しましょう。

Screenshot of the AWS API Gateway CORS (Cross-Origin Resource Sharing) configuration page with the interface displayed in Japanese. The image shows settings for allowed methods, headers, and origins, including a POST method and localhost origin.

その後、Access-Control-Allow-Methods の「POST」にチェックし、Access-Control-Allow-Origin にフロントエンド側のオリジンを入力します。

最後に、「保存」ボタンを押下しましょう。

Screenshot of the AWS API Gateway interface in Japanese, highlighting the 'Deploy API' button for deploying an API, with resource and method details displayed.

保存が完了したら、再度 API のデプロイを行い、変更を反映させましょう。

これで、フロントエンドから API にリクエストを送ることができるようになります。

一点注意点ですが、Amazon API Gateway の REST API のタイムアウト値の上限が 29 秒 (2023 年 12 月現在) なので、Amazon Bedrock の処理に 29 秒以上の時間がかかる場合は、別途対応が必要です。

3-5. フロントエンド作成

今回、以下のような簡易的なフロントエンドを用意しました。ここではフロントエンドについて詳しい解説はしませんが、上記で用意した API にリクエストを送り、返ってきた画像を表示しています。

以下のような画像生成アプリケーションが完成しました !!

作成した API を試す

フロントエンドを用意せずに、作成した API を試したい方は、コマンドラインインターフェイス (CLI) から試すこともできます。 CLI 上で、以下の curl コマンドを実行すると、S3 の署名付き URL が返ってくるのを確認できます。

bash
$ curl -X POST {作成した API のエンドポイント} -H 'Content-Type: application/json' -d '{"input_text":"an image of cat"}'

オブジェクトをローカルにダウンロード

以下の curl コマンドで、返ってきた署名付き URL からオブジェクトをローカルにダウンロードできます。

bash
$ curl -O "{レスポンスの署名付きURL}"

4. まとめ

今回、Amazon Bedrock を用いて画像生成のアプリケーションを開発し、その流れを解説しました。

具体的には、以下のようなアーキテクチャで、Amazon Bedrock によって画像生成用の API を有効にし、Lambda 関数が Amazon Bedrock の用意した API にリクエストを送り、生成された画像を S3 に保存します。

さらに、Lambda 関数は、S3 から署名付き URL を受け取ります。

最後に、Lambda 関数と Amazon API Gateway を組み合わせることでパブリックな API を用意し、フロントエンドで API リクエストを送れるようにしました。

Amazon Bedrock を用いることで、画面をぽちぽち押すだけで画像生成用の API が用意でき、そのおかげで機械学習に詳しくなくても、画像生成の部分を作り込まずにこのようなアプリケーションを開発できました ! また、画像生成だけでなく、チャットやテキスト要約などの API も今回と同じように簡単に使えます。

ご興味のある方は、ぜひ触ってみてください!

なお、Amazon Bedrock の他に生成 AI の活用するサービスとして Amazon CodeWhisperer の記事「Amazon CodeWhisperer を使ってみよう!」もありますので、よろしければ読んでみてください !

Architecture diagram showing a serverless solution using Amazon API Gateway, AWS Lambda, Amazon Simple Storage Service (S3), and Amazon Bedrock, illustrating the flow from a user through API Gateway and Lambda to S3 and Bedrock.

筆者プロフィール

青木 克臣
アマゾン ウェブ サービス ジャパン合同会社
AWS トレーニングサービス本部 テクニカルインストラクター

”分かりやすい”をモットーに、日々 AWS のトレーニングの登壇をしています。
趣味はフットサル、筋トレ、サウナで、推しのサウナはウェルビー栄 (名古屋) です。
Portrait of an AWS employee standing with arms crossed, smiling, and wearing an AWS shirt in a modern office environment.