Générer et gérer des embeddings vectoriels automatiques pour les grandes tables

Vous pouvez générer et gérer des embeddings vectoriels pour une colonne de table entière, ce qui vous offre une solution évolutive pour la création d'embeddings vectoriels à grande échelle. Cette solution est particulièrement utile pour faciliter la recherche sémantique et la génération augmentée par récupération (RAG) sur le contenu textuel, y compris les éléments suivants :

  • Créer une représentation vectorielle continue initiale pour une nouvelle table
  • Générer des embeddings après une importation de données volumineuses
  • Actualiser les embeddings après des modifications importantes des données
  • Mettre à jour les embeddings de manière incrémentielle

Comprendre les embeddings vectoriels automatiques

Les embeddings vectoriels automatiques dans AlloyDB offrent un moyen évolutif d'automatiser la génération et la maintenance des embeddings vectoriels pour vos données. Au lieu de générer manuellement des embeddings pour chaque nouveau texte ou texte modifié, vous pouvez configurer des embeddings vectoriels automatiques pour gérer ce processus à votre place. Cela est particulièrement utile pour les applications qui s'appuient sur des embeddings à jour pour la recherche sémantique, la génération augmentée par récupération (RAG) et d'autres fonctionnalités optimisées par l'IA.

Les embeddings vectoriels automatiques vous permettent d'effectuer les opérations suivantes :

  • Initialiser les embeddings pour une table entière : générez des embeddings pour toutes les données existantes dans une colonne de table avec une seule commande.
  • Synchronisez les embeddings : mettez-les à jour automatiquement lorsque les données sources changent. Vos applications d'IA fonctionnent ainsi toujours avec les informations les plus récentes.
  • Générez des embeddings à grande échelle : créez efficacement des embeddings pour les grandes tables contenant des millions de lignes.
  • Configurez et gérez les embeddings pour plusieurs colonnes d'une même table en appelant les fonctions de gestion pour chaque colonne d'embedding.

Cette fonctionnalité simplifie le développement et la maintenance des applications d'IA en masquant la complexité de la création et de la maintenance des embeddings vectoriels.

Avant de commencer

Avant de pouvoir générer et gérer des embeddings vectoriels pour les grandes tables, procédez comme suit :

  • Connectez-vous à votre base de données à l'aide de psql ou d'AlloyDB pour PostgreSQL Studio en tant qu'utilisateur postgres.
  • Vérifiez que l'extension google_ml_integration est installée.
  • Vérifiez que le flag google_ml_integration.enable_model_support est défini sur on.
  • Vérifiez que l'extension google_ml_integration est en version 1.5.2 ou ultérieure et que le flag google_ml_integration.enable_faster_embedding_generation est défini sur on.

    Pour vérifier la version de votre extension, exécutez la commande suivante :

    SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
    

    Si vous devez mettre à jour l'extension, utilisez la commande ALTER EXTENSION google_ml_integration UPDATE;.

  • Avant de pouvoir générer des embeddings à partir d'une base de données AlloyDB, vous devez configurer AlloyDB pour qu'il fonctionne avec Vertex AI. Pour en savoir plus, consultez Intégrer votre base de données à Vertex AI.

  • Pour gérer et surveiller la génération d'intégrations automatiques, les utilisateurs disposent de l'accès Select aux tables google_ml.embed_gen_progress et google_ml.embed_gen_settings par défaut.

    Pour autoriser un utilisateur à gérer la génération d'intégrations automatiques, accordez-lui les autorisations INSERT, UPDATE et DELETE sur les tables google_ml.embed_gen_progress et google_ml.embed_gen_settings :

    GRANT INSERT, UPDATE, DELETE ON google_ml.embed_gen_progress TO 'USER_NAME';
    

    Remplacez les éléments suivants :

    • USER_NAME : nom de l'utilisateur pour lequel les autorisations sont accordées.
  • Vérifiez que AUTOCOMMIT est défini sur ON dans le client PostgreSQL que vous utilisez.

  • Vérifiez que le modèle d'embedding que vous utilisez dispose d'un quota suffisant pour les embeddings vectoriels automatiques. Un quota insuffisant peut entraîner un ralentissement ou un échec de l'opération d'intégration automatique. Par exemple, voici les limites pour les modèles d'embedding Vertex AI :

    • Limites d'embedding de texte : chaque requête peut comporter jusqu'à 250 textes d'entrée,générant un embedding par texte d'entrée et 20 000 jetons par requête. Seuls les 2 048 premiers jetons de chaque texte d'entrée sont utilisés pour calculer les embeddings.
    • Requêtes par minute :

      • base_model : text-embedding : 1500
      • base_model : gemini-embedding : 100000
    • Limite de jetons du modèle Gemini Embedding : contrairement aux autres modèles d'embedding qui étaient principalement limités par des quotas de requêtes par minute, la série de modèles Gemini Embedding est limitée à 5 000 000 de jetons par minute et par projet.

