1. 참고 유튜브 링크
2. ChatGPT API-Reference
https://platform.openai.com/docs/api-reference/fine-tunes
OpenAI API
An API for accessing new AI models developed by OpenAI
platform.openai.com
3. 유튜브 '나만의 모델 만들기' 따라하기
3.1. 주의! apiKey = 'YOUR_OPENAI_API_KEY'의 값은 개인이 발급한 openai api key로 바꿔 넣어야합니다. + 완성된 코드는 맨 아래에 있습니다.
Q. html과 javascript를 사용하여 cURL 요청을 수행하여 파인튜닝 할수있도록 코딩해줘
<html />curl https://api.openai.com/v1/fine-tunes \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "training_file": "file-XGinujblHPwGLSztz8cPS8XY" }'
A. HTML과 JavaScript를 사용하여 cURL 요청을 수행하여 파인튜닝을 할 수 있도록 코딩한 예시는 다음과 같습니다. 이 코드는 HTML의 버튼 클릭 이벤트를 사용하여 요청을 수행하고, 요청 결과를 웹 페이지에 표시합니다. 하지만 주의해야 할 점은 JavaScript로 직접 cURL 요청을 수행할 수 없기 때문에 일부 기능을 변경하였습니다.
<html />
<!DOCTYPE html>
<html>
<head>
<title>Fine-Tuning API Request</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Fine-Tuning API Request</h1>
<button id="submitBtn">Submit</button>
<div id="response"></div>
<script>
$(document).ready(function() {
$('#submitBtn').click(function() {
const apiKey = 'YOUR_OPENAI_API_KEY';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
const requestData = {
training_file: 'file-XGinujblHPwGLSztz8cPS8XY'
};
const requestConfig = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey
},
body: JSON.stringify(requestData)
};
fetch(fineTunesEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
$('#response').text(JSON.stringify(data));
})
.catch(error => {
console.error('Error:', error);
});
});
});
</script>
</body>
</html>
위의 코드에서 'YOUR_OPENAI_API_KEY' 부분을 실제 OpenAI API 키로 변경해야 합니다. 또한, cURL에서 사용되는 -d 옵션은 요청 본문(body) 데이터를 나타내는 것입니다. 이를 JavaScript의 fetch 함수로 변환할 때는 body 속성을 사용하여 데이터를 전달합니다.
주의: 위의 코드에서는 API 키를 클라이언트에 직접 노출시키고 있습니다. 이는 보안상의 이유로 권장되지 않습니다. 일반적으로 API 키는 서버 사이드에 안전하게 저장되고 서버를 통해 요청을 보내는 것이 좋습니다.


