Optimiser les coûts des fonctions d'IA

Ce document explique comment utiliser le mode optimisé pour les fonctions d'IA gérées dans BigQuery. Ce mode vous permet de traiter des ensembles de données à grande échelle contenant des milliers, voire des milliards de lignes, avec une consommation de jetons de grand modèle de langage (LLM) et une latence de requête considérablement réduites par rapport à l'inférence LLM standard par ligne.

L'exemple suivant montre comment utiliser la fonction AI.CLASSIFY avec le mode optimisé pour catégoriser des articles d'actualité, en utilisant text-embedding-005 comme modèle d'embedding :

SELECT
  title,
  body,
  AI.CLASSIFY(
    body,
    categories => ['tech', 'sport', 'business', 'other'],
    embeddings => AI.EMBED(body, endpoint => 'text-embedding-005', task_type => 'CLASSIFICATION').result,
    -- Optional, 'MINIMIZE_COST' is the default when embeddings are provided.
    optimization_mode => 'MINIMIZE_COST'
   ) AS category
FROM
  `bigquery-public-data.bbc_news.fulltext`;

L'argument optimization_mode => 'MINIMIZE_COST' active le mode optimisé. Il s'agit du paramètre par défaut lorsque des embeddings sont fournis. Vous pouvez donc omettre cet argument.

Dans cet exemple, les embeddings sont générés à la volée. En pratique, nous vous recommandons de matérialiser les embeddings afin qu'ils puissent être réutilisés.

Fonctionnement du mode optimisé

Les fonctions d'IA gérées, AI.IF et AI.CLASSIFY, appellent généralement un LLM à distance pour chaque ligne de votre ensemble de données. Lorsque vous utilisez le mode optimisé, BigQuery entraîne automatiquement un modèle léger et distillé lors de l'exécution de la requête.

La procédure est la suivante :

Workflow de la fonctionnalité d'IA lorsque le mode optimisé est activé

  • Échantillonnage et étiquetage : BigQuery sélectionne un petit échantillon représentatif de vos données et appelle Gemini pour fournir des libellés.
  • Entraînement du modèle distillé : un modèle distillé local est entraîné juste à temps à l'aide des libellés LLM et des embeddings de données comme caractéristiques.
  • Vérification de la qualité : BigQuery évalue la précision du modèle distillé par rapport aux résultats du LLM. Par défaut, si le modèle distillé ne parvient pas à atteindre le seuil de qualité requis, la requête échoue et une erreur s'affiche pour expliquer pourquoi le modèle a été écarté. Si la qualité du modèle est acceptable, BigQuery peut toujours revenir au LLM distant pour des lignes spécifiques afin de maintenir une qualité cohérente ou pour les lignes ne comportant pas d'embeddings valides.
  • Inférence : le modèle distillé traite la majorité des lignes, ce qui réduit considérablement le nombre d'appels Gemini.

Limites

Le mode optimisé présente les limites suivantes :

  • Nombre minimal de lignes : l'entrée de la fonction d'IA doit contenir environ 3 000 lignes pour garantir suffisamment de données pour l'entraînement du modèle.
  • Types de données : pour les requêtes qui font référence à plusieurs colonnes, seules les colonnes de type chaîne sont acceptées pour l'optimisation.
  • Classification multi-étiquette : AI.CLASSIFY avec output_mode => 'multi' n'est pas compatible avec le mode optimisé.
  • Compatibilité des fonctions : seuls les fonctions AI.IF et AI.CLASSIFY sont compatibles avec le mode optimisé.
  • Ratio d'erreur : l'argument max_error_ratio n'est pas compatible avec le mode optimisé.

Avant de commencer

Pour obtenir les autorisations nécessaires pour exécuter des fonctions d'IA gérées dans BigQuery, consultez Définir les autorisations pour les fonctions d'IA générative qui appellent des LLM Vertex AI.

Choisir un modèle d'embedding

Pour utiliser le mode optimisé, vous devez calculer les embeddings de vos données et les fournir à la fonction d'IA. Pour que les colonnes d'entrée aient des embeddings associés, toutes les lignes doivent avoir des dimensions d'embedding cohérentes et être générées par le même modèle d'embedding.

