Créer des index et des vecteurs de requête

Sélectionnez une version de la documentation :

Ce document explique comment utiliser les embeddings stockés pour générer des index et interroger des embeddings. Pour en savoir plus sur le stockage des embeddings, consultez Stocker des embeddings vectoriels.

Vous pouvez créer des index ScaNN, IVF, IVFFlat et HNSW avec AlloyDB.

Avant de commencer

Avant de pouvoir commencer à créer des index, vous devez remplir les conditions préalables suivantes.

  • Les vecteurs d'embeddings sont ajoutés à une table de votre base de données AlloyDB.

  • La version 0.5.0 ou ultérieure de l'extension vector basée sur pgvector, étendue par Google pour AlloyDB, est installée.

    CREATE EXTENSION IF NOT EXISTS vector;
    
  • Pour générer des index ScaNN, installez l'extension alloydb_scann en plus de l'extension vector.

    CREATE EXTENSION IF NOT EXISTS alloydb_scann;
    

Créer un index

Vous pouvez créer l'un des types d'index suivants pour les tables de votre base de données.

Créer un index ScaNN

AlloyDB alloydb_scann est une extension PostgreSQL développée par Google qui implémente un index des voisins les plus proches très efficace basé sur l'algorithme ScaNN.

L'index ScaNN est un index de quantification basé sur une arborescence pour la recherche approximative des plus proches voisins. Il permet de réduire le temps de création d'index et l'empreinte mémoire par rapport à HNSW. De plus, il peut offrir un nombre de requêtes par seconde plus élevé que HNSW en fonction de la charge de travail.

Index arborescent à deux niveaux ScaNN

Pour appliquer un index arborescent à deux niveaux à l'aide de l'algorithme ScaNN à une colonne contenant des embeddings vectoriels stockés, exécutez la requête LDD suivante :

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE);

Remplacez les éléments suivants :

  • INDEX_NAME : nom de l'index que vous souhaitez créer, par exemple my-scann-index. Les noms d'index sont partagés dans toute votre base de données. Assurez-vous que chaque nom d'index est unique pour chaque table de votre base de données.

  • TABLE : table à laquelle ajouter l'index.

  • EMBEDDING_COLUMN : colonne qui stocke les données vector.

  • DISTANCE_FUNCTION : fonction de distance à utiliser avec cet index. Choisissez l'une des options suivantes :

    • Distance L2 : l2

    • Produit scalaire : dot_product

    • Distance de cosinus : cosine

  • NUM_LEAVES_VALUE : nombre de partitions à appliquer à cet index. Définissez une valeur comprise entre 1 et 1 048 576. Pour savoir comment déterminer cette valeur, consultez Ajuster un index ScaNN.

Index ScaNN à trois niveaux

Pour créer un index arborescent à trois niveaux à l'aide de l'algorithme ScaNN dans une colonne contenant des embeddings vectoriels stockés, exécutez la requête LDD suivante :

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

Remplacez les éléments suivants :

  • MAX_NUM_LEVELS : nombre maximal de niveaux de l'arborescence de clustering en K-moyennes. Définissez la valeur sur 1 (par défaut) pour la quantification arborescente à deux niveaux et sur 2 pour la quantification arborescente à trois niveaux.

Une fois l'index créé, vous pouvez exécuter des requêtes de recherche des voisins les plus proches qui l'utilisent en suivant les instructions de la section Envoyer une requête de type plus proches voisins avec un texte donné.

Les paramètres d'index doivent être définis de manière à trouver le juste équilibre entre les requêtes par seconde et le rappel. Pour en savoir plus sur le réglage de l'index ScaNN, consultez Régler un index ScaNN.

Pour créer cet index sur une colonne d'embeddings qui utilise le type de données real[] au lieu de vector, convertissez le type de données de la colonne en vector :

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

Remplacez DIMENSIONS par la largeur dimensionnelle de la colonne d'embeddings. Pour savoir comment trouver les dimensions, examinez la fonction vector_dims dans Fonctions vectorielles.

Pour obtenir une expérience de recherche cohérente, activez la maintenance automatique lorsque vous créez un index ScaNN. Pour en savoir plus, consultez Gérer les index vectoriels. Cette fonctionnalité est disponible en version bêta.

Pour afficher la progression de l'indexation, utilisez la vue pg_stat_progress_create_index :

