반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

Azure OpenAI를 사용하려면 해당 서비스를 사용할 수 있는 권한을 Microsoft 사로부터 얻어야 합니다.

저는 공부 목적으로 필요하다고 신청했는데 거부 됐습니다.

 

 

실제 이 Azure OpenAI를 이용해서 제품을 개발하고자 한다면 한번 신청해 보세요.

신청 방법은 아래 글에 정리 해 놨습니다.

https://coronasdk.tistory.com/1304

 

Azure OpenAI 를 사용하기 위한 사전 요구 사항들 - 사용 요청 거부 됨

OpenAI CookBook 을 거의 다 공부하고 Azure OpenAI 를 공부할 차례 입니다. https://github.com/openai/openai-cookbook GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API Examples and guides for using the OpenAI API. C

coronasdk.tistory.com

 

저는 일단 실습은 못하고 Cookbook에 있는 글로 공부해 보겠습니다.

 

https://github.com/openai/openai-cookbook/blob/main/examples/azure/finetuning.ipynb

 

GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API

Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.

github.com

 

Azure Fine tuning example

In this example we'll try to go over all operations that can be done using the Azure endpoints and their differences with the openAI endpoints (if any).

 

이 예제에서는 Azure endpoints 를  사용하여 수행할 수 있는 모든 작업과 openAI endpoints  (있는 경우)과의 차이점을 살펴보겠습니다.


This example focuses on finetuning but also touches on the majority of operations that are available using the API. This example is meant to be a quick way of showing simple operations and is not meant as a finetune model adaptation tutorial.

 

이 예제는 finetuning에 중점을 두지만 API를 사용하여 사용할 수 있는 대부분의 작업도 다룹니다. 이 예제는 간단한 작업을 빠르게 보여주기 위한 것이며 finetuning 모델 적용 튜토리얼이 아닙니다.

 

import openai
from openai import cli

 

Setup

For the following sections to work properly we first have to setup some things. Let's start with the api_base and api_version. To find your api_base go to https://portal.azure.com, find your resource and then under "Resource Management" -> "Keys and Endpoints" look for the "Endpoint" value.

 

다음 섹션이 제대로 작동하려면 먼저 몇 가지를 설정해야 합니다. api_base 및 api_version부터 시작하겠습니다. api_base를 찾으려면 https://portal.azure.com으로 이동하여 리소스를 찾은 다음 "Resource Management" -> "Keys and Endpoints"에서 "Endpoint" 값을 찾습니다.

 

openai.api_version = '2022-12-01'
openai.api_base = '' # Please add your endpoint here

 

We next have to setup the api_type and api_key. We can either get the key from the portal or we can get it through Microsoft Active Directory Authentication. Depending on this the api_type is either azure or azure_ad.

 

다음으로 api_type 및 api_key를 설정해야 합니다. 포털에서 키를 얻거나 Microsoft Active Directory 인증을 통해 얻을 수 있습니다. 이에 따라 api_type은 azure 또는 azure_ad입니다.

 

Setup: Portal

Let's first look at getting the key from the portal. Go to https://portal.azure.com, find your resource and then under "Resource Management" -> "Keys and Endpoints" look for one of the "Keys" values.

 

먼저 포털에서 키를 가져오는 방법을 살펴보겠습니다. https://portal.azure.com으로 이동하여 리소스를 찾은 다음 "Resource Management" -> "Keys and Endpoints"에서 "Keys" 값 중 하나를 찾습니다.

 

openai.api_type = 'azure'
openai.api_key = ''  # Please add your api key here

(Optional) Setup: Microsoft Active Directory Authentication

Let's now see how we can get a key via Microsoft Active Directory Authentication. Uncomment the following code if you want to use Active Directory Authentication instead of keys from the portal.

 

(선택 사항) 설정: Microsoft Active Directory 인증
이제 Microsoft Active Directory 인증을 통해 키를 얻는 방법을 살펴보겠습니다. 포털의 키 대신 Active Directory 인증을 사용하려면 다음 코드의 주석을 제거하십시오.

 

# from azure.identity import DefaultAzureCredential

# default_credential = DefaultAzureCredential()
# token = default_credential.get_token("https://cognitiveservices.azure.com/.default")

# openai.api_type = 'azure_ad'
# openai.api_key = token.token

 

Files

In the next section we will focus on the files operations: importing, listing, retrieving, deleting. For this we need to create 2 temporary files with some sample data. For the sake of simplicity, we will use the same data for training and validation.

 

다음 섹션에서는 가져오기, 나열, 검색, 삭제와 같은 파일 작업에 중점을 둘 것입니다. 이를 위해 일부 샘플 데이터로 2개의 임시 파일을 생성해야 합니다. 단순화를 위해 교육 및 검증에 동일한 데이터를 사용합니다.

 

import shutil
import json

training_file_name = 'training.jsonl'
validation_file_name = 'validation.jsonl'

sample_data = [{"prompt": "When I go to the store, I want an", "completion": "apple."},
    {"prompt": "When I go to work, I want a", "completion": "coffee."},
    {"prompt": "When I go home, I want a", "completion": "soda."}]

print(f'Generating the training file: {training_file_name}')
with open(training_file_name, 'w') as training_file:
    for entry in sample_data:
        json.dump(entry, training_file)
        training_file.write('\n')

print(f'Copying the training file to the validation file')
shutil.copy(training_file_name, validation_file_name)

 

Files: Listing

List all of the uploaded files and check for the ones that are named "training.jsonl" or "validation.jsonl"

 

업로드된 모든 파일을 나열하고 이름이 "training.jsonl" 또는 "validation.jsonl"인 파일을 확인합니다.

 

print('Checking for existing uploaded files.')
results = []
files = openai.File.list().data
print(f'Found {len(files)} total uploaded files in the subscription.')
for item in files:
    if item["filename"] in [training_file_name, validation_file_name]:
        results.append(item["id"])
print(f'Found {len(results)} already uploaded files that match our names.')

 

Files: Deleting

Let's now delete those found files (if any) since we're going to be re-uploading them next.

 

다음에 다시 업로드할 예정이므로 찾은 파일(있는 경우)을 삭제하겠습니다.

 

print(f'Deleting already uploaded files...')
for id in results:
    openai.File.delete(sid = id)

 

Files: Importing & Retrieving

Now, let's import our two files ('training.jsonl' and 'validation.jsonl') and keep those IDs since we're going to use them later for finetuning.

 

이제 두 파일('training.jsonl' 및 'validation.jsonl')을 가져오고 나중에 미세 조정에 사용할 것이므로 해당 ID를 유지하겠습니다.


For this operation we are going to use the cli wrapper which does a bit more checks before uploading and also gives us progress. In addition, after uploading we're going to check the status our import until it has succeeded (or failed if something goes wrong)

 

이 작업을 위해 업로드하기 전에 조금 더 확인하고 진행률을 제공하는 cli 래퍼를 사용할 것입니다. 또한 업로드 후 가져오기가 성공할 때까지(또는 무언가 잘못되면 실패할 때까지) 가져오기 상태를 확인합니다.

 

import time

def check_status(training_id, validation_id):
    train_status = openai.File.retrieve(training_id)["status"]
    valid_status = openai.File.retrieve(validation_id)["status"]
    print(f'Status (training_file | validation_file): {train_status} | {valid_status}')
    return (train_status, valid_status)

#importing our two files
training_id = cli.FineTune._get_or_upload(training_file_name, True)
validation_id = cli.FineTune._get_or_upload(validation_file_name, True)

#checking the status of the imports
(train_status, valid_status) = check_status(training_id, validation_id)

while train_status not in ["succeeded", "failed"] or valid_status not in ["succeeded", "failed"]:
    time.sleep(1)
    (train_status, valid_status) = check_status(training_id, validation_id)

 

Files: Downloading

Now let's download one of the files, the training file for example, to check that everything was in order during importing and all bits are there.

 

이제 파일 중 하나(예: 교육 파일)를 다운로드하여 가져오는 동안 모든 것이 제대로 작동하고 모든 비트가 있는지 확인합니다.

 

print(f'Downloading training file: {training_id}')
result = openai.File.download(training_id)
print(result.decode('utf-8'))

 

Finetune

In this section we are going to use the two training and validation files that we imported in the previous section, to train a finetune model.

 

이 섹션에서는 finetune  모델을 교육하기 위해 이전 섹션에서 가져온 두 개의 교육 및 검증 파일을 사용할 것입니다.

 

 

Finetune: Adapt

First let's create the finetune adaptation job.

먼저 미세 조정 적응 작업을 생성해 보겠습니다.

 

create_args = {
    "training_file": training_id,
    "validation_file": validation_id,
    "model": "babbage",
    "compute_classification_metrics": True,
    "classification_n_classes": 3,
    "n_epochs": 20,
    "batch_size": 3,
    "learning_rate_multiplier": 0.3
}
resp = openai.FineTune.create(**create_args)
job_id = resp["id"]
status = resp["status"]

print(f'Fine-tunning model with jobID: {job_id}.')

 

Finetune: Streaming

While the job runs, we can subscribe to the streaming events to check the progress of the operation.

작업이 실행되는 동안 스트리밍 이벤트를 구독하여 작업 진행 상황을 확인할 수 있습니다.

 

 

import signal
import datetime

def signal_handler(sig, frame):
    status = openai.FineTune.retrieve(job_id).status
    print(f"Stream interrupted. Job is still {status}.")
    return

print(f'Streaming events for the fine-tuning job: {job_id}')
signal.signal(signal.SIGINT, signal_handler)

events = openai.FineTune.stream_events(job_id)
try:
    for event in events:
        print(f'{datetime.datetime.fromtimestamp(event["created_at"])} {event["message"]}')

except Exception:
    print("Stream interrupted (client disconnected).")

 

Finetune: Listing and Retrieving

Now let's check that our operation was successful and in addition we can look at all of the finetuning operations using a list operation.

이제 작업이 성공했는지 확인하고 목록 작업을 사용하여 모든 finetune  작업을 볼 수 있습니다.

 

status = openai.FineTune.retrieve(id=job_id)["status"]
if status not in ["succeeded", "failed"]:
    print(f'Job not in terminal status: {status}. Waiting.')
    while status not in ["succeeded", "failed"]:
        time.sleep(2)
        status = openai.FineTune.retrieve(id=job_id)["status"]
        print(f'Status: {status}')
else:
    print(f'Finetune job {job_id} finished with status: {status}')

print('Checking other finetune jobs in the subscription.')
result = openai.FineTune.list()
print(f'Found {len(result.data)} finetune jobs.')

 

Finetune: Deleting

Finally we can delete our finetune job.
WARNING: Please skip this step if you want to continue with the next section as the finetune model is needed. (The delete code is commented out by default)

 

마지막으로 finetune  작업을 삭제할 수 있습니다.
경고: finetune 모델이 필요하므로 다음 섹션을 계속하려면 이 단계를 건너뛰십시오. (삭제 코드는 기본적으로 주석 처리됨)

 

# openai.FineTune.delete(sid=job_id)

 

Deployments

In this section we are going to create a deployment using the finetune model that we just adapted and then used the deployment to create a simple completion operation.

 

이 섹션에서는 방금 수정한 finetune  모델을 사용하여 deployment 를 생성한 다음 deployment 를 사용하여 간단한 completion  작업을 생성할 것입니다.

 

Deployments: Create

Let's create a deployment using the fine-tune model.

fine-tune모델을 사용하여 deployment 를 생성해 보겠습니다.

 

#Fist let's get the model of the previous job:
result = openai.FineTune.retrieve(id=job_id)
if result["status"] == 'succeeded':
    model = result["fine_tuned_model"]

# Now let's create the deployment
print(f'Creating a new deployment with model: {model}')
result = openai.Deployment.create(model=model, scale_settings={"scale_type":"standard"})
deployment_id = result["id"]

 

Deployments: Retrieving

Now let's check the status of the newly created deployment

이제 새로 생성된 배포의 상태를 확인하겠습니다.

 

print(f'Checking for deployment status.')
resp = openai.Deployment.retrieve(id=deployment_id)
status = resp["status"]
print(f'Deployment {deployment_id} is with status: {status}')

Deployments: Listing

Now because creating a new deployment takes a long time, let's look in the subscription for an already finished deployment that succeeded.

이제 새 deployment를 만드는 데 시간이 오래 걸리므로 이미 완료된 deployment에 대한 subscription 을 살펴보겠습니다.

 

print('While deployment running, selecting a completed one.')
deployment_id = None
result = openai.Deployment.list()
for deployment in result.data:
    if deployment["status"] == "succeeded":
        deployment_id = deployment["id"]
        break

if not deployment_id:
    print('No deployment with status: succeeded found.')
else:
    print(f'Found a successful deployment with id: {deployment_id}.')

 

Completions

Now let's send a sample completion to the deployment.

이제 deployment에 샘플 completion 을 보내겠습니다.

 

print('Sending a test completion job')
start_phrase = 'When I go home, I want a'
response = openai.Completion.create(deployment_id=deployment_id, prompt=start_phrase, temperature=0, stop=".")
text = response['choices'][0]['text'].replace('\n', '').replace(' .', '.').strip()
print(f'"{start_phrase} {text}."')

 

Deployments: Delete

Finally let's delete the deployment

마지막으로 deployment를 삭제하겠습니다.

 

print(f'Deleting deployment: {deployment_id}')
openai.Deployment.delete(sid=deployment_id)

 

반응형


반응형

Azure OpenAI를 사용하려면 해당 서비스를 사용할 수 있는 권한을 Microsoft 사로부터 얻어야 합니다.

저는 공부 목적으로 필요하다고 신청했는데 거부 됐습니다.

 

 

실제 이 Azure OpenAI를 이용해서 제품을 개발하고자 한다면 한번 신청해 보세요.

 

신청 방법은 아래 글에 정리 해 놨습니다.

 

https://coronasdk.tistory.com/1304

 

Azure OpenAI 를 사용하기 위한 사전 요구 사항들 - 사용 요청 거부 됨

OpenAI CookBook 을 거의 다 공부하고 Azure OpenAI 를 공부할 차례 입니다. https://github.com/openai/openai-cookbook GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API Examples and guides for using the OpenAI API. C

coronasdk.tistory.com

 

저는 일단 실습은 못하고 Cookbook에 있는 글로 공부해 보겠습니다.

 

https://github.com/openai/openai-cookbook/blob/main/examples/azure/embeddings.ipynb

 

GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API

Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.

github.com

 

 

참고로 Azure OpenAI Embeddings + Search 관련 유투브 클립입니다.

 

https://www.youtube.com/watch?v=ocxq84ocYi0 

 

아래부터 Cookbook 내용입니다.

 

Azure embeddings example

 

In this example we'll try to go over all operations for embeddings that can be done using the Azure endpoints.
This example focuses on embeddings but also touches some other operations that are also available using the API. This example is meant to be a quick way of showing simple operations and is not meant as a tutorial.

 

이 예제에서는 Azure endpoints를 사용하여 수행할 수 있는 embeddings 에 대한 작업을 살펴보겠습니다.
이 예제는 임베딩에 중점을 두지만 API를 사용하여 사용할 수 있는 다른 작업도 다룹니다. 이 예제는 간단한 작업을 보여주는 빠른 방법이며 튜토리얼이 아닙니다.

 

import openai
from openai import cli

Setup

For the following sections to work properly we first have to setup some things. Let's start with the api_base and api_version. To find your api_base go to https://portal.azure.com, find your resource and then under "Resource Management" -> "Keys and Endpoints" look for the "Endpoint" value.

 

다음 섹션이 제대로 작동하려면 먼저 몇 가지를 설정해야 합니다. api_base 및 api_version부터 시작하겠습니다. api_base를 찾으려면 https://portal.azure.com으로 이동하여 리소스를 찾은 다음 "Resource Management" -> "Keys and Endpoints" 에서 "Endpoint" 값을 찾습니다.

 

openai.api_version = '2022-12-01'
openai.api_base = '' # Please add your endpoint here

다음으로 api_type 및 api_key를 설정해야 합니다. 포털에서 키를 얻거나 Microsoft Active Directory 인증을 통해 얻을 수 있습니다. 이에 따라 api_type은 azure 또는 azure_ad입니다.

 

Setup: Portal

Let's first look at getting the key from the portal. Go to https://portal.azure.com, find your resource and then under "Resource Management" -> "Keys and Endpoints" look for one of the "Keys" values.

 

먼저 포털에서 키를 가져오는 방법을 살펴보겠습니다. https://portal.azure.com으로 이동하여 리소스를 찾은 다음 "Resource Management" -> "Keys and Endpoints"에서 "Keys" 값 중 하나를 찾습니다.

 

openai.api_type = 'azure'
openai.api_key = ''  # Please add your api key here

(Optional) Setup: Microsoft Active Directory Authentication

Let's now see how we can get a key via Microsoft Active Directory Authentication. Uncomment the following code if you want to use Active Directory Authentication instead of keys from the portal.

 

(선택 사항) 설정: Microsoft Active Directory 인증
이제 Microsoft Active Directory 인증을 통해 키를 얻는 방법을 살펴보겠습니다. 포털의 키 대신 Active Directory 인증을 사용하려면 다음 코드의 주석을 제거하십시오.

 

# from azure.identity import DefaultAzureCredential

# default_credential = DefaultAzureCredential()
# token = default_credential.get_token("https://cognitiveservices.azure.com/.default")

# openai.api_type = 'azure_ad'
# openai.api_key = token.token

 

Deployments

In this section we are going to create a deployment that we can use to create embeddings.

이 섹션에서는 embeddings을 만드는 데 사용할 수 있는 deployment 를 만들 것입니다.

 

Deployments: Create manually

Let's create a deployment using the text-similarity-curie-001 model. Create a new deployment by going to your Resource in your portal under "Resource Management" -> "Model deployments".

text-similarity-curie-001 모델을 사용하여 배포를 생성해 보겠습니다. "Resource Management" -> "Model deployments"에서 포털의 리소스로 이동하여 새 deployment를 만듭니다.

 

(Optional) Deployments: Create programatically

We can also create a deployment using code:

코드를 사용하여 deployment 를 만들 수도 있습니다.

 

model = "text-similarity-curie-001"

# Now let's create the deployment
print(f'Creating a new deployment with model: {model}')
result = openai.Deployment.create(model=model, scale_settings={"scale_type":"standard"})
deployment_id = result["id"]

 

(Optional) Deployments: Retrieving

Now let's check the status of the newly created deployment

이제 새로 생성된 배포의 상태를 확인하겠습니다.

print(f'Checking for deployment status.')
resp = openai.Deployment.retrieve(id=deployment_id)
status = resp["status"]
print(f'Deployment {deployment_id} is with status: {status}')

 

Deployments: Listing

Now because creating a new deployment takes a long time, let's look in the subscription for an already finished deployment that succeeded.

이제 새 deployment 를 만드는 데 시간이 오래 걸리므로 이미 완료된 deployment 에 대한 subscription 을 살펴보겠습니다.

 

print('While deployment running, selecting a completed one that supports embeddings.')
deployment_id = None
result = openai.Deployment.list()
for deployment in result.data:
    if deployment["status"] != "succeeded":
        continue
    
    model = openai.Model.retrieve(deployment["model"])
    if model["capabilities"]["embeddings"] != True:
        continue
    
    deployment_id = deployment["id"]
    break

if not deployment_id:
    print('No deployment with status: succeeded found.')
else:
    print(f'Found a succeeded deployment that supports embeddings with id: {deployment_id}.')

 

Embeddings

Now let's send a sample embedding to the deployment.