Initialiser les embeddings pour une table

Les fonctions de gestion des embeddings vectoriels automatiques sont disponibles dans le schéma ai. Ce schéma fournit une interface pour les dernières fonctionnalités d'IA dans AlloyDB.

Utilisez la fonction SQL ai.initialize_embeddings() pour générer des embeddings pour la colonne de contenu d'une table. Il s'agit d'un appel bloquant :

  • Si la fonction renvoie un résultat positif, la création de l'embedding vectoriel est terminée.
  • La fonction tente automatiquement de résoudre les problèmes temporaires tels que les erreurs de quota de modèle. Un échec ne vous est renvoyé que si ces tentatives de récupération échouent. En cas de problèmes persistants, par exemple une configuration incorrecte de batch_size qui entraîne le dépassement des limites de taille de la requête, ou si l'opération a été annulée manuellement, vous devez relancer l'appel manuellement.

Cette fonction est compatible avec les modèles fournis par Google (par exemple, text-embedding-005 de Vertex AI) ainsi qu'avec les modèles personnalisés que vous avez enregistrés.

Avant de générer des embeddings, créez une colonne content_embeddings dans votre tableau. Cette colonne est généralement de type vector(DIMENSION) et a une valeur DEFAULT NULL.

ALTER TABLE user_reviews ADD COLUMN IF NOT EXISTS content_embeddings vector(768) DEFAULT NULL;

Effectuer une génération par lot

Par défaut, AlloyDB utilise le traitement par lot pour générer des embeddings pour plusieurs entrées de texte dans une seule requête, ce qui améliore l'efficacité. Si vous ne fournissez pas de taille de lot spécifique, AlloyDB applique une valeur par défaut déterminée automatiquement.

Taille du lot d'indices

Le paramètre batch_size dans ai.initialize_embeddings vous permet de guider l'optimiseur de requêtes d'AlloyDB en suggérant une taille de lot préférée pour les modèles directement compatibles. AlloyDB peut réduire dynamiquement cette taille en fonction des limites ou des quotas du modèle, mais votre indication permet d'influencer le plan d'exécution de la requête.

CALL ai.initialize_embeddings(
    model_id => 'text-embedding-005',
    table_name => 'user_reviews',
    content_column => 'content',
    embedding_column => 'content_embeddings',
    batch_size => 50
);

Utiliser un modèle d'embedding personnalisé avec prise en charge des lots

