Partager via


Utiliser Azure OpenAI avec des jeux de données volumineux

Azure OpenAI peut être utilisé pour résoudre un grand nombre de tâches en langage naturel via l’invite de l’API d’achèvement. Pour faciliter la mise à l’échelle de vos flux de travail d’invite à partir de quelques exemples vers des jeux de données volumineux d’exemples, nous avons intégré le service Azure OpenAI à la bibliothèque SynapseML de Machine Learning distribuée. Cette intégration facilite l’utilisation de l’infrastructure de calcul distribuée Apache Spark pour traiter des millions d’invites avec le service OpenAI. Ce tutoriel montre comment appliquer des modèles de langage volumineux à une échelle distribuée à l’aide d’Azure Open AI et d’Azure Synapse Analytics.

Prérequis

  • Un abonnement Azure - En créer un gratuitement

  • Accès accordé à Azure OpenAI dans l’abonnement Azure souhaité

    L’accès à ce service n’est accordé qu’à l’application. Vous pouvez demander l’accès à Azure OpenAI en complétant le formulaire à l’adresse https://aka.ms/oai/access. Ouvrez un problème sur ce dépôt pour nous contacter si vous rencontrez un problème.

  • Une ressource Azure OpenAI : créer une ressource

  • Un cluster Apache Spark avec SynapseML installé : créez un pool Spark Apache serverless ici

Nous vous recommandons de créer un espace de travail Synapse, mais un environnement Azure Databricks, HDInsight ou Spark sur Kubernetes, ou même Python avec le package pyspark, fonctionnera également.

Importer ce guide en tant que notebook

L’étape suivante consiste à ajouter ce code à votre cluster Spark. Vous pouvez créer un notebook dans votre plateforme Spark et copier le code dans ce notebook pour exécuter la démonstration, ou télécharger le notebook et l’importer dans Synapse Analytics.

  1. Téléchargez cette démonstration en tant que notebook (cliquez sur Raw, puis enregistrez le fichier)
  2. Importez le notebook dans l’espace de travail Synapse ou, si vous utilisez Databricks, dans l’espace de travail Databricks
  3. Installez SynapseML sur votre cluster. Consultez les instructions d’installation de Synapse en bas du site web SynapseML. Cela nécessite le collage d’une autre cellule en haut du notebook que vous avez importé
  4. Connectez votre notebook à un cluster et suivez, modifiez et exécutez les cellules ci-dessous.

Remplissez vos informations de service

Ensuite, modifiez la cellule du notebook pour pointer vers votre service. En particulier, définissez les variables resource_name, deployment_name, location et key sur les valeurs correspondantes pour votre ressource Azure OpenAI.

Important

N’oubliez pas de supprimer la clé de votre code une fois que vous avez terminé, et ne la postez jamais publiquement. Pour la production, utilisez un moyen sécurisé de stocker et d’accéder à vos informations d’identification comme Azure Key Vault. Pour plus d’informations, consultez l’article sur la sécurité de Cognitive Services.

import os

# Replace the following values with your Azure OpenAI resource information
resource_name = "RESOURCE_NAME"      # The name of your Azure OpenAI resource.
deployment_name = "DEPLOYMENT_NAME"  # The name of your Azure OpenAI deployment.
location = "RESOURCE_LOCATION"       # The location or region ID for your resource.
key = "RESOURCE_API_KEY"             # The key for your resource.

assert key is not None and resource_name is not None

Créer un jeu de données d’invites

Ensuite, créez un dataframe composé d’une série de lignes, avec une invite par ligne.

Vous pouvez également charger des données directement à partir de Azure Data Lake Storage (ADLS) ou d’autres bases de données. Pour plus d’informations sur le chargement et la préparation des dataframes Spark, consultez le guide de chargement des données Apache Spark.

df = spark.createDataFrame(
    [
        ("Hello my name is",),
        ("The best code is code that's",),
        ("SynapseML is ",),
    ]
).toDF("prompt")

Créer le client Apache Spark OpenAICompletion

Pour appliquer le service d’achèvement OpenAI au dataframe que vous venez de créer, créez un objet OpenAICompletion qui sert de client distribué. Les paramètres du service peuvent être définis avec une valeur unique ou par une colonne du dataframe avec les setters appropriés sur l’objet OpenAICompletion. Ici, nous allons définir maxTokens sur 200. Un jeton est autour de quatre caractères, et cette limite s’applique à la somme de l’invite et au résultat. Nous définissons également le paramètre promptCol avec le nom de la colonne d’invite dans le dataframe.

from synapse.ml.cognitive import OpenAICompletion

completion = (
    OpenAICompletion()
    .setSubscriptionKey(key)
    .setDeploymentName(deployment_name)
    .setUrl("https://{}.openai.azure.com/".format(resource_name))
    .setMaxTokens(200)
    .setPromptCol("prompt")
    .setErrorCol("error")
    .setOutputCol("completions")
)

