ChatGPT 모델 학습 방법 : 파인튜닝(Fine tuning)을 사용한 MBTI와 에니어그램 별 캐릭터 설정 제조기
본문 바로가기
R&D

ChatGPT 모델 학습 방법 : 파인튜닝(Fine tuning)을 사용한 MBTI와 에니어그램 별 캐릭터 설정 제조기

by 누메노스 2023. 2. 23.
반응형

개요

ChatGPT로 열심히 문서요약을 하는 와중 GPT로 장난을 치고싶어졌습니다.

 

기본적으로 인공지능 모델은 파인튜닝이라는 방법을 통해 방대한 백본 네트워크는 그대로 두고 출력단을 학습시킴으로써 사용자가 원하는 출력을 하도록 만들 수 있는데요.

 

문득 MBTI, 애니어그램, 나이, 캐릭터의 성별 및 배경을 입력하면 캐릭터의 스토리를 자동으로 만들어주는 GPT 모델을 만들어보면 어떨까 라는 호기심이 들었습니다.

* 최근 MBTI와 애니어그램에 빠져있습니다.

 

이번 글에서는 파이썬으로 GPT 모델을 학습시키는 방법과 캐릭터의 설정과 배경을 만들어주는 방법을 알아보도록 하겠습니다.

 

이번 글에서는 파인튜닝과 관련된 내용만 다룰 예정이니 GPT API 사용법은 이 글을 참조해주세요.

 

2023.02.16 - [R&D] - ChatGPT API 사용법(파이썬과 GPT API를 활용한 문서 요약기)

 

ChatGPT API 사용법(파이썬과 GPT API를 활용한 문서 요약기)

개요 ChatGPT라는 언어모델의 한계로 인해 장문의 대답이 필요한 질문에도 불구하고 1000자 내외에서 응답이 멈추는 문제가 있습니다. 특히, 저 같은 경우 장문의 문서 요약을 한눈에 알기 쉽게 만

eppiroi.tistory.com


MBTI와 애니어그램 캐릭터 설정 생성기

캐릭터 설정 생성용 ChatGPT 파인튜닝 모델은 MBTI, 애니어그램, 성별, 세계관을 입력받아 캐릭터의 상세한 배경과 스토리 등을 설명합니다.

예를 들면 INTJ, 5w6, 18, Male, VR Fantasy World 를 입력하면 그에 해당하는 캐릭터 설정을 만들어 내는 것 입니다.

 

파인튜닝을 위한 데이터 생성

여러분들 중 경우에 따라 미세 조정에 사용할 데이터가 있을 수 있습니다. 하지만 저는 캐릭터 설정과 같은 데이터가 하나도 없기 때문에 GPT-3에서 직접 캐릭터 설명이 포함된 데이터 세트를 만드는 방법을 알아보겠습니다.

다음 코드는 캐릭터 생성기 제작을 위한 ChatGPT CSV 파일 예시입니다.

import os
import openai
import pandas as pd
import sys
openai.api_key = "Enter Your API Key"

l_MBTI = ['ISFP', 'ISFJ', 'ISTP', 'ISTJ', 'ESFP', 'ESFJ', 'ESTP', 'ESTJ', 'INTP', 'INTJ', 'INFP', 'INFJ','ENTP', 'ENTJ', 'ENFP', 'ENFJ']
l_age = ['18', '20', '30', '40', '50', '60', '90']
l_enneagram = ['1', '2','3','4','5','6','7','8','9']
l_gender = ['Male','Female']
l_world = ['VR Fantasy World', 'Middle age', 'primitive times', 'modern times']

f_prompt = "Imagine a complete and detailed description of a {age}-age {MBTI}-mbti {enneagram}-enneagram {gender}-gender {world}-world fictional character. Write out the entire description in a maximum of 100 words in great detail:"
f_sub_prompt = "{MBTI}, {age}, {enneagram}, {gender}, {world}"

df = pd.DataFrame()

for MBTI in l_MBTI:
    for age in l_age:
        for enneagram in l_enneagram:
            for gender in l_gender:
                for world in l_world: ## 3 times each

                    prompt = f_prompt.format(MBTI=MBTI, enneagram=enneagram,age=age, gender=gender, world=world)

                    sub_prompt = f_sub_prompt.format(MBTI=MBTI, enneagram=enneagram,age=age, gender=gender, world=world)
                    while True :
                        try :
                            response = openai.Completion.create(
                             model="text-davinci-003",
                             prompt=prompt,
                             temperature=1,
                             max_tokens=2000,
                             top_p=1,
                             frequency_penalty=0,
                             presence_penalty=0
                            )
                            break
                        
                        except :
                        
                            print('error')
    finish_reason = response['choices'][0]['finish_reason']
    response_txt = response['choices'][0]['text']
    new_row = {
      'MBTI':MBTI, 
      'age' : age,
      'enneagram':enneagram,
      'gender':gender, 
      'world':world, 
      'prompt':prompt, 
      'sub_prompt':sub_prompt, 
      'response_txt':response_txt, 
      'finish_reason':finish_reason
      }
    
    new_row = pd.DataFrame([new_row])
    
    df = pd.concat([df, new_row], axis=0, ignore_index=True)

df.to_csv("out_openai_completion.csv")

 

변수 f_prompt는 {MBTI}, {age}, {enneagram}, {gender} 및 {world}를 매개변수로 받을 수 있게 설정된 문자열 입니다.

