Générer et rechercher des embeddings multimodaux

Ce tutoriel explique comment générer des embeddings multimodaux pour les images et le texte à l'aide de BigQuery et Vertex AI, puis comment utiliser ces embeddings pour effectuer une recherche sémantique texte vers image.

Ce tutoriel couvre les tâches suivantes :

Ce tutoriel utilise des images d'art du domaine public provenant du Métrotrometus of Art, disponibles dans le bucket gcs-public-data--met de Cloud Storage.

Rôles requis

Pour exécuter ce tutoriel, vous devez disposer des rôles IAM (Identity and Access Management) suivants :

  • Créer et utiliser des ensembles de données, des connexions, des modèles et des notebooks BigQuery : administrateur BigQuery Studio (roles/bigquery.studioAdmin).
  • Accordez des autorisations au compte de service de la connexion : Administrateur IAM du projet (roles/resourcemanager.projectIamAdmin).

Ces rôles prédéfinis contiennent les autorisations requises pour effectuer les tâches décrites dans ce document. Pour afficher les autorisations exactes requises, développez la section Autorisations requises :

Autorisations requises

  • Créez un ensemble de données : bigquery.datasets.create
  • Créer, déléguer et utiliser une connexion : bigquery.connections.*
  • Définissez la connexion par défaut : bigquery.config.*
  • Définissez les autorisations du compte de service : resourcemanager.projects.getIamPolicy et resourcemanager.projects.setIamPolicy.
  • Créez une table d'objets : bigquery.tables.create et bigquery.tables.update
  • Créez un modèle et exécutez l'inférence :
    • bigquery.jobs.create
    • bigquery.models.create
    • bigquery.models.getData
    • bigquery.models.updateData
    • bigquery.models.updateMetadata
  • Créer et utiliser des notebooks :
    • resourcemanager.projects.get
    • resourcemanager.projects.list
    • bigquery.config.get
    • bigquery.jobs.create
    • bigquery.readsessions.create
    • bigquery.readsessions.getData
    • bigquery.readsessions.update
    • dataform.locations.get
    • dataform.locations.list
    • dataform.repositories.create

    • dataform.repositories.list
    • dataform.collections.create
    • dataform.collections.list
    • aiplatform.notebookRuntimeTemplates.apply
    • aiplatform.notebookRuntimeTemplates.get
    • aiplatform.notebookRuntimeTemplates.list
    • aiplatform.notebookRuntimeTemplates.getIamPolicy
    • aiplatform.notebookRuntimes.assign
    • aiplatform.notebookRuntimes.get
    • aiplatform.notebookRuntimes.list
    • aiplatform.operations.list
    • aiplatform.notebookRuntimeTemplates.apply

Vous pouvez également obtenir ces autorisations avec des rôles personnalisés ou d'autres rôles prédéfinis.

Coûts

Dans ce document, vous utilisez les composants facturables de Trusted Cloud by S3NSsuivants :

  • BigQuery ML: You incur costs for the data that you process in BigQuery.
  • Vertex AI: You incur costs for calls to the Vertex AI service that's represented by the remote model.

Vous pouvez obtenir une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.

Les nouveaux utilisateurs de Trusted Cloud peuvent bénéficier d'un essai gratuit.

Pour en savoir plus sur les tarifs de BigQuery, consultez la page Tarifs de BigQuery dans la documentation BigQuery.

Pour en savoir plus sur les tarifs de Vertex AI, consultez la page Tarifs de Vertex AI.

Avant de commencer

  1. In the Trusted Cloud console, on the project selector page, select or create a Trusted Cloud project.

    Go to project selector

  2. Verify that billing is enabled for your Trusted Cloud project.

  3. Enable the BigQuery, BigQuery Connection, and Vertex AI APIs.

    Enable the APIs

Créer un ensemble de données

Créez un ensemble de données BigQuery pour stocker votre modèle de ML.

