I'm constantly looking for ways to automate the work with support requests. An idea has been to fine-tune a GPT-3 model to answer common support-related questions.
Here's how you can use Python to fine-tune a GPT-3 model with your own data for improved performance.
Check out my free video course on fine-tuning a GPT-3 model
If you prefer learning through videos, I've got you covered!
I've created a free video course that teaches you how to fine-tune a GPT-3 model with your own data. The course covers everything in this blog post and more, with step-by-step instructions and examples.
You can access the course for free: https://norahsakal.gumroad.com/l/qwhwa
Happy learning!
Here's what we'll use:
1. OpenAI API 🤖
2. Python 🐍
Here are the steps:
1. Get OpenAI API key
2. Create training data
3. Check the training data
4. Upload training data
5. Fine-tune model
6. Test the new model on a new prompt
Disclaimer
This guide walks you through fine-tuning a GPT-3 model in Python, shown in a Jupyter notebook.
If you're looking for the steps of fine-tuning right in a terminal, OpenAI has a great guide for fine-tuning in your terminal.
Before we go ahead and fine-tune a model, let's get the OpenAI credentials needed for the API calls.
Go to https://beta.openai.com/, log in and click on your avatar and View API keys:

Then create a new secret key and save it for the request:

Now we have all the credentials needed to make an API request.
The next step is to create training data to teach GPT-3 what you'd like to say. The data need to be a JSONL document with a new prompt and the ideal generated text:
{"prompt": "<question>", "completion": "<ideal answer>"}
{"prompt": "<question>", "completion": "<ideal answer>"}
{"prompt": "<question>", "completion": "<ideal answer>"}
Let's start by importing the libraries needed:
import json
import openai
Then add your API key from the previous step:
api_key ="YOUR_OPENAI_API_KEY"
openai.api_key = api_key
Now create a regular dict with the training data. For this guide, I'll add some support questions I've recently received:
training_data = [{
"prompt": "Where is the billing ->",
"completion": " You find the billing in the left-hand side menu.\n"
},{
"prompt":"How do I upgrade my account ->",
"completion": " Visit you user settings in the left-hand side menu, then click 'upgrade account' button at the top.\n"
}]
Make sure to end each prompt with a suffix. According to the OpenAI API reference, you can use ->.
Also, make sure to end each completion with a suffix as well; I'm using .\n.
The next step is to convert the dict to a proper JSONL file. JSONL file is a newline-delimited JSON file, so we'll add a \n at the end of each object:
file_name = "training_data.jsonl"
with open(file_name, "w") as output_file:
for entry in training_data:
json.dump(entry, output_file)
output_file.write("\n")
Now you have the training data as a JSONL file, let's check the training data before starting the fine-tuning.
We can check the training data using a CLI data preparation tool provided by OpenAI. It gives you suggestions about how you can reformat the training data.
Let's try it out with our training data. Run this line in Jupyter notebook:
!openai tools fine_tunes.prepare_data -f training_data.jsonl
You'll get suggestions similar to this:

I'm only using a couple of prompts for this guide, but the suggestions mention that the recommendations are to have at least a few hundred examples.
You'll also see the approximate time depending on how many jobs are ahead of you in the queue:

We're ready to upload the training data in the next section.
Now that you checked the improvement suggestions, let's upload the training data to OpenAI:
upload_response = openai.File.create(
file=open(file_name, "rb"),
purpose='fine-tune'
)
file_id = upload_response.id
upload_response
If you check the response, you'll see the file id which we'll need in the next step when we're training the model:

Use this file id in the next step, where we'll fine-tune a model.
Alrighty, we have the prepared training data, uploaded it, and now we're finally ready to fine-tune the model.
Start the fine-tuning by running this command:
fine_tune_response = openai.FineTune.create(training_file=file_id)
fine_tune_response
The default model is Curie. But if you'd like to use DaVinci instead, then add it as a base model to fine-tune like this:
openai.FineTune.create(training_file=file_id, model="davinci")
The first response will look something like this:

You can use two openai functions to check the progress of your fine-tuning.
You can use openai.FineTune.list_events() and pass in the fine_tune_response id to list all the current events:
fine_tune_events = openai.FineTune.list_events(id=fine_tune_response.id)
This will give you a list of all the events related to the fine-tuning job you're running:

