Fine-tuning OpenAI GPT-3 to build Custom Chatbot

Olasimbo Arigbabu, PhD
6 min readJan 25, 2023

Introduction

Chatbots or digital assistants are applications designed to simulate conversation with humans in the form of text or voice chat over the internet. Advances in chatbot development have progressed rapidly over the years, from simple logic-based bots to those that are now based on natural language understanding (NLU). With regard to the latter, some of the most common frameworks or libraries used for building such chatbots are RASA, Dialogflow, and Amazon Lex, to name a few. These frameworks can apply natural language processing (NLP) and NLU to process input text, classify intents, and trigger the right actions to generate a response.

Photo by William Navarro on Unsplash

With the advent of large language models (LLM), we can directly build fully functional chatbots using these models. A well-known example of such LLM is Generative Pre-trained Transformer 3 (GPT-3) from OpenAI, which can generate human-like texts by fine-tuning dialogue or conversation data with the model. This capability makes it a suitable choice for building a custom chatbot and this article explores the processes involved in fine-tuning the GPT-3 model to build a simple conversational chatbot.

Typically, we would want to fine-tune the model on a dataset of conversational examples such as transcripts from customer service interactions, chat logs, or several scenes of a movie. The fine-tuning process adjusts the model’s parameters to better fit the conversational data, making the chatbot more adept at understanding and replying to user inputs.

To fine-tune GPT-3, we can use the Transformers library from Hugging Face, which provides pre-trained models and tools for fine-tuning. The library offers several GPT-3 models with different sizes and capabilities. The larger the model, the more data it can handle and the more accurate it is likely to be. However, for the sake of simplicity, we would use the OpenAI interface and write very few lines of code to get this working.

In this article, we will build an Interview Digital Assistant using OpenAI GPT-3 with a dataset retrieved from this repo.

Getting Access to OpenAI

Creating an account is pretty straightforward, which can be done using this link. But, what we are interested in is getting the API key to allow us to access the models on OpenAI. Hence, you can follow these steps to get the API key:

  • Log in to your account
  • Go to the top right corner of the page, and click your account name, you will get a drop-down, then click on "View API Keys"
OpenAI User Account Page
  • Click on "Create new secret key". Ensure you immediately copy the generated key and save it in a secure file (we will need it later), or else you won't be able to view it again.

Preparing the Data

Since we are done with creating the account and API key, let's get started with preparing the data that will be used to fine-tune the model. We collected the dataset from a Github repository which mainly contains interview questions and answers.

Sample interview questions and answers

The first step is to install the OpenAI library in our project using pip install openai

Once installed, we can load the data:

import os
import json

import openai
import pandas as pd

from dotenv import load_dotenv

load_dotenv()

os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_KEY')

openai.api_key = os.getenv('OPENAI_KEY')

data = pd.read_csv('data/data.csv')

new_df = pd.DataFrame({'Interview AI': data['Text'].iloc[::2].values, 'Human': data['Text'].iloc[1::2].values})
print(new_df.head(5))

We load the questions into Interview AI column and the corresponding answers into Human column in a dataframe. We also created an environment variable .env file to hold theOPENAI_API_KEY

Next, we convert the data to a standard acceptable by GPT-3. According to the documentation it is important to ensure the data is in JSONL format having two keys: prompt and completion e.g

{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}

Hence, we re-structure the dataset to fit into this design, where we basically loop through each row in the dataframe and assign the Human text to prompt and Interview AItext to completion.

output = []
for index, row in new_df.iterrows():
print(row)
completion = ''
line = {'prompt': row['Human'], 'completion': row['Interview AI']}

output.append(line)

print(output)

with open('data/data.jsonl', 'w') as outfile:
for i in output:
json.dump(i, outfile)
outfile.write('\n')

We then need to use prepare_datacommand, but it will ask some questions at the prompt, which we can provide Y or N response to.

os.system("openai tools fine_tunes.prepare_data -f 'data/data.jsonl' ")

Finally, a file named data_prepared.jsonl is dumped in the directory.

Model Finetuning

To fine-tune the model we need to run a single line of command:

os.system("openai api fine_tunes.create -t 'data/data_prepared.jsonl' -m davinci ")

This basically uses the prepared data to train the davinci model from OpenAI and the fine-tuned model will be stored under the user profile, which can be found in the right panel under Model

OpenAI Playground

Interacting with the model

We can use different approaches to chat with the model. We can directly chat with the model from our Python script, OpenAI Playground or build a web service around the model using frameworks such as Flask or FastAPI.

We will build a simple function to interact with the model for this experiment.

def generate_response(input_text):
response = openai.Completion.create(
engine="davinci:ft-personal-2023-01-25-19-20-17",
prompt="The following is a conversation with DSA an AI assistant. "
"DSA is an interview bot who is very helpful and knowledgeable in data structure and algorithms.\n\n"
"Human: Hello, who are you?\n"
"DSA: I am DSA, an interview digital assistant. How can I help you today?\n"
"Human: {}\nDSA:".format(input_text),
temperature=0.9,
max_tokens=150,
top_p=1,
frequency_penalty=0.0,
presence_penalty=0.6,
stop=["\n", " Human:", " DSA:"]
)
return response.choices[0].text.strip()

output = generate_response(input_text)
print(output)

Putting it all together

import os
import json

import openai
import pandas as pd

from dotenv import load_dotenv

load_dotenv()

os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_KEY')

openai.api_key = os.getenv('OPENAI_KEY')

data = pd.read_csv('data/data.csv')

new_df = pd.DataFrame({'Interview AI': data['Text'].iloc[::2].values, 'Human': data['Text'].iloc[1::2].values})
print(new_df.head(5))

output = []
for index, row in new_df.iterrows():
print(row)
completion = ''
line = {'prompt': row['Human'], 'completion': row['Interview AI']}

output.append(line)

print(output)

with open('data/data.jsonl', 'w') as outfile:
for i in output:
json.dump(i, outfile)
outfile.write('\n')

os.system("openai tools fine_tunes.prepare_data -f 'data/data.jsonl' ")

os.system("openai api fine_tunes.create -t 'data/data_prepared.jsonl' -m davinci ")


def generate_response(input_text):
response = openai.Completion.create(
engine="davinci:ft-personal-2023-01-25-19-20-17",
prompt="The following is a conversation with DSA an AI assistant. "
"DSA is an interview bot who is very helpful and knowledgeable in data structure and algorithms.\n\n"
"Human: Hello, who are you?\n"
"DSA: I am DSA, an interview digital assistant. How can I help you today?\n"
"Human: {}\nDSA:".format(input_text),
temperature=0.9,
max_tokens=150,
top_p=1,
frequency_penalty=0.0,
presence_penalty=0.6,
stop=["\n", " Human:", " DSA:"]
)
return response.choices[0].text.strip()

Example response:

input_text = "what is breadth first search algorithm"
output = generate_response(input_text)
The breadth-first search (BFS) is an algorithm for discovering all the 
reachable nodes from a starting point in a computer network graph or tree data
structure

Conclusion

GPT-3 is a powerful large language generation model that can be fine-tuned to build a custom chatbot. The fine-tuning process adjusts the model’s parameters to better fit conversational data, making the chatbot more adept at understanding and responding to user inputs. The fine-tuned model can be integrated into a chatbot platform to handle user interactions and also generate human-like text for the chatbot to interact with the user. The entire implementation can be found here and the dataset can be downloaded from here.

--

--

Olasimbo Arigbabu, PhD

Machine learning, 3D medical image processing, NLP, conversational AI, CV, speech recognition