이제 배포에 샘플 임베딩을 보내겠습니다.

 

embeddings = openai.Embedding.create(deployment_id=deployment_id,
                                     input="The food was delicious and the waiter...")
                                
print(embeddings)

 

(Optional) Deployments: Delete

Finally let's delete the deployment

 

마지막으로 deployment를 삭제하겠습니다.

 

 

 

 

반응형


반응형

Azure OpenAI를 사용하려면 해당 서비스를 사용할 수 있는 권한을 Microsoft 사로부터 얻어야 합니다.

저는 공부 목적으로 필요하다고 신청했는데 거부 됐습니다.

 

 

실제 이 Azure OpenAI를 이용해서 제품을 개발하고자 한다면 한번 신청해 보세요.

 

신청 방법은 아래 글에 정리 해 놨습니다.

 

https://coronasdk.tistory.com/1304

 

Azure OpenAI 를 사용하기 위한 사전 요구 사항들 - 사용 요청 거부 됨

OpenAI CookBook 을 거의 다 공부하고 Azure OpenAI 를 공부할 차례 입니다. https://github.com/openai/openai-cookbook GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API Examples and guides for using the OpenAI API. C

coronasdk.tistory.com

 

저는 일단 실습은 못하고 Cookbook에 있는 글로 공부해 보겠습니다.

 

https://github.com/openai/openai-cookbook/blob/main/examples/azure/completions.ipynb

 

GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API

Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.

github.com

 

Azure completions example

 

In this example we'll try to go over all operations needed to get completions working using the Azure endpoints.
This example focuses on completions but also touches on some other operations that are also available using the API. This example is meant to be a quick way of showing simple operations and is not meant as a tutorial.

 

이 예제에서는 Azure 엔드포인트를 사용하여 작업을 completions 하는 데 필요한 모든 작업을 살펴보겠습니다.
이 예제는 completions 에 중점을 두지만 API를 사용하여 사용할 수 있는 다른 작업도 다룹니다. 이 예제는 간단한 작업을 보여주는 빠른 방법이며 튜토리얼이 아닙니다.

 

import openai
from openai import cli

 

Setup

For the following sections to work properly we first have to setup some things. Let's start with the api_base and api_version. To find your api_base go to https://portal.azure.com, find your resource and then under "Resource Management" -> "Keys and Endpoints" look for the "Endpoint" value.

 

다음 섹션이 제대로 작동하려면 먼저 몇 가지를 설정해야 합니다. api_base 및 api_version부터 시작하겠습니다. api_base를 찾으려면 https://portal.azure.com으로 이동하여 리소스를 찾은 다음 "리소스 관리" -> ""Keys and Endpoints""에서 "Endpoint" 값을 찾습니다.

 

==> 이 부분이 Azure OpenAI 사용 권한이 필요한 부분 입니다.

 

openai.api_version = '2022-12-01'
openai.api_base = '' # Please add your endpoint here

 

다음으로 api_type 및 api_key를 설정해야 합니다. 포털에서 키를 얻거나 Microsoft Active Directory 인증을 통해 얻을 수 있습니다. 이에 따라 api_type은 azure 또는 azure_ad입니다.

 

Setup: Portal

Let's first look at getting the key from the portal. Go to https://portal.azure.com, find your resource and then under "Resource Management" -> "Keys and Endpoints" look for one of the "Keys" values.

 

먼저 포털에서 키를 가져오는 방법을 살펴보겠습니다. https://portal.azure.com으로 이동하여 리소스를 찾은 다음 "Resource Management" -> "Keys and Endpoints"에서 "Keys" 값 중 하나를 찾습니다.

 

openai.api_type = 'azure'
openai.api_key = ''  # Please add your api key here

 

(Optional) Setup: Microsoft Active Directory Authentication

Let's now see how we can get a key via Microsoft Active Directory Authentication. Uncomment the following code if you want to use Active Directory Authentication instead of keys from the portal.

 

(선택 사항) 설정: Microsoft Active Directory 인증
이제 Microsoft Active Directory 인증을 통해 키를 얻는 방법을 살펴보겠습니다. 포털의 키 대신 Active Directory 인증을 사용하려면 다음 코드의 주석을 제거하십시오.

 

# from azure.identity import DefaultAzureCredential

# default_credential = DefaultAzureCredential()
# token = default_credential.get_token("https://cognitiveservices.azure.com/.default")

# openai.api_type = 'azure_ad'
# openai.api_key = token.token

 

Deployments

In this section we are going to create a deployment using the text-davinci-002 model that we can then use to create completions.

이 섹션에서는 completions 를 생성하는 데 사용할 수 있는 text-davinci-002 모델을 사용하여 배포를 생성할 것입니다.

 

 

Deployments: Create manually

Create a new deployment by going to your Resource in your portal under "Resource Management" -> "Model deployments". Select text-davinci-002 as the model.

 

"리소스 관리" -> "모델 배포"에서 포털의 리소스로 이동하여 새 배포를 만듭니다. text-davinci-002를 모델로 선택합니다.

 

(Optional) Deployments: Create programatically

We can also create a deployment using code:

코드를 사용하여 배포를 만들 수도 있습니다.

 

model = "text-davinci-002"

# Now let's create the deployment
print(f'Creating a new deployment with model: {model}')
result = openai.Deployment.create(model=model, scale_settings={"scale_type":"standard"})
deployment_id = result["id"]
print(f'Successfully created deployment with id: {deployment_id}')

 

(Optional) Deployments: Wait for deployment to succeed

Now let's check the status of the newly created deployment and wait till it is succeeded.

 

이제 새로 생성된 배포의 상태를 확인하고 성공할 때까지 기다리겠습니다.

 

print(f'Checking for deployment status.')
resp = openai.Deployment.retrieve(id=deployment_id)
status = resp["status"]
print(f'Deployment {deployment_id} has status: {status}')
while status not in ["succeeded", "failed"]:
    resp = openai.Deployment.retrieve(id=deployment_id)
    status = resp["status"]
    print(f'Deployment {deployment_id} has status: {status}')

 

Completions

Now let's send a sample completion to the deployment.

 

이제 배포에 샘플 완료를 보내겠습니다.

 

prompt = "The food was delicious and the waiter"
completion = openai.Completion.create(deployment_id=deployment_id,
                                     prompt=prompt, stop=".", temperature=0)
                                
print(f"{prompt}{completion['choices'][0]['text']}.")

 

(Optional) Deployments: Delete

Finally let's delete the deployment

 

print(f'Deleting deployment: {deployment_id}')
openai.Deployment.delete(sid=deployment_id)

 

이 과정을 보니까 Azure OpenAI를 사용하는 것은 그냥 OpenAI API 를 사용하기 이전에 openai.Deployment.create() API를 사용해서 Deployment 부터 하네요.

 

그리고 추가적으로 Deployment 가 완료 되는지 여부를 openai.Deployment.retrieve() 를 사용해서 체크하는 부분이 있구요.

 

이렇게 한번 Deployment가 완료 되면 다른 openai API를 사용하는 방법과 똑 같이 openai.Completion.create() API를 사용해서 prompt 를 전달하고 응답을 받습니다.

 

그리고 마지막으로 해당 Deployment를 Delete 하는 과정이 있구요.

이때는 openai.Deployment.delete() API 를 사용합니다.

 

그냥 OpenAI API 를 사용할 때는 (Azure) 를 거치지 않고) 이 Deployment 단계들은 필요 없습니다. 그냥 openai api key 만 전달 한 후 openAI API를 사용하시면 됩니다.

 

참고로 실제로 실습을 하는 모습을 보려면 아래 유투브 클립을 보시면 됩니다.

 

https://www.youtube.com/watch?v=lHw1tZhXlEo 

 

 

반응형


반응형

OpenAI CookBook 을 거의 다 공부하고 Azure OpenAI 를 공부할 차례 입니다.

 

https://github.com/openai/openai-cookbook

 

GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API

Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.

github.com

 

첫 예제의 Setup 부터 막히더라구요.

 

 

api_base 와 api_version 을 구하는 방법도 모르겠어서 여기 저기 구글링을 해 보았습니다.

(이제는 Binging 을 한다고 말해야 하나?)

 

우선 Microsoft Azure 로 들어가서 Azure OpenAI 서비스를 선택합니다.

(Microsoft Azure 에 가입 돼 있어야 합니다. 일단 가입은 무료입니다.)

 

Azure OpenAI 라고 검색을 하시면 위와 같은 아이콘을 보실 수 있습니다.

 

클릭하면 이런 화면이 뜹니다.

 

여기서 Create 을 클릭하시면 ......

 

 

이런 화면이 뜹니다.

 

밑에 붉은 background 에 있는 글을 보세요.

 

Azure OpenAI Service is currently available to customers via an application form. The selected subscription has not been enabled for use of the service and does not have quota for any pricing tiers. Click here to request access to Azure OpenAI service.

 

Azure OpenAI 서비스는 현재 신청 양식을 통해 고객에게 제공됩니다. 선택한 구독은 서비스 사용을 위해 활성화되지 않았으며 가격 책정 계층에 대한 할당량이 없습니다. Azure OpenAI 서비스에 대한 액세스를 요청하려면 여기를 클릭하십시오.

 

Azure OpenAI 를 사용하려면 따로 신청을 하셔야 합니다.

여기서 링크를 클릭하면 아래와 같은 페이지로 갑니다.

 

저는 여기서 신청서 양식을 다 작성을 하고 마지막에 긴 설문도 다 작성을 하고 Submit을 눌렀습니다.

 

그러면 아래와 같은 화면이 나옵니다.

 

신청은 했는데 이게 승인이 될지 거부가 될지 그리고 승인이 되면 언제 될지 모르겠네요.

 

일단 현재로서는 실습을 하지는 못 하겠고 Cookbook 에 있는 글을 통해서 공부만 해 둬야 겠습니다.

 

 

아래는 Azure OpenAI 를 사용해서 Azure에서 리소스를 생성하고 배치하는 방법을 알려 주는 How-to 페이지 입니다.

여기서도 Prerequisites 로 Auzre 에 가입하고 위 신청서를 작성해야 한다고 나오네요.

 

How-to - Create a resource and deploy a model using Azure OpenAI Service - Azure OpenAI | Microsoft Learn

 

How-to - Create a resource and deploy a model using Azure OpenAI Service - Azure OpenAI

Walkthrough on how to get started with Azure OpenAI and make your first resource and deploy your first model.

learn.microsoft.com

 

아래는 신청서 작성하는 페이지 입니다.

https://aka.ms/oai/access

 

Dynamics 365 Customer Voice

 

customervoice.microsoft.com

 

이상 Azure OpenAI 를 사용하기 위한 Prerequisites 에 대한 Research 내용 공유글 이었습니다.

 

==============================

 

이 글 작성하고 이메일을 확인 했더니 금방 Microsoft 에서 답변 이메일이 왔네요.

 

 

요청은 거부 됐습니다.

 

저는 그냥 솔직하게 공부할 목적으로 사용하고 싶다라고 했는데 이런 경우는 받아들여지지 않네요.

그냥 Cookbook 글만을 통해서 공부만 해야 겠습니다.

반응형


반응형

오늘은 그림을 그리는 OpenAI의 AI 화가 DALL-E API 입니다.

 

https://github.com/openai/openai-cookbook/blob/main/examples/dalle/Image_generations_edits_and_variations_with_DALL-E.ipynb

 

GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API

Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.

github.com

DALL-E

This notebook shows how to use OpenAI's DALL-E image API endpoints.

이 노트북은 OpenAI의 DALL-E 이미지 API endpoints를 사용하는 방법을 보여줍니다.

 

There are three API endpoints:

세 가지 API endpoints가 있습니다.

  • Generations: generates an image or images based on an input caption
  • Generations: 입력 캡션을 기반으로 이미지를 생성합니다.
  • Edits: edits or extends an existing image
  • 편집: 기존 이미지를 편집하거나 확장합니다.
  • Variations: generates variations of an input image
  • 변형: 입력 이미지의 변형을 생성합니다.

Setup

  • Import the packages you'll need
  • 필요한 패키지 가져오기
  • Import your OpenAI API key: You can do this by running ``export OPENAI_API_KEY="your API key"\ in your terminal.
  • OpenAI API key 가져오기 
  • Set a directory to save images to
  • 이미지를 저장할 디렉토리 설정

이제 소스 코드를 보겠습니다.

# imports
import openai  # OpenAI Python library to make API calls
import requests  # used to download images
import os  # used to access filepaths
from PIL import Image  # used to print and edit images

# set API key
openai.api_key = os.environ.get("OPENAI_API_KEY")

 

먼저 필요한 모듈들을 import 합니다.

openai를 import 해 openaai api를 사용할 수 있도록 합니다.

그 다음에 requests 모듈을 import 했습니다. 이 모듈은 openai 에 이미지가 생성 된 후 이 이미지를 나의 local 컴퓨터로 다운로드 받기 위해 필요합니다. 

이 모듈은 파이썬에서 HTTP request를 보낼 수 있도록 합니다. HTTP를 사용해서 OpenAI쪽에 생성돼 있는 이미지를 다운 로드 받게 됩니다.

https://www.w3schools.com/python/module_requests.asp

 

Python Requests Module

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

 

그 다음은 os 모듈 입니다. 나의 local computer에 있는 환경 변수 값도 불러 오고 이미지가 저장될 폴더 위치도 설정하고 저장되는 이미지 파일 이름도 설정하는 등의 일들을 하는데 사용 됩니다.

https://docs.python.org/3/library/os.html

 

os — Miscellaneous operating system interfaces

Source code: Lib/os.py This module provides a portable way of using operating system dependent functionality. If you just want to read or write a file see open(), if you want to manipulate paths, s...

docs.python.org

 

그리고 마지막으로 Image PIL 모듈에 있는 Image 함수를 import 합니다.

이 PIL 모듈은 파이썬에서 이미지를 다룰 때 사용하는 모듈입니다.

https://pillow.readthedocs.io/en/stable/

 

Pillow

Pillow is the friendly PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lundh and Contributors. Pillow for enterprise is available via the Tidelift Subscription...

pillow.readthedocs.io

https://pillow.readthedocs.io/en/stable/handbook/tutorial.html

 

Tutorial

Using the Image class: The most important class in the Python Imaging Library is the Image class, defined in the module with the same name. You can create instances of this class in several ways; e...

pillow.readthedocs.io

 

# set a directory to save DALL-E images to
image_dir_name = "images"
image_dir = os.path.join(os.curdir, image_dir_name)

# create the directory if it doesn't yet exist
if not os.path.isdir(image_dir):
    os.mkdir(image_dir)

# print the directory to save to
print(f"{image_dir=}")

그 다음은 생성한 이미지를 저장할 폴더의 위치를 정해 줍니다.

폴더 이름은 images 가 되고 그 위치는 현재 디렉토리에 있습니다.

 

if 문은 만약에 현재 디렉토리 안에 images라는 폴더가 없다면 mkdir() 을 이용해서 폴더를 생성하게 됩니다.

print() 결과는 아래와 같습니다.

image_dir='.\\images'

 

Generations

The generation API endpoint creates an image based on a text prompt.

 

generation API endpoint는 텍스트 프롬프트를 기반으로 이미지를 생성합니다.

 

Required inputs:

  • prompt (str): A text description of the desired image(s). The maximum length is 1000 characters.
  • 프롬프트(str): 원하는 이미지에 대한 텍스트 설명입니다. 최대 길이는 1000자입니다.

Optional inputs:

  • n (int): The number of images to generate. Must be between 1 and 10. Defaults to 1.
  • n (int): 생성할 이미지의 수. 1에서 10 사이여야 합니다. 기본값은 1입니다.
  • size (str): The size of the generated images. Must be one of "256x256", "512x512", or "1024x1024". Smaller images are faster. Defaults to "1024x1024".
  • size (str): 생성된 이미지의 크기. "256x256", "512x512" 또는 "1024x1024" 중 하나여야 합니다.이미지가 작으면 더 빠릅니다.. 기본값은 "1024x1024"입니다.
  • response_format (str): The format in which the generated images are returned. Must be one of "url" or "b64_json". Defaults to "url".
  • response_format(str): 생성된 이미지가 반환되는 형식입니다. "url" 또는 "b64_json" 중 하나여야 합니다. 기본값은 "url"입니다.
  • user (str): A unique identifier representing your end-user, which will help OpenAI to monitor and detect abuse. Learn more.

* user(str): OpenAI가 남용을 모니터링하고 감지하는 데 도움이 되는 최종 사용자를 나타내는 고유 식별자입니다. 

 

OpenAI API

An API for accessing new AI models developed by OpenAI

platform.openai.com

# create an image

# set the prompt
prompt = "Create picture for a Youtube channel Banner image named AI Madang, express the concept of Artificial Intellegent state-of-the-art technology and the concept of a play ground where human can play happily."

# call the OpenAI API
generation_response = openai.Image.create(
    prompt=prompt,
    n=1,
    size="1024x1024",
    response_format="url",
)

# print response
print(generation_response)

이 코드는 OpenAI 의 openai.Image.create() API를 사용해서 원하는 이미지를 만드는 과정입니다.

 

일단 내가 원하는 이미지를 prompt 변수에 담습니다.

저는 AI Madang 이라는 유투브 채널을 만들려고 하는데 그 채널의 Banner image로 사용할 최첨단 기술과 인간들의 놀이터 느낌이 나는 그림을 만들어 달라고 할 계획입니다.

 

그 다음은 openai.Image.create() API call 을 하는 부분 입니다. prompt가 들어가고 n은 그림 갯수를 나타내니까 그림은 1개만 만들라는 겁니다. 그리고 size는 1024X1024 입니다. response_format 은 url 이구요.

 

이 url을 이용해서 requests 모듈로 HTTP를 통해 이미지를 가져 오고 이것을 os 모듈을 이용해서 내 컴퓨터의 원하는 폴더에 저장 하는 작업을 할 겁니다.

그 이미지를 display 할 때 PIL 모듈의 Image 함수를 사용할 거구요.

 

저 같은 경우는 print 결과가 아래와 같이 나왔습니다.

 

 

OpenAI 에서 이미지가 생성 돼 있고 그 이미지가 위치해 있는 URL 을 받았습니다.

 

저 URL을 클릭하면 openai가 생성한 이미지가 나옵니다.

 

 

이미지가 마음에 안 들어서 몇 번 반복 했는데..... 여전히 마음에 안 드네요.

아직까지 저런 어려운 내용은 제대로 소화를 못 하는 것 같습니다.

 

어쨌든 오늘은 DALL-E API 를 공부하는 과정이니 그냥 넘어 가겠습니다.

 

Note: If you get this error - AttributeError: module 'openai' has no attribute 'Image' - you'll need to upgrade your OpenAI package to the latest version. You can do this by running pip install openai --upgrade in your terminal.

 

참고: AttributeError: module 'openai' has no attribute 'Image' 오류가 발생하면 OpenAI 패키지를 최신 버전으로 업그레이드해야 합니다. 터미널에서 pip install openai --upgrade를 실행하여 이를 수행할 수 있습니다.

 

# save the image
generated_image_name = "generated_image2.png"  # any name you like; the filetype should be .png
generated_image_filepath = os.path.join(image_dir, generated_image_name)
generated_image_url = generation_response["data"][0]["url"]  # extract image URL from response
generated_image = requests.get(generated_image_url).content  # download the image

with open(generated_image_filepath, "wb") as image_file:
    image_file.write(generated_image)  # write the image to the file

이제 이 이미지를 로컬에 저장하는 과정입니다.

generated_image2.png 라고 이름을 정할 생각입니다.

 

