Rechercher des embeddings à l'aide de la recherche vectorielle

Ce tutoriel vous explique comment effectuer une recherche de similarité sur des embeddings stockés dans des tables BigQuery à l'aide de la VECTOR_SEARCH fonction et éventuellement d'un index vectoriel.

Lorsque vous utilisez VECTOR_SEARCH avec un index vectoriel, VECTOR_SEARCH utilise la méthode approximative du voisin le plus proche pour améliorer les performances de la recherche vectorielle, avec le compromis consistant à réduire le rappel et ainsi renvoyer des résultats plus approximatifs. Sans index vectoriel, VECTOR_SEARCH utilise la recherche par force brute pour mesurer la distance de chaque enregistrement.

Autorisations requises

Pour exécuter ce tutoriel, vous devez disposer des autorisations IAM (Identity and Access Management) suivantes :

  • Pour créer un ensemble de données, vous devez disposer de l'autorisation bigquery.datasets.create.
  • Pour créer une table, vous devez disposer des autorisations suivantes :

    • bigquery.tables.create
    • bigquery.tables.updateData
    • bigquery.jobs.create
  • Pour créer un index vectoriel, vous devez disposer de l'autorisation bigquery.tables.createIndex sur la table dans laquelle vous créez l'index.

  • Pour supprimer un index vectoriel, vous devez disposer de l'autorisation bigquery.tables.deleteIndex sur la table dans laquelle vous supprimez l'index.

Chacun des rôles IAM prédéfinis suivants inclut les autorisations dont vous avez besoin pour travailler avec les index vectoriels :

  • Propriétaire de données BigQuery (roles/bigquery.dataOwner)
  • Éditeur de données BigQuery (roles/bigquery.dataEditor)

Coûts

La fonction VECTOR_SEARCH utilise la tarification du calcul BigQuery. La recherche de similarité vous est facturée à l'aide de la tarification à la demande ou des éditions.

  • À la demande : vous êtes facturé en fonction du nombre d'octets analysés dans la table de base, l'index et la requête de recherche.
  • Tarification des éditions : vous êtes facturé en fonction des emplacements requis pour effectuer le job dans votre édition de réservation. Les calculs de similarité plus volumineux et plus complexes entraînent des frais plus élevés.

Pour en savoir plus, consultez la page relative aux tarifs de BigQuery .

Avant de commencer

  1. Dans la Google Cloud console, sur la page de sélection du projet, sélectionnez ou créez un Google Cloud projet.

    Rôles requis pour sélectionner ou créer un projet

    • Sélectionner un projet : la sélection d'un projet ne nécessite pas de rôle IAM spécifique Vous pouvez sélectionner n'importe quel projet pour lequel un rôle vous a été attribué.
    • Créer un projet : pour créer un projet, vous devez disposer du rôle Créateur de projet (roles/resourcemanager.projectCreator), qui contient l'autorisation resourcemanager.projects.create. Découvrez comment attribuer des rôles.

    Accéder au sélecteur de projet

  2. Vérifiez que la facturation est activée pour votre Google Cloud projet.

  3. Activez l'API BigQuery.

    Rôles requis pour activer les API

    Pour activer les API, vous avez besoin du rôle IAM Administrateur d'utilisation du service (roles/serviceusage.serviceUsageAdmin), qui contient l'autorisation serviceusage.services.enable. Découvrez comment attribuer des rôles.

    Activer l'API

Créer un ensemble de données

Créez un ensemble de données BigQuery :

  1. Dans la Google Cloud console, 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.

    Créez un ensemble de données contenant les objets utilisés dans le tutoriel.

  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 vector_search.

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

      Les ensembles de données publics sont stockés dans l'emplacement multirégional US. Par souci de simplicité, stockez votre ensemble de données dans le même emplacement.

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

Créer des tables de test

  1. Créez la table patents contenant les embeddings des brevets en vous basant sur un sous-ensemble de l'ensemble de données public Google Brevets :

    CREATE TABLE vector_search.patents AS
    SELECT * FROM `patents-public-data.google_patents_research.publications`
    WHERE ARRAY_LENGTH(embedding_v1) > 0
     AND publication_number NOT IN ('KR-20180122872-A')
    LIMIT 1000000;
  2. Créez la table patents2 contenant un embedding de brevet afin de trouver les voisins les plus proches pour :

    CREATE TABLE vector_search.patents2 AS
    SELECT * FROM `patents-public-data.google_patents_research.publications`
    WHERE publication_number = 'KR-20180122872-A';

Créer un index vectoriel

  1. Créez l'index vectoriel my_index sur la colonne embeddings_v1 de la table patents :

    CREATE OR REPLACE VECTOR INDEX my_index ON vector_search.patents(embedding_v1)
    STORING(publication_number, title)
    OPTIONS(distance_type='COSINE', index_type='IVF');
  2. Attendez plusieurs minutes que l'index vectoriel soit créé, puis exécutez la requête suivante et vérifiez que la valeur coverage_percentage est 100 :

    SELECT * FROM vector_search.INFORMATION_SCHEMA.VECTOR_INDEXES;

Utiliser la fonction VECTOR_SEARCH avec un index

