일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- SWEA
- 페이코 추천인
- programmers
- php
- 플러터 개발환경 설정
- php 프로그래밍 입문
- 자바
- C언어
- php 프로그래밍 입문 예제
- 플러터
- 페이코 친구코드
- C
- 페이코 초대코드
- Java
- php 프로그래밍
- 최단 경로
- 자바 스프링
- spring
- 파이썬
- php 프로그래밍 입문 문제풀이
- php 프로그래밍 입문 3판
- php 프로그래밍 입문 솔루션
- 배열
- 스프링
- Flutter
- php 프로그래밍 입문 연습문제
- 백준
- JAVA SPRING
- 한정 분기
- 페이코 추천인코드
- Today
- Total
ImJay
[chatGPT] GPT Model 을 Fine-tuning 하여 챗봇 모델을 만들어보자. 본문
목표
1. GPT 모델을 기반으로 한 챗봇
2. 데이터셋을 학습하여 클라이언트 측 프롬프트에 맞춰 올바른 대답을 해야함
조사
1. OpenAI 에서는 GPT 모델에 파인튜닝이 가능하도록 api 를 제공하고 있다.
2. 현재(2023-08-09)까지는 GPT-3 모델에 기반한 ada, babbage, curie, davinci 모델만 파인튜닝이 가능하다.
모델선정
- "ada" 모델:
- "ada" 모델은 GPT-3 중에서 가장 작은 모델로, 대화형 챗봇이나 간단한 자연어 처리 작업에 활용될 수 있습니다.
- 상대적으로 작은 크기로 인해 연산 비용이 더 낮고, 일부 특정 작업에 적합할 수 있습니다.
- "babbage" 모델:
- "babbage" 모델은 "ada"보다 크기가 크며, 좀 더 복잡한 대화나 문장 생성 작업에 활용될 수 있습니다.
- 조금 더 복잡한 언어 이해와 생성 능력을 갖추고 있습니다.
- "curie" 모델:
- "curie" 모델은 중간 크기로, 대화 및 문서 요약, 글 작성 등 다양한 자연어 작업에 사용될 수 있습니다.
- 좀 더 많은 컨텍스트를 이해하고 다양한 작업을 처리하는 능력을 갖추고 있습니다.
- "davinci" 모델:
- "davinci" 모델은 GPT-3 중에서 가장 크고 성능이 뛰어난 모델로, 매우 복잡한 작업이나 글 생성, 문제 해결 등 다양한 영역에서 사용될 수 있습니다.
- 더 많은 데이터와 컨텍스트를 이해하며, 더욱 창의적인 결과를 생성하는 능력을 가지고 있습니다.
모델의 특징과 비용을 고려했을 때, 챗봇의 목적으로는 Ada 모델이 적당한 것으로 보인다.
GPT 모델을 파인튜닝하는 대부분의 글들을 살펴보면 Davinci 모델을 채택하였는데, 테스트 용도나 데이터셋이 크지 않다면 Davinci 를 사용하는 것도 나쁘지 않아 보였다.
파인튜닝 시작
파인튜닝 api 에 대한 공식문서는 OpenAI에서 친절하게 제공하고 있다.
1. OpenAI API Key 발급하기
해당 링크에 접속하여 Create new secret key 버튼을 클릭하고, 이름만 지정하면 간단하게 key 를 발급 받을 수 있다.
( 처음 발급 받는다면, 결제 정보나 기본 설정이 따로 필요할 수 있음 )
2. 데이터셋 준비하기
파인튜닝을 위해 질문과 원하는 답변을 정해진 형식에 맞춰 준비를 시켜야한다.
prompt : 질문, completion : 답변 형식에 맞춰 jsonl 파일로 담겨야 한다.
현재 준비된 데이터셋이 따로 없어 테스트용으로 jsonl 을 생성해주었다.
setTrainingData.py
import json
def createJson(prompt, completion, file_path="dataset.jsonl"):
data = {
"prompt": prompt,
"completion": completion
}
with open(file_path, "a", encoding="utf-8") as jsonl_file:
jsonl_file.write(json.dumps(data, ensure_ascii=False) + "\n")
print('prompt : ', prompt, 'completion : ', completion)
createJson('안녕하세요', '반갑습니다!')
createJson('회원가입이 하고 싶어', '안내해드릴게요!')
createJson('너는 누구야?', '저는 챗봇입니다!')
실행결과
해당 코드를 그대로 실행시키면, 위와 같이 형식에 맞춘 dataset.jsonl 파일이 생성된다.
3. 데이터셋 가공
OpenAI 에서 제공하는 파인튜닝 api 형식에 맞도록 jsonl 의 데이터셋을 한번 더 가공해야한다.
가공하는 것 또한 OpenAI 에서 api 로 제공을 해주므로 우리는 해당 명령어만 작성하면 된다!
LOCAL_FILE : 데이터셋 파일명 ( dataset.jsonl )
이 또한 편하게 사용하고 싶어서, 콘솔 명령어를 대신 입력할 수 있도록 코드를 작성했다.
해당 코드들은 콘솔에 직접 입력해도 되고, 본인이 작성한 코드를 사용해도 된다.
def createDataset():
command = 'openai tools fine_tunes.prepare_data -f '
command += keyInfo.dataset
os.system(command)
createDataset()
keyInfo.dataset 에 파일명을 입력하면,
Python Debug Console 로 내용을 확인 가능하고 옵션을 선택할 수 있다.
명령어 실행 후에 가공된 jsonl 파일 ( dataset_prepared.jsonl ) 이 자동으로 생성된 것을 확인할 수 있다.
4. 파인튜닝 모델 생성
해당 과정에서 api key 가 필요하다.
openai --api-key <API_KEY> fine_tunes .. 형식으로 작성해야 한다.
TRAIN_FILE_ID_OR_PATH : 가공된 데이터셋 파일명 혹은 경로 ( dataset_prepared.jsonl )
BASE_MODEL : 본인이 선택한 모델 ( ada, babbage, curie, davinci )
def createFinetune():
command = 'openai --api-key '
command += keyInfo.apiKey
command += ' api fine_tunes.create -t '
command += keyInfo.dataset
command += ' -m '
command += keyInfo.model
os.system(command)
createFinetune()
keyInfo.apiKey, dataset, model 에 해당하는 값을 입력하면 된다.
절차대로 수행한다면, 원래 성공해야 하는데 ..
Stream interrupted (client disconnected).
To resume the stream, run:
openai api fine_tunes.follow -i <JOB_ID>
해당 오류가 계속 발생한다.
원인은 OpenAI 측에서 사용량이 많아 접속이 끊어졌기 때문이다.
이는 내가 해결할 수 있는 부분이 아니기에..
여러번 같은 작업을 수행해도 계속 연결이 끊겼다는 응답만 돌아왔다.
돈을 내고 사용하겠다고 해도 사용할 수 없는 GPT..
하지만, 이대로 포기할 수는 없었다.
생성된 JOB_ID 를 통해 연결을 재시도 할 수 있다.
요청을 보내고 끊어지는 것도 시간이 오래걸려 계속 보내고 있기엔 시간이 아까워서, 루프를 돌렸다.
def continueFinetune():
command = 'openai --api-key '
command += keyInfo.apiKey
command += ' api fine_tunes.follow -i '
command += keyInfo.jobId
return os.popen(command).read()
def loopFinetune():
res = continueFinetune()
print(res)
cnt = 1
while True:
cnt += 1
if 'Stream interrupted' in res:
print('finetune api loop ', cnt, ' times ..')
res = continueFinetune()
print(res)
else:
print(res)
break
loopFinetune()
파싱하기도 귀찮아서, jobId 도 정적으로 입력해주었다..
루프 돌려놓고 블로그 글을 쓰기 시작했는데,
이정도일줄은 몰랐다.
GPT 모델 말고 다른 모델을 고려해봐야할 수도 있을 것 같다.. 예상 후보군은 koGPT 정도.
하루정도 돌려보면서 나중에 이어서 다시 포스팅을 진행해야 될 것 같다.
참고용 전체 코드
setTrainingData.py
import json
def createJson(prompt, completion, file_path="dataset.jsonl"):
data = {
"prompt": prompt,
"completion": completion
}
with open(file_path, "a", encoding="utf-8") as jsonl_file:
jsonl_file.write(json.dumps(data, ensure_ascii=False) + "\n")
print('prompt : ', prompt, 'completion : ', completion)
createJson('안녕하세요', '반갑습니다!')
createJson('회원가입이 하고 싶어', '안내해드릴게요!')
createJson('너는 누구야?', '저는 챗봇입니다!')
keyInfo.py
apiKey = 'sk-DMw'
jobId = 'ft-K'
dataset = 'dataset.jsonl'
model = 'ada'
이 부분은 직접 수정하셔야된다.
callCmd.py
import os
import keyInfo
def order(command):
os.system(command)
def createDataset():
command = 'openai tools fine_tunes.prepare_data -f '
command += keyInfo.dataset
os.system(command)
def createFinetune():
command = 'openai --api-key '
command += keyInfo.apiKey
command += ' api fine_tunes.create -t '
command += keyInfo.dataset
command += ' -m '
command += keyInfo.model
os.system(command)
def continueFinetune():
command = 'openai --api-key '
command += keyInfo.apiKey
command += ' api fine_tunes.follow -i '
command += keyInfo.jobId
return os.popen(command).read()
def loopFinetune():
res = continueFinetune()
print(res)
cnt = 1
while True:
cnt += 1
if 'Stream interrupted' in res:
print('finetune api loop ', cnt, ' times ..')
res = continueFinetune()
print(res)
else:
print(res)
break
createFinetune()
이부분도 원하는 함수를 호출하셔야됩니다.
'개인 프로젝트' 카테고리의 다른 글
[HTTP] okhttp WARN 30659 (0) | 2023.05.29 |
---|---|
[Java Spring] Notion API 페이지 블록 추가 (Append block children) (2) | 2023.04.28 |
[Java Spring] 오픈 Notion API 를 만들어보자. (0) | 2023.04.05 |
[VMap] 기능 추가, 코드 리팩토링, 버그 수정, (0) | 2023.03.23 |
[VMap] Linux Ubuntu 환경에서 '모니터 지원 주파수 범위 초과' 문제를 해결해보자. (0) | 2023.03.22 |