generated_image_filepath 라는 변수에 위에서 만들었던 images 라는 폴더 경로와 여기서 만들었던 이미지 파일 이름을 결합 시킵니다.

 

그리고 이미지가 있는 url 주소를 generated_image_url 에 담습니다.

 

그리고 requests 모듈의 get() 함수를 사용해서 그 이미지를 위 generated_image_url 로 다운로드 합니다.

 

그 다음 open() 메소드는 PIL 모듈에 있는 함수 입니다. 

 

https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.open

 

Image Module

The Image module provides a class with the same name which is used to represent a PIL image. The module also provides a number of factory functions, including functions to load images from files, a...

pillow.readthedocs.io

 

wb 는 binary format으로 열라는 겁니다.

 

파이썬에서는 기본적으로 text 모드로 열게 되어 있는데 b 라는 의미는 이 텍스트가 아니라 바이너리 모드라는 의미 입니다. w 는 writing 입니다. 이와 반대로 r 은 reading 입니다. 읽기 모드가 아닌 쓰기 모드로 열라는 겁니다.

이렇게 하면 나중에 수정할 수 있습니다.

 

write() 함수를 사용해서 파일로 저장합니다. 이 함수는 Python 함수 입니다.

https://www.w3schools.com/python/ref_file_write.asp

 

Python File write() Method

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

이제 생성된 이미지가 내 컴퓨터 안에 완전히 다운로드 됐습니다.

맨 오른쪽에 이 이미지가 있습니다. 나머지는 전에 연습 할 때 생성한 이미지들입니다.

# print the image
print(generated_image_filepath)
display(Image.open(generated_image_filepath))

이제 이 그림을 JupyterLab 화면에 display 해 보겠습니다.

print() 로는 파일 경로와 이름을 표시하고 display()는 이미지를 표시합니다.

 

실행 결과 입니다.

 

 

 

Variations

The variations endpoint generates new images (variations) similar to an input image.

 

변형(variation) endpoint 는 입력 이미지와 유사한 새 이미지(변형)를 생성합니다.

 

Here we'll generate variations of the image generated above.

 

여기서는 위에서 생성된 이미지의 변형을 생성합니다.

 

Required inputs:

  • image (str): The image to use as the basis for the variation(s). Must be a valid PNG file, less than 4MB, and square.
  • image(str): 변형의 기초로 사용할 이미지입니다. 유효한 PNG 파일이어야 하며 4MB 미만의 정사각형이어야 합니다.
  •  

Optional inputs:

  • n (int): The number of images to generate. Must be between 1 and 10. Defaults to 1.
  • n (int): 생성할 이미지의 수. 1에서 10 사이여야 합니다. 기본값은 1입니다.
  • size (str): The size of the generated images. Must be one of "256x256", "512x512", or "1024x1024". Smaller images are faster. Defaults to "1024x1024".
  • size (str): 생성된 이미지의 크기. "256x256", "512x512" 또는 "1024x1024" 중 하나여야 합니다. 작은 이미지가 더 빠릅니다. 기본값은 "1024x1024"입니다.
  • response_format (str): The format in which the generated images are returned. Must be one of "url" or "b64_json". Defaults to "url".
  • response_format(str): 생성된 이미지가 반환되는 형식입니다. "url" 또는 "b64_json" 중 하나여야 합니다. 기본값은 "url"입니다.
  • user (str): A unique identifier representing your end-user, which will help OpenAI to monitor and detect abuse. Learn more.
 

OpenAI API

An API for accessing new AI models developed by OpenAI

platform.openai.com

user(str): OpenAI가 남용을 모니터링하고 감지하는 데 도움이 되는 최종 사용자를 나타내는 고유 식별자입니다. 

 

# create variations

# call the OpenAI API, using `create_variation` rather than `create`
variation_response = openai.Image.create_variation(
    image=generated_image,  # generated_image is the image generated above
    n=2,
    size="1024x1024",
    response_format="url",
)

# print response
print(variation_response)

 

이 코드는 위에서 생성된 이미지를 openai.Image.create_variation() API 를 사용해서 변형 시키는 겁니다.

이미지는 2개를 생성하고 크기는 1024X1024 입니다. response_format 은 url이구요.

 

프린트한 결과는 아래와 같습니다.

 

 

이미지를 2개 만들라고 했더니 URL도 두개가 나오네요.

 

클릭해 봤더니 다음과 같은 이미지들이 나옵니다.

 

 

 

# save the images
variation_urls = [datum["url"] for datum in variation_response["data"]]  # extract URLs
variation_images = [requests.get(url).content for url in variation_urls]  # download images
variation_image_names = [f"variation_image_{i}.png" for i in range(len(variation_images))]  # create names
variation_image_filepaths = [os.path.join(image_dir, name) for name in variation_image_names]  # create filepaths
for image, filepath in zip(variation_images, variation_image_filepaths):  # loop through the variations
    with open(filepath, "wb") as image_file:  # open the file
        image_file.write(image)  # write the image to the file

다음 코드는 이 두 이미지 파일을 로컬에 save 하는 과정입니다.

 

위의 과정과 똑 같은데 이미지가 두개 이므로 이것을 처리하기 위해 for 문을 사용했습니다.

 

실행 결과 입니다.

 

내 컴퓨터 안에 두개의 파일이 추가 됐습니다.

깜빡하고 이름을 바꾸지 않았더니 기존에 있는 이미지에 덮어 썼네요.

기존 이미지 두개는 날아갔습니다. 뭐 지금은 공부하는 중이니 상관은 없습니다.

실전에서는 아주 조심해야 겠네요. 자동으로 이름에 surfix 나 prefix 같은 것을 달아 주고 또 기존에 같은 이미지가 있으면 새 이미지에 surfix나 prefix 를 붙여주는 로직을 만들어야 겠죠.

 

# print the original image
print(generated_image_filepath)
display(Image.open(generated_image_filepath))

# print the new variations
for variation_image_filepaths in variation_image_filepaths:
    print(variation_image_filepaths)
    display(Image.open(variation_image_filepaths))

 

이 그림을 display 하는 스크립트 입니다.

위에서 한것과 똑 같은데 2개를 display 하기 때문에 for 문을 사용했습니다.

 

원본 파일을 display 하고 for 문 안에서는 변형 이미지 파일 2개를 display 합니다.

결과는 생성했던 3개 파일 모두 display 됩니다.

 

 

 

 

Edits

The edit endpoint uses DALL-E to generate a specified portion of an existing image. Three inputs are needed: the image to edit, a mask specifying the portion to be regenerated, and a prompt describing the desired image.

edit endpoint는 DALL-E를 사용하여 기존 이미지의 지정된 부분을 generate 합니다. 편집할 이미지, 재생성할 부분을 지정하는 마스크, 원하는 이미지를 설명하는 프롬프트의 세 가지 입력이 필요합니다.

 

 

Required inputs:

  • image (str): The image to edit. Must be a valid PNG file, less than 4MB, and square.
  • image (str): 편집할 이미지. 유효한 PNG 파일이어야 하며 4MB 미만의 정사각형이어야 합니다.
  • mask (str): An additional image whose fully transparent areas (e.g. where alpha is zero) indicate where image should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions as image.
  • 마스크(str): 완전히 투명한 영역(예: 알파가 0인 경우)이 이미지를 편집해야 하는 위치를 나타내는 추가 이미지입니다. 4MB 미만의 유효한 PNG 파일이어야 하며 이미지와 크기가 같아야 합니다.
  • prompt (str): A text description of the desired image(s). The maximum length is 1000 characters.
  • 프롬프트(str): 원하는 이미지에 대한 텍스트 설명입니다. 최대 길이는 1000자입니다.

 

Optional inputs:

  • n (int): The number of images to generate. Must be between 1 and 10. Defaults to 1.
  • n (int): 생성할 이미지의 수. 1에서 10 사이여야 합니다. 기본값은 1입니다.
  • size (str): The size of the generated images. Must be one of "256x256", "512x512", or "1024x1024". Smaller images are faster. Defaults to "1024x1024".
  • size (str): 생성된 이미지의 크기. "256x256", "512x512" 또는 "1024x1024" 중 하나여야 합니다. 작은 이미지가 더 빠릅니다. 기본값은 "1024x1024"입니다.
  • response_format (str): The format in which the generated images are returned. Must be one of "url" or "b64_json". Defaults to "url".
  • response_format(str): 생성된 이미지가 반환되는 형식입니다. "url" 또는 "b64_json" 중 하나여야 합니다. 기본값은 "url"입니다.
  • user (str): A unique identifier representing your end-user, which will help OpenAI to monitor and detect abuse. Learn more.
 

OpenAI API

An API for accessing new AI models developed by OpenAI

platform.openai.com

user(str): OpenAI가 남용을 모니터링하고 감지하는 데 도움이 되는 최종 사용자를 나타내는 고유 식별자입니다. 

 

Set Edit Area

An edit requires a "mask" to specify which portion of the image to regenerate. Any pixel with an alpha of 0 (transparent) will be regenerated. The code below creates a 1024x1024 mask where the bottom half is transparent.

편집에는 재생성할 이미지 부분을 지정하는 "마스크"가 필요합니다. 알파가 0(투명)인 모든 픽셀이 재생성됩니다. 아래 코드는 아래쪽 절반이 투명한 1024x1024 마스크를 만듭니다.

# create a mask
width = 1024
height = 1024
mask = Image.new("RGBA", (width, height), (0, 0, 0, 1))  # create an opaque image mask

