Créer des applications d'IA générative à l'aide d'AlloyDB AI

Cette section explique comment appeler des prédictions, et interroger et indexer des embeddings à l'aide de l'extension pgvector. Ces fonctions d'IA basées sur le machine learning sont disponibles via AlloyDB/AI, une suite de fonctionnalités AlloyDB pour PostgreSQL qui vous permet d'appliquer la puissance sémantique et prédictive des modèles de machine learning (ML) à vos données.

Pour en savoir plus sur AlloyDB/AI, consultez https://cloud.google.com//alloydb/docs/ai.

Appeler des prédictions

Pour intégrer Vertex AI à AlloyDB Omni et exécuter des prédictions sur les modèles stockés dans Vertex AI, procédez comme suit.

Avant de commencer

  1. Activez les prédictions en ligne Vertex AI dans GDC.
  2. Créez un secret Kubernetes basé sur la clé de compte de service téléchargée lors des étapes précédentes en exécutant la commande suivante. Assurez-vous de créer le secret Kubernetes dans le même espace de noms que votre ressource DBCluster.

    kubectl create secret generic SECRET_NAME \
    --from-file=PATH_TO_SERVICE_ACCOUNT_KEY/private-key.json \
    -n NAMESPACE

    Remplacez les éléments suivants :

    • SECRET_NAME : nom du secret utilisé lorsque vous créez un fichier manifeste DBCluster pour permettre à AlloyDB Omni d'accéder aux fonctionnalités d'IA Distributed Cloud. Par exemple, vertex-ai-key-alloydb.

    • PATH_TO_SERVICE_ACCOUNT_KEY : chemin d'accès à l'emplacement où vous avez téléchargé la clé de compte de service private-key.json.

    • NAMESPACE : espace de noms du cluster de bases de données.

  3. Installez l'opérateur AlloyDB Omni en suivant les étapes décrites dans Choisir un type de moteur de base de données et créer un cluster de bases de données.

  4. Créez un cluster de base de données avec AlloyDB/AI et définissez vertexAIKeyRef sur le secret Kubernetes créé lors des étapes précédentes dans le champ googleMLExtension du fichier manifeste DBCluster.

    apiVersion: v1
    kind: Secret
    metadata:
      name: db-pw-DBCLUSTER_NAME
      namespace: USER_PROJECT
    type: Opaque
    data:
      DBCLUSTER_NAME: "BASE64_PASSWORD"
    ---
    apiVersion: DBENGINE_NAME.dbadmin.gdc.goog/v1
    kind: DBCluster
    metadata:
      name: DBCLUSTER_NAME
      namespace: USER_PROJECT
    spec:
      primarySpec:
        adminUser:
          passwordRef:
            name: db-pw-DBCLUSTER_NAME
        features:
          googleMLExtension:
            config:
              vertexAIKeyRef: SECRET_NAME
        version: "DB_VERSION"
        resources:
          memory: DB_MEMORY
          cpu: DB_CPU
          disks:
          - name: DataDisk
            size: DB_DATA_DISK
    

    Remplacez les variables suivantes :

    • DBCLUSTER_NAME : nom du cluster de base de données.
    • USER_PROJECT : nom du projet utilisateur dans lequel le cluster de bases de données sera créé.
    • BASE64_PASSWORD : encodage en base64 du mot de passe administrateur de la base de données.
    • DBENGINE_NAME : nom du moteur de base de données. Définissez cet élément sur alloydbomni.
    • DB_VERSION : version du moteur de base de données.
    • DB_MEMORY : quantité de mémoire allouée au cluster de bases de données (par exemple, 5Gi).
    • DB_CPU : nombre de processeurs alloués au cluster de bases de données (par exemple, 2).
    • DB_DATA_DISK : quantité d'espace allouée au cluster de bases de données (par exemple, 10 Gi).

    Appliquez le fichier manifeste.

    kubectl apply -f DB_CLUSTER_YAML

    Remplacez les éléments suivants :

    • DB_CLUSTER_YAML : nom du fichier manifeste de ce cluster de bases de données (par exemple, alloydb-omni-db-cluster.yaml).
  5. Installez l'extension google_ml_integration.

    CREATE EXTENSION google_ml_integration CASCADE;
    