Pour obtenir le meilleur rapport coût/qualité et la meilleure évolutivité, nous vous recommandons de calculer les embeddings de vos données à l'aide d'un modèle d'embedding, tel que text-embedding-005 ou les embeddings Gemini pour les tâches en anglais ou multilingues. Pour les données multimodales (texte et images), utilisez un modèle d'embedding multimodal tel que multimodalembedding@001.

Générer des embeddings

Vous pouvez calculer des embeddings pour vos données à l'aide de la génération autonome gérée par BigQuery ou en créant manuellement les colonnes d'embedding. Les sections suivantes décrivent comment utiliser ces deux approches avec les fonctions AI.CLASSIFY et AI.IF.

Génération autonome d'embeddings

Si vous utilisez la génération autonome d'embeddings, BigQuery utilise automatiquement les embeddings lorsque AI.IF ou AI.CLASSIFY sont appelés. Il s'agit de l'approche recommandée, mais elle est limitée à une colonne d'embedding par table.

L'exemple suivant crée une table avec une colonne d'embedding générée de manière autonome, en utilisant text-embedding-005 comme modèle d'embedding, puis utilise la fonction AI.CLASSIFY pour catégoriser les données :

-- Create a table with an autonomously generated embedding column
CREATE TABLE my_dataset.bbc_news (
  title STRING,
  body STRING,
  body_embedding STRUCT<result ARRAY<FLOAT64>, status STRING>
    GENERATED ALWAYS AS (
      AI.EMBED(
        body,
        connection_id => '<my_connection_id>',
        task_type => 'CLASSIFICATION',
        endpoint => 'text-embedding-005')
    ) STORED
    OPTIONS(asynchronous = TRUE)
);

-- Insert data into the table
INSERT INTO my_dataset.bbc_news (title, body)
SELECT title, body FROM `bigquery-public-data.bbc_news.fulltext`;

-- Run the optimized query.
-- Wait for the background job to finish generating embeddings before running.
SELECT
  title,
  body,
  AI.CLASSIFY(
    body,
    categories => ['tech', 'sport', 'business', 'other']
  ) AS category
FROM
  my_dataset.bbc_news;

Spécification manuelle des colonnes

Si vous disposez déjà d'une colonne d'intégration, spécifiez-la dans l'argument embeddings de AI.IF ou AI.CLASSIFY. Vous pouvez le générer à l'aide de la fonction AI.EMBED.

L'exemple suivant montre comment créer une table avec une colonne d'embedding, en utilisant text-embedding-005 comme modèle d'embedding, puis comment utiliser cette colonne dans une requête AI.CLASSIFY :

-- Create a table with an embedding column
CREATE TABLE my_dataset.bbc_news AS
SELECT
  title,
  body,
  AI.EMBED(
    body,
    endpoint => 'text-embedding-005',
    task_type => 'CLASSIFICATION'
  ).result AS body_embedding
FROM
  `bigquery-public-data.bbc_news.fulltext`;

-- Run the optimized query
SELECT
  title,
  body,
  AI.CLASSIFY(
    body,
    categories => ['tech', 'sport', 'business', 'other'],
    embeddings => body_embedding,
  ) AS category
FROM
  my_dataset.bbc_news;

Si votre requête fait référence à plusieurs colonnes, fournissez une liste de noms de colonnes et de leurs embeddings correspondants dans l'argument embeddings. Exemple : embeddings => [('body', body_embedding), ('title', title_embedding)].

Surveiller l'optimisation des requêtes

Pour vérifier le nombre de lignes optimisées lors de l'exécution de votre requête, vous pouvez consulter les statistiques d'exécution dans la console Google Cloud ou via l'API :

Console

Pour afficher le nombre de lignes optimisées et les messages système concernant l'état de l'optimisation, procédez comme suit :

  1. Dans la console Google Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans le menu de navigation, cliquez sur Explorateur de jobs.

  3. Cliquez sur l'ID du job pour afficher le volet Informations sur le job.

  4. Cliquez sur l'onglet Informations sur le job, puis consultez les métriques et l'état dans le champ Optimisations des fonctions d'IA générative.

    Champ &quot;Optimisations des fonctions d&#39;IA générative&quot; dans l&#39;onglet &quot;Informations sur le job&quot;

API

Vérifiez le FunctionGenAiCostOptimizationStats dans l'objet GenAIFunctionStats des métadonnées du job. Cet objet inclut le nombre de lignes inférées grâce au workflow optimisé et les messages générés par le système qui fournissent des informations sur l'état de l'optimisation.