Si vous souhaitez utiliser un modèle personnalisé ou externe compatible avec le traitement par lot, définissez les fonctions de transformation par lot et spécifiez-les en tant que model_batch_in_transform_fn et model_batch_out_transform_fn lorsque vous créez un modèle. Vous pouvez également spécifier un batch_size dans l'appel initialize_embeddings. Pour les modèles compatibles avec le traitement par lot, nous vous recommandons d'utiliser une valeur batch_size supérieure à 1 pour améliorer les performances.

  1. Définissez les fonctions d'entrée, de sortie et de transformation par lot de votre modèle personnalisé.

    -- Scalar input transform functions
    CREATE OR REPLACE FUNCTION acme_text_input_transform(model_id TEXT, input TEXT) RETURNS JSON;
    CREATE OR REPLACE FUNCTION acme_text_output_transform(model_id TEXT, model_output JSON) RETURNS real[];
    CREATE OR REPLACE FUNCTION acme_generate_headers(model_id TEXT, input TEXT) RETURNS JSON;
    -- Batch input transform functions
    CREATE OR REPLACE FUNCTION acme_text_batch_input_transform(model_id TEXT, input TEXT[]) RETURNS JSON;
    CREATE OR REPLACE FUNCTION acme_text_batch_output_transform(model_id TEXT, model_output JSON) RETURNS real[][];
    
  2. Pour créer votre modèle, spécifiez les fonctions de transformation par lot.

    CALL
      ai.create_model(
        model_id => 'custom-embedding-model',
        model_request_url => 'https://acme.com/models/text/embeddings/v1',
        model_type => 'text_embedding',
        model_in_transform_fn => 'acme_text_input_transform',
        model_out_transform_fn => 'acme_text_output_transform',
        generate_headers_fn => 'acme_generate_headers',
        model_batch_in_transform_fn => 'acme_text_batch_input_transform',
        model_batch_out_transform_fn => 'acme_text_batch_output_transform'
      );
    
  3. Générez des embeddings vectoriels avec votre modèle personnalisé.

    CALL
      ai.initialize_embeddings(
        model_id => 'custom-embedding-model',
        table_name => 'user_reviews',
        content_column => 'content',
        embedding_column => 'content_embeddings',
        batch_size => 10
    );
    

Vous pouvez également utiliser la fonctionnalité d'intégration automatique avec des modèles personnalisés qui ne sont pas compatibles avec le traitement par lot. Pour ce faire, vous devez toujours définir les fonctions de transformation par lot model_batch_in_transform_fn et model_batch_out_transform_fn. Pour un modèle sans traitement par lot, définissez ces fonctions pour traiter une seule entrée à la fois à partir du tableau d'entrée. Lorsque vous appelez ai.initialize_embeddings pour ce modèle, définissez batch_size sur 1.

Actualiser les embeddings de manière incrémentielle

Lorsque vous actualisez un embedding, il est régénéré en fonction de la dernière valeur de la colonne de contenu d'entrée.

Pour vous permettre de contrôler la cohérence et les performances, AlloyDB est compatible avec différents modes d'actualisation incrémentielle des embeddings. Vous pouvez sélectionner un mode à l'aide de l'argument d'énumération incremental_refresh_mode dans ai.initialize_embeddings(). Voici une liste des modes possibles :

  • transactional : les embeddings sont actualisés lors de la mise à jour de la colonne de contenu de la transaction. Ce processus, qui utilise souvent un mécanisme semblable à un déclencheur de base de données pour générer automatiquement des embeddings lorsque la colonne de contenu est mise à jour, peut entraîner une surcharge et ralentir les opérations de mise à jour. La surcharge introduite est un compromis pour maintenir la sémantique transactionnelle et s'assurer que les embeddings sont synchronisés avec le contenu. Ce mode s'appuie sur les fonctions de transformation scalaire de votre modèle. Vous devez donc définir model_in_transform_fn et model_out_transform_fn lorsque vous créez le modèle. Pour utiliser le mode transactional, vous devez disposer du rôle de propriétaire pour le tableau.

    CALL
      ai.initialize_embeddings(
        model_id => 'text-embedding-005',
        table_name => 'user_reviews',
        content_column => 'content',
        embedding_column => 'content_embeddings',
        batch_size => 10,
        incremental_refresh_mode => 'transactional'
    );
    
  • none : il s'agit du mode par défaut. Dans ce mode, AlloyDB ne met pas à jour automatiquement les embeddings. Les modifications incrémentales ne sont pas suivies. Par conséquent, l'appel de la fonction ai.refresh_embeddings() régénère les embeddings pour l'ensemble de la table. Ce mode offre un contrôle total.

Actualiser tous les embeddings d'une table

Une fois que vous avez exécuté ai.initialize_embeddings() pour une table, vous pouvez utiliser la fonction ai.refresh_embeddings() pour régénérer les embeddings. Vous pouvez utiliser une opération d'actualisation pour mettre à jour les embeddings des lignes qui sont modifiées simultanément lors de l'appel initialize_embeddings initial ou pour effectuer une actualisation complète périodique.