Une fois l'index vectoriel créé et rempli, utilisez la fonction VECTOR_SEARCH pour trouver le voisin le plus proche de l'embedding dans la colonne embedding_v1 de la table patents2. Cette requête utilise l'index vectoriel dans la recherche, par conséquent, VECTOR_SEARCH utilise une méthode approximative du voisin le plus proche pour trouver le voisin le plus proche de l'embedding.

Utilisez la fonction VECTOR_SEARCH avec un index :

SELECT query.publication_number AS query_publication_number,
  query.title AS query_title,
  base.publication_number AS base_publication_number,
  base.title AS base_title,
  distance
FROM
  VECTOR_SEARCH(
    TABLE vector_search.patents,
    'embedding_v1',
    TABLE vector_search.patents2,
    top_k => 5,
    distance_type => 'COSINE',
    options => '{"fraction_lists_to_search": 0.005}');

Les résultats ressemblent à ce qui suit :

+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| query_publication_number |                         query_title                         | base_publication_number |                                                        base_title                                                        |      distance       |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-106599080-B          | A kind of rapid generation for keeping away big vast transfer figure based on GIS                                        | 0.14471956347590609 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-114118544-A          | Urban waterlogging detection method and device                                                                           | 0.17472108931171348 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-20200048143-A        | Method and system for mornitoring dry stream using unmanned aerial vehicle                                               | 0.17561990745619782 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-101721695-B1         | Urban Climate Impact Assessment method of Reflecting Urban Planning Scenarios and Analysis System using the same         | 0.17696129365559843 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-109000731-B          | The experimental rig and method that research inlet for stom water chocking-up degree influences water discharged amount | 0.17902723269642917 |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+

Utiliser la fonction VECTOR_SEARCH avec la force brute

Utilisez la fonction VECTOR_SEARCH pour trouver le voisin le plus proche de l'embedding dans la colonne embedding_v1 de la table patents2. Cette requête n'utilise pas l'index vectoriel dans la recherche. Par conséquent, VECTOR_SEARCH trouve le voisin le plus proche de l'embedding :

SELECT query.publication_number AS query_publication_number,
  query.title AS query_title,
  base.publication_number AS base_publication_number,
  base.title AS base_title,
  distance
FROM
  VECTOR_SEARCH(
    TABLE vector_search.patents,
    'embedding_v1',
    TABLE vector_search.patents2,
    top_k => 5,
    distance_type => 'COSINE',
    options => '{"use_brute_force":true}');

Les résultats ressemblent à ce qui suit :

+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| query_publication_number |                         query_title                         | base_publication_number |                                                        base_title                                                        |      distance       |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-106599080-B          | A kind of rapid generation for keeping away big vast transfer figure based on GIS                                        |  0.1447195634759062 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-114118544-A          | Urban waterlogging detection method and device                                                                           |  0.1747210893117136 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-20200048143-A        | Method and system for mornitoring dry stream using unmanned aerial vehicle                                               | 0.17561990745619782 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-101721695-B1         | Urban Climate Impact Assessment method of Reflecting Urban Planning Scenarios and Analysis System using the same         | 0.17696129365559843 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-109000731-B          | The experimental rig and method that research inlet for stom water chocking-up degree influences water discharged amount | 0.17902723269642928 |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+

Évaluer le rappel

Lorsque vous effectuez une recherche vectorielle avec un index, celle-ci renvoie des résultats approximatifs, avec le compromis de réduction du rappel. Vous pouvez calculer le rappel en comparant les résultats renvoyés par la recherche vectorielle avec un index et par la recherche vectorielle avec la force brute. Dans cet ensemble de données, la valeur publication_number identifie de manière unique un brevet. Elle est donc utilisée à des fins de comparaison.

WITH approx_results AS (
  SELECT query.publication_number AS query_publication_number,
    base.publication_number AS base_publication_number
  FROM
    VECTOR_SEARCH(
      TABLE vector_search.patents,
      'embedding_v1',
      TABLE vector_search.patents2,
      top_k => 5,
      distance_type => 'COSINE',
      options => '{"fraction_lists_to_search": 0.005}')
),
  exact_results AS (
  SELECT query.publication_number AS query_publication_number,
    base.publication_number AS base_publication_number
  FROM
    VECTOR_SEARCH(
      TABLE vector_search.patents,
      'embedding_v1',
      TABLE vector_search.patents2,
      top_k => 5,
      distance_type => 'COSINE',
      options => '{"use_brute_force":true}')
)

SELECT
  a.query_publication_number,
  SUM(CASE WHEN a.base_publication_number = e.base_publication_number THEN 1 ELSE 0 END) / 5 AS recall
FROM exact_results e LEFT JOIN approx_results a
  ON e.query_publication_number = a.query_publication_number
GROUP BY a.query_publication_number

Si le rappel est inférieur à ce que vous souhaitez, vous pouvez augmenter la valeur fraction_lists_to_search, mais cela peut entraîner une latence et une utilisation des ressources plus élevées. Pour ajuster votre recherche vectorielle, vous pouvez essayer plusieurs exécutions de VECTOR_SEARCH avec différentes valeurs d'arguments, enregistrer les résultats dans des tables, puis les comparer.

Effectuer un nettoyage

  1. Dans la Google Cloud console, accédez à la page Gérer les ressources.

    Accéder à la page "Gérer les ressources"

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.