Sdílet prostřednictvím


Azure OpenAI pro velké objemy dat

Službu Azure OpenAI je možné použít k řešení velkého počtu úloh přirozeného jazyka prostřednictvím výzvy rozhraní API pro dokončení. Abychom usnadnili škálování výzev z několika příkladů na velké datové sady příkladů, integrujeme službu Azure OpenAI s distribuovanou knihovnou strojového učení SynapseML. Tato integrace usnadňuje použití architektury distribuovaného výpočetního prostředí Apache Spark ke zpracování milionů výzev pomocí služby OpenAI. V tomto kurzu se dozvíte, jak používat velké jazykové modely v distribuovaném měřítku pomocí Azure Open AI a Azure Synapse Analytics.

Požadavky

Mezi klíčové předpoklady pro tento rychlý start patří funkční prostředek Azure OpenAI a cluster Apache Spark s nainstalovaným SynapseML.

Importovat tuto příručku jako poznámkový blok

Dalším krokem je přidání tohoto kódu do clusteru Spark. Můžete vytvořit poznámkový blok na platformě Spark a zkopírovat kód do tohoto poznámkového bloku a spustit ukázku. Nebo si poznámkový blok stáhněte a naimportujte ho do Synapse Analytics.

  1. Stáhněte si tuto ukázku jako poznámkový blok (vyberte Raw a pak soubor uložte).
  2. Import poznámkového bloku do pracovního prostoru Synapse nebo při použití importu prostředků infrastruktury do pracovního prostoru infrastruktury
  3. Nainstalujte SynapseML do clusteru. Pokyny k instalaci pro Synapse najdete v dolní části webu SynapseML. Pokud používáte prostředky infrastruktury, projděte si průvodce instalací. To vyžaduje vložení nadbytečné buňky v horní části importovaného poznámkového bloku.
  4. Připojení poznámkový blok do clusteru a postupujte podle toho, jak upravovat a spouštět buňky.

Vyplnění informací o službě

Dále upravte buňku v poznámkovém bloku tak, aby odkazovat na vaši službu. Konkrétně nastavte service_name, deployment_namea key proměnné tak, locationaby odpovídaly vaší službě OpenAI:

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

Vytvoření datové sady s výzvami

Dále vytvořte datový rámec skládající se z řady řádků s jednou výzvou na řádek.

Data můžete načíst také přímo z ADLS nebo jiných databází. Další informace o načítání a přípravě datových rámců Sparku najdete v průvodci načítáním dat Apache Sparku.

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

Vytvoření klienta Apache Spark OpenAICompletion

Chcete-li použít službu Dokončování OpenAI na vytvořený datový rámec, vytvořte objekt OpenAICompletion, který slouží jako distribuovaný klient. Parametry služby je možné nastavit buď s jednou hodnotou, nebo sloupcem datového rámce s příslušnými zatřikováním objektu OpenAICompletion . Tady nastavíme maxTokens 200. Token je kolem čtyř znaků a tento limit platí pro součet výzvy a výsledku. Nastavujeme také promptCol parametr s názvem sloupce výzvy v datovém rámci.

from synapse.ml.cognitive import OpenAICompletion

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

Transformace datového rámce pomocí klienta OpenAICompletion

Po dokončení datového rámce a dokončení klienta můžete transformovat vstupní datovou sadu a přidat sloupec, který volá completions se všemi informacemi, které služba přidá. Pro zjednodušení vyberte jenom text.

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

Výstup by měl vypadat přibližně takto. Text dokončení se bude lišit od ukázky.

Výzva Chyba text
Dobrý den, moje jméno je null Makaveli jsem 18 let a chci být rapper, když jsem vyrůstá, miluju psaní a tvorbu hudby, kterou jsem z Los Angeles, CA
Nejlepší kód je kód, který je null pochopitelné Toto je subjektivní tvrzení, a neexistuje žádná konečná odpověď.
SynapseML je null Algoritmus strojového učení, který se dokáže naučit, jak předpovědět budoucí výsledek událostí.

Další příklady použití

Generování vkládání textu

Kromě dokončování textu můžeme také vložit text pro použití v podřízených algoritmech nebo architekturách načítání vektorů. Vytváření vložených objektů umožňuje prohledávat a načítat dokumenty z velkých kolekcí a je možné je použít, když pro úkol nestačí příprava výzvy. Další informace o použití OpenAIEmbeddingnajdete v našem průvodci vkládáním.

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

Dokončení chatu

Modely, jako je ChatGPT a GPT-4, umí porozumět chatům místo jednoduchých výzev. Transformátor OpenAIChatCompletion tuto funkci zveřejňuje ve velkém měřítku.

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

Zlepšení propustnosti pomocí dávkování požadavků

V příkladu se do služby odešle několik požadavků, jeden pro každou výzvu. Pokud chcete dokončit více výzev v jednom požadavku, použijte režim dávky. Nejprve v objektu OpenAICompletion místo nastavení sloupce Prompt na Prompt (Výzva) zadejte pro sloupec BatchPrompt hodnotu batchPrompt. Uděláte to tak, že vytvoříte datový rámec se seznamem výzev na řádek.

V současné době platí limit 20 výzev v jednom požadavku a pevný limit 2048 tokenů nebo přibližně 1500 slov.

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

Dále vytvoříme objekt OpenAICompletion. Místo nastavení sloupce výzvy nastavte sloupec batchPrompt, pokud je sloupec typu Array[String].

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

V rámci volání transformace se požadavek provede na každý řádek. Vzhledem k tomu, že jeden řádek obsahuje více výzev, každý požadavek se odešle se všemi výzvami v daném řádku. Výsledky obsahují řádek pro každý řádek v požadavku.

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

Použití automatického minibatcheru

Pokud jsou data ve formátu sloupce, můžete je transponovat do formátu řádku pomocí synapseML 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)

Výzva k vytvoření překladu

Služba Azure OpenAI dokáže řešit mnoho různých úloh přirozeného jazyka prostřednictvím přípravy výzvy. Tady si ukážeme příklad výzvy k překladu jazyka:

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

Výzva k zodpovězení otázky

Tady se zobrazí výzva GPT-3 k zodpovězení obecných otázek:

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