La fonction d'actualisation réutilise les paramètres de l'appel initial. Vous n'avez donc qu'à spécifier la table et la colonne d'intégration. Vous pouvez également fournir un batch_size facultatif pour remplacer la valeur par défaut.

CALL ai.refresh_embeddings(
    table_name => 'user_reviews',
    embedding_column => 'content_embeddings',
    batch_size => 50  -- Optional override
);

Utiliser des données de table lors de la création d'embeddings vectoriels

Bien que ai.initialize_embeddings() soit un appel bloquant pour la session dans laquelle il s'exécute, d'autres connexions peuvent continuer à fonctionner avec la table. Le processus d'intégration vectorielle automatique met à jour les lignes par lots, ce qui implique un verrouillage standard au niveau des lignes. Cela signifie que les opérations LMD simultanées telles que UPDATE ou DELETE ne sont bloquées que brièvement si elles tentent de modifier les mêmes lignes que celles mises à jour par le processus d'intégration. Les requêtes provenant d'autres connexions ne sont pas bloquées. Notez que initialize_embeddings ignore les lignes qui sont modifiées simultanément. Si incremental_refresh_mode est défini sur none, les embeddings de ces lignes modifiées ne sont pas mis à jour tant qu'une actualisation ultérieure n'est pas appelée.

-- connection1 (starts embedding generation)
SELECT
  ai.initialize_embeddings(
    model_id => 'text-embedding-005',
    table_name => 'user_reviews',
    content_column => 'content',
    embedding_column => 'content_embeddings'
  );

-- connection2 (performs DMLs/queries without blocking)
INSERT INTO user_reviews(id, review_time, is_edited, content)
VALUES (48290, now(), false, 'I really liked the product functionality, but wish it came in orange color');

UPDATE user_reviews
SET is_edited = TRUE, content = 'Changing to 5 star. My issue is resolved by the support'
WHERE id = 700;

Si vous annulez initialize_embeddings à l'aide de pg_cancel ou si initialize_embeddings échoue en raison d'une erreur interne, un état d'échec est renvoyé. Les embeddings vectoriels créés avec succès ne sont pas annulés. Pour résoudre l'échec et terminer la création d'embeddings vectoriels, vous devez d'abord nettoyer la configuration à l'aide de la fonction ai.drop_embedding_config(), puis réémettre l'appel ai.initialize_embeddings().

Pour actualiser les embeddings des lignes modifiées simultanément, appelez ai.refresh_embeddings une fois l'appel ai.initialize_embeddings terminé. Cet appel d'actualisation régénère les embeddings pour l'ensemble de la table.

Supprimer les paramètres d'embedding vectoriel automatique

Si vous devez supprimer la configuration d'embedding vectoriel automatique pour une combinaison spécifique de table et de colonne d'embedding, utilisez la fonction ai.drop_embedding_config(). Cette fonction peut être utile pour le nettoyage ou lorsque vous reconfigurez la gestion des embeddings pour une colonne.

CALL
  ai.drop_embedding_config(
    table_name => 'user_reviews',
    embedding_column => 'content_embeddings');

Exemples de génération d'embeddings dans Auto

Cette section fournit des exemples de génération d'embeddings en mode automatique à l'aide de points de terminaison de modèles enregistrés.

Modèle d'embedding OpenAI

Pour générer des embeddings à l'aide du point de terminaison de modèle text-embedding-3-small enregistré fourni par OpenAI, exécutez l'instruction suivante :

CALL ai.initialize_embeddings(
    model_id => 'text-embedding-3-small',
    table_name => 'user_reviews',
    chunk_column => 'content',
    embedding_column => 'content_embeddings'
);

Modèles d'embedding personnalisés

Pour vos propres modèles ou ceux compatibles en externe, vous devez définir des fonctions de transformation d'entrée et de sortie, puis les enregistrer avec ai.create_model. Si vous prévoyez d'utiliser la fonctionnalité d'embedding automatique, vous devez spécifier à la fois les fonctions de transformation scalaire (par exemple, acme_text_input_transform, acme_text_output_transform) et les fonctions de transformation par lot (par exemple, acme_text_batch_input_transform, acme_text_batch_output_transform).

Étapes suivantes