Console

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à la page "BigQuery"

  2. Dans le volet Explorateur, cliquez sur le nom de votre projet.

  3. Cliquez sur Afficher les actions > Créer un ensemble de données.

    Option de menu "Créer un ensemble de données".

  4. Sur la page Créer un ensemble de données, procédez comme suit :

    • Dans le champ ID de l'ensemble de données, saisissez bqml_tutorial.

    • Pour Type d'emplacement, sélectionnez Multirégional, puis sélectionnez US (plusieurs régions aux États-Unis).

    • Conservez les autres paramètres par défaut, puis cliquez sur Créer un ensemble de données.

bq

Pour créer un ensemble de données, exécutez la commande bq mk en spécifiant l'option --location. Pour obtenir la liste complète des paramètres possibles, consultez la documentation de référence sur la commande bq mk --dataset.

  1. Créez un ensemble de données nommé bqml_tutorial avec l'emplacement des données défini sur US et une description de BigQuery ML tutorial dataset :

    bq --location=US mk -d \
     --description "BigQuery ML tutorial dataset." \
     bqml_tutorial

    Au lieu d'utiliser l'option --dataset, la commande utilise le raccourci -d. Si vous omettez -d et --dataset, la commande crée un ensemble de données par défaut.

  2. Vérifiez que l'ensemble de données a été créé :

    bq ls

API

Appelez la méthode datasets.insert avec une ressource d'ensemble de données définie.

{
  "datasetReference": {
     "datasetId": "bqml_tutorial"
  }
}

BigQuery DataFrames

Avant d'essayer cet exemple, suivez les instructions de configuration pour BigQuery DataFrames du guide de démarrage rapide de BigQuery DataFrames. Pour en savoir plus, consultez la documentation de référence sur BigQuery DataFrames.

Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer les ADC pour un environnement de développement local.

import google.cloud.bigquery

bqclient = google.cloud.bigquery.Client()
bqclient.create_dataset("bqml_tutorial", exists_ok=True)

Créer la table d'objets

Créez une table d'objets sur les images artistiques dans le bucket gcs-public-data--met public de Cloud Storage. La table d'objets permet d'analyser les images sans les déplacer depuis Cloud Storage.

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez la requête suivante :

    CREATE OR REPLACE EXTERNAL TABLE `bqml_tutorial.met_images`
    WITH CONNECTION DEFAULT
    OPTIONS
      ( object_metadata = 'SIMPLE',
        uris = ['gs://gcs-public-data--met/*']
      );

Explorer les données d'image

Créez un notebook Colab Enterprise dans BigQuery pour explorer les données d'image.

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Créez un notebook à l'aide de l'éditeur BigQuery.

  3. Connectez le notebook à l'environnement d'exécution par défaut.

  4. Configurez le notebook :

    1. Ajoutez une cellule de code au notebook.
    2. Copiez et collez le code suivant dans la cellule de code :

      #@title Set up credentials
      
      from google.colab import auth
      auth.authenticate_user()
      print('Authenticated')
      
      PROJECT_ID='PROJECT_ID'
      from google.cloud import bigquery
      client = bigquery.Client(PROJECT_ID)
      

      Remplacez PROJECT_ID par le nom du projet que vous utilisez pour ce tutoriel.

    3. Exécutez la cellule de code.

  5. Activez l'affichage des tables :

    1. Ajoutez une cellule de code au notebook.
    2. Copiez et collez le code suivant dans la cellule de code :

      #@title Enable data table display
      %load_ext google.colab.data_table
      
    3. Exécutez la cellule de code.

  6. Créez une fonction permettant d'afficher les images :

    1. Ajoutez une cellule de code au notebook.
    2. Copiez et collez le code suivant dans la cellule de code :

      #@title Util function to display images
      import io
      from PIL import Image
      import matplotlib.pyplot as plt
      import tensorflow as tf
      
      def printImages(results):
       image_results_list = list(results)
       amt_of_images = len(image_results_list)
      
       fig, axes = plt.subplots(nrows=amt_of_images, ncols=2, figsize=(20, 20))
       fig.tight_layout()
       fig.subplots_adjust(hspace=0.5)
       for i in range(amt_of_images):
         gcs_uri = image_results_list[i][0]
         text = image_results_list[i][1]
         f = tf.io.gfile.GFile(gcs_uri, 'rb')
         stream = io.BytesIO(f.read())
         img = Image.open(stream)
         axes[i, 0].axis('off')
         axes[i, 0].imshow(img)
         axes[i, 1].axis('off')
         axes[i, 1].text(0, 0, text, fontsize=10)
       plt.show()
      
    3. Exécutez la cellule de code.

  7. Affichez les images :

    1. Ajoutez une cellule de code au notebook.
    2. Copiez et collez le code suivant dans la cellule de code :

      #@title Display Met images
      
      inspect_obj_table_query = """
      SELECT uri, content_type
      FROM bqml_tutorial.met_images
      WHERE content_type = 'image/jpeg'
      Order by uri
      LIMIT 10;
      """
      printImages(client.query(inspect_obj_table_query))
      
    3. Exécutez la cellule de code.

      Le résultat doit ressembler à ce qui suit :

      Images représentant des objets du musée d'Art métropolitain

  8. Enregistrez le notebook sous le nom met-image-analysis.

