マルチモーダル エンベディング

マルチモーダル エンベディング(multimodalembedding)モデルは、指定された入力に基づいてディメンション ベクトル(128、256、512、1,408 ディメンション)を生成します。この入力には、任意のテキスト、画像、動画を組み合わせることができます。エンベディング ベクトルは、画像分類やコンテンツ モデレーションなどの後続のタスクに使用できます。

テキスト、画像、動画のエンベディング ベクトルは、同じディメンションを持つ同じセマンティック空間にあります。そのため、これらのベクトルは、テキストによる画像の検索や画像による動画の検索などのユースケースでも使用できます。

ユースケース

マルチモーダル エンベディングの一般的なユースケースは次のとおりです。

  • 画像または動画の分類: 画像または動画を入力として受け取り、1 つ以上のクラス(ラベル)を予測します。
  • 画像検索: 関連する画像や類似の画像を検索できます。
  • 動画コンテンツ検索
    • セマンティック検索の使用: テキストを入力として受け取り、クエリに一致するランク付けされたフレームのセットを返します。
    • 類似性検索の使用:
      • 動画を入力として受け取り、クエリに一致する動画のセットを返します。
      • 画像を入力として受け取り、クエリに一致する動画のセットを返します。
  • レコメンデーション: 画像または動画に基づいて商品または広告のレコメンデーションを生成します(類似性検索)。

コンソールでこのモデルを確認するには、Model Garden に移動して Embeddings for Multimodal モデルカードを使用します。

