Läs på engelska

Dela via


Azure OpenAI för stordata

Azure OpenAI-tjänsten kan användas för att lösa ett stort antal uppgifter på naturligt språk genom att fråga api:et för slutförande. För att göra det enklare att skala dina frågande arbetsflöden från några exempel till stora datauppsättningar med exempel, integrerade vi Azure OpenAI-tjänsten med det distribuerade maskininlärningsbiblioteket SynapseML. Den här integreringen gör det enkelt att använda Apache Spark-ramverket för distribuerad databehandling för att bearbeta miljontals frågor med OpenAI-tjänsten. Den här självstudien visar hur du använder stora språkmodeller i distribuerad skala med hjälp av Azure OpenAI och Azure Synapse Analytics.

Förutsättningar

De viktigaste förutsättningarna för den här snabbstarten är en fungerande Azure OpenAI-resurs och ett Apache Spark-kluster med SynapseML installerat.

Importera den här guiden som en notebook-fil

Nästa steg är att lägga till den här koden i Spark-klustret. Du kan antingen skapa en notebook-fil på Spark-plattformen och kopiera koden till den här notebook-filen för att köra demonstrationen. Eller ladda ned anteckningsboken och importera den till Synapse Analytics

  1. Ladda ned den här demonstrationen som en notebook-fil (välj Raw och spara sedan filen)
  2. Importera anteckningsboken till Synapse-arbetsytan eller om du använder import av infrastrukturresurser till arbetsytan Infrastruktur
  3. Installera SynapseML i klustret. Se installationsanvisningarna för Synapse längst ned på SynapseML-webbplatsen. Om du använder Infrastruktur kontrollerar du installationsguiden. Detta kräver att du klistrar in en extra cell överst i anteckningsboken som du har importerat.
  4. Anslut anteckningsboken till ett kluster och följ med, redigera och köra cellerna.

Fyll i tjänstinformation

Redigera sedan cellen i notebook-filen så att den pekar på din tjänst. Ange särskilt variablerna service_name, deployment_name, locationoch key så att de matchar openAI-tjänsten:

import os
from pyspark.sql import SparkSession
from synapse.ml.core.platform import running_on_synapse, find_secret

# Bootstrap Spark Session
spark = SparkSession.builder.getOrCreate()

if running_on_synapse():
    from notebookutils.visualization import display

# Fill in the following lines with your service information
# Learn more about selecting which embedding model to choose: https://openai.com/blog/new-and-improved-embedding-model
service_name = "synapseml-openai"
deployment_name = "gpt-35-turbo"
deployment_name_embeddings = "text-embedding-ada-002"

key = find_secret(
    "openai-api-key"
)  # please replace this line with your key as a string

assert key is not None and service_name is not None

Skapa en datauppsättning med prompter

Skapa sedan en dataram som består av en serie rader, med en fråga per rad.

Du kan också läsa in data direkt från ADLS eller andra databaser. Mer information om hur du läser in och förbereder Spark-dataramar finns i datainläsningsguiden för Apache Spark.

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

Skapa Apache Spark-klienten OpenAICompletion

Om du vill tillämpa OpenAI Completion-tjänsten på din dataram som du skapade skapar du ett OpenAICompletion-objekt som fungerar som en distribuerad klient. Parametrar för tjänsten kan anges antingen med ett enda värde eller av en kolumn i dataramen med lämpliga uppsättningar på OpenAICompletion objektet. Här ställer vi in maxTokens på 200. En token är cirka fyra tecken, och den här gränsen gäller för summan av prompten och resultatet. Vi ställer också in parametern promptCol med namnet på promptkolumnen i dataramen.

from synapse.ml.cognitive import OpenAICompletion

completion = (
    OpenAICompletion()
    .setSubscriptionKey(key)
    .setDeploymentName(deployment_name)
    .setCustomServiceName(service_name)
    .setMaxTokens(200)
    .setPromptCol("prompt")
    .setErrorCol("error")
    .setOutputCol("completions")
)

Transformera dataramen med OpenAICompletion-klienten

När du har slutfört dataramen och slutförandeklienten kan du transformera indatauppsättningen och lägga till en kolumn med namnet completions med all information som tjänsten lägger till. Välj bara texten för enkelhetens skull.

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"),
    )
)

Dina utdata bör se ut ungefär så här. Slutförandetexten skiljer sig från exemplet.