submit버튼을 눌렀더니 다음과 같은 에러메세지가 뜬다. (파일아이디가 필요하다는 뜻)
Q. 저것을 수행하기 전에 데이터셋 파일업로드를 먼저 해야해. 다음에 맞게 코딩하고 방금 코드와 연결할 수 있도록 해줘.
<html />요청 : curl https://api.openai.com/v1/files \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -F purpose="fine-tune" \ -F file="@mydata.jsonl" 응답 : { "id": "file-XjGxS3KTG0uNmNOK362iJua3", "object": "file", "bytes": 140, "created_at": 1613779121, "filename": "mydata.jsonl", "purpose": "fine-tune" }
A. 아래의 코드는 데이터셋 파일 업로드 요청과 이전에 작성한 파인튜닝 요청 코드를 연결한 예시입니다. 파일 업로드 요청을 먼저 수행하고, 그 후에 파인튜닝 요청을 수행합니다.
<html />
<!DOCTYPE html>
<html>
<head>
<title>Fine-Tuning API Request</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Fine-Tuning API Request</h1>
<form id="fileUploadForm" enctype="multipart/form-data">
<label for="file">Dataset File:</label>
<input type="file" id="file" required><br><br>
<input type="submit" value="Upload File">
</form>
<button id="submitBtn" disabled>Submit Fine-Tuning</button>
<div id="response"></div>
<script>
$(document).ready(function() {
$('#fileUploadForm').submit(function(event) {
event.preventDefault();
const apiKey = 'YOUR_OPENAI_API_KEY';
const fileUploadEndpoint = 'https://api.openai.com/v1/files';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
const fileInput = document.getElementById('file');
const file = fileInput.files[0];
const fileUploadData = new FormData();
fileUploadData.append('purpose', 'fine-tune');
fileUploadData.append('file', file);
const fileUploadConfig = {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + apiKey
},
body: fileUploadData
};
fetch(fileUploadEndpoint, fileUploadConfig)
.then(response => response.json())
.then(data => {
console.log(data);
const fileId = data.id;
enableFineTuningButton(fileId);
})
.catch(error => {
console.error('Error:', error);
});
});
$('#submitBtn').click(function() {
const apiKey = 'YOUR_OPENAI_API_KEY';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
const fileId = $('#submitBtn').data('file-id');
const requestData = {
training_file: fileId
};
const requestConfig = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey
},
body: JSON.stringify(requestData)
};
fetch(fineTunesEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
$('#response').text(JSON.stringify(data));
})
.catch(error => {
console.error('Error:', error);
});
});
function enableFineTuningButton(fileId) {
$('#submitBtn').data('file-id', fileId);
$('#submitBtn').prop('disabled', false);
}
});
</script>
</body>
</html>
위의 코드에서 'YOUR_OPENAI_API_KEY' 부분을 실제 OpenAI API 키로 변경해야 합니다. 파일을 업로드한 후에 Fine-Tuning 버튼이 활성화되며, Fine-Tuning 버튼을 클릭하면 이전과 동일한 방식으로 파인튜닝 요청이 수행됩니다