<a{: class="button button-primary" l10n-attrs-original-order="href,target,class,track-name,track-type" l10n-encrypted-href="SAHUNDUxy6reWq97H1UtVltigmNHgUGOXn/QVSGplOi71dheYhG9dKuv3S+0ajmQkfzB9oP/Mo2x7xIe1klR5WMcFGqgYIW2vdvnDTxO1+88jFCqaIV0kUsj2YehOF0AqvP4zdF86Pqj1NbCoHpRoQ==" target="console" track-name="consoleLink" track-type="tasks" }="">Model Garden に移動</a{:>

HTTP リクエスト

POST https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/us-central1/publishers/google/models/multimodalembedding:predict

リクエストの本文

{
  "instances": [
    {
      "text": string,
      "image": {
        // Union field can be only one of the following:
        "bytesBase64Encoded": string,
        "gcsUri": string,
        // End of list of possible types for union field.
        "mimeType": string
      },
      "video": {
        // Union field can be only one of the following:
        "bytesBase64Encoded": string,
        "gcsUri": string,
        // End of list of possible types for union field.
        "videoSegmentConfig": {
          "startOffsetSec": integer,
          "endOffsetSec": integer,
          "intervalSec": integer
        }
      },
      "parameters": {
        "dimension": integer
      }
    }
  ]
}

マルチモーダル生成モデル multimodal embeddings では、次のパラメータを使用します。詳細については、マルチモーダル エンベディングを取得するをご覧ください。

パラメータ 説明 使用できる値
instances 情報を取得するデータ(テキスト、画像、動画)を含むオブジェクトを含む配列。 配列(1 個のオブジェクトを許可)
text エンベディングを作成する入力テキスト。 文字列(最大 32 トークン)
image.bytesBase64Encoded エンベディングを取得する画像。image.bytesBase64Encoded を指定した場合、image.gcsUri は設定できません。 Base64 エンコードされた画像文字列(BMP、GIF、JPG、または PNG ファイル、最大 20 MB)
image.gcsUri エンベディングを取得する画像の Cloud Storage URI。image.gcsUri を指定した場合、image.bytesBase64Encoded は設定できません。 Cloud Storage 内の画像ファイルの文字列 URI(BMP、GIF、JPG、または PNG ファイル、最大 20 MB)
image.mimeType 省略可。指定する画像の MIME タイプ。 文字列(image/bmpimage/gifimage/jpeg、または image/png
video.bytesBase64Encoded エンベディングを取得する動画。video.bytesBase64Encoded を指定した場合、video.gcsUri は設定できません。 Base64 エンコードの動画文字列(AVI、FLV、MKV、MOV、MP4、MPEG、MPG、WEBM、または WMV ファイル)
video.gcsUri エンベディングを取得する動画の Cloud Storage URI。video.gcsUri を指定した場合、video.bytesBase64Encoded は設定できません。 Cloud Storage にある動画ファイルの文字列 URI(AVI、FLV、MKV、MOV、MP4、MPEG、MPG、WEBM、または WMV ファイル)
videoSegmentConfig.startOffsetSec 省略可。モデルがエンベディング検出を開始する時間(秒)。デフォルト: 0 整数
videoSegmentConfig.endOffsetSec 省略可。モデルがエンベディング検出を終了する時間(秒)。デフォルト: 120 整数
videoSegmentConfig.intervalSec 省略可。エンベディングが生成される動画データ セグメントの時間(秒)。この値は、機能の料金に影響する動画エンベディング モード(Essential、Standard、または Plus)に対応します。

Essential モードintervalSec ≧ 15): エンベディングが生成される動画のセグメントが最少。費用が最も低いオプション。
Standard ティア(8 ≦ intervalSec < 15): 生成されるエンベディングのセグメントは Essential モードよりも多く、Plus モードよりも少なくなります。費用が中間のオプション。
Plus モード(4 ≦ intervalSec < 8): エンベディングを生成する動画のセグメントが最多。費用が最も高いオプション。

デフォルト: 16(Essential モード)
整数(最小値: 4)
parameters.dimension 省略可。エンベディングを生成するベクトル ディメンション(テキストまたは画像のみ)。設定しない場合、デフォルト値の 1,408 が使用されます。 整数。128256512、または 1408(デフォルト)。

リクエストの例

REST

次の例では、画像、テキスト、動画のデータを使用します。リクエストの本文で、これらのデータ型を任意に組み合わせて使用できます。

また、このサンプルでは Cloud Storage にある動画を使用しています。video.bytesBase64Encoded フィールドを使用して、動画の base64 エンコード文字列表現を指定することもできます。

リクエストのデータを使用する前に、次のように置き換えます。

  • LOCATION: プロジェクトのリージョン。たとえば、us-central1europe-west2asia-northeast3 です。使用可能なリージョンの一覧については、Vertex AI の生成 AI のロケーションをご覧ください。
  • PROJECT_ID: Google Cloud プロジェクト ID
  • TEXT: エンベディングを取得するターゲット テキスト。例: a cat
  • IMAGE_URI: エンベディングを取得するターゲット動画の Cloud Storage URI。例: gs://my-bucket/embeddings/supermarket-img.png

    また、画像を base64 エンコードのバイト文字列として指定することもできます。

    [...]
    "image": {
      "bytesBase64Encoded": "B64_ENCODED_IMAGE"
    }
    [...]
    
  • VIDEO_URI: エンベディングを取得するターゲット動画の Cloud Storage URI。例: gs://my-bucket/embeddings/supermarket-video.mp4

    また、動画を base64 エンコードのバイト文字列として指定することもできます。

    [...]
    "video": {
      "bytesBase64Encoded": "B64_ENCODED_VIDEO"
    }
    [...]
    
  • videoSegmentConfig (START_SECOND, END_SECOND, INTERVAL_SECONDS)。省略可。エンベディングが生成される特定の動画セグメント(秒単位)。

    例:

    [...]
    "videoSegmentConfig": {
      "startOffsetSec": 10,
      "endOffsetSec": 60,
      "intervalSec": 10
    }
    [...]

    この構成を使用して、10 秒から 60 秒までの動画データを指定し、[10, 20), [20, 30), [30, 40), [40, 50), [50, 60) の 10 秒の動画間隔のエンベディングを生成します。この動画間隔("intervalSec": 10)は、Standard 動画エンベディング モードになり、ユーザーには Standard モードの料金レートで請求されます。

    videoSegmentConfig を省略すると、サービスはデフォルト値の "videoSegmentConfig": { "startOffsetSec": 0, "endOffsetSec": 120, "intervalSec": 16 } を使用します。この動画間隔("intervalSec": 16)は、Essential 動画エンベディング モードになり、ユーザーには Essential モードの料金レートで請求されます。

HTTP メソッドと URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict

リクエストの本文(JSON):

{
  "instances": [
    {
      "text": "TEXT",
      "image": {
        "gcsUri": "IMAGE_URI"
      },
      "video": {
        "gcsUri": "VIDEO_URI",
        "videoSegmentConfig": {
          "startOffsetSec": START_SECOND,
          "endOffsetSec": END_SECOND,
          "intervalSec": INTERVAL_SECONDS
        }
      }
    }
  ]
}

リクエストを送信するには、次のいずれかのオプションを選択します。

curl

リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict"

PowerShell

リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/multimodalembedding@001:predict" | Select-Object -Expand Content
モデルが返すエンベディングは、1,408 個の浮動小数点ベクトルです。スペースの関係上、次のサンプル レスポンスの一部は表示されていません。
{
  "predictions": [
    {
      "textEmbedding": [
        0.0105433334,
        -0.00302835181,
        0.00656806398,
        0.00603460241,
        [...]
        0.00445805816,
        0.0139605571,
        -0.00170318608,
        -0.00490092579
      ],
      "videoEmbeddings": [
        {
          "startOffsetSec": 0,
          "endOffsetSec": 7,
          "embedding": [
            -0.00673126569,
            0.0248149596,
            0.0128901172,
            0.0107588246,
            [...]
            -0.00180952181,
            -0.0054573305,
            0.0117037306,
            0.0169312079
          ]
        }
      ],
      "imageEmbedding": [
        -0.00728622358,
        0.031021487,
        -0.00206603738,
        0.0273937676,
        [...]
        -0.00204976718,
        0.00321615417,
        0.0121978866,
        0.0193375275
      ]
    }
  ],
  "deployedModelId": "DEPLOYED_MODEL_ID"
}

Python

Python をインストールまたは更新する方法については、Vertex AI SDK for Python をインストールするをご覧ください。詳細については、Python API リファレンス ドキュメントをご覧ください。

from typing import Optional

import vertexai
from vertexai.vision_models import (
    Image,
    MultiModalEmbeddingModel,
    MultiModalEmbeddingResponse,
    Video,
    VideoSegmentConfig,
)

def get_image_video_text_embeddings(
    project_id: str,
    location: str,
    image_path: str,
    video_path: str,
    contextual_text: Optional[str] = None,
    dimension: Optional[int] = 1408,
    video_segment_config: Optional[VideoSegmentConfig] = None,
) -> MultiModalEmbeddingResponse:
    """Example of how to generate multimodal embeddings from image, video, and text.

    Args:
        project_id: Google Cloud Project ID, used to initialize vertexai
        location: Google Cloud Region, used to initialize vertexai
        image_path: Path to image (local or Google Cloud Storage) to generate embeddings for.
        video_path: Path to video (local or Google Cloud Storage) to generate embeddings for.
        contextual_text: Text to generate embeddings for.
        dimension: Dimension for the returned embeddings.
            https://cloud.google.com/vertex-ai/docs/generative-ai/embeddings/get-multimodal-embeddings#low-dimension
        video_segment_config: Define specific segments to generate embeddings for.
            https://cloud.google.com/vertex-ai/docs/generative-ai/embeddings/get-multimodal-embeddings#video-best-practices
    """

    vertexai.init(project=project_id, location=location)

    model = MultiModalEmbeddingModel.from_pretrained("multimodalembedding")
    image = Image.load_from_file(image_path)
    video = Video.load_from_file(video_path)

    embeddings = model.get_embeddings(
        image=image,
        video=video,
        video_segment_config=video_segment_config,
        contextual_text=contextual_text,
        dimension=dimension,
    )

    print(f"Image Embedding: {embeddings.image_embedding}")

    # Video Embeddings are segmented based on the video_segment_config.
    print("Video Embeddings:")
    for video_embedding in embeddings.video_embeddings:
        print(
            f"Video Segment: {video_embedding.start_offset_sec} - {video_embedding.end_offset_sec}"
        )
        print(f"Embedding: {video_embedding.embedding}")

    print(f"Text Embedding: {embeddings.text_embedding}")

Node.js

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある Node.js の設定手順を完了してください。詳細については、Vertex AI Node.js API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

/**
 * TODO(developer): Uncomment these variables before running the sample.\
 * (Not necessary if passing values as arguments)
 */
// const project = 'YOUR_PROJECT_ID';
// const location = 'YOUR_PROJECT_LOCATION';
// const bastImagePath = "YOUR_BASED_IMAGE_PATH"
// const textPrompt = 'YOUR_TEXT_PROMPT';
const aiplatform = require('@google-cloud/aiplatform');

// Imports the Google Cloud Prediction service client
const {PredictionServiceClient} = aiplatform.v1;

// Import the helper module for converting arbitrary protobuf.Value objects.
const {helpers} = aiplatform;

// Specifies the location of the api endpoint
const clientOptions = {
  apiEndpoint: 'us-central1-aiplatform.googleapis.com',
};
const publisher = 'google';
const model = 'multimodalembedding@001';

// Instantiates a client
const predictionServiceClient = new PredictionServiceClient(clientOptions);

async function predictImageFromImageAndText() {
  // Configure the parent resource
  const endpoint = `projects/${project}/locations/${location}/publishers/${publisher}/models/${model}`;

  const fs = require('fs');
  const imageFile = fs.readFileSync(baseImagePath);

  // Convert the image data to a Buffer and base64 encode it.
  const encodedImage = Buffer.from(imageFile).toString('base64');

  const prompt = {
    text: textPrompt,
    image: {
      bytesBase64Encoded: encodedImage,
    },
  };
  const instanceValue = helpers.toValue(prompt);
  const instances = [instanceValue];

  const parameter = {
    sampleCount: 1,
  };
  const parameters = helpers.toValue(parameter);

  const request = {
    endpoint,
    instances,
    parameters,
  };

  // Predict request
  const [response] = await predictionServiceClient.predict(request);
  console.log('Get image embedding response');
  const predictions = response.predictions;
  console.log('\tPredictions :');
  for (const prediction of predictions) {
    console.log(`\t\tPrediction : ${JSON.stringify(prediction)}`);
  }
}

await predictImageFromImageAndText();

Java

このサンプルを試す前に、Vertex AI クライアント ライブラリをインストールするにある Java の設定手順を完了してください。詳細については、Vertex AI Java API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。


import com.google.cloud.aiplatform.v1beta1.EndpointName;
import com.google.cloud.aiplatform.v1beta1.PredictResponse;
import com.google.cloud.aiplatform.v1beta1.PredictionServiceClient;
import com.google.cloud.aiplatform.v1beta1.PredictionServiceSettings;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Value;
import com.google.protobuf.util.JsonFormat;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PredictImageFromImageAndTextSample {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace this variable before running the sample.
    String project = "YOUR_PROJECT_ID";
    String textPrompt = "YOUR_TEXT_PROMPT";
    String baseImagePath = "YOUR_BASE_IMAGE_PATH";

    // Learn how to use text prompts to update an image:
    // https://cloud.google.com/vertex-ai/docs/generative-ai/image/edit-images
    Map<String, Object> parameters = new HashMap<String, Object>();
    parameters.put("sampleCount", 1);

    String location = "us-central1";
    String publisher = "google";
    String model = "multimodalembedding@001";

    predictImageFromImageAndText(
        project, location, publisher, model, textPrompt, baseImagePath, parameters);
  }

  // Update images using text prompts
  public static void predictImageFromImageAndText(
      String project,
      String location,
      String publisher,
      String model,
      String textPrompt,
      String baseImagePath,
      Map<String, Object> parameters)
      throws IOException {
    final String endpoint = String.format("%s-aiplatform.googleapis.com:443", location);
    final PredictionServiceSettings predictionServiceSettings =
        PredictionServiceSettings.newBuilder().setEndpoint(endpoint).build();

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (PredictionServiceClient predictionServiceClient =
        PredictionServiceClient.create(predictionServiceSettings)) {
      final EndpointName endpointName =
          EndpointName.ofProjectLocationPublisherModelName(project, location, publisher, model);

      // Convert the image to Base64
      byte[] imageData = Base64.getEncoder().encode(Files.readAllBytes(Paths.get(baseImagePath)));
      String encodedImage = new String(imageData, StandardCharsets.UTF_8);

      JsonObject jsonInstance = new JsonObject();
      jsonInstance.addProperty("text", textPrompt);
      JsonObject jsonImage = new JsonObject();
      jsonImage.addProperty("bytesBase64Encoded", encodedImage);
      jsonInstance.add("image", jsonImage);

      Value instanceValue = stringToValue(jsonInstance.toString());
      List<Value> instances = new ArrayList<>();
      instances.add(instanceValue);

      Gson gson = new Gson();
      String gsonString = gson.toJson(parameters);
      Value parameterValue = stringToValue(gsonString);

      PredictResponse predictResponse =
          predictionServiceClient.predict(endpointName, instances, parameterValue);
      System.out.println("Predict Response");
      System.out.println(predictResponse);
      for (Value prediction : predictResponse.getPredictionsList()) {
        System.out.format("\tPrediction: %s\n", prediction);
      }
    }
  }

  // Convert a Json string to a protobuf.Value
  static Value stringToValue(String value) throws InvalidProtocolBufferException {
    Value.Builder builder = Value.newBuilder();
    JsonFormat.parser().merge(value, builder);
    return builder.build();
  }
}

レスポンスの本文

{
  "predictions": [
    {
      "textEmbedding": [
        float,
        // array of 128, 256, 512, or 1408 float values
        float
      ],
      "imageEmbedding": [
        float,
        // array of 128, 256, 512, or 1408 float values
        float
      ],
      "videoEmbeddings": [
        {
          "startOffsetSec": integer,
          "endOffsetSec": integer,
          "embedding": [
            float,
            // array of 1408 float values
            float
          ]
        }
      ]
    }
  ],
  "deployedModelId": string
}
レスポンス要素 説明
imageEmbedding 浮動小数点型の 128、256、512、または 1,408 ディメンションのリスト。
textEmbedding 浮動小数点型の 128、256、512、または 1,408 ディメンションのリスト。
videoEmbeddings エンベディングが生成された動画セグメントの開始時間と終了時間(秒単位)を持つ浮動小数点型の 1,408 ディメンションのリスト。