# set the bottom half to be transparent
for x in range(width):
    for y in range(height // 2, height):  # only loop over the bottom half of the mask
        # set alpha (A) to zero to turn pixel transparent
        alpha = 0
        mask.putpixel((x, y), (0, 0, 0, alpha))

# save the mask
mask_name = "bottom_half_mask.png"
mask_filepath = os.path.join(image_dir, mask_name)
mask.save(mask_filepath)

이렇게 생성한 마스크는 아래 반쪽만 알파갑을 준 것입니다. 그냥 눈으로 보면 별 티는 안 납니다.

 

Perform Edit

Now we supply our image, caption and mask to the API to get 5 examples of edits to our image

 

이제 이미지, 캡션 및 마스크를 API에 제공하여 이미지 편집의 5가지 예를 얻습니다.

 

# edit an image

# call the OpenAI API
edit_response = openai.Image.create_edit(
    image=open(generated_image_filepath, "rb"),  # from the generation section
    mask=open(mask_filepath, "rb"),  # from right above
    prompt=prompt,  # from the generation section
    n=1,
    size="1024x1024",
    response_format="url",
)

# print response
print(edit_response)

openai.Image.create_edit() API 를 사용해서 원본 이미지를 편집을 합니다.

 

결과는 아래와 같습니다.

 

 

URL을 클릭을 하니 아래와 같은 이미지가 나옵니다.

 

# save the image
edited_image_name = "edited_image.png"  # any name you like; the filetype should be .png
edited_image_filepath = os.path.join(image_dir, edited_image_name)
edited_image_url = edit_response["data"][0]["url"]  # extract image URL from response
edited_image = requests.get(edited_image_url).content  # download the image

with open(edited_image_filepath, "wb") as image_file:
    image_file.write(edited_image)  # write the image to the file

 

이 이미지 파일을 로컬에 저장합니다.

 

edited_image.png 파일이 생겼습니다.

사실은 기존에 있던 파일에 덮어 쓰기를 했습니다.

 

보시면 원본파일은 generated_image2.png 에서 아래 절반이 바뀐 것을 보실 수 있습니다.

 

# print the original image
print(generated_image_filepath)
display(Image.open(generated_image_filepath))

# print edited image
print(edited_image_filepath)
display(Image.open(edited_image_filepath))

이 부분은 Jupyterlab에 display 하는 부분 입니다.

원본과 편집본 두개를 display 합니다.

 

 

이렇게 하니까 아래 절 반이 바뀐 것을 쉽게 알 수가 있네요.

 

여기까지 OpenAI 의 DALL-E API 를 공부해 봤습니다.

반응형


반응형

오늘은 오랜만에 실습 예제 입니다.

 

Fine-tunning을 실제로 해 보도록 하겠습니다.

 

https://github.com/openai/openai-cookbook/blob/main/examples/Fine-tuned_classification.ipynb

 

GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API

Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.

github.com

 

Fine tuning classification example

아래 예제는 ada 모델을 이용해서 이메일 내용을 보고 이게 Baseball과 연관 돼 있는지 아니면 Hockey와 연관 돼 있는 건지 GPT-3 가 인지할 수 있도록 Fine-Tuning을 사용해서 훈련시키고 새로운 모델을 만드는 과정을 보여 줍니다.

 

from sklearn.datasets import fetch_20newsgroups
import pandas as pd
import openai

categories = ['rec.sport.baseball', 'rec.sport.hockey']
sports_dataset = fetch_20newsgroups(subset='train', shuffle=True, random_state=42, categories=categories)

 

이 예제에서 사용하는 데이터는 sklearn에서 제공하는 샘플 데이터인 fetch_20newsgroups를 사용합니다.

 

fetch_20newsgroups 는 데이터를 다루는 연습용으로 만들어진 데이터 세트 입니다.

20개의 newsgroup에서 데이터를 가져온 겁니다. 이 뉴스그룹들은 대부분 게시판이고 사용자들이 올른 글들이 데이터가 되는 겁니다. 예를 들어 내가 낚시에 관심이 있어서 낚시 관련된 카페 같은 뉴스 그룹에 가입하고 거기에 글을 올리듯이 사람들이 글을 올린 데이터 들 입니다.

 

여기에는 20개의 주제들이 있습니다. 그리고 총 샘플들은 18846개가 있고 1차원 배열이고 text로 이뤄져 있습니다.

 

이 중에서 Baseball 과 Hockey 관련된 데이터를 가지고 이 예제에서는 Fine-Tuning을 연습하는 소스코드를 만들게 됩니다.

 

https://scikit-learn.org/stable/modules/generated/sklearn.datasets.fetch_20newsgroups.html

 

sklearn.datasets.fetch_20newsgroups

Examples using sklearn.datasets.fetch_20newsgroups: Biclustering documents with the Spectral Co-clustering algorithm Biclustering documents with the Spectral Co-clustering algorithm Topic extractio...

scikit-learn.org

참고로 이 데이터세트에는 아래와 같은 주제들의 글들이 있습니다.

 

'alt.atheism',
 'comp.graphics',
 'comp.os.ms-windows.misc',
 'comp.sys.ibm.pc.hardware',
 'comp.sys.mac.hardware',
 'comp.windows.x',
 'misc.forsale',
 'rec.autos',
 'rec.motorcycles',
 'rec.sport.baseball',
 'rec.sport.hockey',
 'sci.crypt',
 'sci.electronics',
 'sci.med',
 'sci.space',
 'soc.religion.christian',
 'talk.politics.guns',
 'talk.politics.mideast',
 'talk.politics.misc',
 'talk.religion.misc'

https://scikit-learn.org/stable/datasets/real_world.html#newsgroups-dataset

 

7.2. Real world datasets

scikit-learn provides tools to load larger datasets, downloading them if necessary. They can be loaded using the following functions: The Olivetti faces dataset: This dataset contains a set of face...

scikit-learn.org

 

그리고 Pandas와 openai 모듈을 import 합니다.

 

관련 모듈을 import 한 다음에 한 일은 이 예제에서 다룰 topic들을 선택하는 겁니다. 이 두 topic들을 categories라는 배열 변수에 아이템으로 넣습니다.

그리고 sports_dataset 라는 변수에 이 fetch_20newsgroups에 있는 데이터 들 중 위에서 선택한 rec.sport.baseball과 rec.sport.hockey 뉴스그룹에 있는 데이터들만 담습니다.

 

데이터를 다루려면 우선 그 데이터으 구조를 잘 알아야 합니다.

 

이 데이터의 첫번째 데이터만 한번 출력해 보겠습니다.

print(sports_dataset['data'][0])

그러면 결과는 이렇게 나옵니다.

From: dougb@comm.mot.com (Doug Bank)
Subject: Re: Info needed for Cleveland tickets
Reply-To: dougb@ecs.comm.mot.com
Organization: Motorola Land Mobile Products Sector
Distribution: usa
Nntp-Posting-Host: 145.1.146.35
Lines: 17

In article <1993Apr1.234031.4950@leland.Stanford.EDU>, bohnert@leland.Stanford.EDU (matthew bohnert) writes:

|> I'm going to be in Cleveland Thursday, April 15 to Sunday, April 18.
|> Does anybody know if the Tribe will be in town on those dates, and
|> if so, who're they playing and if tickets are available?

The tribe will be in town from April 16 to the 19th.
There are ALWAYS tickets available! (Though they are playing Toronto,
and many Toronto fans make the trip to Cleveland as it is easier to
get tickets in Cleveland than in Toronto.  Either way, I seriously
doubt they will sell out until the end of the season.)

-- 
Doug Bank                       Private Systems Division
dougb@ecs.comm.mot.com          Motorola Communications Sector
dougb@nwu.edu                   Schaumburg, Illinois
dougb@casbah.acns.nwu.edu       708-576-8207

데이터는 글을 올린사람, 주제, Reply-To,, Organization, Distribution, 아이피 주소. 라인 수, 내용 등등등 ...

대충 어떤 식으로 데이터들이 구성 돼 있는지 알 수 있을 것 같습니다.

 

이건 sports_dataset 의 data라는 아이템에 들어 있는 첫 번째 데이터인 것이고 이 sports_dataset은 어떤 구조로 돼 있는지 한번 알아 볼까요?

 

#print(sports_dataset['data'][0])
print(sports_dataset)

결과의 일 부분인데요. sports_dataset 배열은 첫번째 item 이 data 입니다. 그리고 이 data 안에는 여러 글들이 있습니다. 각 글들은 From: 으로 시작합니다. 첫번째 글은 바로 위에서 출력한 그 글입니다. dougb@comm.mot.com으로 시작해서 708-576-8207 로 끝납니다.

data는 이렇게 구성이 돼 있고 그렇다면 다른 아이템에는 무엇이 있을 까요?

 

그 다음에는 target_names인데 이 변수에는 baseball과 hockey 토픽만 들어 있다는걸 확인 할 수 있습니다.

그리고 'target' : array(0,1,0...,... 이렇게 돼 있는 것은 data의 첫번째 데이터는 baseball 뉴스그룹에서 온 것이고 두번째 데이터는 hockey 그룹에서 그리고 세번째는 baseball 그룹에서 온 것이라는 것을 말합니다.

data에 있는 데이터 가지고는 이것이 어느 뉴스그룹 소속인지 알 수 없는데 이 target_names 라는 두번째 아이템에서 그 정보를 얻을 수 있네요.

 

오늘 다룰 Fine-Tunning 예제에서는 이 두가지 정보만 있으면 GPT-3 AI 를 훈련 시킬 수 있습니다.

 

참고로 target_names의 아이템만 알 수 있는 방법은 아래와 같습니다.

 

sports_dataset.target_names[sports_dataset['target'][0]]

그러면 결과 값은 아래와 같습니다.

'rec.sport.baseball'

 

그러면 전체 데이터와 각 주제별 데이터 갯수를 한번 알아 보겠습니다.

 

len_all, len_baseball, len_hockey = len(sports_dataset.data), len([e for e in sports_dataset.target if e == 0]), len([e for e in sports_dataset.target if e == 1])
print(f"Total examples: {len_all}, Baseball examples: {len_baseball}, Hockey examples: {len_hockey}")

len(sports_dataset.data) 는 이 sports_dataset에 있는 data 아이템에 있는 데이터 수를 가져 옵니다.

len([e for e in sports_dataset.target if e == 0] 는 data에 있는 데이터 중 target 이 0인 데이터 즉 rec.sport.baseball에 속한 데이터만 가져 옵니다. 

같은 방법으로 Hockey 에 속한 데이터만 가져 오려면 이러헥 사용 합니다. len([e for e in sports_dataset.target if e == 1]

결과는 아래와 같습니다.

Total examples: 1197, Baseball examples: 597, Hockey examples: 600

전체 데이터 갯수는 1197개이고 야구와 관련된 글은 597개 그리고 하키와 관련된 글은 600개 입니다.

 

이제 이 데이터의 구조에 대해서 어느정도 파악을 했습니다.

 

그러면 이 데이터를 Fune-Tuning 시키기 위한 구조로 바꾸어 주어야 합니다.

Fine-Tunning은 AI를 교육 시키는 겁니다. 이 AI를 교육시키기 위해서는 데이터를 제공해야 합니다.

GPT-3라는 AI가 알아 들을 수 있는 데이터 구조는 이전 Guide에서 설명 된 부분이 있습니다.

 

GPT-3는 Prompt 와 Completion 이 두 부분으로 나뉘어진 데이터세트를 제공하면 됩니다.

그러면 이 아이는 그것을 보고 패턴을 찾아내서 학습하게 되는 겁니다.

이런 내용의 글은 야구와 관련 돼 있고 또 저런 내용의 글은 하키와 관련 돼 있다는 것을 알아 내는 것이죠.

 

예를 들어 위에서 출력한 첫번째 글을 보시죠.

 

여기에는 이 글이 야구와 관련돼 있는지 하키와 관련 돼 있는지에 대한 명시적인 정보는 없습니다.

다면 이 글에는 Cleveland에 갈거고 팬들끼리 좀 모이자는 내용이 있습니다. 그리고 상대팀 이름도 있고 어디서 경기가 열리는지 뭐 이런 정보가 있습니다.

미국에서 야구에 대해 관심 있는 사람이라면 이 글은 야구와 관련된 글이라는 것을 알겠죠.

이렇게 주어진 정보만 가지고 이게 야구와 관련된 글인지 하키와 관련된 글인지 알아 내도록 GPT-3를 훈련 시킬 겁니다.

그 훈련된 AI모델은 나만의 모델이 될 겁니다.

그래서 앞으로 내가 어떤 글을 그 모델에게 보내면 그 Custom AI Model은 그게 야구와 관련된 글인지 하키와 관련된 글인지를 저에게 알려 줄 것입니다.

 

Fine Tuning과 관련 한 기초적인 내용을 아시려면 아래 블로그 글을 참조하세요.

 

https://coronasdk.tistory.com/1221

 

Guides - Fine tuning

https://beta.openai.com/docs/guides/fine-tuning OpenAI API An API for accessing new AI models developed by OpenAI beta.openai.com Fine-tuning Learn how to customize a model for your application. 당신의 어플리케이션을 위해 어떻게 모델을

coronasdk.tistory.com

 

그러면 GPT-3를 훈련 시키기 위한 데이터 세트 형식으로 위 데이터를 변경 시켜 보겠습니다.

Prompt 와 Completion 이 두가지 컬럼이 있어야 합니다.

Prompt에는 data 정보들이 있고 Completion에는 그 글이 야구와 관련된 글인지 하키와 관련된 글인지에 대한 정보들이 들거 갈 겁니다.

 

import pandas as pd

labels = [sports_dataset.target_names[x].split('.')[-1] for x in sports_dataset['target']]
texts = [text.strip() for text in sports_dataset['data']]
df = pd.DataFrame(zip(texts, labels), columns = ['prompt','completion']) #[:300]
df.head()

파이썬에서 데이터를 다루는 모델은 pandas를 많이 사용 합니다.

 

labels 부분을 보겠습니다.

위에서 sports_dataset['target'] 에는 0 과 1이라는 정보들이 있고 이 정보는 data에 있는 정보가 targetnames 의 첫번째 인수에 속하는 건지 두번째 인수에 속하는 건지를 알려 주는 것이라고 했습니다.

첫번째 인수는 rec.sport.baseball이고 두번째 인수는 rec.sport.hockey 입니다.

 

이 target 값에 대한 for 문이 도는데요 data 갯수가 1197이고 target의 각 인수들 (0,1) 은 각 데이터의 인수들과 매핑 돼 있으니까 이 for 문은 1197번 돌 겁니다. 이렇게 돌면서 target_names에서 해당 인수를 가져 와서 . 으로 그 텍스트를 분리 한 다음에 -1 번째 즉 맨 마지막 글자를 가지고 오게 됩니다. 그러면 baseball과 hockey라는 글자만 선택 되게 되죠.

즉 labels에는 baseball 과 hockey라는 글자들이 들어가게 되는데 이는 target 에 0이 있으면 baseball 1이 있으면 hockey가 들어가는 1197개의 인수를 가지고 있는 배열이 순서대로 들어가게 되는 겁니다.

 

그러면 이제 data에 있는 각 데이터를 순서대로 배열로 집어 넣으면 되겠죠?

texts = [text.strip() for text in sports_dataset['data']]

이 부분이 그 일을 합니다.

sports_dataset 에 있는 data 만큼 for 문을 돕니다. data는 1197개의 인수를 가지고 있으니 이 for 문도 1197번 돌 겁니다.

이 데이터를 그냥 texts 라는 변수에 배열 형태로 집어 넣는 겁니다. text.strip()은 해당 text의 앞 뒤에 있는 공백들을 제거 하는 겁니다.

이 부분도 중요 합니다. 데이터의 앞 뒤 공백을 제거해서 깨끗한 데이터를 만듭니다.

 

이제 data의 각 글을 가지고 있는 배열과 각 글들이 어느 주제에 속하는지에 대한 정보를 가지고 있는 배열들이 완성 됐습니다.

이 정보를 가지고 pandas로 GPT-3 AI 를 훈련 시킬 수 있는 형태의 데이터 세트로 만들겠습니다.

 

파이썬에서 zip() 함수는 두 배열을 튜플 형식으로 짝 지어 주는 함수 입니다. 

https://www.w3schools.com/python/ref_func_zip.asp

 

Python zip() Function

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

아래와 같이 두 배열의 인수들을 짝 지어 줍니다.

zip(texts, labels) <- 이렇게 하면 데이터와 topic이 짝 지어 지겠죠.

이 값은 pandas의 DataFrame의 첫번째 인수로 전달 되고 두번째 인수로는 컬럼 이름이 전달 됩니다. (columns = ['prompt','completion'])

 

그 다음 df.head() 로 이렇게 만들어진 DataFrame에서 처음에 오는 5개의 데이터를 출력해 봅니다.

 

의도한 대로 각 게시글과 그 게시글이 baseball에 속한 것인지 hockey에 속한 것인지에 대한 정보가 있네요.

 

이 cookbook에는 300개의 데이터만 사용할 것이라고 돼 있는데 어디에서 그게 돼 있는지 모르겠네요.

len() 을 찍어봐도 1197 개가 찍힙니다.

cookbook 설명대로 300개의 데이터만 사용하려면 아래와 같이 해야 할 것 같습니다.

 

import pandas as pd

labels = [sports_dataset.target_names[x].split('.')[-1] for x in sports_dataset['target']]
texts = [text.strip() for text in sports_dataset['data']]
df = pd.DataFrame(zip(texts, labels), columns = ['prompt','completion']) #[:300]
df = df.head(300)
print(df)

저는 이 300개의 데이터만 이용하겠습니다.

GPT-3 의 Fine-tuning 을 사용할 때 데이터 크기에 따라서 과금 될 거니까.. 그냥 조금만 하겠습니다. 지금은 공부하는 단계이니까 Custom model의 정확도 보다는 Custom model을 Fine tuning을 사용해서 만드는 과정을 배우면 되니까요.

 

그 다음은 이 DataFrame을 json 파일로 만드는 겁니다.

 

df.to_json("sport2.jsonl", orient='records', lines=True)

to_json() 함수를 사용해서 sport2.jsonl 이라는 파일을 만듭니다. 

orient='records' 라는 말은 리스트 형태가 된다는 얘기입니다.

 

orient   str

Indication of expected JSON string format.

  • Series:
    • default is ‘index’
    • allowed values are: {‘split’, ‘records’, ‘index’, ‘table’}.
  • DataFrame:
    • default is ‘columns’
    • allowed values are: {‘split’, ‘records’, ‘index’, ‘columns’, ‘values’, ‘table’}.
  • The format of the JSON string:
    • ‘split’ : dict like {‘index’ -> [index], ‘columns’ -> [columns], ‘data’ -> [values]}
    • ‘records’ : list like [{column -> value}, … , {column -> value}]
    • ‘index’ : dict like {index -> {column -> value}}
    • ‘columns’ : dict like {column -> {index -> value}}
    • ‘values’ : just the values array
    • ‘table’ : dict like {‘schema’: {schema}, ‘data’: {data}}

    Describing the data, where data component is like orient='records'.

     

    lines = True는 orient가 records일 경우 True로 설정해야 합니다.

     

    linesbool, default False

    If ‘orient’ is ‘records’ write out line-delimited json format. Will throw ValueError if incorrect ‘orient’ since others are not list-like.

     

    https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_json.html

 

pandas.DataFrame.to_json — pandas 1.5.3 documentation

The time unit to encode to, governs timestamp and ISO8601 precision. One of ‘s’, ‘ms’, ‘us’, ‘ns’ for second, millisecond, microsecond, and nanosecond respectively. For on-the-fly compression of the output data. If ‘infer’ and ‘path_o

pandas.pydata.org

 

이 부분을 실행하면 해당 디렉토리에 sport2.jsonl 파일이 생성됩니다.

 

이 파일 내용은 아래와 같습니다.

 

prompt 에는 내용이 있고 completion에는 baseball나 hockey가 들어 있습니다. 총 300개의 prompt - completion 쌍이 있습니다.

 

Cookbook에는 다음 단계로 openai 를 업데이트 하라고 돼 있습니다. 

!pip install --upgrade openai

이렇게 해 줍니다. 저같은 경우는 자주 업데이트를 해 줘서 별로 변경되는 내용은 없었습니다.

 

이제 openai의 fine_tunes 함수를 사용할 차례입니다.

 

!openai tools fine_tunes.prepare_data -f sport2.jsonl -q

주피터 노트북에서는 위와 같이 입력하고 Command 창을 사용할 경우에는 !를 없앤 나머지 부분을 타이핑 하면 됩니다.

 

만약 이것을 실행했는데 아래와 같은 메세지가 보인다면 Environment Variable을 설정해 주면 됩니다.

이 문제를 해결하려면 아래 블로그 글을 확인하세요.

https://coronasdk.tistory.com/1295

 

openai 명령어를 command 창에서 인식을 하지 못 할 때...

아래와 같이 command 창에서 openai 를 인식하지 못하는 문제를 해결하는 방법을 알아 보겠습니다. 'openai' is not recognized as an internal or external command, operable program or batch file. 저같은 경우는 Windows에서 P

coronasdk.tistory.com

문제가 없다면 아래와 같은 결과가 나옵니다.

 

 

openai aools fine_tunes.prepare_data는 데이터를 검증하고 제안하고 형식을 다시 지정해 주는 툴입니다.

위 결과를 보면 Analyzing... (분석중)으로 시작해서 이 파일에는 총 300개의 prompt-completion 쌍이 있고 모델을 fine-tune 하려고 하는 것 같은데 저렴한 ada 모델을 사용하세요... 뭐 이렇게 분석과 제안내용이 표시됩니다.

그리고 너무 긴 글이 3개 있고 134, 200,281 번째 줄. .....이렇게 나오고 이 3개는 너무 길어서 제외한다고 나오네요.

 

이 결과로 sport2_prepared_train.jsonl 과 sport2_prepared_valid.jsonl 파일 두개를 만들어 냅니다.

그리고 이제 fine_tunes.create을 사용해서 fine-tuning을 하면 된다고 나오네요.

 

Fine-tuning을 하게 되면 curie 모델을 사용하면 대략 9분 46초 정도 걸릴 것이고 ada 모델을 사용하면 그보다 더 조금 걸릴 거라네요.

 

폴더를 다시 봤더니 정말 두개의 jsonl 파일이 더 생성 되었습니다.

 

sport2_prepared_train.jsonl에는 위에 너무 길다는 3개의 데이터를 없앤 나머지 297개의 데이터가 있습니다.

sport2_prepared_valid.jsonl에는 60개의 데이터가 있습니다.

 

train 데이터와 valid 데이터 이렇게 두개가 생성 되었네요. 이 두개를 생성한 이유는 나중에 새 데이터에 대한 예상 성능을 쉽게 측정하기 위해서 GPT-3 의 fine_tunes.prepare_data 함수가 만든 겁니다.

 

Fine-tuning

이제 다 준비가 됐습니다. 실제로 Fine tuning을 하면 됩니다.

참고로 지금 우리는 내용을 주면 이 내용이 야구에 대한건지 하키에 대한건지 분류 해 주는 fine tuned 된 모델을 생성하려고 합니다.

이 작업은 classification task에 속합니다.

그래서 train 과 valid 두 데이터 세트가 위에서 생성된 거구요.

 

이제 Fine-tuning을 하기 위해 아래 명령어를 사용하면 됩니다.

 

!openai api fine_tunes.create -t "sport2_prepared_train.jsonl" -v "sport2_prepared_valid.jsonl" --compute_classification_metrics --classification_positive_class " baseball" -m ada

 

fine_tunes.create 함수를 사용했고 training data로는 sport2_prepared_train.jsonl 파일이 있고 valid data로는 sport2.prepared_valid_jsonl이 제공된다고 돼 있습니다.

그 다음엔 compute_classification_metrics와 classification_positive_class "baseball" 이 주어 졌는데 이는 위에서 fine_tunes.prepare_data 에서 추천한 내용입니다. classification metics를 계산하기 위해 필요하기 때문에 추천 했습니다.

 

그리고 마지막에 -m ada는 ada 모델을 사용하겠다는 겁니다.

 

이 부분을 실행하면 요금이 청구가 됩니다.

Fine-tuning models 같은 경우 과금은 아래와 같이 됩니다.

 

ada 모델을 사용하니까 토큰 1천개당 0.0004불이 training 과정에 들게 됩니다.

Usage도 있네요 나중에 Fine Tune 된 Custom Model을 사용하게 되면 토큰 1천개당 0.0016 불이 과금 됩니다.

 

https://openai.com/pricing

 

Pricing

Simple and flexible. Only pay for what you use.

openai.com

 

저는 이 fine_tunes.create를 실행하고 30분이 넘었는데도 아무런 응답이 없어서 fine_tunes.list로 체크해 봤습니다.

 

 

그런데 이것도 답변이 없더라구요.

그래서 한참을 더 기다렸습니다.

결국 이날 되지 않아서 GPT-4 발표를 유투브에서 하길래 그 내용만 살펴 보다 끝났네요.

다음날 다시 Jupyterlab 실행 시키고 나서 !openai api fine_tunes.list 를 해 보았습니다.

이제 나왔네요.

저는 11일에도 한번 공부하다가 만든게 있어서 모델이 2개 나왔는데요.

그건 delete로 지워 버렸습니다.

!openai api models.delete -i ada:ft-personal-2023-03-11-15-30-13

결과는 아래와 같이나왔습니다.

{
  "deleted": true,
  "id": "ada:ft-personal-2023-03-11-15-30-13",
  "object": "model"
}

그 후 나온 list 에 대한 결과 입니다.

{
  "data": [
    {
      "created_at": 1678817966,
      "fine_tuned_model": "ada:ft-personal-2023-03-14-18-36-10",
      "hyperparams": {
        "batch_size": 1,
        "classification_positive_class": " baseball",
        "compute_classification_metrics": true,
        "learning_rate_multiplier": 0.1,
        "n_epochs": 4,
        "prompt_loss_weight": 0.01
      },
      "id": "ft-GI4Lb4z2d7TrYstNw15SXhlN",
      "model": "ada",
      "object": "fine-tune",
      "organization_id": "org-어카운트 organization ID",
      "result_files": [
        {
          "bytes": 51539,
          "created_at": 1678818971,
          "filename": "compiled_results.csv",
          "id": "file-5QHkdzACEhvgPxFAopnL4KUe",
          "object": "file",
          "purpose": "fine-tune-results",
          "status": "processed",
          "status_details": null
        }
      ],
      "status": "succeeded",
      "training_files": [
        {
          "bytes": 391121,
          "created_at": 1678817965,
          "filename": "sport2_prepared_train.jsonl",
          "id": "file-pxuc7tJA3rJ5mVI8HKWNe62p",
          "object": "file",
          "purpose": "fine-tune",
          "status": "processed",
          "status_details": null
        }
      ],
      "updated_at": 1678818971,
      "validation_files": [
        {
          "bytes": 89587,
          "created_at": 1678817966,
          "filename": "sport2_prepared_valid.jsonl",
          "id": "file-IDNYZdlWRpi6jhlKhqVs3OaQ",
          "object": "file",
          "purpose": "fine-tune",
          "status": "processed",
          "status_details": null
        }
      ]
    }
  ],
  "object": "list"
}

이번에 만든 모델 이름은 ada:ft-personal-2023-03-14-18-36-10 입니다.

result_files 에 보면 compiled_results.csv 을 생성했다고 하네요.

제 컴퓨터의 폴더를 보니까 아무것도 없더라구요. 아마 OpenAI 내에 보관 되 있는 것 같습니다.

그 다음은 training_files 와 validation_files에 대한 정보를 보여 줍니다.

 

참고로 Cook Book에서는 fine_tunes.create이 진행되는 과정에서 아래와 같은 메세지를 보여 준다고 합니다.

(저는 중간에 끄고 다른일을 봐서 이런 메세지는 못 봤습니다.)

 

 

참고로 이날 300개를 fine-tuning 한 가격은 0.21 달러입니다.

며칠 전에 1197개를 fine tuning 했을 때는 0.78 달러가 나왔었습니다.

 

 

[Advanced] Results and expected model performance

아래 명령어로 생성된 result 파일을 다운 받을 수 있습니다.

 

처음엔 result_files에 있는 ID를 넣었더니 No fine-tune job 이라는 에러 메세지가 나오네요.

여기에는 Fine tune id 를 넣어야 합니다.

그런데 저 같은 경우는 Bad file descriptor 에러 메세지가 나왔습니다.

jupyterlab을 껐다 다시 켜고 했는데도 똑 같더라구요.

 

그런데 제 컴터 폴더에 가 보니까 csv 파일이 생성 돼 있었습니다. 그런데 파일 사이즈는 0이더라구요. 내용이 아무것도 없는거죠.

 

그래서 fine_tunes.create을 다시 해 봤습니다. 새로운 모델을 생성해서 해 보려구요. 

 

이 작업은 시간이 많이 걸릴 것 같습니다.

fine_tunes.create은 일단 걸어 놨고 이 작업이 언제 끝날 지 모르겠네요.

 

GPT-4 에 대한 새로운 글들을 읽어보고 다시 시작해 봤습니다.

Jupyterlab에서 하지 않고 Command 창에서 해 봤는데 여기서도 똑 같네요.

 

 

직접 실습은 어려울 것 같고 Cookbook에 있는 설명을 보면서 공부해야 겠습니다.

 

results = pd.read_csv('result.csv')
results[results['classification/accuracy'].notnull()].tail(1)

일단 result.csv 파일을 생성하는데 성공하면 그 데이터를 pandas의 read_csv를 사용해서 읽어 옵니다.

그 다음줄은 그냥 한 줄 출력해 보는 라인 입니다.

 

결과는 아래와 같습니다.

The accuracy reaches 99.6%. On the plot below we can see how accuracy on the validation set increases during the training run.

정확도는 99.6%에 이릅니다. 아래 플롯에서 훈련 실행 중에 유효성 검사 세트의 정확도가 어떻게 증가하는지 확인할 수 있습니다.

results[results['classification/accuracy'].notnull()]['classification/accuracy'].plot()

그 다음은 이 데이터를 plot 해 봅니다. 결과 화면은 아래와 같습니다.

 

result.csv 파일을 살펴 봤구요.

이제 Fine-tuning으로 만든 새로운 모델을 직접 사용할 차례 입니다.

 

Using the model

We can now call the model to get the predictions.

이제 이 새로운 모델을 call 해서 예측을 해 볼 수 있습니다.

 

test = pd.read_json('sport2_prepared_valid.jsonl', lines=True)
test.head()

 

We need to use the same separator following the prompt which we used during fine-tuning. In this case it is \n\n###\n\n. Since we're concerned with classification, we want the temperature to be as low as possible, and we only require one token completion to determine the prediction of the model.

 

fine-tuning 중에 사용한 프롬프트 다음에 동일한 구분 기호를 사용해야 합니다. 이 경우 \n\n###\n\n입니다. 우리는 분류와 관련이 있기 때문에 temperature 가 가능한 한 낮아지기를 원하며 모델의 예측을 결정하기 위해 하나의 token completion만 필요합니다.

 

ft_model = 'ada:ft-openai-2021-07-30-12-26-20'
res = openai.Completion.create(model=ft_model, prompt=test['prompt'][0] + '\n\n###\n\n', max_tokens=1, temperature=0)
res['choices'][0]['text']

Cookbook 에서 Fine tuning으로 생성한 모델 이름을 ft_model 변수에 넣습니다.

 

그리고 위에 test에 있는 첫번째 prompt를 전달합니다. (우리는 이미 이 내용이 hockey 와 관련 돼 있다는 걸 알고 있습니다.)

이렇게 하면 결과는 이렇습니다.

' hockey'

새로 만든 모델을 써서 정답을 얻어 냈습니다.

 

To get the log probabilities, we can specify logprobs parameter on the completion request

로그 확률을 얻기 위해 완료 요청에 logprobs 매개변수를 지정할 수 있습니다.

 

res = openai.Completion.create(model=ft_model, prompt=test['prompt'][0] + '\n\n###\n\n', max_tokens=1, temperature=0, logprobs=2)
res['choices'][0]['logprobs']['top_logprobs'][0]
<OpenAIObject at 0x7fe114e435c8> JSON: {
  " baseball": -7.6311407,
  " hockey": -0.0006307676
}

이 결과는 입력값이 어느것과 더 가까운지를 숫자로 보여 줍니다. 

Baseball 보다는 hockey 에 훨썬 더 가깝다는 것을 알 수 있습니다.

 

We can see that the model predicts hockey as a lot more likely than baseball, which is the correct prediction. By requesting log_probs, we can see the prediction (log) probability for each class.

 

모델이 야구보다 하키를 훨씬 더 많이 예측한다는 것을 알 수 있습니다. 이것이 정확한 예측입니다. log_probs를 요청하면 각 클래스에 대한 예측(로그) 확률을 볼 수 있습니다.

 

Generalization

Interestingly, our fine-tuned classifier is quite versatile. Despite being trained on emails to different mailing lists, it also successfully predicts tweets.

 

흥미롭게도 fine-tuned classifier는 매우 다재다능합니다. 다른 메일링 리스트에 대한 이메일에 대한 교육을 받았음에도 불구하고 트윗을 성공적으로 예측합니다.

sample_hockey_tweet = """Thank you to the 
@Canes
 and all you amazing Caniacs that have been so supportive! You guys are some of the best fans in the NHL without a doubt! Really excited to start this new chapter in my career with the 
@DetroitRedWings
 !!"""
res = openai.Completion.create(model=ft_model, prompt=sample_hockey_tweet + '\n\n###\n\n', max_tokens=1, temperature=0, logprobs=2)
res['choices'][0]['text']

 

이 내용은 이전에 없던 내용 입니다..

내용에 NHL이라는 단어가 있네요. National Hockey league 겠죠?

그러면 이 이메일은 하키와 관련한 이메일 일 겁니다.

Fine tuning으로 만든 새로운 모델도 이것을 정확하게 맞춥니다.

 

' hockey'
sample_baseball_tweet="""BREAKING: The Tampa Bay Rays are finalizing a deal to acquire slugger Nelson Cruz from the Minnesota Twins, sources tell ESPN."""
res = openai.Completion.create(model=ft_model, prompt=sample_baseball_tweet + '\n\n###\n\n', max_tokens=1, temperature=0, logprobs=2)
res['choices'][0]['text']

그 다음 예제에서는 Tampa Bay Rays , Minnesota Twins 라는 내용이 나옵니다.

Minnesota Twins 는 한 때 박병호 선수가 있었던 메이저리그 야구 팀입니다.

당시에 제가 미네소타에 살고 있어서 구경하러 갔던 기억이 있네요.

 

' baseball'

GPT-3 도 이 내용이 야구와 관련 돼 있다는 걸 알아 차리네요.

 

이상으로 Fine tuning 하는 방법을 알아 봤습니다.

반응형


반응형

오늘은 Openai Cookbook 에 있는 Fine Tuning 관련 글을 공부해 보겠습니다.

 

https://docs.google.com/document/d/1rqj7dkuvl7Byd5KQPUJRxc19BJt8wo0yHNwK84KfU3Q/edit

 

[PUBLIC] Best practices for fine-tuning GPT-3 to classify text

This document is a draft of a guide that will be added to the next revision of the OpenAI documentation. If you have any feedback, feel free to let us know. One note: this doc shares metrics for text-davinci-002, but that model is not yet available for fin

docs.google.com

 

This document is a draft of a guide that will be added to the next revision of the OpenAI documentation. If you have any feedback, feel free to let us know.

 

이 문서는 OpenAI 문서의 다음 개정판에 추가될 가이드의 초안입니다. 의견이 있으시면 언제든지 알려주십시오.

 

One note: this doc shares metrics for text-davinci-002, but that model is not yet available for fine-tuning.

참고: 이 문서는 text-davinci-002에 대한 메트릭을 공유하지만 해당 모델은 아직 미세 조정에 사용할 수 없습니다.

 

Best practices for fine-tuning GPT-3 to classify text

GPT-3’s understanding of language makes it excellent at text classification. Typically, the best way to classify text with GPT-3 is to fine-tune GPT-3 on training examples. Fine-tuned GPT-3 models can meet and exceed state-of-the-art records on text classification benchmarks.

 

GPT-3의 언어 이해력은 텍스트 분류에 탁월합니다. 일반적으로 GPT-3으로 텍스트를 분류하는 가장 좋은 방법은 training examples 로 GPT-3을 fine-tune하는 것입니다. Fine-tuned GPT-3 모델은 텍스트 분류 벤치마크에서 최신 기록을 충족하거나 능가할 수 있습니다.

 

This article shares best practices for fine-tuning GPT-3 to classify text.

 

이 문서에서는 GPT-3을 fine-tuning 하여 텍스트를 분류하는 모범 사례를 공유합니다.

 

Other resources:

Outline:

Best practices for fine-tuning GPT-3 to classify text

Other resources:

Outline:

How fine-tuning GPT-3 works

Training data

How to format your training data

Separator sequences

How to pick labels

How much training data do you need

How to evaluate your fine-tuned model

Example fine-tuning calls using the OpenAI CLI

The following metrics will be displayed in your results file if you set --compute_classification_metrics:

For multiclass classification

For binary classification

Example outputs

Example metrics evolution over a training run, visualized with Weights & Biases

How to pick the right model

How to pick training hyperparameters

More detail on prompt_loss_weight

Example hyperparameter sweeps

n_epochs

learning_rate_multiplier

prompt_loss_weight

How to pick inference parameters

Advanced techniques

Add reasoning steps

Fine-tune a fine-tuned model

Common mistakes

Common mistake #1: Insufficiently specified training data

Common mistake #2: Input data format that doesn’t match the training data format

More examples

 

 

How fine-tuning GPT-3 works

 

The OpenAI fine-tuning guide explains how to fine-tune your own custom version of GPT-3. You provide a list of training examples (each split into prompt and completion) and the model learns from those examples to predict the completion to a given prompt.

 

OpenAI fine-tuning guide는 사용자 지정 GPT-3 버전을 fine-tune하는 방법을 설명합니다. 교육 예제 목록(각각 prompt completion로 분할)을 제공하면 모델이 해당 예제에서 학습하여 주어진 prompt에 대한 completion 를 예측합니다.

 

Example dataset:

 

Prompt Completion
“burger -->” “ edible”
“paper towels -->” “ inedible”
“vino -->” “ edible”
“bananas -->” “ edible”
“dog toy -->” “ inedible”

In JSONL format:

{"prompt": "burger -->", "completion": " edible"}

{"prompt": "paper towels -->", "completion": " inedible"}

{"prompt": "vino -->", "completion": " edible"}

{"prompt": "bananas -->", "completion": " edible"}

{"prompt": "dog toy -->", "completion": " inedible"}

 

During fine-tuning, the model reads the training examples and after each token of text, it predicts the next token. This predicted next token is compared with the actual next token, and the model’s internal weights are updated to make it more likely to predict correctly in the future. As training continues, the model learns to produce the patterns demonstrated in your training examples.

 

fine-tuning 중에 모델은 교육 예제를 읽고 텍스트의 각 토큰을 받아들여 그 다음 토큰이 무엇이 올 지 예측을 하게 됩니다.  이 예측된 다음 토큰은 실제 다음 토큰과 비교되고 모델의 내부 가중치가 업데이트되어 향후에 올바르게 예측할 가능성이 높아집니다. 학습이 계속됨에 따라 모델은 학습 예제에 표시된 패턴을 생성하는 방법을 배웁니다.

 

After your custom model is fine-tuned, you can call it via the API to classify new examples:

 

사용자 지정 모델이 fine-tuned된 후 API를 통해 호출하여 새 예제를 분류할 수 있습니다.

 

Prompt Completion
“toothpaste -->” ???

Example API call to get the most likely token

가장 유사한 토큰을 얻는 API call 예제

api_response = openai.Completion.create(
    model="{fine-tuned model goes here, without brackets}",
    prompt="toothpaste -->",
    temperature=0,
    max_tokens=1
)
completion_text = api_response['choices'][0]['text']
if completion_text == ' edible':
    label = 'edible'
elif completion_text == ' in':
    label = 'inedible'
else:
    label = 'other'

As ‘ edible’ is 1 token and ‘ inedible’ is 3 tokens, in this example, we request just one completion token and count ‘ in’ as a match for ‘ inedible’.

 

'edible'은 토큰 1개이고 'inedible'은 토큰 3개이므로 이 예에서는 완료 토큰 하나만 요청하고 'inedible'에 대한 일치 항목으로 'in'을 계산합니다.

 

Example API call to get probabilities for the 5 most likely tokens

 가장 유사한 토큰 5개에 대한 probabilities를 얻기 위한 API call 예제

api_response = openai.Completion.create(
    model="{fine-tuned model goes here, without brackets}",
    prompt="toothpaste -->",
    temperature=0,
    max_tokens=1,
    logprobs=5
)
dict_of_logprobs = api_response['choices'][0]['logprobs']['top_logprobs'][0].to_dict()
dict_of_probs = {k: 2.718**v for k, v in dict_of_logprobs.items()}

 

Training data

 

The most important determinant of success is training data.

Fine-tuning 성공의 가장 중요한 결정 요인은 학습 데이터입니다.

 

Your training data should be:

학습 데이터는 다음과 같아야 합니다.

  • Large (ideally thousands or tens of thousands of examples)
  • 대규모(이상적으로는 수천 또는 수만 개의 예)
  • High-quality (consistently formatted and cleaned of incomplete or incorrect examples)
  • 고품질(불완전하거나 잘못된 예를 일관되게 형식화하고 정리)
  • Representative (training data should be similar to the data upon which you’ll use your model)
  • 대표(학습 데이터는 모델을 사용할 데이터와 유사해야 함)
  • Sufficiently specified (i.e., containing enough information in the input to generate what you want to see in the output)
  • 충분히 특정화 되어야 함 (즉, 출력에서 보고 싶은 것을 생성하기 위해 입력에 충분한 정보 포함)

 

If you aren’t getting good results, the first place to look is your training data. Try following the tips below about data formatting, label selection, and quantity of training data needed. Also review our list of common mistakes.

 

좋은 결과를 얻지 못한 경우 가장 먼저 살펴봐야 할 곳은 훈련 데이터입니다. 데이터 형식, 레이블 선택 및 필요한 학습 데이터 양에 대한 아래 팁을 따르십시오. common mistakes 목록도 검토하십시오.

 

How to format your training data

 

Prompts for a fine-tuned model do not typically need instructions or examples, as the model can learn the task from the training examples. Including instructions shouldn’t hurt performance, but the extra text tokens will add cost to each API call.

 

모델이 교육 예제에서 작업을 학습할 수 있으므로 fine-tuned 모델에 대한 프롬프트에는 일반적으로 지침(instruction)이나 예제가 필요하지 않습니다. 지침(instruction)을 포함해도 성능이 저하되지는 않지만 추가 텍스트 토큰으로 인해 각 API 호출에 비용이 추가됩니다.

 

Prompt Tokens Recommended
“burger -->"
“Label the following item as either edible or inedible.

Item: burger
Label:”
20 
“Item: cake
Category: edible

Item: pan
Category: inedible

Item: burger
Category:”
26 

 

Instructions can still be useful when fine-tuning a single model to do multiple tasks. For example, if you train a model to classify multiple features from the same text string (e.g., whether an item is edible or whether it’s handheld), you’ll need some type of instruction to tell the model which feature you want labeled.

 

지침(instruction)은 여러 작업을 수행하기 위해 단일 모델을 fine-tuning할 때 여전히 유용할 수 있습니다. 예를 들어, 동일한 텍스트 문자열에서 여러 기능을 분류하도록 모델을 훈련하는 경우(예: 항목이 먹을 수 있는지 또는 휴대 가능한지 여부) 라벨을 지정하려는 기능을 모델에 알려주는 일종의 지침이 필요합니다.

 

Example training data:

Prompt Completion
“burger --> edible:” “ yes”
“burger --> handheld:” “ yes”
“car --> edible:” “ no”
“car --> handheld:” “ no”

 

Example prompt for unseen example:

Prompt Completion
“cheese --> edible:” ???

 

Note that for most models, the prompt + completion for each example must be less than 2048 tokens (roughly two pages of text). For text-davinci-002, the limit is 4000 tokens (roughly four pages of text).

 

대부분의 모델에서 각 예제에 대한 prompt + completion은 2048 토큰(약 2페이지의 텍스트) 미만이어야 합니다. text-davinci-002의 경우 한도는 4000개 토큰(약 4페이지의 텍스트)입니다.

Separator sequences

For classification, end your text prompts with a text sequence to tell the model that the input text is done and the classification should begin. Without such a signal, the model may append additional invented text before appending a class label, resulting in outputs like:

 

분류를 위해 입력 텍스트가 완료되고 분류가 시작되어야 함을 모델에 알리는 텍스트 시퀀스로 텍스트 프롬프트를 종료합니다. 이러한 신호가 없으면 모델은 클래스 레이블을 appending 하기 전에 추가  invented text append 하여 다음과 같은 결과를 얻을 수 있습니다.

 

  • burger edible (accurate)
  • burger and fries edible (not quite was asked for)
  • burger-patterned novelty tie inedible (inaccurate)
  • burger burger burger burger (no label generated)

Examples of separator sequences

Prompt Recommended
“burger”
“burger -->”
“burger

###

“burger >>>”
“burger

Label:”

 

Be sure that the sequence you choose is very unlikely to otherwise appear in your text (e.g., avoid ‘###’ or ‘->’ when classifying Python code). Otherwise, your choice of sequence usually doesn’t matter much.

 

선택한 sequence 가 텍스트에 다른 방법으로 사용되는 부호인지 확인하세요. (예: Python 코드를 분류할 때 '###' 또는 '->'를 피하십시오). 그러한 경우가 아니라면 시퀀스 선택은 일반적으로 그다지 중요하지 않습니다.

 

How to pick labels

One common question is what to use as class labels.

일반적인 질문 중 하나는 클래스 레이블로 무엇을 사용할 것인가입니다.

 

In general, fine-tuning can work with any label, whether the label has semantic meaning (e.g., “ edible”) or not (e.g., “1”). That said, in cases with little training data per label, it’s possible that semantic labels work better, so that the model can leverage its knowledge of the label’s meaning.

 

일반적으로 fine-tuning은 레이블에 semantic  의미(예: "식용")가 있든 없든(예: "1") 모든 레이블에서 작동할 수 있습니다. 즉, 레이블당 학습 데이터가 적은 경우 시맨틱 레이블이 더 잘 작동하여 모델이 레이블의 의미에 대한 지식을 활용할 수 있습니다.

 

When convenient, we recommend single-token labels. You can check the number of tokens in a string with the OpenAI tokenizer. Single-token labels have a few advantages:

 

가능하면 단일 토큰 레이블을 사용하는 것이 좋습니다. OpenAI 토크나이저를 사용하여 문자열의 토큰 수를 확인할 수 있습니다. 단일 토큰 레이블에는 다음과 같은 몇 가지 장점이 있습니다.

  • Lowest cost . 적은 비용
  • Easier to get their probabilities, which are useful for metrics confidence scores, precision, recall
  • 메트릭 신뢰도 점수, 정밀도, recall에 유용한 확률을 쉽게 얻을 수 있습니다.
  • No hassle from specifying stop sequences or post-processing completions in order to compare labels of different length
  • 다른 길이의 레이블을 비교하기 위해 중지 시퀀스 또는 후처리 완료를 지정하는 번거로움이 없습니다.

Example labels

Prompt Label Recommended
“burger -->” “ edible”
“burger -->” “ 1”
“burger -->” “ yes”
“burger -->” “ A burger can be eaten” (but still works)

 

One useful fact: all numbers <500 are single tokens. 500 이하는 single token입니다.

 

If you do use multi-token labels, we recommend that each label begin with a different token. If multiple labels begin with the same token, an unsure model might end up biased toward those labels due to greedy sampling.

 

multi-token label을 사용하는 경우 각 레이블이 서로 다른 토큰으로 시작하는 것이 좋습니다. 여러 레이블이 동일한 토큰으로 시작하는 경우 greedy  샘플링으로 인해 불확실한 모델이 해당 레이블로 편향될 수 있습니다.

 

How much training data do you need

How much data you need depends on the task and desired performance.

 

필요한 데이터의 양은 작업과 원하는 성능에 따라 다릅니다.


Below is an illustrative example of how adding training examples improves classification accuracy.

 

아래는 학습 예제를 추가하여 분류 정확도를 향상시키는 방법을 보여주는 예시입니다.

 

Illustrative examples of text classification performance on the Stanford Natural Language Inference (SNLI) Corpus, in which ordered pairs of sentences are classified by their logical relationship: either contradicted, entailed (implied), or neutral. Default fine-tuning parameters were used when not otherwise specified.

 

SNLI(Stanford Natural Language Inference) 코퍼스의 텍스트 분류 성능에 대한 예시로, 정렬된 문장 쌍이 논리적 관계(모순됨, 함축됨(암시됨) 또는 중립)에 따라 분류됩니다. 달리 지정되지 않은 경우 기본 fine-tuning 매개변수가 사용되었습니다.

 

Very roughly, we typically see that a few thousand examples are needed to get good performance:

 

아주 대략적으로 말해서 좋은 성능을 얻으려면 일반적으로 수천 개의 예제가 필요하다는 것을 알 수 있습니다.

 

Examples per label Performance (rough estimate)
Hundreds Decent
Thousands Good
Tens of thousands or more Great

 

To assess the value of getting more data, you can train models on subsets of your current dataset—e.g., 25%, 50%, 100%—and then see how performance scales with dataset size. If you plot accuracy versus number of training examples, the slope at 100% will indicate the improvement you can expect from getting more data. (Note that you cannot infer the value of additional data from the evolution of accuracy during a single training run, as a model half-trained on twice the data is not equivalent to a fully trained model.) 

 

더 많은 데이터를 얻는 가치를 평가하기 위해 현재 데이터 세트의 하위 집합(예: 25%, 50%, 100%)에서 모델을 교육한 다음 데이터 세트 크기에 따라 성능이 어떻게 확장되는지 확인할 수 있습니다. 정확도 대 교육 예제 수를 플로팅하는 경우 100%의 기울기는 더 많은 데이터를 얻을 때 기대할 수 있는 개선을 나타냅니다. (두 배의 데이터로 절반만 훈련된 모델은 완전히 훈련된 모델과 동일하지 않기 때문에 단일 훈련 실행 동안 정확도의 진화에서 추가 데이터의 가치를 추론할 수 없습니다.)

 

How to evaluate your fine-tuned model

Evaluating your fine-tuned model is crucial to (a) improve your model and (b) tell when it’s good enough to be deployed.

 

fine-tuned 모델을 평가하는 것은 (a) 모델을 개선하고 (b) 언제 배포하기에 충분한 지를 알려주는 데 중요합니다.

 

Many metrics can be used to characterize the performance of a classifier

 

많은 메트릭을 사용하여 분류기의 성능을 특성화할 수 있습니다.

 

  • Accuracy
  • F1
  • Precision / Positive Predicted Value / False Discovery Rate
  • Recall / Sensitivity
  • Specificity
  • AUC / AUROC (area under the receiver operator characteristic curve)
  • AUPRC (area under the precision recall curve)
  • Cross entropy

Which metric to use depends on your specific application and how you weigh different types of mistakes. For example, if detecting something rare but consequential, where a false negative is costlier than a false positive, you might care about recall more than accuracy.

 

사용할 메트릭은 특정 응용 프로그램과 다양한 유형의 실수에 가중치를 두는 방법에 따라 다릅니다. 예를 들어 거짓 음성이 거짓 긍정보다 비용이 많이 드는 드물지만 결과적인 것을 감지하는 경우 정확도보다 리콜에 더 관심을 가질 수 있습니다.

 

The OpenAI API offers the option to calculate some of these classification metrics. If enabled, these metrics will be periodically calculated during fine-tuning as well as for your final model. You will see them as additional columns in your results file

 

OpenAI API는 이러한 분류 메트릭 중 일부를 계산하는 옵션을 제공합니다. 활성화된 경우 이러한 지표는 최종 모델뿐만 아니라 미세 조정 중에 주기적으로 계산됩니다. 결과 파일에 추가 열로 표시됩니다.

 

To enable classification metrics, you’ll need to:

분류 지표를 활성화하려면 다음을 수행해야 합니다.:

  • use single-token class labels
  • 단일 토큰 클래스 레이블 사용
  • provide a validation file (same format as the training file)
  • 유효성 검사 파일 제공(교육 파일과 동일한 형식)
  • set the flag --compute_classification_metrics
  • compute_classification_metrics 플래그 설정
  • for multiclass classification: set the argument --classification_n_classes
  • 다중 클래스 분류: --classification_n_classes 인수 설정
  • for binary classification: set the argument --classification_positive_class
  • 이진 분류: --classification_positive_class 인수 설정

 

Example fine-tuning calls using the OpenAI CLI

 

# For multiclass classification
openai api fine_tunes.create \
  -t <TRAIN_FILE_ID_OR_PATH> \
  -v <VALIDATION_FILE_OR_PATH> \
  -m <MODEL> \
  --compute_classification_metrics \
  --classification_n_classes <NUMBER_OF_CLASSES>
# For binary classification
openai api fine_tunes.create \
  -t <TRAIN_FILE_ID_OR_PATH> \
  -v <VALIDATION_FILE_OR_PATH> \
  -m <MODEL> \
  --compute_classification_metrics \
  --classification_n_classes 2 \
  --classification_positive_class <POSITIVE_CLASS_FROM_DATASET>

 

The following metrics will be displayed in your results file if you set --compute_classification_metrics:For multiclass classification

compute_classification_metrics 를 설정하면 결과 파일에 다음 지표가 표시됩니다.

  • classification/accuracy: accuracy
  • classification/weighted_f1_score: weighted F-1 score

For binary classification

 

The following metrics are based on a classification threshold of 0.5 (i.e. when the probability is > 0.5, an example is classified as belonging to the positive class.)

 

다음 메트릭은 0.5의 분류 임계값을 기반으로 합니다(즉, 확률이 > 0.5인 경우 예는 포지티브 클래스에 속하는 것으로 분류됨).

  • classification/accuracy
  • classification/precision
  • classification/recall
  • classification/f{beta}
  • classification/auroc - AUROC
  • classification/auprc - AUPRC

Note that these evaluations assume that you are using text labels for classes that tokenize down to a single token, as described above. If these conditions do not hold, the numbers you get will likely be wrong.

 

이러한 평가에서는 위에서 설명한 대로 단일 토큰으로 토큰화하는 클래스에 대해 텍스트 레이블을 사용하고 있다고 가정합니다. 이러한 조건이 충족되지 않으면 얻은 숫자가 잘못되었을 수 있습니다.

 

Example outputs

Example metrics evolution over a training run, visualized with Weights & Biases

 

Weights & Biases로 시각화된 교육 실행에 대한 메트릭 진화의 예

 

 

How to pick the right model

OpenAI offers fine-tuning for 5 models: OpenAI는 fine-tuning에 다음 5가지 모델을 사용할 것을 권장합니다.

  • ada (cheapest and fastest)
  • babbage
  • curie
  • davinci
  • text-davinci-002 (highest quality)

 

Which model to use will depend on your use case and how you value quality versus price and speed. 

 

사용할 모델은 사용 사례와 품질 대 가격 및 속도의 가치를 어떻게 평가하는지에 따라 달라집니다.

 

Generally, we see text classification use cases falling into two categories: simple and complex.

 

일반적으로 텍스트 분류 사용 사례는 단순과 복합의 두 가지 범주로 나뉩니다.

 

For tasks that are simple or straightforward, such as classifying sentiment, larger models offer diminishing benefit, as illustrated below:

 

감정 분류와 같이 간단하거나 직접적인 작업의 경우 더 큰 모델은 아래 그림과 같이 이점이 적습니다.

 

Model Illustrative accuracy* Training cost** Inference cost**
ada 89% $0.0004 / 1K tokens (~3,000 pages per dollar) $0.0016 / 1K tokens (~800 pages per dollar)
babbage 90% $0.0006 / 1K tokens (~2,000 pages per dollar) $0.0024 / 1K tokens (~500 pages per dollar)
curie 91% $0.003 / 1K tokens (~400 pages per dollar) $0.012 / 1K tokens (~100 pages per dollar)
davinci 92% $0.03 / 1K tokens (~40 pages per dollar) $0.12 / 1K tokens (~10 pages per dollar)
text-davinci-002 93% unreleased unreleased

 

*Illustrative accuracy on the SNLI dataset, in which sentence pairs are classified as contradictions, implications, or neutral

*문장 쌍이 모순, 암시 또는 중립으로 분류되는 SNLI 데이터 세트에 대한 설명 정확도

**Pages per dollar figures assume ~800 tokens per page. OpenAI Pricing.

 

Illustrative examples of text classification performance on the Stanford Natural Language Inference (SNLI) Corpus, in which ordered pairs of sentences are classified by their logical relationship: either contradicted, entailed (implied), or neutral. Default fine-tuning parameters were used when not otherwise specified.

 

SNLI(Stanford Natural Language Inference) 코퍼스의 텍스트 분류 성능에 대한 예시로, 정렬된 문장 쌍이 논리적 관계(모순됨, 함축됨(암시됨) 또는 중립)에 따라 분류됩니다. 달리 지정되지 않은 경우 기본 미세 조정 매개변수가 사용되었습니다.

 

For complex tasks, requiring subtle interpretation or reasoning or prior knowledge or coding ability, the performance gaps between models can be larger, and better models like curie or text-davinci-002 could be the best fit.

 

미묘한 해석이나 추론 또는 사전 지식이나 코딩 능력이 필요한 복잡한 작업의 경우 모델 간의 성능 차이가 더 클 수 있으며 curie 또는 text-davinci-002와 같은 더 나은 모델이 가장 적합할 수 있습니다.

 

A single project might end up trying all models. One illustrative development path might look like this:

단일 프로젝트에서 모든 모델을 시도하게 될 수 있습니다. 예시적인 개발 경로는 다음과 같습니다.

  • Test code using the cheapest & fastest model (ada)
  • 가장 저렴하고 빠른 모델(ada)을 사용하여 테스트 코드
  • Run a few early experiments to check whether your dataset works as expected with a middling model (curie)
  • 중간 모델(curie)에서 데이터 세트가 예상대로 작동하는지 확인하기 위해 몇 가지 초기 실험을 실행합니다.
  • Run a few more experiments with the best model to see how far you can push performance (text-davinci-002)
  • 최상의 모델로 몇 가지 실험을 더 실행하여 성능을 얼마나 높일 수 있는지 확인하십시오(text-davinci-002).
  • Once you have good results, do a training run with all models to map out the price-performance frontier and select the model that makes the most sense for your use case  (ada, babbage, curie, davinci, text-davinci-002)
  • 좋은 결과를 얻으면 모든 모델로 교육 실행을 수행하여 가격 대비 성능 한계를 파악하고 사용 사례에 가장 적합한 모델(ada, babbage, curie, davinci, text-davinci-002)을 선택합니다.

Another possible development path that uses multiple models could be:

여러 모델을 사용하는 또 다른 가능한 개발 경로는 다음과 같습니다.

  • Starting with a small dataset, train the best possible model (text-davinci-002)
  • 작은 데이터 세트로 시작하여 가능한 최상의 모델 훈련(text-davinci-002)
  • Use this fine-tuned model to generate many more labels and expand your dataset by multiples
  • 이 미세 조정된 모델을 사용하여 더 많은 레이블을 생성하고 데이터 세트를 배수로 확장하십시오.
  • Use this new dataset to train a cheaper model (ada)
  • 이 새로운 데이터 세트를 사용하여 더 저렴한 모델(ada) 훈련

 

How to pick training hyperparameters

Fine-tuning can be adjusted with various parameters. Typically, the default parameters work well and adjustments only result in small performance changes.

 

미세 조정은 다양한 매개변수로 조정할 수 있습니다. 일반적으로 기본 매개변수는 잘 작동하며 조정해도 성능이 약간만 변경됩니다.

 

Parameter Default Recommendation
n_epochs

controls how many times each example is trained on

각 예제가 훈련되는 횟수를 제어합니다.
4 For classification, we’ve seen good performance with numbers like 4 or 10. Small datasets may need more epochs and large datasets may need fewer epochs.

분류의 경우 4 또는 10과 같은 숫자로 좋은 성능을 보였습니다. 작은 데이터 세트에는 더 많은 에포크가 필요할 수 있고 큰 데이터 세트에는 더 적은 에포크가 필요할 수 있습니다.


If you see low training accuracy, try increasing n_epochs. If you see high training accuracy but low validation accuracy (overfitting), try lowering n_epochs.

훈련 정확도가 낮은 경우 n_epochs를 늘려 보십시오. 훈련 정확도는 높지만 검증 정확도(과적합)가 낮은 경우 n_epochs를 낮추십시오.


You can get training and validation accuracies by setting compute_classification_metrics to True and passing a validation file with labeled examples not in the training data. You can see graphs of these metrics evolving during fine-tuning with a Weights & Biases account.

compute_classification_metrics를 True로 설정하고 교육 데이터에 없는 레이블이 지정된 예제가 있는 유효성 검사 파일을 전달하여 교육 및 유효성 검사 정확도를 얻을 수 있습니다. Weights & Biases 계정을 사용하여 미세 조정하는 동안 진화하는 이러한 지표의 그래프를 볼 수 있습니다.
batch_size
controls the number of training examples used in a single training pass
단일 교육 패스에 사용되는 교육 예제의 수를 제어합니다.
null
(which dynamically adjusts to 0.2% of training set, capped at 256)
(트레이닝 세트의 0.2%로 동적으로 조정되며 256으로 제한됨)
We’ve seen good performance in the range of 0.01% to 2%, but worse performance at 5%+. In general, larger batch sizes tend to work better for larger datasets.

우리는 0.01%에서 2% 범위에서 좋은 성능을 보았지만 5% 이상에서는 더 나쁜 성능을 보였습니다. 일반적으로 더 큰 배치 크기는 더 큰 데이터 세트에서 더 잘 작동하는 경향이 있습니다.
learning_rate_multiplier
controls rate at which the model weights are updated
모델 가중치가 업데이트되는 속도를 제어합니다.
null
(which dynamically adjusts to 0.05, 0.1, or 0.2 depending on batch size)
(배치 크기에 따라 0.05, 0.1 또는 0.2로 동적으로 조정됨)
We’ve seen good performance in the range of 0.02 to 0.5. Larger learning rates tend to perform better with larger batch sizes.

0.02~0.5 범위에서 좋은 성능을 보였습니다. 더 큰 학습 속도는 더 큰 배치 크기에서 더 잘 수행되는 경향이 있습니다.
prompt_loss_weight
controls how much the model learns from prompt tokens vs completion tokens
모델이 프롬프트 토큰과 완료 토큰에서 학습하는 양을 제어합니다.



0.1 If prompts are very long relative to completions, it may make sense to reduce this weight to avoid over-prioritizing learning the prompt. In our tests, reducing this to 0 is sometimes slightly worse or sometimes about the same, depending on the dataset.

프롬프트가 완료에 비해 매우 긴 경우 프롬프트 학습에 과도한 우선순위를 두지 않도록 이 가중치를 줄이는 것이 좋습니다. 테스트에서 데이터 세트에 따라 이를 0으로 줄이는 것이 때때로 약간 더 나쁘거나 거의 동일합니다.

 

More detail on prompt_loss_weight

 

When a model is fine-tuned, it learns to produce text it sees in both the prompt and the completion. In fact, from the point of view of the model being fine-tuned, the distinction between prompt and completion is mostly arbitrary. The only difference between prompt text and completion text is that the model learns less from each prompt token than it does from each completion token. This ratio is controlled by the prompt_loss_weight, which by default is 10%.

 

모델이 미세 조정되면 prompt and the completion 모두에 표시되는 텍스트를 생성하는 방법을 학습합니다. 실제로 미세 조정되는 모델의 관점에서 신속함과 완료의 구분은 대부분 임의적입니다. 프롬프트 텍스트와 완료 텍스트의 유일한 차이점은 모델이 각 완료 토큰에서 학습하는 것보다 각 프롬프트 토큰에서 학습하는 내용이 적다는 것입니다. 이 비율은 prompt_loss_weight에 의해 제어되며 기본적으로 10%입니다.

 

A prompt_loss_weight of 100% means that the model learns from prompt and completion tokens equally. In this scenario, you would get identical results with all training text in the prompt, all training text in the completion, or any split between them. For classification, we recommend against 100%.

 

100%의 prompt_loss_weight는 모델이 프롬프트 및 완료 토큰에서 동일하게 학습함을 의미합니다. 이 시나리오에서는 프롬프트의 모든 학습 텍스트, 완성의 모든 학습 텍스트 또는 이들 간의 분할에 대해 동일한 결과를 얻습니다. 분류의 경우 100% 대비를 권장합니다.

 

A prompt loss weight of 0% means that the model’s learning is focused entirely on the completion tokens. Note that even in this case, prompts are still necessary because they set the context for each completion. Sometimes we’ve seen a weight of 0% reduce classification performance slightly or make results slightly more sensitive to learning rate; one hypothesis is that a small amount of prompt learning helps preserve or enhance the model’s ability to understand inputs.

 

0%의 즉각적인 손실 가중치는 모델의 학습이 완료 토큰에 전적으로 집중되어 있음을 의미합니다. 이 경우에도 프롬프트는 각 완료에 대한 컨텍스트를 설정하기 때문에 여전히 필요합니다. 때때로 우리는 0%의 가중치가 분류 성능을 약간 감소시키거나 결과가 학습률에 약간 더 민감해지는 것을 보았습니다. 한 가지 가설은 소량의 즉각적인 학습이 입력을 이해하는 모델의 능력을 유지하거나 향상시키는 데 도움이 된다는 것입니다.

 

Example hyperparameter sweeps

n_epochs

The impact of additional epochs is particularly high here, because only 100 training examples were used.

 

100개의 학습 예제만 사용되었기 때문에 추가 에포크의 영향이 여기에서 특히 높습니다.

learning_rate_multiplier

prompt_loss_weight

How to pick inference parameters

 

Parameter Recommendation
model (discussed above) [add link]
temperature Set temperature=0 for classification. Positive values add randomness to completions, which can be good for creative tasks but is bad for a short deterministic task like classification.
분류를 위해 온도=0으로 설정합니다. 양수 값은 완성에 임의성을 추가하므로 창의적인 작업에는 좋을 수 있지만 분류와 같은 짧은 결정론적 작업에는 좋지 않습니다.
max_tokens If using single-token labels (or labels with unique first tokens), set max_tokens=1. If using longer labels, set to the length of your longest label.
단일 토큰 레이블(또는 고유한 첫 번째 토큰이 있는 레이블)을 사용하는 경우 max_tokens=1로 설정합니다. 더 긴 레이블을 사용하는 경우 가장 긴 레이블의 길이로 설정하십시오.
stop If using labels of different length, you can optionally append a stop sequence like ‘ END’ to your training completions. Then, pass stop=‘ END’ in your inference call to prevent the model from generating excess text after appending short labels. (Otherwise, you can get completions like “burger -->” “ edible edible edible edible edible edible” as the model continues to generate output after the label is appended.) An alternative solution is to post-process the completions and look for prefixes that match any labels.
길이가 다른 레이블을 사용하는 경우 선택적으로 학습 완료에 ' END'와 같은 중지 시퀀스를 추가할 수 있습니다. 그런 다음 짧은 레이블을 추가한 후 모델이 과도한 텍스트를 생성하지 않도록 추론 호출에서 stop=' END'를 전달합니다. (그렇지 않으면 레이블이 추가된 후에도 모델이 계속 출력을 생성하므로 "burger -->" " edible edible edible edible edible"와 같은 완성을 얻을 수 있습니다.) 대체 솔루션은 완성을 후처리하고 접두사를 찾는 것입니다. 모든 레이블과 일치합니다.
logit_bias If using single-token labels, set logit_bias={“label1”: 100, “label2”:100, …} with your labels in place of “label1” etc.

For tasks with little data or complex labels, models can output tokens for invented classes never specified in your training set. logit_bias can fix this by upweighting your label tokens so that illegal label tokens are never produced. If using logit_bias in conjunction with multi-token labels, take extra care to check how your labels are being split into tokens, as logit_bias only operates on individual tokens, not sequences.

데이터가 적거나 레이블이 복잡한 작업의 경우 모델은 훈련 세트에 지정되지 않은 발명된 클래스에 대한 토큰을 출력할 수 있습니다. logit_bias는 불법 레이블 토큰이 생성되지 않도록 레이블 토큰의 가중치를 높여 이 문제를 해결할 수 있습니다. 다중 토큰 레이블과 함께 logit_bias를 사용하는 경우 logit_bias는 시퀀스가 아닌 개별 토큰에서만 작동하므로 레이블이 토큰으로 분할되는 방식을 특히 주의하십시오.


Logit_bias can also be used to bias specific labels to appear more or less frequently.
Logit_bias를 사용하여 특정 레이블이 더 자주 또는 덜 자주 표시되도록 바이어스할 수도 있습니다.
logprobs Getting the probabilities of each label can be useful for computing confidence scores, precision-recall curves, calibrating debiasing using logit_bias, or general debugging.
각 레이블의 확률을 얻는 것은 신뢰도 점수 계산, 정밀도 재현 곡선, logit_bias를 사용한 편향성 보정 보정 또는 일반 디버깅에 유용할 수 있습니다.


Setting logprobs=5 will return, for each token position of the completion, the top 5 most likely tokens and the natural logs of their probabilities. To convert logprobs into probabilities, raise e to the power of the logprob (probability = e^logprob). The probabilities returned are independent of temperature and represent what the probability would have been if the temperature had been set to 1. By default 5 is the maximum number of logprobs returned, but exceptions can be requested by emailing support@openai.com and describing your use case.

logprobs=5로 설정하면 완료의 각 토큰 위치에 대해 가장 가능성이 높은 상위 5개 토큰과 해당 확률의 자연 로그가 반환됩니다. logprobs를 확률로 변환하려면 e를 logprob의 거듭제곱으로 올립니다(probability = e^logprob). 반환된 확률은 온도와 무관하며 온도가 1로 설정되었을 경우의 확률을 나타냅니다. 기본적으로 5는 반환되는 logprobs의 최대 수. 예외는 support@openai.com으로 이메일을 보내주세요 귀하의 사용 사례를 보내 주세요.


Example API call to get probabilities for the 5 most likely tokens
가능성이 가장 높은 5개의 토큰에 대한 확률을 얻기 위한 API 호출 예

api_response = openai.Completion.create(
    model="{fine-tuned model goes here, without brackets}",
    prompt="toothpaste -->",
    temperature=0,
    max_tokens=1,
    logprobs=5
)
dict_of_logprobs = api_response['choices'][0]['logprobs']['top_logprobs'][0].to_dict()
dict_of_probs = {k: 2.718**v for k, v in dict_of_logprobs.items()}
echo In cases where you want the probability of a particular label that isn’t showing up in the list of logprobs, the echo parameter is useful. If echo is set to True and logprobs is set to a number, the API response will include logprobs for every token of the prompt as well as the completion. So, to get the logprob for any particular label, append that label to the prompt and make an API call with echo=True, logprobs=0, and max_tokens=0.

logprobs 목록에 나타나지 않는 특정 레이블의 확률을 원하는 경우 echo 매개변수가 유용합니다. echo가 True로 설정되고 logprobs가 숫자로 설정되면 API 응답에는 완료뿐 아니라 프롬프트의 모든 토큰에 대한 logprobs가 포함됩니다. 따라서 특정 레이블에 대한 logprob를 가져오려면 해당 레이블을 프롬프트에 추가하고 echo=True, logprobs=0 및 max_tokens=0으로 API 호출을 수행합니다.


Example API call to get the logprobs of prompt tokens

프롬프트 토큰의 logprobs를 가져오기 위한 API 호출 예
import openai


response = openai.Completion.create(
 model="text-davinci-002",
 prompt="burger --> edible",
 temperature=0,
 max_tokens=0,
 logprobs=0,
 echo=True
)


print(response['choices'][0]['logprobs']['token_logprobs'])


===
[None, -0.8182136, -7.7480173, -15.915648]

 

Advanced techniques

Add reasoning steps

For complex tasks that require reasoning, one useful technique you can experiment with is inserting explanations before the final answer. Giving the model extra time and space to think ‘aloud’ can increase the odds it arrives at the correct final answer.

 

추론이 필요한 복잡한 작업의 경우 실험할 수 있는 유용한 기술 중 하나는 최종 답변 앞에 설명을 삽입하는 것입니다. 모델에게 '큰 소리로' 생각할 수 있는 추가 시간과 공간을 제공하면 올바른 최종 답변에 도달할 가능성이 높아질 수 있습니다.

 

Example (from Zelikman, Wu, et al.):

Prompt Completion Completion with reasoning
“Q: Where do you put your grapes just before checking out?
Answer Choices:
(a) mouth
(b) grocery cart
(c) supermarket
(d) fruit basket
(e) fruit market
A:”
“(b)” “The answer should be the place where grocery items are placed before checking out. Of the above choices, grocery cart makes the most sense for holding grocery items. Therefore, the answer is grocery cart (b).”

“답은 체크아웃하기 전에 식료품을 두는 장소여야 합니다. 위의 선택 중에서 식료품 카트는 식료품을 보관하는 데 가장 적합합니다. 따라서 정답은 식료품 카트(b)입니다.”

Although it can sound daunting to write many example explanations, it turns out you can use large language models to write the explanations. In 2022, Zelikman, Wu, et al. published a procedure called STaR (Self-Taught Reasoner) in which a few-shot prompt can be used to generate a set of {questions, rationales, answers} from just a set of {questions, answers}

많은 예제 설명을 작성하는 것이 어렵게 들릴 수 있지만 큰 언어 모델을 사용하여 설명을 작성할 수 있습니다. 2022년 Zelikman, Wu, et al. {질문, 답변} 세트에서 {질문, 근거, 답변} 세트를 생성하기 위해 몇 번의 프롬프트를 사용할 수 있는 STaR(Self-Taught Reasoner)라는 절차를 발표했습니다.

 

 

Sequential fine-tuning

Models can be fine-tuned sequentially as many times as you like. One way you can use this is to pre-train your model on a large amount of relevant text, such as unstructured domain text or similar classification tasks, and then afterwards fine-tune on examples of the task you want the model to perform. An example procedure could look like:

 

모델은 원하는 만큼 순차적으로 미세 조정할 수 있습니다. 이를 사용할 수 있는 한 가지 방법은 구조화되지 않은 도메인 텍스트 또는 유사한 분류 작업과 같은 많은 양의 관련 텍스트에 대해 모델을 사전 훈련한 다음 나중에 모델이 수행할 작업의 예를 미세 조정하는 것입니다. 예제 절차는 다음과 같습니다.

 

  • Step 1: Fine-tune on cheap, semi-relevant data
    • E.g., unstructured domain text (such as legal or medical text)
    • E.g., similar task data (such as another large classification set)
  • Step 2: Fine-tune on expensive labeled examples
  • E.g., text and classes (if training a classifier)

To fine-tune a previously fine-tuned model, pass in the fine-tuned model name when creating a new fine-tuning job (e.g. -m curie:ft-<org>-<date>). Other training parameters do not have to be changed, however if your new training data is much smaller than your previous training data, you may find it useful to reduce learning_rate_multiplier by a factor of 2 to 4.

 

이전에 미세 조정된 모델을 미세 조정하려면 새 미세 조정 작업을 생성할 때 미세 조정된 모델 이름을 전달합니다(예: -m curie:ft-<org>-<date>). 다른 훈련 매개변수는 변경할 필요가 없지만 새 훈련 데이터가 이전 훈련 데이터보다 훨씬 작은 경우 learning_rate_multiplier를 2~4배 줄이는 것이 유용할 수 있습니다.

 

Common mistakes

The most common mistakes when fine-tuning text classifiers are usually related to training data.

 

텍스트 분류기를 미세 조정할 때 가장 흔한 실수는 일반적으로 훈련 데이터와 관련이 있습니다.

Common mistake #1: Insufficiently specified training data

One thing to keep in mind is that training data is more than just a mapping of inputs to correct answers. Crucially, the inputs need to contain the information needed to derive an answer.

 

한 가지 명심해야 할 점은 교육 데이터가 정답에 대한 입력의 매핑 이상이라는 것입니다. 결정적으로 입력에는 답을 도출하는 데 필요한 정보가 포함되어야 합니다.

 

For example, consider fine-tuning a model to predict someone’s grades using the following dataset:

 

예를 들어 다음 데이터 세트를 사용하여 누군가의 성적을 예측하도록 모델을 미세 조정하는 것을 고려하십시오.

 

Prompt Completion
“Alice >>>” “ A”
“Bob >>>” “ B+”
“Coco >>>” “ A-”
“Dominic >>>” “ B”

 

Prompt Completion
“Esmeralda >>>” ???

Without knowing why these students got the grades they did, there is insufficient information for the model to learn from and no hope of making a good personalized prediction for Esmeralda.

 

이 학생들이 자신이 받은 성적을 받은 이유를 모르면 모델이 배울 수 있는 정보가 충분하지 않으며 Esmeralda에 대해 좋은 개인화된 예측을 할 수 있는 희망이 없습니다.

 

This can happen more subtly when some information is given but some is still missing. For example, if fine-tuning a classifier on whether a business expense is allowed or disallowed, and the business expense policy varies by date or by location or by employee type, make sure the input contains information on dates, locations, and employee type.

 

이것은 일부 정보가 제공되었지만 일부가 여전히 누락된 경우 더 미묘하게 발생할 수 있습니다. 예를 들어 비즈니스 비용이 허용되는지 여부에 대한 분류자를 미세 조정하고 비즈니스 비용 정책이 날짜, 위치 또는 직원 유형에 따라 달라지는 경우 입력에 날짜, 위치 및 직원 유형에 대한 정보가 포함되어 있는지 확인하십시오.

 

Prompt Completion
“Amount: $50
Item: Steak dinner

###

“ allowed”
“Amount: $50
Item: Steak dinner

###

“ disallowed”

 

Prompt Completion
“Amount: $50
Item: Steak dinner

###

???

 

Common mistake #2: Input data format that doesn’t match the training data format

Make sure that when you use your fine-tuned model, your submitted prompts match the format of your training data.

 

미세 조정된 모델을 사용할 때 제출된 프롬프트가 훈련 데이터의 형식과 일치하는지 확인하십시오.

 

Training data format API call OK?
“dog toy -->” “dog toy” Missing separator
“Amount: $50
Item: Steak dinner

###

“Is a $50 steak dinner allowed?

###

Different format
“Esmeralda >>>” “Esmeralda >>> ” Extra space appended

 

More examples

Below, we share more examples of training data for possible classifiers.

 

아래에서 가능한 분류기에 대한 훈련 데이터의 더 많은 예를 공유합니다.

 

Truthful consistency classifier

Prompt Completion
"Company: BHFF insurance
Product: allround insurance
Ad: One stop shop for all your insurance needs!
Supported:"
“ yes”
"Company: Loft conversion specialists
Product: -
Ad: Straight teeth in weeks!
Supported:"

“ no”

 

Product review classifier (with multiple classes labeled in parallel)

Prompt Completion
"4/5 stars

Camera seems fine. Not amazing, but perfectly decent.

Biggest complaint is that the cable is only 5 feet long, which I didn't think to check. It's my fault, so I won't return it, but 5 feet is really short if you have multiple monitors and probably impossible if you have a desktop on the floor next to a standing desk.

###

Positives:"

“ fine, perfectly decent
Negatives: not amazing, cable is only 5 feet long
Overall sentiment: positive
Possible improvements: longer cable
Return risk: 1
Support priority: low
Customer type: N/A”
"4/5 stars

I bought this on sale for $70. I'm satisfied with it.

(1) The instructions weren't that bad. (There was really only one ambiguous step, and it was easy to make an educated guess at the right way to go. Surprised by the ordering of one of the steps because some bars were hanging there for a while, but whatever.)

(2) It definitely is labor intensive - the most painful step is screwing in 24 small wood screws to get the hooks attached. And it takes a bit of skill to get them all vertically parallel. Got a big blister from all the screwing. And the angles made it hard to use power tools - ended up screwing in by hand because it was easier to stay vertical next to the hook.

(3) I weight 170 pounds and honestly the bench seems fine for supporting my weight. I was worried from the other reviews. But my trick was to leave things a little loose until the end and then really tighten everything once it was all together. I think really tightening at the end prevents any squeaky rocking. But only used it one day so far, so we'll see.

Overall this is definitely cheap, but feels totally fine. It's cheap in a cheap way, not cheap in a junky knockoff way. Would buy again. Looks great.

###

Positives:"


“ instructions weren’t that bad, looks great
Negatives: ambiguous step, labor intensive, got a big blister, cheap
Overall sentiment: positive
Possible improvements: less ambiguous instructions
Return risk: 0
Support priority: low
Customer type: N/A”
"5/5 stars

I'm a fan. It's shiny and pure metal. Exactly what I wanted.

###

Positives:”
“ shiny, pure metal
Negatives: N/A
Overall sentiment: positive
Possible improvements: N/A
Return risk: 0
Support priority: low
Customer type: N/A

 

Sentiment analyzer

Prompt Completion
"Overjoyed with the new iPhone! ->"

“ positive”
"@lakers disappoint for a third straight night https://t.co/38EFe43 ->"


“ negative”

 

Email prioritizer

Prompt Completion
"Subject: Update my address
From: Joe Doe
To: support@ourcompany.com
Date: 2021-06-03
Content: Hi,
I would like to update my billing address to match my delivery address.

Please let me know once done.

Thanks,
Joe

###

"

“ 4”

 

Legal claim detector

Prompt Completion
"When the IPV (injection) is used, 90% or more of individuals develop protective antibodies to all three serotypes of polio virus after two doses of inactivated polio vaccine (IPV), and at least 99% are immune to polio virus following three doses. -->"

“ efficacy”
"Jonas Edward Salk (/sɔːlk/; born Jonas Salk; October 28, 1914 – June 23, 1995) was an American virologist and medical researcher who developed one of the first successful polio vaccines. He was born in New York City and attended the City College of New York and New York University School of Medicine. -->"


“ not”

 

News subject detector

Prompt Completion
"PC World - Upcoming chip set will include built-in security features for your PC. >>>"

“ 4”

(where 4 = Sci/Tech)
“Newspapers in Greece reflect a mixture of exhilaration that the Athens Olympics proved successful, and relief that they passed off without any major setback. >>>”

“ 2”

(where 2 = Sports)

 

Logical relationship detector

Prompt Completion
"A land rover is being driven across a river.
A vehicle is crossing a river.

###

"

“ implication”
"Violin soloists take the stage during the orchestra's opening show at the theater.
People are playing the harmonica while standing on a roof.

###

"


“ contradiction”

 

반응형


반응형

OpenAI Cookbook을 공부하고 있는 사이에 새롭게 올라온 글이 있습니다.

ChatGPT와 관련한 글인데요.

2023년 3월 1일에 최초로 올라왔습니다.

 

오늘은 이 글을 공부해 보도록 하겠습니다.

 

https://github.com/openai/openai-cookbook/blob/main/examples/How_to_format_inputs_to_ChatGPT_models.ipynb

 

GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API

Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.

github.com

 

How to format inputs to ChatGPT models

ChatGPT는 gpt-3.5-turbo로 만들어 졌고 OpenAI의 가장 진보된 모델입니다.

OpenAI API를 사용해서 gpt-3.5-turbo로 여러분들만의 어플리케이션을 build 하실 수 있습니다.

 

Chat 모델은 일련의 메세지를 입력값으로 받고 AI 가 작성한 메세지를 output으로 반환합니다.

 

이 가이드는 몇가지 예제 API호출을 사용하여 채팅 형식을 보여 줍니다.

 

1. Import the openai library

# if needed, install and/or upgrade to the latest version of the OpenAI Python library
%pip install --upgrade openai

OpenAI 최신 버전으로 업데이트 하려면 pip install -- upgrade 명령으로 업데이트 합니다.

저는 윈도우즈 명령창에서 업데이트 했습니다.

2023년 3월 1일 ChatGPT API 가 OpenAI API 에 추가 됐습니다.

이 Chat API 콜의 모델 이름은  gpt-3.5-turbo 입니다. 이 모델은 ChatGPT 에서 사용되는 바로 그 모델입니다.

 

이와 관련한 Guide document도 추가 됐습니다.

https://platform.openai.com/docs/guides/chat

 

OpenAI API

An API for accessing new AI models developed by OpenAI

platform.openai.com

이 API를 사용하는 가격은 1천개의 토큰당 0.002 달러입니다. 

 

그 다음은 openai 모듈을 import 합니다.

 

저 같은 경우는 openai api key 를 파일에서 읽허서 보내기 때문에 그 부분도 넣었습니다.

 

2. An example chat API call

chat API 콜은 다음 두가지 입력값들이 요구 됩니다.

 

  • model: the name of the model you want to use (e.g., gpt-3.5-turbo)
  • 모델 : 사용하고자 할 모델 이름 (e.g., gpt-3.5-turbo)
  • messages: a list of message objects, where each object has at least two fields:
  • 메세지 : 메세지 객체 리스트. 각 객체들은 최소한 아래 두개의 field를 가지고 있어야 한다. 
    • role: the role of the messenger (either system, user, or assistant)
    • 역할 : 메센저의 역할 (시스템인지 사용자인지 혹은 조력자인지...)
    • content: the content of the message (e.g., Write me a beautiful poem)
    • 내용 : 메세지의 내용 (예. , 저에게 아름다운 시를 써 주세요.)

 

일반적으로 대화는 시스템 메세지로 시작하고 그 뒤에 사용자 및 조력자 메세지가 교대로 오지만 꼭 이 형식을 따를 필요는 없습니다.

ChatGPT 가 사용하는 Chat API가 실제로 어떻게 작동하는지 알아보기 위해 Chat API 를 호출하는 예제를 한번 살펴보겠습니다.

 

이 ChatGPT에서 사용하는 ChatAPI를 호출하는 방법은 openai.ChatCompletion.create() 을 호출하는 겁니다.

 

위 호출에 대한 response 객체는 여러 필드들이 있습니다.

 

  • choices: a list of completion objects (only one, unless you set n greater than 1)
  • choices : completion 객체의 리스트 (n을 1보다 높게 세팅하지 않는 한 한개만 존재한다.)
    • message: the message object generated by the model, with role and content
    • message : 모델에 의해 생성된 메세지 객체 (role, content)
    • finish_reason: the reason the model stopped generating text (either stop, or length if max_tokens limit was reached)
    • finish_reason: 모델이 텍스트 생성을 중지한 이유 (stop 이거나 max_tokens를 초과했을 경우는 그 길이)
    • index: the index of the completion in the list of choices
    • index: choices에 있는 리스트의 completion 의 index
  • created: the timestamp of the request
  • created : 해당 request의 요청 시간 정보
  • id: the ID of the request (해당 request의 ID)
  • model: the full name of the model used to generate the response
  • model ; response를 발생시키는데 사용된 모델의 full name
  • object: the type of object returned (e.g., chat.completion) 
  • object : 반환된 객체의 유형 (e.g., chat.completion)
  • usage: the number of tokens used to generate the replies, counting prompt, completion, and total
  • usage : response를 생성하는데 사용된 토큰 수. completion, prompt, totak 토큰 수

 

위 Request 에서 보면 messages 안에 있는 첫번째 아이템의 role 이 system 입니다.

이는 ChatGPT에게 현 상황을 설명하는 겁니다.

여기서는 너는 아주 도움을 잘 주는 조력자이다 라고 ChatGPT에게 규정했습니다.

그 다음의 user는 똑 똑 하고 노크를 하죠.

그 다음 조력자는 누구세요? 라고 묻습니다.

그 다음 user는 Orange 라고 대답하죠.

 

여기까지  ChatGPT에게 제공된 상황입니다.

 

그러면 그 다음은 ChatGPT가 알아서 그 다음에 올 수 있는 알맞는 대답을 response 할 차례입니다.

 

ChatGPT의 대답의 구조는 위에 설명 한 대로 입니다.

여기서 대답은 choices - message - content 에 있는 Orange who? 라는 겁니다.

 

나머지는 모두 이 request와 response 에 대한 데이터들입니다.

 

여기서 실제 ChatGPT가 상황에 맞게 대답한 부분만 받으려면 아래와 같이 하면 됩니다.

 

이렇게 하면 실제 ChatGPT가 대답한 Orange who? 라는 부분만 취할 수 있습니다.

 

대화 기반이 아닌 작업도 첫번째 user message 부분에 instruction을 넣음으로서 chat format 에 맞춰서 사용할 수 있습니다.

예를 들어 모델에게 비동기 프로그래밍을 설명하는데 검은 수염이 난 해적이 말하는 스타일로 설명하도록 요청하려면 대화를 다음과 같이 구성하시면 됩니다.

이렇게 하면 ChatGPT가 비동기 프로그래밍을 설명하는데 그 말투가 검은 수염난 해적이 말하는 것처럼 만들어서 대답을 합니다.

 

이것을 그 말투의 느낌까지 살려서 한글로 번역하는 것은 힘드니까 대충 구글 번역기를 돌려 보겠습니다.

 

어이 친구! 비동기 프로그래밍은 동시에 다른 작업을 수행하는 해적 선원을 갖는 것과 같습니다. 예, 다음 작업을 시작하기 전에 하나의 작업이 완료되기를 기다리는 대신 한 번에 여러 작업을 실행할 수 있습니다. 그것은 다른 사람들이 갑판을 청소하고 대포를 장전하는 동안 내 승무원이 돛을 올리는 것과 같습니다. 각 작업은 독립적으로 작동하지만 모두 배의 전반적인 성공에 기여합니다. 이는 기름칠이 잘 된 해적선이 더 빠르고 원활하게 항해할 수 있는 것처럼 코드를 더 빠르고 효율적으로 실행하는 강력한 방법입니다. Arr!

 

재밌네요.

 

상황 설명을 하는 system message 없이 한번 요청해 보겠습니다.

 

 

이렇게 해도 ChatGPT는 제대로 대답 합니다.

 

3. Tips for instructing gpt-3.5-turbo-0301

모델들에게 가장 잘 instructing 하는 방법은 모델의 버전에 따라 다를 수 있습니다. 아래 예제는 gpt-3.5-turbo-0301 버전에 적용할 때 가장 효과가 좋은 instructiong 입니다. 이후의 모델에서는 적용되지 않을 수 있습니다.

 

System messages

시스템 메세지는 다른 성격이나 행동 양식을 부여함으로서 assistant를 잘 준비 하도록 하는데 사용할 수 있습니다.

하지만 모델은 일반적으로 system message에 그렇게 절대적으로 주의를 기울이지는 않습니다. 그러므로 정말 중요한 부분은 user 메세지에 배치하라고 권고 드립니다.

 

다음은 assitant가 개념을 아주 깊이 있게 설명하도록 유도하는 system 메세지의 예 입니다.

 

# An example of a system message that primes the assistant to explain concepts in great depth
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a friendly and helpful teaching assistant. You explain concepts in great depth using simple terms, and you give examples to help people learn. At the end of each explanation, you ask a question to check for understanding"},
        {"role": "user", "content": "Can you explain how fractions work?"},
    ],
    temperature=0,
)

print(response["choices"][0]["message"]["content"])

 

아래는 Assitent 에게 간략하고 핵심적인 답변만 하라고 유도하는 system 메세지의 예입니다.

# An example of a system message that primes the assistant to give brief, to-the-point answers
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a laconic assistant. You reply with brief, to-the-point answers with no elaboration."},
        {"role": "user", "content": "Can you explain how fractions work?"},
    ],
    temperature=0,
)

print(response["choices"][0]["message"]["content"])

System message의 유도에 따라 대답을 자세하게 하거나 간력하게 하도록 하는 방법을 보았습니다.

 

Few-shot prompting

어떤 경우에는 당신이 원하는 것을 모델에게 설명하는 것 보다 그냥 보여주는게 더 편할 때가 있습니다.

이렇게 모델에게 당신이 무엇을 원하는지 보여주는 방법 중 하나는 fake example 메세지를 사용하는 것입니다.

 

모델이 비지니스 전문 용어를 더 간단한 말로 번역하도록 준비시키는 faked few-shot 대화를 넣어 주는 예제 입니다.

# An example of a faked few-shot conversation to prime the model into translating business jargon to simpler speech
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a helpful, pattern-following assistant."},
        {"role": "user", "content": "Help me translate the following corporate jargon into plain English."},
        {"role": "assistant", "content": "Sure, I'd be happy to!"},
        {"role": "user", "content": "New synergies will help drive top-line growth."},
        {"role": "assistant", "content": "Things working well together will increase revenue."},
        {"role": "user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
        {"role": "assistant", "content": "Let's talk later when we're less busy about how to do better."},
        {"role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable."},
    ],
    temperature=0,
)