유튜브에서 나온 화면과 조금 다르지만 파일 업로드하는 버튼이 생겼다.
Q.
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
...
이 규격으로 json 데이터셋을 만들거야.
{"prompt": "탈모 치료보상", "completion": "탈모는 치료 목적(질병, 스트레스성 원형 탈모)의 경우 보상이 가능하나, 외모 개선(모발 이식 발모제 등)의 경우 보상이 불가합니다."}
이 예제를 기준으로 10개의 데이터셋을 만들어줘.
A. 아래는 주어진 예제를 기준으로 10개의 데이터셋을 생성하는 TypeScript 코드입니다. 이 코드는 Node.js 환경에서 실행됩니다.
(생략)
Q. node.js환경 없이 바로 jsonl예제 코드를 작성해줘.
A. 다음은 JSONL 형식의 데이터셋 예제 코드입니다. 각 줄은 JSON 객체로 이루어져 있으며, 예시에서 제공한 데이터셋을 기반으로 10개의 데이터셋이 생성되었습니다.
<html />{"prompt": "탈모 치료보상", "completion": "탈모는 치료 목적(질병, 스트레스성 원형 탈모)의 경우 보상이 가능하나, 외모 개선(모발 이식 발모제 등)의 경우 보상이 불가합니다."} {"prompt": "탈모 치료비", "completion": "탈모 치료비는 일반적으로 개인의 지출로 간주되며 보험으로 보상되지 않습니다."} {"prompt": "탈모 원인", "completion": "탈모의 주요 원인은 유전적인 요소, 호르몬 변화, 스트레스, 영양 부족 등이 있습니다."} {"prompt": "탈모 예방법", "completion": "탈모 예방을 위해 건강한 식습관을 유지하고 스트레스를 관리하며 모발을 너무 자주 노출시키지 않는 것이 중요합니다."} {"prompt": "탈모 치료 방법", "completion": "탈모 치료 방법에는 모발 이식, 발모제 사용, 레이저 치료 등이 있습니다."} {"prompt": "탈모 치료 제품", "completion": "탈모 치료를 위해 시장에는 다양한 발모제 제품이 있으며, 의사와 상담한 후에 사용하는 것이 좋습니다."} {"prompt": "탈모 관련 질문", "completion": "탈모와 관련된 질문이 있으신가요? 전문가와 상담하고 치료 옵션에 대해 알아보세요."} {"prompt": "탈모 유형", "completion": "탈모의 주요 유형으로는 남성 패턴 탈모, 여성 패턴 탈모, 원형 탈모 등이 있습니다."} {"prompt": "탈모 치료 비용", "completion": "탈모 치료 비용은 여러 요인에 따라 다르며, 치료 방법과 환자의 개별 상황에 따라 결정됩니다."} {"prompt": "탈모와 자신감", "completion": "탈모는 자신감에 영향을 줄 수 있지만, 적절한 탈모 관리와 자기관리를 통해 자신감을 회복할 수 있습니다."}
위의 예제 코드를 참고하여 필요한 만큼 데이터셋을 추가하거나 내용을 수정하실 수 있습니다. 이후에는 수정된 JSONL 파일을 사용하여 파인튜닝을 진행할 수 있습니다.
chatGPT가 만든 대로 10개의 데이터셋을 복사해서 data.jsonl파일을 만들었다.
Q. 업로드한 결과로 파인튜닝까지 할 수 있는 UI로 다시 코딩해줘.
A. 아래는 HTML과 JavaScript를 사용하여 데이터셋 파일 업로드와 파인튜닝 요청을 수행할 수 있는 UI 코드입니다.
<html />
<!DOCTYPE html>
<html>
<head>
<title>Fine-Tuning API Request</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Fine-Tuning API Request</h1>
<form id="fileUploadForm" enctype="multipart/form-data">
<label for="file">Dataset File:</label>
<input type="file" id="file" required><br><br>
<input type="submit" value="Upload File">
</form>
<button id="submitBtn" disabled>Submit Fine-Tuning</button>
<div id="response"></div>
<script>
$(document).ready(function() {
$('#fileUploadForm').submit(function(event) {
event.preventDefault();
const apiKey = 'YOUR_OPENAI_API_KEY';
const fileUploadEndpoint = 'https://api.openai.com/v1/files';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
const fileInput = document.getElementById('file');
const file = fileInput.files[0];
const fileUploadData = new FormData();
fileUploadData.append('purpose', 'fine-tune');
fileUploadData.append('file', file);
const fileUploadConfig = {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + apiKey
},
body: fileUploadData
};
fetch(fileUploadEndpoint, fileUploadConfig)
.then(response => response.json())
.then(data => {
console.log(data);
const fileId = data.id;
enableFineTuningButton(fileId);
})
.catch(error => {
console.error('Error:', error);
});
});
$('#submitBtn').click(function() {
const apiKey = 'YOUR_OPENAI_API_KEY';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
const fileId = $('#submitBtn').data('file-id');
const requestData = {
training_file: fileId
};
const requestConfig = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey
},
body: JSON.stringify(requestData)
};
fetch(fineTunesEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
$('#response').text(JSON.stringify(data));
})
.catch(error => {
console.error('Error:', error);
});
});
function enableFineTuningButton(fileId) {
$('#submitBtn').data('file-id', fileId);
$('#submitBtn').prop('disabled', false);
}
});
</script>
</body>
</html>
위의 코드에서 'YOUR_OPENAI_API_KEY' 부분을 실제 OpenAI API 키로 변경해야 합니다. 파일을 업로드한 후에 Fine-Tuning 버튼이 활성화되며, Fine-Tuning 버튼을 클릭하면 파인튜닝 요청이 수행되고 응답이 화면에 표시됩니다.
Q. submit fine-tuning버튼을 눌렀을 때 나오는 결과가 나열되지 않고 가독성 있게 출력되도록 수정해줘.
A. 아래는 submit 버튼을 눌렀을 때 결과를 가독성 있게 출력하는 업데이트된 JavaScript 코드입니다. 결과는 <pre> 태그 내에 표시되며, JSON.stringify() 함수의 들여쓰기를 2로 설정하여 응답을 들여쓰기하여 표시합니다.
<html />
<!DOCTYPE html>
<html>
<head>
<title>Fine-Tuning API Request</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Fine-Tuning API Request</h1>
<form id="fileUploadForm" enctype="multipart/form-data">
<label for="file">Dataset File:</label>
<input type="file" id="file" required><br><br>
<input type="submit" value="Upload File">
</form>
<button id="submitBtn" disabled>Submit Fine-Tuning</button>
<pre id="response"></pre>
<script>
$(document).ready(function() {
$('#fileUploadForm').submit(function(event) {
event.preventDefault();
const apiKey = 'YOUR_OPENAI_API_KEY';
const fileUploadEndpoint = 'https://api.openai.com/v1/files';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
const fileInput = document.getElementById('file');
const file = fileInput.files[0];
const fileUploadData = new FormData();
fileUploadData.append('purpose', 'fine-tune');
fileUploadData.append('file', file);
const fileUploadConfig = {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + apiKey
},
body: fileUploadData
};
fetch(fileUploadEndpoint, fileUploadConfig)
.then(response => response.json())
.then(data => {
console.log(data);
const fileId = data.id;
enableFineTuningButton(fileId);
})
.catch(error => {
console.error('Error:', error);
});
});
$('#submitBtn').click(function() {
const apiKey = 'YOUR_OPENAI_API_KEY';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
const fileId = $('#submitBtn').data('file-id');
const requestData = {
training_file: fileId
};
const requestConfig = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey
},
body: JSON.stringify(requestData)
};
fetch(fineTunesEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
$('#response').text(JSON.stringify(data, null, 2));
})
.catch(error => {
console.error('Error:', error);
});
});
function enableFineTuningButton(fileId) {
$('#submitBtn').data('file-id', fileId);
$('#submitBtn').prop('disabled', false);
}
});
</script>
</body>
</html>
위의 코드에서 'YOUR_OPENAI_API_KEY' 부분을 실제 OpenAI API 키로 변경해야 합니다. 결과는 들여쓰기된 JSON 형식으로 <pre> 태그 내에 표시되므로 가독성이 향상됩니다.


