Supercharge Your GPT Model: Custom Data Fine-Tuning using Node.js
How to Customize Your GPT Model: A Simple Guide to Personalized Training Data Integration
While GPT and ChatGPT are already powerful on their own, they are limited in that the training data is not up to date and could be missing information on niche topics. I wanted to learn how to easily train a GPT model using arbitrary, custom data, so I did. Next, I decided to document the process for other people to use.
In this tutorial you’ll learn how to fine-tune GPT with your own custom data from scratch.
To view the final codebase for this tutorial, click here. The video for this tutorial is available here.
API
The OpenAI GPT APIs and SDKs make it easy to fine-tune a model using either Python, Node.js, or just an HTTP request. There are also quite a few community-maintained libraries for other languages like PHP and Ruby.
In this tutorial we’ll be using the OpenAI Node.js SDK. This SDK is simple to use and allows you to make API calls to OpenAI in just a couple of lines of code.
For instance, to retrieve a completion we can just call the createCompletion
method:
const response = await openai.createCompletion({
model: 'davinci',
prompt: "What is Lens Protocol",
max_tokens: 200
})
In our case, we’ll just be replacing the davinci
model with our own model that will use our custom data set we’ve uploaded for training.
Prerequisites
To follow along with this tutorial, you’ll need to have the following installed on your machine:
Python
Node.js
You’ll also need an OpenAI API Key. You can get one at https://openai.com.
Getting started
To get started, we’ll create a new Node.js project in an empty directory:
mkdir custom-ai-model
cd custom-ai-model
npm init --y
Update the new package.json file to use ES Modules by adding this line of configuration:
"type": "module",
Next, set the environment variable to hold your OpenAI API Key. You can set this in your terminal session or in a configuration file like .bashrc
or .zshrc
:
export OPENAI_KEY="your-api-key"
Next, we’ll install the openai
npm package:
npm install openai
Finally we’ll install the OpenAI CLI and the OpenAI datalib:
pip install --upgrade openai openai"[datalib]"
Now we’re ready to start writing some code!
Creating the training data
There are a handful of models available from OpenAI, but when fine-tuning the original GPT-3 base models are currently the only models available to start from, like davinci, curie, babbage, and ada. We’ll be using davinci.
Your data needs to be created in a JSONL document in the following format, with each declaration separated in a new line:
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
It is recommended to provide at least a few hundred of these examples, most sources recommending 500 or more.
In my experience, creating a few dozen inputs will at least give you some basic result that you can test out in this tutorial, but it is not enough to use as a production ready product.
From the docs: … performance tends to linearly increase with every doubling of the number of examples. Increasing the number of examples is usually the best and most reliable way of improving performance.
Once you’ve created your document, OpenAI provides a command line utility which will improve the format of your data and is recommended to run before you upload.
openai tools fine_tunes.prepare_data -f <LOCAL_FILE>
You can view, and even copy and use, my example data set here for this tutorial.
Once your data set is ready, we can create a script to upload it to OpenAI.
Creating the API interface
This file will define the API that we’ll be using to interact with the OpenAI APIs.
Since we’ll be re-using this code over and over, we’ll separate it into it’s own file and just import it into our other files.
Create a file named api.js and add the following code:
/* api.js */
import { Configuration, OpenAIApi } from 'openai'
const openaiApiKey = process.env.OPENAI_KEY
const configuration = new Configuration({
apiKey: openaiApiKey
})
export const openai = new OpenAIApi(configuration)
Uploading the training data
Now that we’ve created the API, we can use it to upload our file to use later.
Create a file named uploadFile.js and add the following code:
/* uploadFile.js */
import { openai } from './api.js'
import fs from 'fs'
async function upload() {
try {
const response = await openai.createFile(
fs.createReadStream('./data_prepared.jsonl'),
"fine-tune"
);
console.log('File ID: ', response.data.id)
} catch (err) {
console.log('err: ', err)
}
}
upload()
Next, run the script:
node uploadFile.js
When the upload is complete, take note of the the File ID that is logged out, we’ll be needing it in the next step.
Creating the Fine Tune
Now that we’ve uploaded the training data and have the file ID, we can use it to custom train our model.
To do so, create a new file named createFineTune.js and add the following code:
/* createFineTune.js */
import { openai } from './api.js'
async function createFineTune() {
try {
const response = await openai.createFineTune({
training_file: 'your-file-id',
model: 'davinci'
})
console.log('response: ', response)
} catch (err) {
console.log('error: ', err.response.data.error)
}
}
createFineTune()
Next, execute the script to start fine tuning your model:
node createFineTune.js
Listing your Fine Tunes
Once the fine tune is created, it will take some time to process. We can get the status of the fine tune, as well as the model ID, by calling the listFineTunes
API method.
Create a new file named listFineTunes.js and add the following code:
/* listFineTunes.js */
import { openai } from './api.js'
async function listFineTunes() {
try {
const response = await openai.listFineTunes()
console.log('data: ', response.data.data)
} catch (err) {
console.log('error:', err)
}
}
listFineTunes()
Run the script.
node listFineTunes.js
It will take the process a few minutes to finish. Once the process is completed and you run the script again, you should see the fine_tuned_model
field populated with the new model ID.
Take note of this fine_tuned_model ID, you’ll need it in the next step.
Testing it out
Now that the fine tune has processed and our. new model is ready, we can try it out!
Create a new file named createCompletion.js. Here, add the following code. Be sure to update the fine_tuned_model
value with your model name:
/* createCompletion.js */
import { openai } from './api.js'
async function createCompletion() {
try {
const response = await openai.createCompletion({
model: 'your-custom-model-name',
prompt: 'What is Lens Protocol',
max_tokens: 200
})
if (response.data) {
console.log('choices: ', response.data.choices)
}
} catch (err) {
console.log('err: ', err)
}
}
createCompletion()
Run the script:
node createCompletion.js
🎉 Congratulations
You’ve successfully deployed your own custom model using GPT3!
To view the final codebase for this tutorial, click here.
That's a very informative post! Really well written and clarifies how to use openai API.
Hi Nader thanks for this post, is it possible to restrict the fine tune model to respond only to certain prompts ? Example only prompts related to tech or specific field should be answered otherwise should respond with 'Not related'. Is this scenario possible ?