print(response["choices"][0]["message"]["content"])

제가 얻은 답은 위와 같습니다.

 

예제의 대화가 실제 대화가 아니고 이것을 다시 참조해서는 안된다는 점을 모델에게 명확하게 하기 위해 system message의 필드 이름을 example_user 와 example_assistant 로 바꾸어서 해 보겠습니다.

위의 few-shot 예제를 이렇게 좀 바꿔서 다시 시작해 보겠습니다.

 

# The business jargon translation example, but with example names for the example messages
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a helpful, pattern-following assistant that translates corporate jargon into plain English."},
        {"role": "system", "name":"example_user", "content": "New synergies will help drive top-line growth."},
        {"role": "system", "name": "example_assistant", "content": "Things working well together will increase revenue."},
        {"role": "system", "name":"example_user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
        {"role": "system", "name": "example_assistant", "content": "Let's talk later when we're less busy about how to do better."},
        {"role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable."},
    ],
    temperature=0,
)

print(response["choices"][0]["message"]["content"])

제가 받은 답은 위와 같습니다.

 

엔지니어링 대화에 대한 모든 시도가 첫번째 시도에서 다 성공하는 것은 아닙니다.

 

첫번째 시도가 실패하면 다른 방법으로 priming을 하던가 혹은 모델의 condition들을 바꾸어서 다시 시도하는 실험을 두려워 하지 마세요. 

 