Créer le modèle distant

Créez un modèle distant représentant un modèle d'embedding multimodal Vertex AI hébergé :

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez la requête suivante :

    CREATE OR REPLACE MODEL `bqml_tutorial.multimodal_embedding_model`
      REMOTE WITH CONNECTION DEFAULT
      OPTIONS (ENDPOINT = 'multimodalembedding@001');

    L'exécution de la requête prend plusieurs secondes, après quoi le modèle multimodal_embedding_model apparaît dans l'ensemble de données bqml_tutorial dans le volet Explorateur. Étant donné que la requête utilise une instruction CREATE MODEL pour créer un modèle, il n'y a aucun résultat de requête.

Générer des embeddings d'images

Générez des embeddings à partir des images de la table d'objets à l'aide de la fonction ML.GENERATE_EMBEDDING, puis écrivez-les dans une table pour les utiliser ultérieurement. La génération d'embeddings est une opération coûteuse. La requête utilise donc une sous-requête incluant LIMIT pour limiter la génération d'embeddings à 10 000 images au lieu d'intégrer l'ensemble de données complet composé de 601 294 images. Cela permet également de maintenir le nombre d'images sous la limite de 25 000 pour la fonction ML.GENERATE_EMBEDDING. L'exécution de cette requête prend environ 40 minutes.

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez la requête suivante :

    CREATE OR REPLACE TABLE `bqml_tutorial.met_image_embeddings`
    AS
    SELECT *
    FROM
      ML.GENERATE_EMBEDDING(
        MODEL `bqml_tutorial.multimodal_embedding_model`,
        (SELECT * FROM `bqml_tutorial.met_images` WHERE content_type = 'image/jpeg' LIMIT 10000))

Corriger les erreurs de génération d'embeddings

Recherchez et corrigez les erreurs de génération d'embeddings. La génération d'embeddings peut échouer en raison des quotas de l'IA générative sur Vertex AI ou de l'indisponibilité du service.

La fonction ML.GENERATE_EMBEDDING renvoie les détails de l'erreur dans la colonne ml_generate_embedding_status. Cette colonne est vide si la génération d'embeddings a réussi, ou contient un message d'erreur en cas d'échec de la génération d'embeddings.

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, exécutez la requête suivante pour vérifier la présence d'échecs de génération d'embeddings :

    SELECT DISTINCT(ml_generate_embedding_status),
      COUNT(uri) AS num_rows
    FROM bqml_tutorial.met_image_embeddings
    GROUP BY 1;
  3. Si des lignes contenant des erreurs sont renvoyées, supprimez celles pour lesquelles la génération d'embeddings a échoué :

    DELETE FROM `bqml_tutorial.met_image_embeddings`
    WHERE ml_generate_embedding_status = 'A retryable error occurred: RESOURCE_EXHAUSTED error from remote service/endpoint.';

