Imagen を Cloud Run にデプロイする

Imagen を Cloud Run にデプロイする

この Codelab について

subject最終更新: 10月 24, 2024
account_circle作成者: Laurie White

1. この Codelab について

最終更新日: 2024 年 10 月 11 日

脚本: ローリー ホワイト

画像生成

正直なところ、大規模言語モデル(LLM)による画像生成は楽しいものです。もちろん、プロンプトから画像を生成するビジネス アプリケーションはたくさんあります。カスタマイズされた広告から魅力的なプレゼンテーションまで、さまざまな用途があります。(Google Cloud ウェブサイトには、Creative エージェントを使用する企業の具体的なユースケースが多数掲載されています)。それでも、「緑色の犬が草原で楽しそうにしている」画像をリクエストすると、面白い結果が返ってくることがあります。

画像生成に興味をお持ちなのは、仕事のためか、趣味のためか(またはその両方か)、画像生成プログラムを使用することと、ウェブ アプリケーションにデプロイすることの間には、いくつかの課題があります。このラボでは、これらの課題を克服する方法について学習します。

作成するアプリの概要

この Codelab では、テキスト プロンプトを受け取って、そのプロンプトを使用して生成された画像を含むウェブページを返すアプリを作成します。

学習内容

このラボでは、次のことを学習します。

  • Google Imagen を使用してノートブック環境でテキスト プロンプトから画像を作成する方法
  • Imagen コードをノートブックからウェブアプリに移行する際の難しさ
  • Imagen を使用して画像を生成する Cloud Run アプリケーションをデプロイする方法
  • Imagen の画像を HTML に含める方法

この Codelab では、Imagen とデプロイに焦点を当てます。関連のない概念やコードブロックについては詳しく触れず、コードはコピーして貼るだけの状態で提供されています。

必要なもの

この Codelab の完全なコードは、https://github.com/Annie29/imagen-deployment で入手できます。

2. API を有効にする

この Codelab で使用するプロジェクトを選択します。作業が完了したら、すべての作業を簡単に削除できるように、新しいプロジェクトを作成することをおすすめします。

Imagen を使用するには、いくつかの API を有効にする必要があります。

  1. Google Cloud Console に移動します。
  2. Vertex AI ダッシュボードに移動します。
  3. [すべての推奨 API を有効化] を選択します。

a8f336f7380a9eab.png

3. Google Imagen の概要(任意)

Imagen に精通している場合は、このセクションをスキップできます。