예를 들어 한 개발자는 모델이 더 높은 품질의 응답을 제공하도록 하기 위해 "지금까지 훌륭했어요. 완벽했습니다." 라는 사용자 메세지를 삽입했을 때 정확도가 더 증가한다는 것을 발견한 사례도 있습니다.

 

모델의 신뢰도를 높이는 방법에 대한 자세한 내용은   techniques to increase reliability 가이드를 참조하세요. 채팅용 모델용으로 작성된 것은 아니지만 기본 원칙은 동일하게 적용 될 수 있습니다.

https://coronasdk.tistory.com/1277

 

Openai cookbook : GPT-3 , Guide Techniques to improve reliability

오늘 공부할 내용은 답변의 신뢰성을 높이기 위한 여러 방법들을 알아보는 겁니다. 실습보다는 이론적인 것들이 많은 것 같습니다. 내용이 좀 긴데 일단 한번 시작해 보겠습니다. 원본 페이지는

coronasdk.tistory.com

 

4. Counting tokens

여러분이 Request를 submit 하면 API 는 그 메세지를 일련의 토큰들로 변환합니다.

 

여기서 토큰의 수는 다음과 같은 것들에 영향을 미칩니다.

  • the cost of the request
  • request에 대한 과금
  • the time it takes to generate the response
  • response를 발생시키는데 걸리느 ㄴ시간
  • when the reply gets cut off from hitting the maximum token limit (4096 for gpt-3.5-turbo)
  • 최대 토큰 수 제한 (gpt-3.5-turbo 의 경우 4096)에 다다랐을 때는 request 중 나머지는 잘려 나가게 됨