You can also use openai.FineTune.retrieve(id=fine_tune_response.id) to retrieve a specific fine-tune:
retrieve_response = openai.FineTune.retrieve(id=fine_tune_response.id)
This will give you a JSON object with information about a specific fine-tune job:

When your fine-tuning job is first in line, your fine-tuning event starts:

Troubleshooting fine_tuned_model as null
During the fine-tuning process, thefine_tuned_modelkey may not be immediately available in the fine_tune_response object returned byopenai.FineTune.create().To check the status of your fine-tuning process, you can call the
openai.FineTune.retrieve()function and pass in the fine_tune_response.id. This function will return a JSON object with information about the training status, such as the current epoch, the current batch, the training loss, and the validation loss.After the fine-tuning process is complete, you can check the status of all your fine-tuned models by calling
openai.FineTune.list(). This will list all of your fine-tunes and their current status.Once the fine-tuning process is complete, you can retrieve the fine_tuned_model key by calling the openai.
FineTune.retrieve()function again and passing in the fine_tune_response.id. This will return a JSON object with the key fine_tuned_model and the ID of the fine-tuned model that you can use for further completions.
Once the fine-tuning is finished, go ahead and save the name of the fine-tuned model:
# Option 1 | if response.fine_tuned_model != null
fine_tuned_model = response.fine_tuned_model
fine_tuned_model
# Option 2 | if response.fine_tuned_model == null
retrieve_response = openai.FineTune.retrieve(response.id)
fine_tuned_model = retrieve_response.fine_tuned_model
fine_tuned_model
It will look something like this:

We now have a fine-tuned model. Let's try it out on a new prompt in the next section.
We're finally at the last step, where we'll try our fine-tuned model on a new prompt.
I only ran my fine-tuning on 2 prompts, so I'm not expecting a super-accurate completion.
Start by creating a new prompt.
Remember to end the prompt with the same suffix as we used in the training data; ->:
new_prompt = "How do I find my billing? ->"
Next, run the completion with your fine-tuned model:
answer = openai.Completion.create(
model=fine_tuned_model,
prompt=new_prompt,
max_tokens=100,
temperature=0
)
answer['choices'][0]['text']
Here's what I got:

Great! Now you have a fine-tuned GPT-3 model ready for future prompts.
Expand the training data
The training data analysis by OpenAI in step 2 of this guide suggests expanding the training data amount. I only used 2 prompts in this guide. The suggestion says at least a few hundred examples/prompts.
FAQ might not be the best use case
FAQ-related questions might not be the best use case for fine-tuning. If you'd like to automate your support questions, a question-answering approach might be better suited than fine-tuning a GPT-3 model.
1. Repo with source code
Here is the repo with a Jupyter notebook with all the source code if you'd like to implement this on your own ⬇️
https://github.com/norahsakal/fine-tune-gpt3-model
2. Do you need help with fine-tuning your own GPT-3 model? Or do you have other questions?
I'm happy to help, don't hesitate to reach out ➡️ [email protected]
Or shoot me a DM on Twitter @norahsakal
Originally published at https://norahsakal.com/blog/fine-tune-gpt3-model
Really awesome write-up. Quick question if you don't mind. Would it be possible to feed GPT with custom knowledge and then ask it questions to which it responds with answers based on the input/text data we provided to it? For example, if I feed it a 100 page text document and therefore send a prompt, it should respond with an answer that is from the 100 page text document.
Is this possible? In your example, it's a Tech support bot for which there are a limited set of questions and answers so prompting in this case is fine however, if we have a 100 page text document, it would be a nightmare to do this.
Really curious about this and hoping you could shed some light on whether this can be done (with a brief description of how to do this) or why it can't be done.
Given your specific use case, alternative approaches might be more effective than fine-tuning since OpenAI suggests using at least several hundred examples for successful fine-tuning.
I usually recommend considering an approach that uses embeddings and a search-ask method rather than fine-tuning.
Here's an analogy I found that tells the difference between the two:
"Fine-tuning a model is akin to cramming for an exam a week in advance. You might retain the information for a short time, but there's a risk of forgetting details or confusing facts. This is similar to long-term memory.
However, using the Search-Ask method and inserting knowledge into a message is like having open-book notes during an exam. With the information immediately accessible, the model can provide more accurate responses. This resembles short-term memory."
Link to the quote: https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb
By applying this approach, you can leverage the data you have to create embeddings. Then when you ask a question, the most relevant sections of those 100-page text documents would be sent to GPT-3 or GPT-4, which would then generate a response based on this data.
This strategy ensures accuracy, as answers are solely based on the data you've provided.
I've written a couple of blog posts on building chatbots for product data and how to use embeddings (search-ask method):
Building a Chatbot from Scratch: https://norahsakal.com/blog/chatgpt-audio-chatbot
Using Embeddings for Product Recommendations: https://norahsakal.com/blog/chatgpt-product-recommendation-embeddings
Here's a tutorial I found for how to build your own chatbot with an existing chat interface: https://beebom.com/how-build-own-ai-chatbot-with-chatgpt-api/
Good luck, and let me know how it goes! @iamjson
Great resource, Norah! Thank you for sharing!
Just wanted to let you know that I've created a mini-course on fine-tuning GPT-3 models based on this blog post – feel free to check it out! https://norahsakal.gumroad.com/l/qwhwa
@djomlax
Thanks for checking it out! 🙌 @djomlax
Norah, this is amazing - the detail is very appreciated!
Thank you so much for your support, Elliott! It means a lot 🙏 @elliottzelinskas
Hi Norah,
Nicely documented!
Its worth mentioning that you can opt out of openAI's API to train a variant of GPT-3, GPT-J.
Still many people make use of GPT-2.
Thanks for checking it out! @terry_remyx
Thanks for sharing the link to GPT-J. I heard of it but I didn't know it's that easy to fine-tune, good to know!
Fine-tuning a GPT-3 model involves providing specific prompts and adjusting parameters. I encountered a similar challenge with InquireSalary. To address this, tailor prompts to your domain, experiment with temperature and max tokens, and iterate for optimal results. Additionally, consider using OpenAI's fine-tuning guide for detailed instructions.
Hi there, so I am trying to get the fine_tuned_model, but it shows None instead of the model's name. Can someone help me?
Hi!
I've added 2 new sections to the post:
6. Check fine-tuning progress
7. Save fine-tuned model
So refresh the post and check out those two new sections, there I'm talking a bit more about troubleshooting fine_tuned_model as null
@MisterK
Thanks! It really worked. However, I have another issue: I put the prompts of the training_data and I cant get the excepted output/completion. I change the tempeture, but I still get random stuff. What can I do?
Thanks for your reply!
Have you been fine-tuning a model with your own data? If so, how many examples have you used for this purpose?
OpenAI suggests using at least several hundred examples for successful fine-tuning.
In my tutorial, I demonstrated with only two examples for simplicity and learning purposes, but a more substantial dataset will likely yield better results.
Real-world applications typically require fine-tuning with hundreds, if not thousands, of examples to achieve optimal results.
Depending on your use case, you could try another approach that uses embeddings and a search-ask method, rather than fine-tuning.
Here's an analogy I found that tells the difference between the two:
"Fine-tuning a model is akin to cramming for an exam a week in advance. You might retain the information for a short time, but there's a risk of forgetting details or confusing facts. This is similar to long-term memory.
However, using the Search-Ask method and inserting knowledge into a message is like having open-book notes during an exam. With the information immediately accessible, the model can provide more accurate responses. This resembles short-term memory."
Link to the quote: https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb
Let me know if I can do anything to help! @MisterK
Ok, now I get it. Thank you very much! :)
My pleasure! Just happy to help :)
Bing Chat brought me here. Indeed, a very helpful article!
Just wanted to let you know that I've created a mini-course on fine-tuning GPT-3 models based on this blog post – feel free to check it out! https://norahsakal.gumroad.com/l/qwhwa
@LukaszWiktor
Thank you for checking it out Lukasz! Appreciate your feedback 🙏 @LukaszWiktor
Thanks for sharing. Btw, which tool do you use to generate the screenshots?
Thank you Tom! I'm using Keynote for all the screenshots 🙌
Like this ⬇️

Wow, very cool. I didn't know it before