次の方法で共有


大規模なデータセットで Azure OpenAI を使用する

Azure OpenAI を使用すると、入力候補 API を要求することで、多数の自然言語タスクを解決できます。 プロンプト ワークフローをいくつかの例から大規模なデータセットの例に簡単にスケーリングできるように、Azure OpenAI サービスと分散機械学習ライブラリ SynapseML を統合しました。 この統合により、Apache Spark 分散コンピューティング フレームワークを使用して、OpenAI サービスで何百万ものプロンプトを処理することが容易になります。 このチュートリアルでは、Azure Open AI と Azure Synapse Analytics を使用して、大規模な言語モデルを分散スケールで適用する方法について説明します。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • 目的の Azure サブスクリプション内の Azure OpenAI に付与されるアクセス

    現時点では、このサービスへのアクセスは申請によってのみ許可されます。 Azure OpenAI へのアクセスを申請するには、https://aka.ms/oai/access のフォームに入力してください。 問題がある場合は、このリポジトリで問題を開いてお問い合わせください。

  • Azure OpenAI リソース: リソースを作成する

  • SynapseML がインストールされた Apache Spark クラスター - ここでサーバーレス Apache Spark プールを作成します

Synapse ワークスペースを作成することをお勧めしますが、Azure Databricks、HDInsight、Spark on Kubernete、または pyspark パッケージを含む Python 環境も機能します。

このガイドをノートブックとしてインポートする

次の手順では、このコードを Spark クラスターに追加します。 Spark プラットフォームでノートブックを作成し、このノートブックにコードをコピーしてデモを実行するか、ノートブックをダウンロードして Synapse Analytics にインポートすることができます。

  1. このデモをノートブックとしてダウンロードします ([Raw](未加工) をクリックし、ファイルを保存します)
  2. ノートブックを Synapse ワークスペースにインポートするか、Databricks を使用している場合は、Databricks ワークスペースにインポートします
  3. クラスターに SynapseML をインストールします。 SynapseML Web サイトの下部にある Synapse のインストール手順を参照してください。 このためには、インポートしたノートブックの上部に別のセルを貼り付ける必要があります
  4. ノートブックをクラスターに接続し、以下のセルを編集して実行します。

サービス情報を入力する

次に、ノートブック内のセルを編集して、サービスをポイントします。 特に、resource_namedeployment_namelocationkey 変数を、Azure OpenAI リソースの対応する値に設定します。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳細については、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

プロンプトのデータセットを作成する

次に、一連の行で構成され、行ごとに 1 つのプロンプトがあるデータフレームを作成します。

Azure Data Lake Storage (ADLS) またはその他のデータベースから直接データを読み込むこともできます。 Spark データフレームの読み込みと準備の詳細については、Apache Spark データ読み込みガイドを参照してください。

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

OpenAICompletion Apache Spark クライアントを作成する

先ほど作成したデータフレームに OpenAI Completion サービスを適用するには、分散クライアントとして機能する OpenAICompletion オブジェクトを作成します。 サービスのパラメーターは、単一の値で設定することも、OpenAICompletion オブジェクト上の適切なセッターを含むデータフレームの列で設定することもできます。 ここでは、maxTokens を200 に設定します。 トークンは 4 文字ぐらいで、この制限はプロンプトと結果の合計に適用されます。 また、データフレームのプロンプト列の名前を使用して promptCol パラメーターを設定します。

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

OpenAICompletion クライアントを使用してデータフレームを変換する

データフレームと入力候補クライアントができたので、入力データセットを変換し、サービスが追加するすべての情報と共に completions という列を追加できます。 わかりやすくするために、テキストのみを選択します。

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

出力は次の例のようになります。入力候補のテキストは異なる場合があることに注意してください。

prompt error text
Hello my name is (こんにちは、私の名前は) undefined Makaveli I'm eighteen years old and I want to (Makaveli です。18 歳です。私は)
be a rapper when I grow up I love writing and making music I'm from Los (大人になったらラッパーになりたいと思っています。作曲することが大好きです)
Angeles, CA (カリフォルニア州ロサンゼルスから来ました)
The best code is code that's (最適なコードは、) undefined understandable This is a subjective statement, (理解可能なものです。これは主観的なステートメントです)
and there is no definitive answer. (明確な答えはありません)
SynapseML is (SynapseM は、) undefined A machine learning algorithm that is able to learn how to predict the future outcome of events.(イベントの将来の結果を予測する方法を学習できる機械学習アルゴリズムです)

その他の使用例

要求のバッチ処理を使用してスループットを向上させる

上記の例では、プロンプトごとに 1 つずつ、サービスに対して複数の要求を行います。 1 つの要求で複数のプロンプトを完了すために、バッチ モードを使用します。 まず、OpenAICompletion オブジェクトで Prompt 列を "Prompt" に設定する代わりに、BatchPrompt 列に "batchPrompt" を指定します。 そのためには、行ごとにプロンプトの一覧を含むデータフレームを作成します。

注意

現在、1 つの要求に 20 件のプロンプトという制限があり、2048 個の "トークン" (約 1500 ワード) という制限があります。

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

次に、OpenAICompletion オブジェクトを作成します。 prompt 列を設定するのではなく、列の型が Array[String] の場合は、batchPrompt 列を設定します。

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

変換の呼び出しでは、行ごとに要求が行われます。 1 つの行に複数のプロンプトがあるため、各要求は、その行のすべてのプロンプトと共に送信されます。 結果には、要求の各行の行が含まれます。

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

注意

現在、1 つの要求に 20 件のプロンプトという制限があり、2048 個の "トークン" (約 1500 ワード) という制限があります。

自動ミニバッチ機能の使用

データが列形式の場合は、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)

翻訳のための迅速なエンジニアリング

Azure OpenAI は、プロンプト エンジニアリングを通じて、さまざまな自然言語タスクを解決できます。 言語翻訳を求めるプロンプトの例を次に示します。

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

質問の回答を求めるプロンプト

ここでは、GPT-3 モデルに一般的な知識に関する質問への回答を求めます。

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