2023년 3월 1일부터 다음 함수를 사용해서 메세지 목록에서 사용될 토큰의 갯수를 미리 계산할 수 있습니다.

 

import tiktoken


def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0301"):
    """Returns the number of tokens used by a list of messages."""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        encoding = tiktoken.get_encoding("cl100k_base")
    if model == "gpt-3.5-turbo-0301":  # note: future models may deviate from this
        num_tokens = 0
        for message in messages:
            num_tokens += 4  # every message follows <im_start>{role/name}\n{content}<im_end>\n
            for key, value in message.items():
                num_tokens += len(encoding.encode(value))
                if key == "name":  # if there's a name, the role is omitted
                    num_tokens += -1  # role is always required and always 1 token
        num_tokens += 2  # every reply is primed with <im_start>assistant
        return num_tokens
    else:
        raise NotImplementedError(f"""num_tokens_from_messages() is not presently implemented for model {model}.
See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens.""")

tiktoken을 import 합니다.

num_tokens_from_messages() 함수를 만듭니다.

이 함수의 입력값은 메세지와 모델명 입니다.

tiktoken의 encoding_for_model()을 사용해서 encoding을 정합니다.

여기서 에러가 날 경우 cl100k_base 를 사용합니다. (이는 임베딩에서 사용했던 인코딩 입니다.)

 

