多模态嵌入

Embeddings for Multimodal (multimodalembedding) 模型会根据您提供的输入生成维度向量(128、256、512 或 1408 维度)。此输入可包括任何文本、图片或视频的组合。然后,嵌入向量可用于其他后续任务,例如图片分类或内容审核。

文本、图片和视频嵌入向量位于同一语义空间中,并且具有相同的维度。因此,这些向量可以互换用于应用场景,例如按文本搜索图片或按图片搜索视频。

使用场景

多模态嵌入的一些常见应用场景包括:

  • 图片或视频分类:将图片或视频作为输入,并预测一个或多个类别(标签)。
  • 图片搜索:搜索相关或类似的图片。
  • 视频内容搜索
    • 使用语义搜索:将文本作为输入,并返回一组与查询匹配的已排序帧。
    • 使用相似度搜索功能
      • 将视频作为输入,并返回一组与查询匹配的视频。
      • 将一张图片作为输入,并返回一组与查询匹配的视频。
  • 推荐:根据图片或视频生成产品或广告推荐(相似度搜索)。

如需在控制台中探索此模型,请参阅 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/jpegimage/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 可选。为其生成嵌入的视频数据片段的时间(以秒为单位)。此值对应于视频嵌入模式(基本、标准或 Plus),该模式会影响功能价格

基本模式 (intervalSec >= 15):为其生成嵌入的视频片段最少。最低费用选项。
标准层级 (8 <= intervalSec < 15):为其生成嵌入的视频片段多于基本模式,但少于 Plus 模式。中间费用选项。
Plus 模式 (4 <= intervalSec < 8):为其生成嵌入的视频片段最多。最高费用选项。

默认值:16(基本模式)
整数(最小值:4)
parameters.dimension 可选。要为其生成嵌入的向量维度(仅限文本或图片)。如果未设置,则系统会使用默认值 1408。 整数(1282565121408 [默认值])

示例请求

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"
    }
    [...]
    
  • videoSegmentConfigSTART_SECONDEND_SECONDINTERVAL_SECONDS)。可选。为其生成嵌入的特定视频片段(以秒为单位)。

    例如:

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

    使用此配置可指定从 10 秒到 60 秒的视频数据,并为以下 10 秒的视频间隔生成嵌入:[10, 20), [20, 30), [30, 40), [40, 50), [50, 60)。 此视频间隔 ("intervalSec": 10) 属于标准视频嵌入模式,用户按标准模式价格费率计费。

    如果省略 videoSegmentConfig,则服务使用以下默认值: "videoSegmentConfig": { "startOffsetSec": 0, "endOffsetSec": 120, "intervalSec": 16 }。 此视频间隔 ("intervalSec": 16) 属于基本视频嵌入模式,用户按基本模式价格费率计费。

HTTP 方法和网址:

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
模型返回的嵌入是 1408 个浮点矢量。以下示例响应会缩短。
{
  "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,请参阅安装 Python 版 Vertex AI SDK。如需了解详情,请参阅 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 或 1408 维度的浮点数列表。
textEmbedding 128、256、512 或 1408 维度的浮点数列表。
videoEmbeddings 1408 维度的浮点数列表,其中包含为其生成嵌入的视频片段的开始时间和结束时间(以秒为单位)。