SELECT * FROM pg_stat_progress_create_index;

La colonne phase indique l'état actuel de la création de votre index. La phase building index: tree training disparaît une fois l'index créé.

Pour régler votre index afin d'obtenir un équilibre entre le rappel et les RPS cibles, consultez Régler un index ScaNN.

Analyser votre table indexée

Après avoir créé l'index ScaNN, vous devez exécuter la commande ANALYZE pour mettre à jour les statistiques sur vos données.

ANALYZE TABLE;

Créer des index en parallèle

AlloyDB peut générer automatiquement plusieurs nœuds de calcul parallèles, en fonction de votre ensemble de données et du type d'index que vous choisissez de créer pour accélérer la création de l'index.

La création d'index en parallèle est souvent déclenchée lorsque vous créez un index ScaNN à trois niveaux ou si votre ensemble de données dépasse 100 millions de lignes.

Bien qu'AlloyDB optimise automatiquement le nombre de nœuds de calcul en parallèle, vous pouvez les ajuster à l'aide des paramètres de planification des requêtes PostgreSQL max_parallel_maintenance_workers, max_parallel_workers et min_parallel_table_scan_size.

Exécuter une requête

Une fois que vous avez stocké et indexé les embeddings dans votre base de données, vous pouvez commencer à les interroger à l'aide de la fonctionnalité de requête pgvector. Vous ne pouvez pas exécuter de requêtes de recherche groupées à l'aide de l'extension alloydb_scann.

Pour trouver les voisins sémantiques les plus proches d'un vecteur d'embedding, vous pouvez exécuter l'exemple de requête suivant, dans lequel vous définissez la même fonction de distance que celle utilisée lors de la création de l'index.

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT

Remplacez les éléments suivants :

  • TABLE : table contenant l'embedding auquel comparer le texte.

  • INDEX_NAME : nom de l'index que vous souhaitez utiliser (par exemple, my-scann-index).

  • EMBEDDING_COLUMN : colonne contenant les embeddings stockés.

  • DISTANCE_FUNCTION_QUERY : fonction de distance à utiliser avec cette requête. Choisissez l'une des options suivantes, selon la fonction de distance utilisée lors de la création de l'index :

    • Distance L2 : <->

    • Produit interne : <#>

    • Distance de cosinus : <=>

  • EMBEDDING : vecteur d'embedding pour lequel vous souhaitez trouver les plus proches voisins sémantiques qui sont stockés.

  • ROW_COUNT : nombre de lignes à afficher.

    Spécifiez 1 si vous souhaitez n'obtenir que la meilleure correspondance.

Pour d'autres exemples de requêtes, consultez Effectuer des requêtes.

Vous pouvez également utiliser la fonction embedding() pour traduire le texte en vecteur. Vous appliquez le vecteur à l'un des opérateurs pgvector correspondant aux plus proches voisins, <-> pour la distance L2, afin de rechercher les lignes de la base de données présentant les embeddings les plus approchants sur le plan sémantique.

Comme embedding() renvoie un tableau real, vous devez convertir explicitement l'appel embedding() en type de données vector pour utiliser ces valeurs avec les opérateurs pgvector.

  CREATE EXTENSION IF NOT EXISTS google_ml_integration;
  CREATE EXTENSION IF NOT EXISTS vector;

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN::vector
    <-> embedding('MODEL_IDVERSION_TAG', 'TEXT')
    LIMIT ROW_COUNT

Remplacez les éléments suivants :

  • MODEL_ID : ID du modèle à interroger.

    Si vous utilisez Vertex AI Model Garden, spécifiez text-embedding-005 comme ID de modèle. Il s'agit des modèles cloud qu'AlloyDB peut utiliser pour les embeddings textuels. Pour en savoir plus, consultez Embeddings textuels.

  • VERSION_TAG (facultatif) : tag de version du modèle à interroger. Ajoutez le préfixe @ au tag.

    Si vous utilisez l'un des modèles text-embedding en anglais avec Vertex AI, spécifiez l'un des tags de version (par exemple, text-embedding-005) listés dans la section Versions de modèle.

    Google vous recommande vivement de spécifier le tag de version. Si vous ne spécifiez pas le tag de version, AlloyDB utilise toujours la dernière version du modèle, ce qui peut entraîner des résultats inattendus.

  • TEXT : texte à traduire en embedding vectoriel.

Étapes suivantes