if 문에서 모델이 gpt-3.5-turbo-0301 인 경우 그 안의 내용을 실행하게 됩니다.

그 안의 for 문은 메세지 목록의 아이템 수 만큼 루프를 돕니다.

그리고 각각의 메세지마다 4를 + 해 줍니다.

그리고 그 각각의 메세지에 대한 토큰 값을 다음 for 문 안에서 len(encoding.encode(value) 를 사용해서 계산합니다.

key 가 name 인 경우 role은 항상 1개의 토큰만 사용하기 때문에 이 부분을 빼 줍니다.

그리고 각각의 reply 마다 2씩 더해 줍니다.

 

이렇게 해서 계산된 값을 반환합니다.

 

그 다음에 아래 messages를 정해 줍니다.

 

messages = [
    {"role": "system", "content": "You are a helpful, pattern-following assistant that translates corporate jargon into plain English."},
    {"role": "system", "name":"example_user", "content": "New synergies will help drive top-line growth."},
    {"role": "system", "name": "example_assistant", "content": "Things working well together will increase revenue."},
    {"role": "system", "name":"example_user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
    {"role": "system", "name": "example_assistant", "content": "Let's talk later when we're less busy about how to do better."},
    {"role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable."},
]

그 다음에 이 메세지의를 파라미터로 num_tokens_from_messages() 함수를 호출해서 토큰 값을 받고 그것을 print 해 줍니다.

# example token count from the function defined above
print(f"{num_tokens_from_messages(messages)} prompt tokens counted.")

그러면 126개의 토큰이 사용됐다고 나옵니다.

 

참고로 이 글에서 만든 파이썬 소스코드는 아래와 같습니다.

 

# import the OpenAI Python library for calling the OpenAI API
import openai

def open_file(filepath):
    with open(filepath, 'r', encoding='utf-8') as infile:
        return infile.read()

openai.api_key = open_file('openaiapikey.txt')

# Example OpenAI Python library request
MODEL = "gpt-3.5-turbo"
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Knock knock."},
        {"role": "assistant", "content": "Who's there?"},
        {"role": "user", "content": "Orange."},
    ],
    temperature=0,
)

response

response['choices'][0]['message']['content']

# example with a system message
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain asynchronous programming in the style of the pirate Blackbeard."},
    ],
    temperature=0,
)

print(response['choices'][0]['message']['content'])

# example without a system message
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "user", "content": "Explain asynchronous programming in the style of the pirate Blackbeard."},
    ],
    temperature=0,
)

print(response['choices'][0]['message']['content'])

# An example of a system message that primes the assistant to explain concepts in great depth
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a friendly and helpful teaching assistant. You explain concepts in great depth using simple terms, and you give examples to help people learn. At the end of each explanation, you ask a question to check for understanding"},
        {"role": "user", "content": "Can you explain how fractions work?"},
    ],
    temperature=0,
)

print(response["choices"][0]["message"]["content"])

# An example of a system message that primes the assistant to give brief, to-the-point answers
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a laconic assistant. You reply with brief, to-the-point answers with no elaboration."},
        {"role": "user", "content": "Can you explain how fractions work?"},
    ],
    temperature=0,
)

print(response["choices"][0]["message"]["content"])

# An example of a faked few-shot conversation to prime the model into translating business jargon to simpler speech
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a helpful, pattern-following assistant."},
        {"role": "user", "content": "Help me translate the following corporate jargon into plain English."},
        {"role": "assistant", "content": "Sure, I'd be happy to!"},
        {"role": "user", "content": "New synergies will help drive top-line growth."},
        {"role": "assistant", "content": "Things working well together will increase revenue."},
        {"role": "user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
        {"role": "assistant", "content": "Let's talk later when we're less busy about how to do better."},
        {"role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable."},
    ],
    temperature=0,
)

print(response["choices"][0]["message"]["content"])

# The business jargon translation example, but with example names for the example messages
response = openai.ChatCompletion.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a helpful, pattern-following assistant that translates corporate jargon into plain English."},
        {"role": "system", "name":"example_user", "content": "New synergies will help drive top-line growth."},
        {"role": "system", "name": "example_assistant", "content": "Things working well together will increase revenue."},
        {"role": "system", "name":"example_user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
        {"role": "system", "name": "example_assistant", "content": "Let's talk later when we're less busy about how to do better."},
        {"role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable."},
    ],
    temperature=0,
)

print(response["choices"][0]["message"]["content"])

import tiktoken


def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0301"):
    """Returns the number of tokens used by a list of messages."""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        encoding = tiktoken.get_encoding("cl100k_base")
    if model == "gpt-3.5-turbo-0301":  # note: future models may deviate from this
        num_tokens = 0
        for message in messages:
            num_tokens += 4  # every message follows <im_start>{role/name}\n{content}<im_end>\n
            for key, value in message.items():
                num_tokens += len(encoding.encode(value))
                if key == "name":  # if there's a name, the role is omitted
                    num_tokens += -1  # role is always required and always 1 token
        num_tokens += 2  # every reply is primed with <im_start>assistant
        return num_tokens
    else:
        raise NotImplementedError(f"""num_tokens_from_messages() is not presently implemented for model {model}.
See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens.""")

messages = [
    {"role": "system", "content": "You are a helpful, pattern-following assistant that translates corporate jargon into plain English."},
    {"role": "system", "name":"example_user", "content": "New synergies will help drive top-line growth."},
    {"role": "system", "name": "example_assistant", "content": "Things working well together will increase revenue."},
    {"role": "system", "name":"example_user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
    {"role": "system", "name": "example_assistant", "content": "Let's talk later when we're less busy about how to do better."},
    {"role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable."},
]

# example token count from the function defined above
print(f"{num_tokens_from_messages(messages)} prompt tokens counted.")
반응형


반응형

오늘 공부할 Code Editing examples 원본 페이지는 아래에 있습니다.

 

https://github.com/openai/openai-cookbook/blob/main/code_editing_examples.md

 

GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API

Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.

github.com

 

Code editing example

OpenAI의 edits endpoint는 특별히 코드를 수정하는데 유용합니다.

Completions와 달리 Edits는 두개의 입력값을 받습니다. 수정할 코드와 instruction 입니다.

예를 들어 한 파이썬 함수를 수정하기를 원한다고 합시다. 당신은 그 함수와 'docstring을 추가하라' 같은 지시문을 함께 제공해야 할 것입니다.

 

Example text input to code-davinci-edit-001:

 

def tribonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    elif n == 2:
        return 1
    elif n == 3:
        return 2
    else:
        return tribonacci(n-1) + tribonacci(n-2) + tribonacci(n-3)

Example instruction inputs:

add a docstring
Add typing, using Python 3.9 conventions
improved the runtime
Add a test.
Translate to JavaScript (or Rust or Lisp or any language you like)

자바스크립트로 runtime과 translating을 개선시키고 난 후의 output 예제.

function tribonacci(n) {
  let a = 0;
  let b = 1;
  let c = 1;
  for (let i = 0; i < n; i++) {
    [a, b, c] = [b, c, a + b + c];
  }
  return a;
}

위에서 보는 바와 같이 code-davinci-edit-001은 exponential down을 통해 함수의 실행 시간을 성공적으로 줄였습니다. 그리고 파이썬을 자바스크립트로 변환까지 했습니다.

 

OpenAI Playground에서 code-davinci-edit-001을 사용하여 코드 편집을 실험해 보세요.

OpenAI Playground

 

OpenAI API

An API for accessing new AI models developed by OpenAI

platform.openai.com

 

반응형


반응형

오늘은 Openai cookbook의 Code explanation 예제 페이지를 살펴 보겠습니다.

https://github.com/openai/openai-cookbook/blob/main/code_explanation_examples.md

 

GitHub - openai/openai-cookbook: Examples and guides for using the OpenAI API

Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.

github.com

 

Code explanation examples

GPT의 코드에 대한 이해는 많은 use case들에 적용할 수 있습니다.

 

  • Generating in-code documentation (e.g., Python docstrings, git commit messages)
  • 코드 내 문서 생성 (예 파이썬 docstrings, git commit 메세지)
  • Generating out-of-code documentation (e.g., man pages)
  • 코드 외 문서 생성 (예 매뉴얼 페이지
  • An interactive code exploration tool
  • 대화형 코드 탐색 도구
  • Communicating program results back to users via a natural language interface
  • 프로그램 결과를 자연어 인터페이스를 통해 사용자에게 다시 전달

예를 들어 당신이 한 SQL 쿼리에 대해 이해하기를 원한다면 code-davinci-002 에게 아래 예제 프롬프트를 제공하는 방법을 사용할 수 있습니다.

 

A SQL query:
```
SELECT c.customer_id
FROM Customers c
JOIN Streaming s
ON c.customer_id = s.customer_id
WHERE c.signup_date BETWEEN '2020-03-01' AND '2020-03-31'
AND s.watch_date BETWEEN c.signup_date AND DATE_ADD(c.signup_date, INTERVAL 30 DAY)
GROUP BY c.customer_id
HAVING SUM(s.watch_minutes) > 50 * 60
```

Questions:
1. What does the SQL query do?
2. Why might someone be interested in this time period?
3. Why might a company be interested in this SQL query?

Answers:

 

Output

1. The SQL query finds all customers who signed up in March 2020 and watched more than 50 hours of content in the first 30 days after signing up.
2. The time period is interesting because it is the first month of the COVID-19 pandemic.
3. A company might be interested in this SQL query because it can help them understand how the pandemic has affected their business.

Note : code-davinci-002는 instruction을 따르도록 훈련되지 않았으므로 일반적으로 output을 조정하는데 도움이 되는 예제 또는 기타 structure와 생성을 제때에 멈출 수 있게 하는 stop sequence들이 필요합니다. 더 쉽게 프롬프트 하려면 text-davinci-003을 사용하세요.

 

반응형
이전 1 2 3 다음