Appeler une prédiction

Appelez une prédiction en ligne à l'aide d'un point de terminaison de modèle Vertex AI en exécutant la fonction SQL ml_predict_row() suivante :

  SELECT ml_predict_row('PREDICTION_ENDPOINT/PROJECT_NAMESPACE/ORGANIZATION/ZONE/DNS/DNS_SUFFIX', '{ "instances": [ INSTANCES ], "parameters":
  PARAMETERS');

Remplacez les éléments suivants :

  • PREDICTION_ENDPOINT : nom qualifié du point de terminaison Vertex AI

  • PROJECT_NAMESPACE : espace de noms dans lequel le point de terminaison Vertex AI est déployé

  • ORGANIZATION : nom de l'organisation dans laquelle le point de terminaison Vertex AI est déployé

  • ZONE : zone dans laquelle votre point de terminaison Vertex AI est déployé

  • DNS : DNS de votre organisation

  • DNS_SUFFIX : suffixe de l'objet DNS

  • INSTANCES : entrées de l'appel de prédiction, au format JSON.

  • PARAMETERS : paramètres de l'appel de prédiction, au format JSON.

Interroger et indexer des embeddings à l'aide de pgvector

L'extension PostgreSQL pgvector vous permet d'utiliser des opérateurs et des fonctions spécifiques aux vecteurs lorsque vous stockez, indexez et interrogez des embeddings de texte dans votre base de données. AlloyDB fournit des optimisations pour exploiter l'extension pgvector, ce qui vous permet de créer des index pouvant accélérer certaines requêtes impliquant des embeddings.

Pour en savoir plus sur l'utilisation d'AlloyDB en tant que LLM, et sur la génération et le stockage d'embeddings vectoriels basés sur un LLM, consultez https://cloud.google.com/alloydb/docs/ai/work-with-embeddings#index.

Créer des index et interroger des vecteurs à l'aide de ScaNN

Cette section vous explique comment utiliser les embeddings stockés pour générer des index et interroger des embeddings. Vous pouvez créer des index ScaNN avec AlloyDB.

Avant de commencer

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

  • Les vecteurs d'embedding 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 postgres_ann en plus de l'extension vector.

    CREATE EXTENSION IF NOT EXISTS postgres_ann;
    

Créer un index ScaNN

Vous pouvez créer un index ScaNN pour les tables de votre base de données.

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

L'index ScaNN est un index de quantification basé sur un arbre pour la recherche approximative des plus proches voisins. Il offre un temps de création d'index réduit et une faible empreinte mémoire. De plus, il fournit un RPS rapide 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 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.

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 K-means. Définissez 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 RPS et le rappel.

Pour créer cet index sur une colonne d'embeddings qui utilise le type de données real[] au lieu de vector, convertissez la colonne en type de données 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'embedding.

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

Exécuter une requête

Une fois que vous avez stocké et indexé les embeddings dans votre base de données, vous pouvez commencer à effectuer des requêtes à 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 postgres_ann.

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ées.

  • DISTANCE_FUNCTION_QUERY : fonction de distance à utiliser avec cette requête. Choisissez l'une des options suivantes en fonction de 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.

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 similaires sur le plan de la sémantique. Notez que vous devez d'abord enregistrer le modèle Gecko d'embedding de texte pour utiliser cette fonction.

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 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 textembedding-gecko@003 comme ID de modèle. Il s'agit des modèles cloud que Distributed Cloud peut utiliser pour les embeddings de texte.

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

    Si vous utilisez l'un des modèles textembedding-gecko en anglais avec Vertex AI, spécifiez l'un des tags de version (par exemple, textembedding-gecko@003).

    Google vous recommande vivement de toujours 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.

Métriques d'index vectoriel

Cette section liste les métriques liées aux index vectoriels que vous générez dans AlloyDB. Vous pouvez afficher ces métriques à l'aide de la vue pg_stat_ann_indexes disponible lorsque vous installez l'extension postgres_ann.

Métriques d'usabilité

Les métriques d'usabilité incluent des métriques qui vous aident à comprendre l'état de l'utilisation de l'index avec des métriques telles que la configuration de l'index et le nombre d'analyses de l'index.

Nom de la métrique Type de données Description
relid OID Identifiant unique de la table contenant l'index vectoriel.
indexrelid OID Identifiant unique de l'index vectoriel.
schemaname NAME Nom du schéma auquel appartient l'index.
relname NAME Nom de la table contenant l'index.
indexrelname NAME Nom de l'index.
indextype NAME Type d'index. Cette valeur est toujours définie sur postgres_ann.
indexconfig TEXT[] Configuration (nombre de feuilles et quantificateur, par exemple) définie pour l'index lors de sa création.
indexsize TEXT Taille de l'index.
indexscan BIGINT Nombre d'analyses d'index lancées sur l'index.

Métriques de réglage

Les métriques d'ajustement fournissent des insights sur l'optimisation actuelle de votre index. Vous pouvez ainsi appliquer des recommandations pour améliorer les performances des requêtes.

Nom de la métrique Type de données Description
insertcount BIGINT Nombre d'opérations d'insertion dans l'index. Cette métrique inclut également le nombre de lignes qui existaient avant la création de l'index.
updatecount BIGINT Nombre d'opérations de mise à jour sur l'index. Cette métrique ne tient pas compte des mises à jour HOT.
deletecount BIGINT Nombre d'opérations de suppression sur l'index.
distribution JSONB Distributions vectorielles dans toutes les partitions de l'index.

Les champs suivants affichent la distribution :
  • maximum (INT8) : nombre maximal de vecteurs dans toutes les partitions.
  • minimum (INT8) : nombre minimal de vecteurs dans toutes les partitions.
  • average (FLOAT) : nombre moyen de vecteurs dans toutes les partitions.
  • outliers (INT8[]) : valeurs aberrantes les plus élevées dans toutes les partitions. Cette valeur indique les 20 valeurs aberrantes les plus élevées.

Remarque : En raison des caractéristiques inhérentes à l'algorithme de clustering K-means, il y aura toujours un certain degré de variance dans la distribution des vecteurs entre les partitions, même lorsque l'index est créé initialement.

Recommandation d'optimisation basée sur les métriques

Mutation
Les métriques insertcount, updatecount et deletecount indiquent ensemble les modifications ou les mutations du vecteur pour l'index.
L'index est créé avec un nombre spécifique de vecteurs et de partitions. Lorsque des opérations telles que l'insertion, la mise à jour ou la suppression sont effectuées sur l'index vectoriel, elles n'affectent que l'ensemble initial de partitions dans lesquelles résident les vecteurs. Par conséquent, le nombre de vecteurs dans chaque partition fluctue au fil du temps, ce qui peut avoir un impact sur le rappel, les RPS ou les deux.
 Si vous rencontrez des problèmes de lenteur ou de précision (par exemple, un faible RPS ou un mauvais rappel) dans vos requêtes de recherche ANN au fil du temps, pensez à examiner ces métriques. Un nombre élevé de mutations par rapport au nombre total de vecteurs peut indiquer qu'une réindexation est nécessaire.
Distribution
 La métrique distribution affiche les distributions de vecteurs dans toutes les partitions.
Lorsque vous créez un index, il est créé avec un nombre spécifique de vecteurs et de partitions fixes. Le processus de partitionnement et la distribution ultérieure sont basés sur cette considération. Si des vecteurs supplémentaires sont ajoutés, ils sont partitionnés entre les partitions existantes, ce qui entraîne une distribution différente de celle qui existait lors de la création de l'index. Étant donné que la distribution finale ne prend pas en compte tous les vecteurs simultanément, le rappel, les RPS ou les deux peuvent être affectés.
Si vous constatez une baisse progressive des performances de vos requêtes de recherche ANN, comme des temps de réponse plus lents ou une précision réduite des résultats (mesurée par les RPS ou le rappel), pensez à vérifier cette métrique et à réindexer.