Créer un index IVF

Cette page explique comment utiliser les embeddings stockés pour générer des index et interroger des embeddings à l'aide d'un index IVF avec AlloyDB pour PostgreSQL. Pour en savoir plus sur le stockage des embeddings, consultez Stocker des embeddings vectoriels.

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;
    

Créer un index IVF

pgvector standard permet d'exploiter la recherche approximative du voisin le plus proche via l'indexation. AlloyDB étend cette capacité avec une fonctionnalité de quantification scalaire, que vous pouvez spécifier lorsque vous créez un index. Lorsqu'elle est activée, la quantification scalaire peut accélérer considérablement les requêtes utilisant des vecteurs dimensionnels plus importants et vous permet de stocker des vecteurs comportant jusqu'à 8 000 dimensions.

Pour activer la quantification scalaire sur un index basé sur l'extension pgvector, spécifiez IVF comme méthode d'index et SQ8 comme quantificateur :

CREATE INDEX INDEX_NAME ON TABLE
  USING ivf (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (lists = LIST_COUNT, quantizer = 'QUANTIZER');

Remplacez les éléments suivants :

  • INDEX_NAME : nom de l'index que vous souhaitez créer, par exemple my-ivf-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 : vector_l2_ops

    • Produit interne : vector_ip_ops

    • Distance de cosinus : vector_cosine_ops

  • LIST_COUNT : nombre de listes à utiliser avec cet index. Pour savoir comment déterminer cette valeur, consultez Régler un index IVF.

  • QUANTIZER : type de quantificateur que vous souhaitez utiliser.

    Choisissez l'une des options suivantes :

    • SQ8 : recommandé. La réponse aux requêtes est plus rapide, mais cela entraîne une perte de rappel (ce qui n'a pas d'incidence sur les scénarios de production).
    • FLAT : la réponse aux requêtes est plus lente et l'utilisation de la mémoire est plus importante (avec une perte de rappel négligeable).

    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 ivf (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)))'}} DISTANCE_FUNCTION)
  WITH (lists = LIST_COUNT, quantizer = 'SQ8');

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 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 postings indique que la création de l'index est presque terminée.

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

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.

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

Étapes suivantes