Node.js로 chatGPT Fine-Tuning하기
최근 GPT를 이용해 원고의 교정 / 교열을 자동화 하는 업무를 진행하게 되어, Fine-Tuning 하는 방법을 알아보았습니다.
GPT API를 이용해 NODE.JS로 파인튜닝을 하는 방법입니다.
순서 : 프로젝트 세팅 > jsonl 파일 작성 > Fine-Tuning
프로젝트 세팅
1. 새 폴더를 만들고 vscode로 프로젝트를 엽니다. 터미널을 열고 아래의 명령어를 입력합니다.
npm init -y
2. 그 결과 pacakge.json 파일이 생성되며, 해당 파일의 마지막 라인에 "type":"module"을 추가해 줍니다.
{
"name": "gpt-fine-tuning",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type":"module"
}
3. 터미널에 아래 명령어를 입력해 패키지를 설치해 줍시다.
- dotenv: .env 파일에서 환경 변수를 process.env 객체로 로드하는 데 사용됩니다.
npm i dotenv openai
4. 3개의 파일 ( index.js / .env / style-and-tone.jsonl )을 생성해 줍시다.
직접 생성하거나 터미널에서 touch index.js 명령어로 생성할 수 있습니다.
5. env 파일에 자신의 api key를 넣어줍시다.
OPENAI_API_KEY="자신의 api key"
여기까지 프로젝트 세팅이 완료되었습니다.
.jsonl 파일 작성하기
아래와 같은 형식으로 .jsonl 파일을 작성해 줍시다.
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 끓는점은 몇도야?"},{"role":"assistant","content":"끼약!!!꺆꾺갸꺄!!! 물의 끓는점은 100도에요!!!!!!"}]}
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 어는점은 몇도야?"},{"role":"assistant","content":"끼앾꾞!!! 촥촥!!! 물의 어는점은 0도에요!!!!,!"}]}
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 끓는점은 몇도야?"},{"role":"assistant","content":"끼약!!!꺆꾺갸꺄!!! 물의 끓는점은 100도에요!!!!!!"}]}
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 어는점은 몇도야?"},{"role":"assistant","content":"끼앾꾞!!! 촥촥!!! 물의 어는점은 0도에요!!!!,!"}]}
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 끓는점은 몇도야?"},{"role":"assistant","content":"끼약!!!꺆꾺갸꺄!!! 물의 끓는점은 100도에요!!!!!!"}]}
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 어는점은 몇도야?"},{"role":"assistant","content":"끼앾꾞!!! 촥촥!!! 물의 어는점은 0도에요!!!!,!"}]}
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 끓는점은 몇도야?"},{"role":"assistant","content":"끼약!!!꺆꾺갸꺄!!! 물의 끓는점은 100도에요!!!!!!"}]}
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 어는점은 몇도야?"},{"role":"assistant","content":"끼앾꾞!!! 촥촥!!! 물의 어는점은 0도에요!!!!,!"}]}
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 끓는점은 몇도야?"},{"role":"assistant","content":"끼약!!!꺆꾺갸꺄!!! 물의 끓는점은 100도에요!!!!!!"}]}
{"messages":[{"role":"system","content":"지키는 아주 산만한 챗봇입니다."},{"role":"user","content":"물의 어는점은 몇도야?"},{"role":"assistant","content":"끼앾꾞!!! 촥촥!!! 물의 어는점은 0도에요!!!!,!"}]}
구성에 대한 설명
- role
- system : 챗봇의 특성을 정의합니다.
- user : 사용자가 입력할 프롬프트를 설정합니다.
- assistant : 챗봇의 대답을 설정합니다.
최소 10개 이상의 프롬프트가 필요하기 때문에, 위 예에서는 2개의 데이터를 5번씩 반복했습니다.
작성을 마친 후에는, 하단 사이트를 이용하시면 jsonl 파일의 유효성을 검증할 수 있습니다.
https://jsonlines.org/validator/
JSON Lines Validator
jsonlines.org
Fine-Tuning
포스팅 하단에 index.js 전체 코드 첨부해 두었습니다.
1. Jsonl 파일 openAI에 업로드
index.js 파일에 코드 작성 후 터미널에 node index.js 명령어를 입력해 파일 업로드 후, 해당 부분 주석처리
// Import Dependencies
import OpenAI from "openai";
import fs from "fs";
import dotenv from "dotenv";
dotenv.config();
const openai = new OpenAI(process.env.OPENAI_API_KEY);
// 1. Upload Jsonl File to OpenAI
await openai.files.create({
file: fs.createReadStream("./style-and-tone.jsonl"),
purpose: "fine-tune",
});
2. 업로드 된 파일 목록 확인
// 2. List Files
const files = await openai.files.list();
console.log(files);
3. Fine-Tuned 생성
1) openai 패키지를 이용
// 3. Fine Tune
const fineTune = await openai.fineTuning.jobs
.create({
training_file: "file-UfAFZs......생략", // 위 2번의 ID
model: "gpt-3.5-turbo",
})
.catch((err) => console.log(err));
console.log(fineTune);
위 방법은 openai 패키지를 이용하는 방법으로 추후 메서드 혹은 방법이 바뀔 수 있으니 위에 코드로 실행이 되지 않는다면, 이 방법으로 해보시는 걸 추천드립니다.
위 코드와 같은 동작을 하는 코드입니다.
// 3-2. Fine Tune 2
const requestData = {
training_file: "file-UfAFZsqWvS.....",
model: "gpt-3.5-turbo",
};
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
};
fetch("https://api.openai.com/v1/fine_tuning/jobs", {
method: "POST",
headers,
body: JSON.stringify(requestData),
})
.then((res) => res.json())
.then((data) => console.log("res :", data))
.catch((err) => console.log("err :", err));
데이터셋의 개수에 따라 training이 완료되는데, 몇분에서 몇시간 까지 소요 될 수 있습니다.
하단 링크를 통해, openAI Fine-tuning 페이지로 이동해서, 생성된 것을 확인할 수 있습니다. ( 완료시 email도 옵니다. )
https://platform.openai.com/finetune
4. completion
// 4. AFter training is complete, create a completion
const completion = await openai.chat.completions.create({
messages: [{ role: "user", content: "물이 끓는 온도는 몇도야?" }],
model: "ft:gpt-3.5-turbo-0613:personal::8S..생략", //https://platform.openai.com/finetune에 기재된 Model id
});
console.log(completion);
console.log(completion.choices[0].message);
오우,,,,, 내가 원하는 대답이 아니다 쓋,,,,, 빠른 시일 내에 다시 테스트 해보겠습니다.....

참고