snabb fel text
Hej mitt namn är NULL Makaveli Jag är arton år gammal och jag vill bli rappare när jag växer upp jag älskar att skriva och göra musik jag är från Los Angeles, CA
Den bästa koden är kod som är NULL begripligt Detta är ett subjektivt uttalande, och det finns inget definitivt svar.
SynapseML är NULL En maskininlärningsalgoritm som kan lära sig att förutsäga framtida resultat av händelser.

Fler användningsexempel

Generera text inbäddningar

Förutom att fylla i text kan vi även bädda in text för användning i underordnade algoritmer eller arkitekturer för vektorhämtning. Genom att skapa inbäddningar kan du söka efter och hämta dokument från stora samlingar och kan användas när prompttekniken inte räcker för uppgiften. Mer information om hur du använder OpenAIEmbeddingfinns i vår inbäddningsguide.

from synapse.ml.cognitive import OpenAIEmbedding

embedding = (
    OpenAIEmbedding()
    .setSubscriptionKey(key)
    .setDeploymentName(deployment_name_embeddings)
    .setCustomServiceName(service_name)
    .setTextCol("prompt")
    .setErrorCol("error")
    .setOutputCol("embeddings")
)

display(embedding.transform(df))

Chatten har slutförts

Modeller som ChatGPT och GPT-4 kan förstå chattar i stället för enskilda frågor. Transformatorn OpenAIChatCompletion exponerar den här funktionen i stor skala.

from synapse.ml.cognitive import OpenAIChatCompletion
from pyspark.sql import Row
from pyspark.sql.types import *


def make_message(role, content):
    return Row(role=role, content=content, name=role)


chat_df = spark.createDataFrame(
    [
        (
            [
                make_message(
                    "system", "You are an AI chatbot with red as your favorite color"
                ),
                make_message("user", "Whats your favorite color"),
            ],
        ),
        (
            [
                make_message("system", "You are very excited"),
                make_message("user", "How are you today"),
            ],
        ),
    ]
).toDF("messages")


chat_completion = (
    OpenAIChatCompletion()
    .setSubscriptionKey(key)
    .setDeploymentName(deployment_name)
    .setCustomServiceName(service_name)
    .setMessagesCol("messages")
    .setErrorCol("error")
    .setOutputCol("chat_completions")
)

display(
    chat_completion.transform(chat_df).select(
        "messages", "chat_completions.choices.message.content"
    )
)

Förbättra dataflödet med batchbearbetning av begäranden

Exemplet gör flera begäranden till tjänsten, en för varje fråga. Om du vill slutföra flera frågor i en enda begäran använder du batchläge. I objektet OpenAICompletion anger du först "batchPrompt" för kolumnen BatchPrompt i stället för att ange promptkolumnen till "Prompt". Det gör du genom att skapa en dataram med en lista med frågor per rad.

När det här skrivs finns det för närvarande en gräns på 20 frågor i en enda begäran och en hård gräns på 2 048 "tokens" eller cirka 1 500 ord.

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")

Sedan skapar vi OpenAICompletion-objektet. I stället för att ange promptkolumnen anger du batchPrompt-kolumnen om din kolumn är av typen Array[String].

batch_completion = (
    OpenAICompletion()
    .setSubscriptionKey(key)
    .setDeploymentName(deployment_name)
    .setCustomServiceName(service_name)
    .setMaxTokens(200)
    .setBatchPromptCol("batchPrompt")
    .setErrorCol("error")
    .setOutputCol("completions")
)

I anropet till transformering görs en begäran per rad. Eftersom det finns flera frågor på en rad skickas varje begäran med alla prompter på den raden. Resultatet innehåller en rad för varje rad i begäran.

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

Använda en automatisk minibatcher

Om dina data är i kolumnformat kan du transponera dem till radformat med hjälp av SynapseML:s FixedMiniBatcherTransformer.

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)

Fråga efter teknik för översättning

Azure OpenAI-tjänsten kan lösa många olika uppgifter med naturligt språk via prompt-teknik. Här visar vi ett exempel på frågor om språköversättning:

translate_df = spark.createDataFrame(
    [
        ("Japanese: Ookina hako \nEnglish: Big box \nJapanese: Midori tako\nEnglish:",),
        (
            "French: Quel heure et il au Montreal? \nEnglish: What time is it in Montreal? \nFrench: Ou est le poulet? \nEnglish:",
        ),
    ]
).toDF("prompt")

display(completion.transform(translate_df))

Fråga efter svar på frågor

Här frågar vi GPT-3 om svar på allmän kunskapsfråga:

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))