다음을 통해 공유


빅 데이터를 위한 Azure OpenAI

Azure OpenAI 서비스는 완료 API의 프롬프트 처리를 통해 많은 자연어 작업을 해결하는 데 사용할 수 있습니다. 프롬프트 워크플로를 몇 가지 예제에서 대규모 예제 데이터 세트로 쉽게 확장할 수 있도록 Azure OpenAI 서비스를 분산 기계 학습 라이브러리인 SynapseML과 통합했습니다. 이러한 통합으로 Apache Spark 분산 컴퓨팅 프레임워크를 쉽게 사용할 수 있어 OpenAI 서비스를 통해 수백만 개의 프롬프트를 처리할 수 있습니다. 이 자습서에서는 Azure OpenAI 및 Azure Synapse Analytics를 사용하여 대규모 언어 모델을 분산된 규모로 적용하는 방법을 보여줍니다.

필수 조건

이 빠른 시작의 주요 필수 구성 요소에는 작동하는 Azure OpenAI 리소스 및 SynapseML이 설치된 Apache Spark 클러스터가 포함됩니다.

  • Microsoft Fabric 구독을 구매합니다. 또는 무료 Microsoft Fabric 평가판에 등록합니다.

  • Microsoft Fabric에 로그인합니다.

  • 홈페이지 왼쪽의 환경 전환기를 사용하여 Synapse 데이터 과학 환경으로 전환합니다.

    데이터 과학을 선택할 위치를 보여 주는 환경 전환기 메뉴의 스크린샷.

이 가이드를 Notebook으로 가져오기

다음 단계에서는 이 코드를 Spark 클러스터에 추가합니다. Spark 플랫폼에서 Notebook을 만들고 코드를 이 Notebook에 복사하여 데모를 실행할 수 있습니다. 또는 Notebook을 다운로드하여 Synapse Analytics로 가져옵니다.

  1. 이 데모를 Notebook으로 다운로드합니다(원시를 선택한 다음, 파일 저장).
  2. Notebook을 Synapse 작업 영역으로 가져오거나 패브릭을 사용하는 경우 패브릭 작업 영역으로 가져옵니다.
  3. 클러스터에 SynapseML을 설치합니다. SynapseML 웹 사이트의 맨 아래에 있는 Synapse에 대한 설치 지침을 참조하세요. 패브릭을 사용하는 경우 설치 가이드를 확인합니다. 이렇게 하려면 가져온 Notebook의 맨 위에 추가로 셀을 붙여넣어야 합니다.
  4. Notebook을 클러스터에 연결하고 셀을 편집하고 실행하면서 따라해 봅니다.

서비스 정보 채우기

다음으로, 서비스를 가리키도록 Notebook의 셀을 편집합니다. 특히 OpenAI 서비스와 일치하도록 service_name, deployment_name, location, key 변수를 설정합니다.

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

프롬프트의 데이터 세트 만들기

다음으로, 행당 하나의 프롬프트를 사용하여 일련의 행으로 구성된 데이터 프레임을 만듭니다.

ADLS 또는 다른 데이터베이스에서 직접 데이터를 로드할 수도 있습니다. Spark 데이터 프레임 로드 및 준비에 대한 자세한 내용은 Apache Spark 데이터 로드 가이드를 참조하세요.

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

OpenAICompletion Apache Spark 클라이언트 만들기

방금 만든 데이터 프레임에 OpenAI Completion 서비스를 적용하려면 분산 클라이언트 역할을 하는 OpenAICompletion 개체를 만듭니다. 서비스의 매개 변수는 단일 값으로 설정하거나 OpenAICompletion 개체에 적절한 setter가 있는 데이터 프레임의 열로 설정할 수 있습니다. 여기서는 maxTokens를 200으로 설정하고 있습니다. 토큰은 약 4자이며 이 제한은 프롬프트와 결과의 합계에 적용됩니다. 또한 promptCol 매개 변수를 데이터 프레임의 프롬프트 열 이름으로 설정합니다.

from synapse.ml.cognitive import OpenAICompletion

completion = (
    OpenAICompletion()
    .setSubscriptionKey(key)
    .setDeploymentName(deployment_name)
    .setCustomServiceName(service_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
안녕하세요, 제 이름은 null Makaveli 저는 열여덟 살이고 크면 래퍼가 되고 싶고 곡을 쓰고 만드는 걸 좋아하고 캘리포니아 로스앤젤레스에 살고 있습니다.
가장 좋은 코드는 null 이해하기 쉬운 코드입니다. 이는 주관적인 설명이며 확실한 대답은 없습니다.
SynapseML은 null 이벤트의 향후 결과를 예측하는 방법을 배울 수 있는 기계 학습 알고리즘입니다.

추가 사용 예제

텍스트 포함 생성

텍스트 완료 외에도 다운스트림 알고리즘이나 벡터 검색 아키텍처에 사용할 텍스트를 삽입할 수도 있습니다. 포함을 만들면 대규모 컬렉션에서 문서를 검색하고 검색할 수 있으며 프롬프트 엔지니어링이 작업에 충분하지 않을 때 사용할 수 있습니다. OpenAIEmbedding 사용에 대한 자세한 내용은 포함 가이드를 참조하세요.

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

채팅 완료

ChatGPT 및 GPT-4와 같은 모델은 단일 프롬프트 대신 채팅을 이해할 수 있습니다. OpenAIChatCompletion 변환기는 이 기능을 대규모로 공개합니다.

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

요청 일괄 처리를 사용하여 처리량 향상

예제에서는 각 프롬프트에 대해 하나씩 서비스에 대한 여러 요청을 만듭니다. 단일 요청으로 여러 프롬프트를 완료하려면 일괄 처리 모드를 사용합니다. 먼저, OpenAICompletion 개체에서 프롬프트 열을 "Prompt"로 설정하는 대신 BatchPrompt 열에 대해 "batchPrompt"를 지정합니다. 이렇게 하려면 행 하나당 프롬프트 목록이 있는 데이터 프레임을 만듭니다.

현재 문서 날짜 기준으로 단일 요청에서는 프롬프트 20개, “토큰” 2,048개, 단어 약 1,500개로 엄격하게 제한됩니다.

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 개체를 만듭니다. 프롬프트 열을 설정하는 대신 열이 형식 Array[String]인 경우 batchPrompt 열을 설정합니다.

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

변환 호출에서 행당 요청이 만들어집니다. 단일 행에 여러 프롬프트가 있으므로 각 요청은 해당 행의 모든 프롬프트와 함께 전송됩니다. 결과에는 요청의 각 행에 대한 행이 포함됩니다.

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

자동 미니 일괄 처리기 사용

데이터가 열 형식인 경우 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: 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))

질문 답변 프롬프트

여기서는 일반적인 지식을 묻는 질문 답변에 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))