Transformer le dataframe avec le client OpenAICompletion

Maintenant que vous disposez du dataframe et du client d’achèvement, vous pouvez transformer votre jeu de données d’entrée et ajouter une colonne appelée completions avec toutes les informations ajoutées par le service. Pour plus de facilité, nous allons sélectionner uniquement le texte.

from pyspark.sql.functions import col

completed_df = completion.transform(df).cache()
display(completed_df.select(
  col("prompt"), col("error"), col("completions.choices.text").getItem(0).alias("text")))

Votre résultat doit ressembler à l’exemple suivant ; notez que le texte d’achèvement peut varier.

prompt error text
Bonjour, je m’appelle non défini Makaveli, j’ai dix-huit ans et je voudrais
devenir un rappeur J’aime écrire et faire de la musique Je suis originaire de Los
Los Angeles, CA
Le meilleur code est le code qui est non défini compréhensible Il s’agit d’une déclaration subjective,
et il n’y a pas de réponse définitive.
SynapseML est non défini Un algorithme de Machine Learning capable d’apprendre à prédire le résultat futur des événements.

Autres exemples d’utilisation

Améliorer le débit avec le traitement par lots de requêtes

L’exemple ci-dessus effectue plusieurs requêtes au service, une pour chaque invite. Pour effectuer plusieurs invites dans une seule requête, utilisez le mode par lots. Tout d’abord, dans l’objet OpenAICompletion, au lieu de définir la colonne Prompt sur « Prompt », spécifiez « batchPrompt » pour la colonne BatchPrompt. Pour ce faire, créez un dataframe avec une liste d’invites par ligne.

Notes

Il existe actuellement une limite de 20 invites dans une seule requête et une limite de 2 048 « jetons » ou d’environ 1 500 mots.

batch_df = spark.createDataFrame(
    [
        (["The time has come", "Pleased to", "Today stocks", "Here's to"],),
        (["The only thing", "Ask not what", "Every litter", "I am"],),
    ]
).toDF("batchPrompt")

Ensuite, nous créons l’objet OpenAICompletion. Au lieu de définir la colonne d’invite, définissez la colonne batchPrompt si votre colonne est de type Array[String].

batch_completion = (
    OpenAICompletion()
    .setSubscriptionKey(key)
    .setDeploymentName(deployment_name)
    .setUrl("https://{}.openai.azure.com/".format(resource_name))
    .setMaxTokens(200)
    .setBatchPromptCol("batchPrompt")
    .setErrorCol("error")
    .setOutputCol("completions")
)

Dans l’appel à transformer, une requête est ensuite effectuée par ligne. Étant donné qu’il existe plusieurs invites dans une seule ligne, chaque requête est envoyée avec toutes les invites de cette ligne. Les résultats contiennent une ligne pour chaque ligne de la requête.

completed_batch_df = batch_completion.transform(batch_df).cache()
display(completed_batch_df)

Notes

Il existe actuellement une limite de 20 invites dans une seule requête et une limite de 2 048 « jetons » ou d’environ 1 500 mots.

Utilisation de l’outil de mise par lots

Si vos données sont en colonne, vous pouvez les transposer en ligne en utilisant FixedMiniBatcherTransformer de SynapseML.

from pyspark.sql.types import StringType
from synapse.ml.stages import FixedMiniBatchTransformer
from synapse.ml.core.spark import FluentAPI

completed_autobatch_df = (df
 .coalesce(1) # Force a single partition so that our little 4-row dataframe makes a batch of size 4, you can remove this step for large datasets
 .mlTransform(FixedMiniBatchTransformer(batchSize=4))
 .withColumnRenamed("prompt", "batchPrompt") 
 .mlTransform(batch_completion))

display(completed_autobatch_df)

Ingénierie d’invite pour la traduction

Azure OpenAI peut résoudre de nombreuses tâches de langage naturel différentes par le biais de l’ingénierie d’invite. Voici un exemple d’invite de traduction de langage de programmation :

translate_df = spark.createDataFrame(
    [
        ("Japanese: Ookina hako \nEnglish: Big box \nJapanese: Midori tako\nEnglish:",),
        ("French: Quelle heure est-il à Montréal? \nEnglish: What time is it in Montreal? \nFrench: Où est le poulet? \nEnglish:",),
    ]
).toDF("prompt")

display(completion.transform(translate_df))

Demander la réponse aux questions

Ici, nous demandons au modèle GPT-3 de répondre aux questions générales :

qa_df = spark.createDataFrame(
    [
        (
            "Q: Where is the Grand Canyon?\nA: The Grand Canyon is in Arizona.\n\nQ: What is the weight of the Burj Khalifa in kilograms?\nA:",
        )
    ]
).toDF("prompt")

display(completion.transform(qa_df))