"status" : "pending" 은 학습을 하고 있는 상태라는 뜻이다.
Q. curl https://api.openai.com/v1/fine-tunes \
-H "Authorization: Bearer $OPENAI_API_KEY"
이걸 사용하여 파인튜닝 리스트를 가져오는 부분을 추가해주고, 추가되는 소스만 출력해줘.
거기서 현재 상태도 조회할 수 있도록 기존소스에 추가해줘
A. 아래는 기존 코드에 현재 상태를 조회하는 기능을 추가한 HTML 및 JavaScript 코드입니다.
<html />
<!DOCTYPE html>
<html>
<head>
<title>Fine-Tuning API</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Fine-Tuning API</h1>
<h2>Get Fine-Tuning List</h2>
<button id="getListBtn">Get List</button>
<pre id="listResponse"></pre>
<h2>Get Fine-Tuning Status</h2>
<form id="getStatusForm">
<label for="statusId">Status ID:</label>
<input type="text" id="statusId" required>
<input type="submit" value="Get Status">
</form>
<pre id="statusResponse"></pre>
<script>
$(document).ready(function() {
const apiKey = 'YOUR_OPENAI_API_KEY';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
$('#getListBtn').click(function() {
const requestConfig = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + apiKey
}
};
fetch(fineTunesEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
const currentSource = $('pre#listResponse').text();
const newSource = JSON.stringify(data, null, 2);
if (currentSource === newSource) {
$('pre#listResponse').text('No new sources found.');
} else {
$('pre#listResponse').text(newSource);
}
})
.catch(error => {
console.error('Error:', error);
});
});
$('#getStatusForm').submit(function(event) {
event.preventDefault();
const statusId = $('#statusId').val();
const statusEndpoint = `${fineTunesEndpoint}/${statusId}`;
const requestConfig = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + apiKey
}
};
fetch(statusEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
$('pre#statusResponse').text(JSON.stringify(data, null, 2));
})
.catch(error => {
console.error('Error:', error);
});
});
});
</script>
</body>
</html>
위의 코드에서 'YOUR_OPENAI_API_KEY' 부분을 실제 OpenAI API 키로 변경해야 합니다. "Get List" 버튼을 클릭하면 파인튜닝 리스트를 가져오고, "Get Status" 버튼을 클릭하여 상태 ID를 입력하고 제출하면 해당 파인튜닝의 상태를 조회할 수 있습니다. 결과는 각각의 <pre> 태그에 표시됩니다.
Q. 방금 너가 써준 코드의 기능을 설명해줘
A. 제공한 코드는 OpenAI Fine-Tuning API를 사용하여 파인튜닝 작업을 관리하는 기능을 포함한 UI를 생성하는 코드입니다. 각각의 기능을 설명하겠습니다:
1. Get Fine-Tuning List:
- "Get List" 버튼을 클릭하면 OpenAI Fine-Tuning API에서 현재 진행 중인 파인튜닝 작업의 목록을 가져옵니다.
- 목록은 JSON 형식으로 `<pre>` 태그에 출력됩니다.
- 이전에 가져온 목록과 비교하여 새로운 소스가 있으면 목록을 업데이트하고, 새로운 소스가 없으면 "No new sources found."라는 메시지를 출력합니다.
2. Get Fine-Tuning Status:
- 상태 ID를 입력하는 텍스트 필드와 "Get Status" 버튼이 있습니다.
- 상태 ID는 Fine-Tuning 작업의 고유 식별자입니다.
- "Get Status" 버튼을 클릭하면 입력한 상태 ID를 사용하여 해당 Fine-Tuning 작업의 상태를 조회합니다.
- 상태는 JSON 형식으로 `<pre>` 태그에 출력됩니다.
이 코드를 사용하면 OpenAI Fine-Tuning API를 쉽게 호출하고, 파인튜닝 작업의 목록을 확인하고, 특정 작업의 상태를 조회할 수 있습니다. 이를 통해 파인튜닝 작업을 관리하고 모니터링할 수 있습니다.
Q. 방금 만든 코드와 이 코드의 내용을 합치고, step 1: upload file, step 2: fine-tune model, step3 : get fine-tune list 로 단계를 구분해줘.
(위의 Submit fine-tuning이 들어간 코드)
A. 아래는 업로드 파일, 파인튜닝 제출 및 파인튜닝 리스트 가져오기 기능이 통합된 HTML 코드입니다. 코드 내에 주석으로 단계별 설명을 추가하였습니다.
<html />
<!DOCTYPE html>
<html>
<head>
<title>Fine-Tuning API Request</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Fine-Tuning API Request</h1>
<h2>Step 1: Upload File</h2>
<form id="fileUploadForm" enctype="multipart/form-data">
<label for="file">Dataset File:</label>
<input type="file" id="file" required><br><br>
<input type="submit" value="Upload File">
</form>
<h2>Step 2: Submit Fine-Tuning</h2>
<button id="submitBtn" disabled>Submit Fine-Tuning</button>
<pre id="response"></pre>
<h2>Step 3: Get Fine-Tuning List</h2>
<button id="getListBtn">Get List</button>
<pre id="listResponse"></pre>
<script>
$(document).ready(function() {
const apiKey = 'YOUR_OPENAI_API_KEY';
const fileUploadEndpoint = 'https://api.openai.com/v1/files';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
// Step 1: Upload File
$('#fileUploadForm').submit(function(event) {
event.preventDefault();
const fileInput = document.getElementById('file');
const file = fileInput.files[0];
const fileUploadData = new FormData();
fileUploadData.append('purpose', 'fine-tune');
fileUploadData.append('file', file);
const fileUploadConfig = {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + apiKey
},
body: fileUploadData
};
fetch(fileUploadEndpoint, fileUploadConfig)
.then(response => response.json())
.then(data => {
const fileId = data.id;
enableFineTuningButton(fileId);
})
.catch(error => {
console.error('Error:', error);
});
});
// Step 2: Submit Fine-Tuning
$('#submitBtn').click(function() {
const fileId = $('#submitBtn').data('file-id');
const requestData = {
training_file: fileId
};
const requestConfig = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey
},
body: JSON.stringify(requestData)
};
fetch(fineTunesEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
$('#response').text(JSON.stringify(data, null, 2));
})
.catch(error => {
console.error('Error:', error);
});
});
// Step 3: Get Fine-Tuning List
$('#getListBtn').click(function() {
const requestConfig = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + apiKey
}
};
fetch(fineTunesEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
const currentSource = $('pre#listResponse').text();
const newSource = JSON.stringify(data, null, 2);
if (currentSource !== newSource) {
$('pre#listResponse').text(newSource);
} else {
$('pre#listResponse').text('No new sources found.');
}
})
.catch(error => {
console.error('Error:', error);
});
});
function enableFineTuningButton(fileId) {
$('#submitBtn').data('file-id', fileId);
$('#submitBtn').prop('disabled', false);
}
});
</script>
</body>
</html>
이 코드는 세 단계로 구성되어 있습니다.
1. Step 1: Upload File
- "Upload File" 버튼을 클릭하여 데이터셋 파일을 업로드합니다.
- 파일을 선택하고 업로드하면 Fine-Tuning에 필요한 파일을 OpenAI API로 전송합니다.
- 파일 업로드가 성공하면 "Submit Fine-Tuning" 버튼이 활성화됩니다.
2. Step 2: Submit Fine-Tuning
- "Submit Fine-Tuning" 버튼을 클릭하여 Fine-Tuning 작업을 제출합니다.
- 업로드한 파일의 ID를 사용하여 Fine-Tuning API에 요청을 보내고 결과를 출력합니다.
3. Step 3: Get Fine-Tuning List
- "Get List" 버튼을 클릭하여 현재 진행 중인 Fine-Tuning 작업의 목록을 가져옵니다.
- 이전에 가져온 목록과 비교하여 새로운 소스가 있으면 목록을 업데이트하고, 새로운 소스가 없으면 "No new sources found."라는 메시지를 출력합니다.
- Fine-Tuning 작업의 목록은 JSON 형식으로 출력됩니다.
이렇게 코드를 사용하면 데이터셋 파일을 업로드하고 Fine-Tuning 작업을 제출하며, 목록을 가져오는 세 단계를 수행할 수 있습니다.
Q. 여기 코드에서 ada, babbage, curie, davinci 중 모델을 선택할 수 있도록 수정해줘
A. 다음은 코드를 수정하여 ada, babbage, curie, davinci 중에서 모델을 선택할 수 있도록 하는 방법입니다:
<html />
<!DOCTYPE html>
<html>
<head>
<title>Fine-Tuning API Request</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Fine-Tuning API Request</h1>
<h2>Step 1: Upload File</h2>
<form id="fileUploadForm" enctype="multipart/form-data">
<label for="file">Dataset File:</label>
<input type="file" id="file" required><br><br>
<input type="submit" value="Upload File">
</form>
<h2>Step 2: Submit Fine-Tuning</h2>
<label for="model">Select Model:</label>
<select id="model" required>
<option value="ada">Ada</option>
<option value="babbage">Babbage</option>
<option value="curie">Curie</option>
<option value="davinci">Davinci</option>
</select><br><br>
<button id="submitBtn" disabled>Submit Fine-Tuning</button>
<pre id="response"></pre>
<h2>Step 3: Get Fine-Tuning List</h2>
<button id="getListBtn">Get List</button>
<pre id="listResponse"></pre>
<script>
$(document).ready(function() {
const apiKey = 'YOUR_OPENAI_API_KEY';
const fileUploadEndpoint = 'https://api.openai.com/v1/files';
const fineTunesEndpoint = 'https://api.openai.com/v1/fine-tunes';
// Step 1: Upload File
$('#fileUploadForm').submit(function(event) {
event.preventDefault();
const fileInput = document.getElementById('file');
const file = fileInput.files[0];
const fileUploadData = new FormData();
fileUploadData.append('purpose', 'fine-tune');
fileUploadData.append('file', file);
const fileUploadConfig = {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + apiKey
},
body: fileUploadData
};
fetch(fileUploadEndpoint, fileUploadConfig)
.then(response => response.json())
.then(data => {
const fileId = data.id;
enableFineTuningButton(fileId);
})
.catch(error => {
console.error('Error:', error);
});
});
// Step 2: Submit Fine-Tuning
$('#submitBtn').click(function() {
const fileId = $('#submitBtn').data('file-id');
const model = $('#model').val();
const requestData = {
training_file: fileId,
model: model
};
const requestConfig = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey
},
body: JSON.stringify(requestData)
};
fetch(fineTunesEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
$('#response').text(JSON.stringify(data, null, 2));
})
.catch(error => {
console.error('Error:', error);
});
});
// Step 3: Get Fine-Tuning List
$('#getListBtn').click(function() {
const requestConfig = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + apiKey
}
};
fetch(fineTunesEndpoint, requestConfig)
.then(response => response.json())
.then(data => {
let newSource = '';
const currentSource = $('pre#listResponse').text();
data.data.forEach(fineTune => {
newSource += `ID: ${fineTune.id}\n`;
newSource += `Model: ${fineTune.model}\n`;
newSource += `Status: ${fineTune.status}\n`;
newSource += `Created At: ${new Date(fineTune.created_at * 1000).toLocaleString()}\n\n`;
});
if (currentSource !== newSource) {
$('pre#listResponse').text(newSource);
} else {
$('pre#listResponse').text('No new sources found.');
}
})
.catch(error => {
console.error('Error:', error);
});
});
function enableFineTuningButton(fileId) {
$('#submitBtn').data('file-id', fileId);
$('#submitBtn').prop('disabled', false);
}
});
</script>
</body>
</html>