Résoudre les problèmes

Les sections suivantes expliquent comment diagnostiquer et résoudre les problèmes courants liés à l'utilisation du mode optimisé.

La taille des données est trop petite

Problème : données insuffisantes pour l'entraînement du modèle. Le message d'erreur suivant peut s'afficher : Fail to apply cost optimization because the data size is too small.

Solution : Augmentez la taille de votre entrée à environ 3 000 lignes et vérifiez que des embeddings valides ont été correctement générés pour toutes les lignes.

Peu ou pas d'échantillons dans certaines classes

Problème : nombre insuffisant d'échantillons pour certaines catégories lors de la phase d'échantillonnage, ce qui empêche l'entraînement du modèle. Le message d'erreur suivant peut s'afficher : Fail to apply cost optimization because some classes have few or no samples.

Solution :

  • Supprimez les catégories rares de l'appel de fonction AI.CLASSIFY.
  • Combinez plusieurs catégories rares dans une catégorie plus large pour augmenter la taille de l'échantillon dans la catégorie combinée. Par exemple, regroupez plusieurs catégories rares dans une catégorie OTHER.

Les embeddings ont des dimensions incohérentes

Problème : Incohérences entre les dimensions d'embedding sur les différentes lignes. Le message d'erreur suivant peut s'afficher : Fail to apply cost optimization because the embeddings have inconsistent dimensions.

Solution : vérifiez que les embeddings sont générés par le même modèle et qu'ils ont la même longueur de vecteur d'embedding. Vous pouvez utiliser une requête SQL semblable à celle ci-dessous pour vérifier que les embeddings d'une colonne ont la même longueur :

SELECT ARRAY_LENGTH(body_embedding.result), COUNT(*)
FROM `PROJECT_ID.DATASET.TABLE_NAME`
GROUP BY 1;

La complexité de la requête est trop élevée

Problème : Le modèle distillé ne peut pas atteindre un seuil de précision élevé. Le message d'erreur suivant peut s'afficher : Fail to apply cost optimization because the prompt complexity is too high.

Solution :

  • Utilisez des catégories qui s'excluent mutuellement.

    • Évitez les catégories qui se chevauchent, dans lesquelles une entrée peut appartenir à plusieurs catégories à la fois. Par exemple, évitez les catégories telles que ['terrible', 'bad', 'okay', 'good', 'excellent'].
    • Fournissez des descriptions de catégories pour aider le LLM à lever toute ambiguïté entre les catégories. Exemple :

      AI.CLASSIFY(
        review,
        categories => [
          ('terrible', 'Review where customer was not happy and the message indicates they will never try this product again'),
          ('bad', 'Review where customer was not happy but suggested improvements to the product'),
          ('okay', 'Review where customer was neutral about the product. Short reviews qualify for this category'),
          ('good', 'Review where customers were happy using this product but had minor critiques'),
          ('excellent', 'Review where customers were very happy using this product and will recommend others to try it too')],
        embeddings => review_embeddings)
      
  • Essayez des modèles d'embedding plus avancés, comme text-embedding-005 ou multimodalembedding.

  • Contactez bqml-feedback@google.com pour obtenir de l'aide supplémentaire pour le débogage.

Nombre inattendu de lignes traitées par le LLM

Problème : Les statistiques d'exécution des requêtes montrent qu'un nombre de lignes anormalement élevé a été traité par le LLM distant au lieu du modèle distillé. Cela peut être dû aux raisons suivantes :

  • Le modèle distillé a bien été entraîné, mais certaines lignes comportaient des embeddings manquants. Ces lignes sont traitées par le LLM distant.
  • Le modèle distillé n'a pas pu être appliqué à chaque ligne et a dû revenir au LLM distant pour maintenir une qualité cohérente.

Solution : Vérifiez que les embeddings sont correctement générés et valides pour toutes les lignes de vos données. Si le problème persiste, contactez bqml-feedback@google.com pour le déboguer.

Colonne d'intégration autonome non détectée

Problème : BigQuery ne parvient pas à détecter une colonne d'embedding autonome. Cela peut se produire si votre script utilise une table temporaire et que la référence à la table d'origine est perdue.

Solution : Utilisez le paramètre embeddings pour transmettre explicitement une colonne d'intégration autonome (par exemple, embeddings => content_embedding.result), ce qui déclenche l'optimisation des coûts.

Étapes suivantes