Pythonコードで画像生成。AWSのAIモデル Amazon Nova Canvas

個人利用でも安く使えそうな Nova Lite, Nova Micro が登場したので遊んでみた。
今度は、画像生成ができる Nova Canvas で遊ぶ。Kagoyaの仮想サーバー(Ubuntu 22.04)でPythonコードを書く。

## Amazon Nova モデル概要と準備
UbuntuでpythonのAWSモジュール(boto3)を実行するにはIAMユーザーの設定とAWS SDKのインストールが必要です。準備の手順は[AWSの生成AIモデル Amazon Nova Lite で遊んでみる](https://qiita.com/1Kano/items/49bc8965fddb050babc0 "Qiita")に記載してあります。

## 画像を生成して遊ぶ

画像生成リクエストで指定できるパラメーター
- textToImageParams
  - text: どんな画像にするのか説明したテキスト(1~1,024文字)
  - negativeText: 画像に含めない内容を説明するテキスト(1~1,024文字)
- imageGenerationConfig
  - numberOfImages: 生成する画像の数(1~最大5)
  - width, heiht: 画像のサイズ(標準1,024)
  - quality: 画像の品質("standard" または "premium")
  - cfgScale: どの程度プロンプトに従って画像生成するか(1.1~最大10)
  - seed: 生成プロセスの初期ノイズ(最小0~最大858,993,459)

pythonコード

``` bedrock_image.py
import sys
import boto3
import json
from botocore.exceptions import ClientError
import base64
from PIL import Image

# Bedrock runtime client の作成, Nova Lite モデルを使う。バージニア北部リージョンで利用可能
bedrockRuntime = boto3.client("bedrock-runtime", region_name="us-east-1")
MODEL_ID = "amazon.nova-canvas-v1:0"

def runjob():
    # プロンプト入力例
    if len(sys.argv) < 2:
        print("書式$ python3 bedrock_image.py 'ここに生成したい画像を説明する'")
        sys.exit(1)
    else:
        prompt = sys.argv[1]
        print( prompt )

    # モデルのネイティブ構造を使ってリクエストする
    body_json = json.dumps({
        "taskType": "TEXT_IMAGE",
        "textToImageParams": {
            "text": prompt
        },
        "imageGenerationConfig": {
            "numberOfImages": 1,
            "height": 1024,
            "width": 1024,
            "cfgScale": 8.0,
            "seed": 0
        }
    })

    # リクエスト実行
    try:
        print("invoke実行")
        response = bedrockRuntime.invoke_model(
            body = body_json,
            modelId = MODEL_ID,
            accept= "application/json",
            contentType = "application/json"
        )
        # 画像取得
        print("画像処理")
        response_body = json.loads( response.get("body").read() )
        base64_image = response_body.get("images")[0]
        base64_bytes = base64_image.encode('ascii')
        image_bytes = base64.b64decode(base64_bytes)

        # generated_text の取得と表示
        with open("generatedImage.png", 'wb') as file:
            file.write( image_bytes )
        print(f"画像を保存しました")

    except (ClientError, Exception) as e:
        print(f"ERROR: 実行できません '{MODEL_ID}', Reason: {e}")
        exit(1)

if __name__ == "__main__":
    runjob()
```

コードのアップデートはgithubに置く
https://github.com/IchiroKano/aws-nova

### 実行してみる
まずはシンプルに「ネコの写真」を描画してみよう

```
$ python3 bedrock_image.py ネコの写真
画像を保存しました

$ ls -la
-rw-rw-r--  1 kano kano 1436240 Jan  2 10:22 generatedImage.png
```

しまった。GUIの無いSSH接続のLinuxだった。
ApacheのHTMLフォルダにコピーしてブラウザで表示することにした。
` $ cp generatedImage.png /var/www/html/img/cat.png `

Nova Canvas が生成した画像がこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/1ebc921b-6a57-9abc-a9bb-09e2bbfb86ef.png)

画像を1枚生成すると約6.4円かかります（=\\$0.04 x 160円/$）画質はすごく綺麗。
たくさん画像生成してみたいけど１枚約6円かかるのか。なんか色々とアプリを作って遊べそうだけど１日に10枚も画像を作ると30日で1,800円か。趣味のお小遣いでは課金が怖いな、コードは無効化しておこうかな。

ちなみに Windows の Copilotで同じく「ネコの写真」を作ったのがこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/f97883ff-6126-f329-860c-39065afe9138.png)

## まとめ
Amazon Bedrock の生成AIモデル Nova Lite を使えるようになっていれば、Nova Canvas モデルで画像を生成するまでに1時間かからなかった。課金が怖いので予算アラートも設定した。