드롭다운 버튼이 생겼고 리스트가 가독성 있게 바뀌었다.(!)

이전 글과 마찬가지로 playground에서 Model에서 fine-tuning 모델 중 내가 만든 파인튜닝 모델을 고르고, 파인튜닝을 확인할 수 있다.

역시나 헛소리 대잔치...
데이터가 부족해서 이런 결과가 나온것이 맞는 것 같다.
역시 영상과 마찬가지로 데이터 증강이 필요한 것 같다.


이번엔 시작문구를 달아주니 시작부분은... 잘 들어간 모습이다.
이번에는 데이터 증강으로 10개를 100개로 복붙하여 늘리고 띄어쓰기나 물음표 삭제 등을 통해 데이터를 조금씩 바꾸었다.
그리고 모델을 Davinci로 변경하였다.
{
"object": "fine-tune",
"id": "ft-x50cI7uG54iSJWyLIUfbVOVL",
"hyperparams": {
"n_epochs": 4,
"batch_size": null,
"prompt_loss_weight": 0.01,
"learning_rate_multiplier": null
},
"organization_id": "org-7bHoMu3dtPmrDhskZb8MRUAN",
"model": "davinci",
"training_files": [
{
"object": "file",
"id": "file-ardxZxEzf7Sl1925C5v1DtoI",
"purpose": "fine-tune",
"filename": "talmo.jsonl",
"bytes": 22110,
"created_at": 1685426167,
"status": "uploaded",
"status_details": null
}
],
"validation_files": [],
"result_files": [],
"created_at": 1685426170,
"updated_at": 1685426170,
"status": "pending",
"fine_tuned_model": null,
"events": [
{
"object": "fine-tune-event",
"level": "info",
"message": "Created fine-tune: ft-x50cI7uG54iSJWyLIUfbVOVL",
"created_at": 1685426170
}
]
}
submit fine-tuning버튼을 누르면 나오는 텍스트
파인튜닝 모델의 status는 pending->running->succeeded 순서로 진행된다.
Davinci가 제일 똑똑해서인지 running에 오래 머물러있었다.(10분이내로 걸렸다.)
다시 playground로 가서 Model을 방금 만든 모델로 선택하고, temperature는 0.7로 설정하고, stop sequences를 프롬프트의 시작으로 설정했다.

드디어 정상적인 답변을 한다! ㅎ
챗봇을 어떻게 만들어야할지 감이 왔지만, fine-tuning은 데이터를 정제하고 추리고 가공해야 하는 작업이 99%임을 느꼈다. 데이터셋이 최소 수백개에서 천개 이상 필요한 것 같다. 그 부분은 데이터전문가의 분야인 것 같다. chatGPT에게 100개라도 만들어달라고 하면 빠꾸당하기 때문이다.(...)
비용 측면도 무시할 수 없다. 한글이 영어보다 글자 대비 가격이 두 배이기 때문이다... 거기다 Davinci모델이 똑똑한 만큼 가격도 제일 비싸다. 학습을 시킬 때나 출력할 때나 모두 토큰을 사용한다고 하니, 유저가 많다면 엄청난 돈이 청구될 수 있다.