Imagen を使用するウェブアプリを作成する前に、Imagen でできることを確認しておきましょう。幸い、シンプルな Imagen コードを実行するノートブックがいくつかあるので、まずはそのうちの 1 つから始めましょう。

  1. ノートブック(https://github.com/GoogleCloudPlatform/generative-ai/blob/main/vision/getting-started/image_generation.ipynb)に移動します。
  2. [Colab で開く] を選択して、Google のノートブック サーバーでノートブックを開きます。
  3. [ファイル] -> [ドライブにコピーを保存] を選択するか、ページ上部の [ドライブにコピー] をクリックして、このノートブックの独自のコピーを作成します。
  4. 元のコピーを閉じます(間違ったコピーで作業しないようにするため)。
  5. 右上の [接続] ボタンをクリックしてランタイムに接続する必要があります。2afdc8fa660a89bd.png
  6. ノートブックの各セルを順に確認します。
  7. セルを実行するには、セルの左側にある [] または矢印をクリックするか、[ランタイム] メニューの [選択内容を実行] オプション(またはそのショートカット dfec032ef6c31296.png)を使用します。
  8. 現在のランタイムを再起動すると、システムがクラッシュしたというメッセージが表示されます。慌てる必要はありません。これは正常な動作です。
  9. ノートブック環境を認証する必要があります。
  10. コードの右側のボックスにプロジェクト ID(名前ではない)とロケーション(ロケーションを設定していない場合は us-central1 を使用)を入力すると、Colab によってコードに挿入されます。
  11. [画像を生成] に進むと、Imagen の機能を確認できます。プロンプトを変更してセルを再実行すると、さまざまな画像を生成できます。
  12. ここまでで、Imagen がノートブックから画像を作成する方法を理解できたはずです。画像パラメータの詳細については、このノートブックを完了するか、後で確認してください。

4. 画像を表示するウェブ アプリケーションの作成を開始する

Cloud Run で Flask フレームワークを使用して Python でアプリをビルドします。

Python Flask アプリは、次のようにフォルダに設定されます。

app-folder
    templates
        template.html
        (etc.)
        anothertemplate.html
    main.py
    requirements.txt

テンプレートは HTML を含むファイルです。通常、プログラムが生成したテキストを挿入する名前付きプレースホルダが含まれています。main.py はウェブサーバー アプリ自体で、requirements.txtmain.py が使用するすべての標準以外のライブラリのリストです。

アプリには 2 つのページがあります。1 つ目のページはプロンプトを取得するためのページで、2 つ目のページは画像を表示し、ユーザーが別のプロンプトを入力できるようにするページです。

まず、プロジェクト フレームワークを作成します。

ファイル構造の作成

この Codelab では、プロジェクトが imageapp フォルダにあることを前提としています。別の名前を使用する場合は、必要に応じてコマンドを更新してください。

画面の右上にあるプロンプト アイコンを選択して Cloud Shell に入ります。

28135f700c5b12b0.png

シェル ウィンドウの上部にある矢印を使用して、シェルを新しいタブに移動すると、作業スペースを広げることができます。

310422ac131813e1.png

Cloud Shell のホーム ディレクトリで imageapp フォルダを作成し、そのフォルダに移動して templates フォルダを作成します。これは、コマンドラインまたは Cloud Shell エディタから行えます。

テンプレートを作成する

アプリには 2 つのページがあります。1 つ目のページ(home.html)はプロンプトを取得し、2 つ目のページ(display.html)は画像を表示してユーザーが別のプロンプトを入力できるようにします。

Cloud Shell エディタまたは任意の Linux エディタを使用して、2 つのテンプレートを作成します。imageapp/templates フォルダ内に、ユーザーに表示する最初のページ home.html を作成します。変数 prompt を使用して、ユーザーが入力した説明を返します。

templates/home.html

<!DOCTYPE html>
<html>
   <head>
       <title>Let's draw a picture</title>
   </head>
   <body>
       <h1>Let's draw a picture</h1>
       <form  action="/" method="post" >
           <input type="text" id="prompt" name="prompt">
           <input type="submit" value="Send">
       </form>
   </body>
</html>

次に、画像を表示する display.html を作成します。画像の場所は image_url になります。

templates/display.html

<!DOCTYPE html>
<html>
   <head>
       <title>Let's draw a picture</title>
   </head>
   <body>
       <h1>Let's draw a picture</h1>

       <div>
           <form  action="/" method="post" >
               <input type="text" id="prompt" name="prompt">
               <input type="submit" value="Send">
           </form>

           <p></p>
       </div>

       <div id="picture">
           <img id="pict" name="pict" alt="The created image" src="{{image_uri}}" style="width:100%;">
       </div>

   </body>
</html>

5. コードの開始

プログラムに必要なすべてのライブラリが利用できるように、requirements.txt ファイルを作成する必要があります。現時点では、requirements.txt ファイルに flask を含めるだけです。

main.py ファイルには、ウェブリクエストを処理するコードが含まれています。処理する必要があるリクエストは、ホームページの GET リクエストと、生成する画像を記述するフォームを送信する POST リクエストの 2 つだけです。

Cloud Shell エディタまたは任意の Linux エディタを使用して、imageapp フォルダに main.py ファイルを作成します。以下の骨組みから始めます。

main.py

import flask

app = flask.Flask(__name__)

@app.route("/", methods=["GET"])
def home_page():
   
return flask.render_template("home.html")

@app.route("/", methods=["POST"])
def display_image():
   
# Code to get the prompt (called prompt) from the submitted form
   
# Code to generate the image
   
# Code to create a URL for the image (called image_url)

   
return flask.render_template("display.html", prompt=prompt, image_url=image_url)

# Initialize the web server app when the code locally (Cloud Run handles it in that environment)
if __name__ == "__main__":
   
app.run(debug=True, host="0.0.0.0", port=8080)

実際、これがアプリのほぼ全体です。display_image には、Python コードで補足する必要があるコメントが 3 つありますが、それだけです。

不足している部分を埋めていきましょう。Flask を使用すると、プロンプトを簡単に取得できます。以下のように、コメントの後に行を追加します。

# Code to get the prompt (called prompt) from the submitted form
prompt
= flask.request.form["prompt"]

アプリをすぐにテストする場合は、display_imagereturn ステートメントの前に行を追加して、image_url に値(画像を指す有効な URL)を指定します。

例: image_url="<your url here>"

プログラムは、Cloud Shell からローカルで実行できます(python main.py コマンドを使用)。画面の右上にある [ポート 8080 でプレビュー] を使用してプレビューできます。

a80b4abd28cb7eed.png

現在のプログラムでは、指定した URL の画像が常に表示されます。次に、その値をアプリから取得する方法を見てみましょう。image_url に静的値を指定する行は削除してください。

6. イメージを作成する

Google Cloud には、Vertex AI の生成 AI 用の Python API があります。これを使用するには、プログラムの上部近くに、他のインポートとともにこれをインポートする行を追加する必要があります。

from vertexai.vision_models import ImageGenerationModel

vertexairequirements.txt ファイルに含めます。

ImageGenerationModel のドキュメントで、使用方法を確認できます。モデルを作成し、プロンプトからモデルから画像を生成します。2 番目のステップのコード(イメージを作成して response に保存するコード)を main.py に追加します。

# Code to generate the image
model = ImageGenerationModel.from_pretrained("imagegeneration@006")
response = model.generate_images(prompt=prompt)[0]

generate_images に送信されたパラメータに応じて、一度に最大 4 つの画像を作成できるため、この例のように画像が 1 つしか返されない場合でも、返される値は GeneratedImage のリストになります。

次に、画像を WWW ページに表示する必要があります。GeneratedImage には画像を show するメソッドがありますが、ノートブック環境でのみ機能します。ただし、画像を保存する方法はあります。画像は保存され、テンプレートのレンダリング時に保存された画像の URL が送信されます。

これは少し複雑で、さまざまな方法があります。簡単な方法の一つを、手順を追って見てみましょう。(また、視覚的に学習したい場合は、以下の手順の画像もご利用いただけます)。

まず、画像を保存する必要があります。名前はプログラムは複数のユーザーが同時に使用できるため、静的名前を使用すると問題が発生する可能性があります。ユーザーごとに個別のイメージ名を作成することもできます(UUID などを使用して)。より簡単な方法は、Python の tempfile ライブラリを使用する方法です。このライブラリを使用すると、一意の名前の臨時ファイルを作成できます。次のコードは、一時ファイルを作成し、その名前を取得して、画像生成ステップのレスポンスを一時ファイルに書き込みます。先に URL を取得する必要があるため、この値はまだコードに入力しません。

with tempfile.NamedTemporaryFile("wb") as f:
    filename
= f.name
    response
.save(filename, include_generation_parameters=False)
   
# process the saved file here, before it goes away

保存したファイルを処理する方法はいくつかありますが、最も簡単で安全な方法の一つがデータ URL を使用する方法です。

データ URL を使用すると、パスだけでなく実際のデータも URL で送信できます。データ URL の構文は次のとおりです。

data:[image/png][;base64],<data>

画像の base64 エンコードを取得するには、tempfile によって保存されたファイルを開き、変数に読み込む必要があります。はい、これは大きな文字列になりますが、最新のブラウザとサーバーで問題なく使用できます。次に、base64 ライブラリを使用して、データを URL で送信できる文字列にエンコードします。

3 つ目のステップ(URL の作成)を行う最終的なコードは次のようになります。

# Code to create a URL for the image (called image_url)
with tempfile.NamedTemporaryFile("wb") as f:
    filename = f.name
    response.save(filename, include_generation_parameters=False)
    # process the saved file here, before it goes away
    with open(filename, "rb") as image_file:
        binary_image = image_file.read()
        base64_image = base64.b64encode(binary_image).decode("utf-8")
        image_url = f"data:image/png;base64,{base64_image}"

以下の画像に、これらの手順をすべて示します。

268876579dc02376.png

プログラムの開始時に tempfile と base64 をインポートする必要があります。

import tempfile
import base64

Cloud Shell からプログラムを実行してみます。main.py のあるフォルダに移動し、次のコマンドを実行します。

python main.py

画面右上の [ポート 8080 でプレビュー] を使用してプレビューできます。

a80b4abd28cb7eed.png

7. 一般的なエラー

プログラムの実行中(テスト中またはデプロイ後)に、次のようなメッセージが表示されることがあります。

2366c3bba6273517.png

これは、Google の責任ある AI への取り組みに違反するプロンプトが原因である可能性が高いです。「カラフルなボールで遊ぶ子猫」というシンプルなプロンプトでも、この問題が発生することがあります。(ただし、「カラフルなおもちゃで遊ぶ子猫」の画像は取得できます)。

このエラーに対処するため、画像の生成時に発生する例外をキャッチするコードを追加します。存在する場合は、home.html テンプレートが再びレンダリングされ、メッセージが表示されます。

まず、エラーが発生した場合に表示される最初のフォームの後に、home.html テンプレートに div を追加します。

<!DOCTYPE html>
<html>
   <head>
       <title>Let's draw a picture</title>
   </head>
   <body>
       <h1>Let's draw a picture</h1>
       <form  action="/" method="post" >
           <input type="text" id="prompt" name="prompt">
           <input type="submit" value="Send">
       </form>
       {% if mistake %}
       <div id="warning">
       The prompt contains sensitive words that violate
       <a href=\"https://ai.google/responsibility/responsible-ai-practices\">
           Google's Responsible AI practices</a>.
       Try rephrasing the prompt."</div>

       {% endif %}

   </body>
</html>

次に、display_image で generate_images コードを呼び出すときに発生する可能性のある例外をキャッチするコードを main.py に追加します。例外が発生した場合、コードはメッセージとともに home.html テンプレートをレンダリングします。

# Code to generate the image
   model = ImageGenerationModel.from_pretrained("imagegeneration@006")
   try:
       response = model.generate_images(prompt=prompt)[0]  
   except:
       #  This is probably due to a questionable prompt
       return flask.render_template("home.html", warning=True)

これは Imagen の責任ある AI 機能の唯一の機能ではありません。人物や子供の生成を保護する機能や、画像の一般的なフィルタが多数用意されています。詳しくは、こちらをご覧ください。

8. ウェブにアプリをデプロイする

アプリをウェブにデプロイするには、Cloud Shell の imageapp フォルダにあるコマンドを使用します。コマンドでは必ず実際のプロジェクト ID を使用してください。

gcloud run deploy imageapp \
  --source . \
  --region us-central1 \
  --allow-unauthenticated \
  --project your-project-id

次のようなレスポンスが表示され、申請書の場所が示されます。

Service [imageapp] revision [imageapp-00001-t48] has been deployed and is serving 100 percent of traffic.
Service URL: https://imageapp-708208532564.us-central1.run.app```

9. クリーンアップ

サービスが使用されていない場合、Cloud Run の料金は発生しませんが、コンテナ イメージを Artifact Registry に保存すると課金される場合があります。リポジトリを削除するか、Cloud プロジェクトを削除して、料金が発生しないようにできます。Cloud プロジェクトを削除すると、そのプロジェクト内で使用されているすべてのリソースに対する課金が停止します。

コンテナ イメージ リポジトリを削除するには:

gcloud artifacts repositories delete cloud-run-source-deploy \
  --location $REGION

Cloud Run サービスを削除するには:

gcloud run services delete imageapp \
  --platform managed \
  --region $REGION

Google Cloud プロジェクトを削除するには:

  1. 現在のプロジェクト ID を取得します。
PROJECT_ID=$(gcloud config get-value core/project)
  1. 削除するプロジェクトであることを確認します。
echo $PROJECT_ID
  1. プロジェクトの削除:
gcloud projects delete $PROJECT_ID

10. 完了

これで、Imagen によって作成された画像を表示するウェブ アプリケーションが正常に作成されました。これをアプリで使用するにはどうすればよいか

次のステップ

以下の Codelab をご覧ください。

参考資料