Bedrock Night in 大阪(JAWS-UG AI/ML×大阪×東京支部コラボ)- 画像生成大喜利枠の話
2024年7月30日に開催された JAWS-UG AI/ML と JAWS-UG 大阪支部 そして JAWS-UG 東京支部のコラボによる「Bedrock Night in 大阪」が開催されました。
その中でトレノケート山下さんが企画された画像生成大喜利にオオギリストとして参加しました。
その際の生成AIの利用方法や、プロンプトの与え方、生成結果を残しておきます。
先に結果から
結果は、私と JAWS-UG 神戸支部の運営スタッフであるヤマダ氏( @benkyo_ganbaman )が優勝ということになり、結果的にイベント前に私がツイートしていた内容がフラグになってしまいました。
Bedrock Night in 大阪(JAWS-UG AI/ML×大阪×東京支部コラボ)に向けて出勤。
— kazzpapa3 (@kazzpapa3) July 30, 2024
先週、昨日と少し真面目な登壇をしたから「Bedrockでおもしろ画像生成!大喜利大会」は能天気に楽しもう。
ただ大喜利枠でJAWSUG神戸メンバーのヤマダ氏(@benkyo_ganbaman)が出るので、彼には負けられない。#jawsug_aiml
今回の大喜利大会の優勝はヤマダさんでした!
— 🍎Yuki Ogawa🍎 (@_YukiOgawa) July 30, 2024
画像はカジュアル面談です!#jawsug_aiml #jawsugosaka #jawsug pic.twitter.com/NtpxnwoEsT
今回のライバルたち
笑いに貪欲な5名の回答者たち。
ちょうど真ん中、クイズダービーでいう「はらたいら」の位置が私です。
#jawsug_aiml #jawsugosaka #jawsug 大喜利(なお回答者の顔は) pic.twitter.com/PhuTVMX9HR
— SUZUKI Masaki@クラウドエンジニア (@makky12) July 30, 2024
やっていたことの記録
今回の企画が発表されてすぐに申し込みを行い、早々に参加が確定していたので、ある程度の想定をもって準備と練習をしておきたいと考えていました。
DeepL などでプロンプト文章を翻訳しながら、Amazon Bedrock で用意されているプレイグラウンドを使った生成をしても良かったのですが、生成画像をいちいちダウンロードをしてから S3 バケットにアップロードし直す、とかが面倒だったので、AWS CLI というか bash が好きな私としてシェルスクリプトで用意しておき、何かあれば微調整できるようにしておこうと考えていました。
処理の概要
sequenceDiagram
bash/local->>Amazon Translate: プロンプト入力(日本語)
Amazon Translate-->>bash/local: 機械翻訳(英語)
bash/local->>bash/local: ファイル名の指定
bash/local->>bash/local: seed 値の指定
bash/local->>bash/local: 画像サイズの指定
bash/local->>bash/local: cfg_scale の値を指定
bash/local->>bash/local: 利用モデルの指定
alt Amazon Titan Image
bash/local->>bash/local: Amazon Titan Image に合わせたリクエストボディの組み立て
bash/local->>Amazon Bedrock: bedrock-runtime invoke-model サブコマンドの実行
Amazon Bedrock-->>bash/local: Amazon Bedrock による生成
bash/local->>bash/local: 生成結果のデコード、画像ファイル化
else Stable Diffusion
bash/local->>bash/local: Stable Diffusion に合わせたリクエストボディの組み立て
bash/local->>Amazon Bedrock: bedrock-runtime invoke-model サブコマンドの実行
Amazon Bedrock-->>bash/local: Amazon Bedrock による画像生成
bash/local->>bash/local: 生成結果のデコード、画像ファイル化
end
bash/local->>Amazon S3: s3 cp サブコマンドによるファイルアップロード
出来上がったシェルスクリプト
突貫で作成したので変数のスコープやエラーハンドリングの考慮などは一切なし。
実行ログの出力も一旦は iTerm2 の設定で記録するようにしたので、かなり雑なスクリプトだが、私自身が手元で実行するのでまあよしとした。作成時間は調査を含めて 1.5日 くらい。
なお、前提条件としてスクリプト2行目で選択しているリージョンで、Amazon Bedrock のモデルアクセスで Stability AI の SDXL 1.0 を有効化しておくこと。(ただし、画像の生成に Titan Image Generator G1 しか使用しない場合は不要)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
|
AWS が用意する開発支援
プレイグラウンド環境でなんらかの画像生成をやってみたのちに、「サンプルをロード」ボタンの右側の三点リーダーを縦にしたようなアイコンをクリックすると、いくつかのメニューが表示されます。
その中から「API リクエストを表示」を選択するとポップアップ画面で AWS CLI で実行した場合に投入するコマンドが表示されます。
このコマンドを確認することにより、リクエストボディに何を含めれば良いかが容易に理解できるため、今回のスクリプト作成では大いに役立ちました。
また、サンプルで output のファイルとして invoke-model-output.txt を指定しているように、生成画像が画像ファイルそのままとしてダウンロードできるわけではなく、いくつかの返却値のうちの 1 value として base64 エンコードされた文字列として併記されていること、その返却される JSON の形式が amazon.titan-image-generator-v1 と stability.stable-diffusion-xl-v1 で異なることや、そもそものリクエストボディに含めるパラメータが若干異なることを把握しました。
それらを受けて、前述のスクリプト内での処理のように選択されたモデルに応じたリクエストボディの組み立て〜実行結果の JSON ファイルからの取り出し部分の処理を分ける目的の個別のファンクション化につながっています。
現地で気づいた大きな失敗
当日の 18時頃に、山下さんから、各オオギリストごとに用意したスイッチロール先の IAM ロール ARN、およびアップロード用の S3 バケットの案内がありました。
そこまで私がテストしていた内容でも直接 S3 バケットへのアップロードをするプログラムにしていたため、アップロード先の変更と assume-role する処理を含めるだけの軽微な修正で大喜利枠へ登壇しました。
その後、山下さんからとても意地悪な設問を次々投げられたのですが、今の処理だと、プロンプト入力 → 機械翻訳による英語化 → 利用するモデルの選択 → 選択されたモデルに応じたリクエストボディ組み立て → 画像生成 → S3 バケットへのアップロード、と一気通貫でやるスクリプトとなっているため、生成された画像を「私が見ていないままアップロードすることになる」という重大な事実に気づき、スクリプトの 69〜70行目、および 108〜109行目をコメントアウトし、ローカルで画像を確認してから、ブラウザで開いた S3 コンソールへ手動でアップロードする手順に変更しました。
その他、立ちはだかる壁
特に Amazon Titan を利用したときに特に多かった印象だが、投入するプロンプトで望ましくない文章やニュアンスが含まれていた時に、「Our filters automatically flagged this prompt because it may conflict our AUP or AWS Responsible AI Policy. Please adjust your text prompt to submit a new request.」として reject されてしまうケースが多かった。(出題者の山下さんが選定したお題が、直感ではネガティブ寄りな発想になりがちなキーワードだったのはこれへの誘導だったのか?だとしたら策士だわ)
クイズダービーでの竹下景子席に座っていたライバルの @Riz3f7 さんもこの部分でなかなか苦戦したようで、私のスクリプトでは bedrock-runtime invoke-model サブコマンドがエラーとなる想定をしていないこと、bedrock-runtime invoke-model がエラーとなっても output ファイル自体は発生エラーなどを含めた JSON の返却が行われるため、中に含まれる画像情報が格納されるべき value をデコードすると 0 バイトの画像が生成されてしまい、そのまま S3 のアップロードが行われて、空の画像を表示させてしまう原因も作ってしまったのは反省。
個人的に良かったと思う点
個人的には、1.5日程度の時間で一気通貫で行える処理を作れる体験を得られたので、Amazon Bedrock がうまく抽象化してさまざまなモデルを利用できるようにしていることを理解できた。
また、ログを後から確認できることで、投入したプロンプトやパラメータを容易に追跡できるため、意図した生成にならなかった理由を探るのにも役立つと感じた。
後でログと生成結果を確認してみたところ、今回は 日本語 → 英語 を Amazon Translate に自動翻訳していることと、その翻訳文章自体を確認するステップを挟めていないことで、英語文面ではどのようなプロンプトを与えていることになっているのかをノールックだったことも難しかった要因と思う。
生成された画像たち
iTerm2 でのログからどのような日本語を入力したのか、どのモデルを選択し、どのようなパラメータを投入したのかの後追いが容易だったので以下に晒す。
その1(お題は 炎上商法/出力に失敗)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
その2(お題は Amazon Web Services)
1 2 3 4 5 6 7 8 9 10 11 12 |
|
日本語プロンプトの想定:「アマゾン」はそのまま、Web=蜘蛛の巣を連想、Services をお店的なイメージで書いたと思う。
その3(お題は Amazon Web Services)
1 2 3 4 5 6 7 8 9 10 11 12 |
|
その4(お題は Amazon Web Services)
1 2 3 4 5 6 7 8 9 10 11 12 |
|
その5(お題は 裏口入学)
1 2 3 4 5 6 7 8 9 10 11 12 |
|
その6(お題は 隙間バイト)
1 2 3 4 5 6 7 8 9 10 11 |
|
その7(お題は 山崎春のパンまつり)
1 2 3 4 5 6 7 8 9 10 11 12 |
|
その8(お題は 独身貴族)
1 2 3 4 5 6 7 8 9 10 11 12 |
|
日本語プロンプトの想定:「ハーフパンツ姿」で髭男爵のひぐちくんのような出で立ちにしたかった想定
その9(お題は 矢場とん)
1 2 3 4 5 6 7 8 9 10 11 12 |
|
日本語プロンプトの想定:やばい=矢場い、という語源から、矢場=弓道、みたいな感じにしたかった想定
感想
参加してみて、Amazon Bedrock を用いた画像生成が「出来はともかく」容易に行えることを理解できて学びになった。
やはり、こういった祭りイベントは参加して実際にヒリつくような思いをすることで、お題に対してプロンプトの検討を即応する難しさと、自分の実装上後から振り返れる経験も得られて楽しかったし有益だった。
ただ、お題の難易度が極悪・意地悪だったと(個人的に)思うので、もう少しマイルドにしたお題で JAWS-UG 神戸支部でのお楽しみコンテンツにしてもいいかもなと思った。