Créer un index vectoriel

Vous pouvez éventuellement utiliser l'instruction CREATE VECTOR INDEX pour créer l'index vectoriel met_images_index sur la colonne ml_generate_embedding_result de la table met_images_embeddings. Un index vectoriel vous permet d'effectuer une recherche vectorielle plus rapidement, avec le compromis de réduire le rappel et donc de renvoyer des résultats plus approximatifs.

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez la requête suivante :

    CREATE OR REPLACE
      VECTOR INDEX `met_images_index`
    ON
      bqml_tutorial.met_image_embeddings(ml_generate_embedding_result)
      OPTIONS (
        index_type = 'IVF',
        distance_type = 'COSINE');
  3. L'index vectoriel est créé de manière asynchrone. Pour vérifier si l'index vectoriel a été créé, interrogez la vue INFORMATION_SCHEMA.VECTOR_INDEXES et vérifiez que la valeur coverage_percentage est supérieure à 0 et que la valeur last_refresh_time n'est pas NULL :

    SELECT table_name, index_name, index_status,
      coverage_percentage, last_refresh_time, disable_reason
    FROM bqml_tutorial.INFORMATION_SCHEMA.VECTOR_INDEXES
    WHERE index_name = 'met_images_index';

Générer un embedding pour le texte de recherche

Pour rechercher des images correspondant à une chaîne de recherche de texte spécifiée, vous devez d'abord créer un embedding textuel (ou "plongement textuel") pour cette chaîne. Utilisez le même modèle distant pour créer l'embedding textuel que celui utilisé pour créer les embeddings d'images, puis écrivez l'embedding textuel dans une table pour l'utiliser lors d'une étape suivante. La chaîne de recherche est pictures of white or cream colored dress from victorian era.

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez la requête suivante :

    CREATE OR REPLACE TABLE `bqml_tutorial.search_embedding`
    AS
    SELECT * FROM ML.GENERATE_EMBEDDING(
      MODEL `bqml_tutorial.multimodal_embedding_model`,
      (
        SELECT 'pictures of white or cream colored dress from victorian era' AS content
      )
    );

Utilisez la fonction VECTOR_SEARCH pour effectuer une recherche sémantique d'images qui correspondent le mieux à la chaîne de recherche représentée par l'embedding textuel.

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, exécutez la requête suivante pour effectuer une recherche sémantique et écrire les résultats dans une table :

    CREATE OR REPLACE TABLE `bqml_tutorial.vector_search_results` AS
    SELECT base.uri AS gcs_uri, distance
    FROM
      VECTOR_SEARCH(
        TABLE `bqml_tutorial.met_image_embeddings`,
        'ml_generate_embedding_result',
        TABLE `bqml_tutorial.search_embedding`,
        'ml_generate_embedding_result',
        top_k => 3);

Visualiser les résultats de la recherche sémantique

Visualiser les résultats de la recherche sémantique à l'aide d'un notebook.

  1. Dans la console Trusted Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Ouvrez le notebook met-image-analysis que vous avez créé précédemment.

  3. Visualisez les résultats de la recherche vectorielle :

    1. Ajoutez une cellule de code au notebook.
    2. Copiez et collez le code suivant dans la cellule de code :

      query = """
        SELECT * FROM `bqml_tutorial.vector_search_results`
        ORDER BY distance;
      """
      
      printImages(client.query(query))
      
    3. Exécutez la cellule de code.

      Le résultat doit ressembler à ce qui suit :

      Images renvoyées à partir d'une requête de recherche vectorielle multimodale

Effectuer un nettoyage

  1. In the Trusted Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.