Imagine a complete and detailed description of a {age}-age {MBTI}-mbti {enneagram}-enneagram {gender}-gender {world}-world fictional character. Write out the entire description in a maximum of 100 words in great detail:


처음 다섯 개의 for 루프에서 {MBTI}, {age}, {enneagram}, {gender} 및 {world}의 서로 다른 값을 반복합니다. 루프의 각 단계에서 변수를 다른 값으로 대체합니다. 그런 다음 openai.Completion.create 함수를 사용하여 프롬프트에 대한 응답을 생성하도록 GPT에 요청합니다.

 

Open API의 response에 대한 설명은 이전 포스트에서 설명했으므로 넘기도록 하겠습니다.

 

response_txt에는 GPT 모델의 출력이 포함되어 있습니다.

 

반응형

모델 파인튜닝 시작하기

import pandas as pd
import openai
import subprocess

df = pd.read_csv("out_openai_completion.csv")

prepared_data = df.loc[:,['sub_prompt','response_txt']]
prepared_data.rename(columns={'sub_prompt':'prompt', 'response_txt':'completion'}, inplace=True)
prepared_data.to_csv('prepared_data.csv',index=False)

os.environ['OPENAI_API_KEY'] ="YOUR_API_KEY"
os.environ['OPENAI_ORG_ID'] = 'YOUR_ORG_KEY'

## prepared_data.csv --> prepared_data_prepared.json
subprocess.run('openai tools fine_tunes.prepare_data --file prepared_data.csv --quiet'.split())

## Start fine-tuning
subprocess.run('openai api fine_tunes.create --training_file prepared_data_prepared.jsonl --model davinci --suffix "MBTI_ENNEA"'.split())

 

이 코드는 out_openai_completion.csv 파일을 연 후 openai를 사용하여 GPT-3 모델을 파인튜닝합니다.

 

 파인튜닝된 모델은 제가  'INTJ, 40, 9, Male, VR Fantasy World'를 입력하면 VR 판타지 세상에서 살아가는 MBTI는 INTJ이며 애니어그램은 9번 유형을 갖는 40대의 남자 캐릭터의 설명을 생성합니다.

 

파인 튜닝을 수행하려면 사용자가 입력할 수 있는 예제와 해당하는 원하는 응답을 GPT에 제공해야 합니다.

 

데이터 프레임 df에는 sub_prompt 및 response_txt 열에는 사용자가 원하는 응답이 있는 입력의 예시가 포함되어 있습니다.

 

위의 코드에서 먼저 이 두 개의 콜론을 추출한 다음 컬럼을 prompt와 completion로 바꾼 후 데이터 프레임을 생성합니다.

 

데이터 프레임은 prepared_data.csv에 저장됩니다.

 

prepared_data.csv 파일은 다음과 같습니다.

prepared_data.csv 예시

 

이렇게 파인튜닝 과정이 완료되었습니다.

 

JSON 파일의 형태는 다음과 같습니다.

{"prompt":"ISFP, 18, 1, Male, VR Fantasy World ->","completion":" \n\nAn 18 year old ISFP male, his enneagram type 1, lives in a virtual reality fantasy world. He is of average height, with strong features and a fair complexion. His hair is brown and usually styled in a messy, yet purposeful way. His eyes are expressive and deep brown. His shy, introverted nature means he often wears comfortable clothes, preferring loose fitting shirts and trousers. He is kind and compassionate, but often spends his time alone, venturing into the wilds of his virtual world and exploring its depths. His compassion and love for nature helps him to truly understand the wonders of his world, and he is never afraid to go beyond what his eyes can see. END"}
{"prompt":"ISFP, 18, 1, Male, Middle age ->","completion":" \n\nHe is a mysterious, introverted man in his middle years, a combination of ISFP, MBTI type 1, and Enneagram. He is quiet, methodical, and independent. Especially attuned to the subtleties of his environment, he deeply values personal freedom. Usually cooperative, he is unlikely to make waves. A good listener and attuned to the feelings of others, he supports people without interfering. He has a creative streak behind his reserved exterior, exploring ideas with a distant imagination. His integrity and sincerity make him a loyal friend. While not overtly demanding, he has a strong need for personal satisfaction. END"}

 

이제 파인튜닝된 모델을 테스트해보는 과정만 남았습니다!

 


파인튜닝된 모델 테스트

 

학습된 모델을 테스트해보기 위해서 아래 링크로 들어가주세요.

Playground - OpenAI API

 

OpenAI API

An API for accessing new AI models developed by OpenAI

platform.openai.com

모델이 변경되야하는데... 변경이 안되네요.

 

subprocess.run('openai api fine_tunes.create -t prepared_data_prepared.jsonl -m davinci',stdout=True)으로 분명히 업로드를 성공했는데....


결론
이번 글에서는 ChatGPT를 파인튜닝하기 위한 데이터를 생성하는 방법과 파인 튜닝을 수행하는 방법을 소개했습니다.
저는 MBTI, 에니어그램, 성별, 나이 및 세계관으로 캐릭터를 만들어내는 모델을 만들었지만 여러분의 창의력으로 더 재밌는 모델을 만들어 보셨으면 좋겠습니다.
미완성 글이지만 수정이 되는데로 업로드하도록 하겠습니다.

 

댓글