Amazon Titan Image Generator G1 を AWS Lambda から試してみた

こんにちは、SCSK 浦野です。

1月があっという間に過ぎてしまい、すでに2月の中旬であることに焦りを覚えている筆者です。

昨年は自分の中では生成AIに驚かされ続けた1年でした。興味がある分野でもありましたので、自宅でRVCでボイスチェンジをしてみたり、Stable Diffusion で絵を生成してみたりしていましたが、ここのところはあまり触れていませんでした。
そんななか、AWSのブログを見ていたところ「Amazon Bedrock を利用して、画像生成アプリケーションを開発してみた!」という記事を見つけました。
昨年 Amazon Titan Image Generator G1 が発表されておりましたが、こちらも触れられていなかったので、モデルを Amazon Titan Image Generator G1 に変更して試してみました。その際に少し追加の手順が必要になりましたので、共有できればと思います。

前提など

手順は「Amazon Bedrock を利用して、画像生成アプリケーションを開発してみた!」を参考に実施致します。
但し、Amazon Titan Image Generator G1 を使ってみたいので、モデルの選択で Amazon Titan Image Generator G1 を選択、呼び出し等はそれに合わせて変更します。

Amazon BedrockでTitan Image Generator G1を利用可能にする

  1. Amazon Bedrock を開き、左ペインの「モデルアクセス」をクリック、右上の「モデルのアクセスを管理」をクリックします。
  2. 表示された画面でTitan Image Generator G1のチェックボックスにチェックを入れて、「変更を保存」をクリックします。
    変更後、アクセスのステータスが「アクセスが付与されました」となっていることを確認します。 

S3バケット作成

生成された画像を保存するバケットを作成します。

  1. コンソールでS3に移動し、「バケットを作成」から適当な名前を付けえたバケットを作成します。バケットの設定は全てデフォルトで作成します。 

Lambda関数作成

  1. コンソールでLambdaに移動し、 「関数の作成」をクリック
  2. 適当な関数名を指定、ランタイムで「Python 3.12」を選択し、その他はデフォルトで「関数の作成」をクリックします。
  3. コードを書きたいところですが、先に Lambda の IAM ロールを変更します。
    この際に Titan Image Generator G1を利用するので、Resource の部分でamazon.titan-image-generator-v1を指定します。 
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "bedrock:InvokeModel"
            ],
            "Resource": [
                "arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-image-generator-v1"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::{作成したバケット名}/*"
            ]
        }
    ]
}

 

  1. コードを記述します。Titan Image Generator G1を利用するため、Titan Image Generator G1に合わせた設定で記述します。
  2. コードを保存後に、「設定」からタイムアウトを3分程度に変更します。(筆者が試した範囲では1枚生成されるのに30秒前後かかっていました)
import json
import boto3
from io import BytesIO
import base64
from PIL import Image
from botocore.config import Config
import uuid

def lambda_handler(event, context):
    bedrock_runtime = boto3.client('bedrock-runtime')
    my_config = Config(region_name="us-east-1", signature_version="s3v4")
    s3 = boto3.client("s3", config=my_config)
    bucket_name = '{作成したバケット名}'

    text = event['input_text']
    image_num = 1

    body = json.dumps({
        "taskType": "TEXT_IMAGE",
        "textToImageParams": {
            "text": text,
        },
        "imageGenerationConfig": {
            "numberOfImages": image_num,
            "quality": "premium",
            "height": 768,
            "width": 1280,
            "cfgScale": 7.5,
            "seed": 0
        }
    })

    response = bedrock_runtime.invoke_model(
        body=body,
        modelId="amazon.titan-image-generator-v1",
        accept="application/json",
        contentType="application/json"
    )
    
    response_body = json.loads(response['body'].read())
    images = [Image.open(BytesIO(base64.b64decode(base64_image))) for base64_image in response_body.get("images")]

    presigned_urls = []
    for img in images: 
        img_data = BytesIO()
        img.save(img_data, format='PNG') 
        img_data.seek(0)
        random_uuid = uuid.uuid4().hex
        s3_key = f"{random_uuid}.png"
        
        s3.upload_fileobj(img_data, bucket_name, s3_key, ExtraArgs={'ContentType': 'image/png'})
        
        presigned_url = s3.generate_presigned_url(
            'get_object',
            Params={'Bucket': bucket_name, 'Key': s3_key},
            ExpiresIn=3600
        )
        presigned_urls.append(presigned_url)
    
    return {
        'statusCode': 200,
        'body': json.dumps({'presigned_urls': presigned_urls})
    }

Lambda Layerの登録

記載したコードでは画像処理ライブラリのPillowを利用していますが、デフォルトのランタイムには含まれていない為、Lambda Layerの登録を行う必要があります。
python 3.12の環境でライブラリをインストールし(Cloud9等で環境を準備できます)、zipファイルに圧縮してレイヤーにアップロードして登録後、Lambda関数側の「レイヤー」から登録したレイヤーを追加してください。
 

テスト実行

  1. Lambdaの画面にある「Test」ボタンを押し、テストイベントを設定します。イベントJSONには、以下のような形で生成を希望するテキストを記述します。「保存」を押して保存後に、「テスト」を押すと生成が実行されます。
{
  "input_text": "Mt Fuji"
}

実行し、成功するとレスポンスとしてURLが返されますので、ブラウザにURLを入れると生成された画像を見ることができました。

参考元では、APIの設定やフロントの作成もありますが、同様の手順で実装できますので本記事ではスキップさせて頂きます。

タイトルとURLをコピーしました