File size: 5,082 Bytes
18b090f
 
 
 
 
 
 
 
 
3ce50f4
18b090f
 
3d015f3
18b090f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43eb109
18b090f
753aacd
18b090f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3ce50f4
18b090f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86f71f5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18b090f
 
3ce50f4
86f71f5
3ce50f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86f71f5
 
 
 
 
 
18b090f
3ce50f4
 
18b090f
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# %% [markdown]
# # ChatBot app with Gradio

# %%
import os
from dotenv import load_dotenv, find_dotenv
import gradio as gr
import openai

_ = load_dotenv(find_dotenv(filename="secrets.env", raise_error_if_not_found=False))

# Global variable
# ROOT_DIR = os.environ["ROOT_DIR"]
AUTH_USERNAME = os.environ["AUTH_USERNAME"]
AUTH_PASSWORD = os.environ["AUTH_PASSWORD"]

# Load credentials
openai.api_key = os.environ["OPENAI_API_KEY"]

SYSTEM_PROMPT = "You are a helpful assistant and do your best to answer the user's questions.\
	You do not make up answers."

# %% [markdown]
# ## Define and test the API calls

# %%
# define the function that will make the API calls 
def APIcall(prompt:str, temperature = 0.7, max_tokens = 1024, model="GPT-3.5", stream=True):
	if model == "GPT-3.5":
		model = "gpt-3.5-turbo-0125"
	else:
		model = "gpt-4-turbo-preview"
	# make the API call with the given parameter
	response = openai.chat.completions.create(
		model=model,
		messages=prompt,
		max_tokens = max_tokens,
		temperature=temperature,
		stream=stream,
	)

	# return the completed text
	if stream:
		for chunk in response:
			output = chunk.choices[0].delta.content # when Stream is set to True
			yield output
	else:
		output = response.choices[0].message.content # when Stream is set to False


# %% [markdown]
# ## Building the ChatBot with Gradio

# %%
# Helper function: format the prompt to include history
def formatPrompt(newMsg:str, chatHistory, instruction):
	
	# start with the system prompt
	messages = []
	messages.append({
		"role": "system",
		"content": instruction
	})

	# add the history
	for turn in chatHistory:
		# retrieve the user and assistant messages from history
		userMsg, AssistantMsg = turn
		
		# add the user message
		messages.append({
			"role": "user",
			"content": userMsg
		})

		# add the assistant message
		messages.append({
			"role": "assistant",
			"content": AssistantMsg
		})
	
	# add the last message that needs to be answer
	messages.append({
		"role": "user",
		"content": newMsg
	})

	# return the formated messages 
	return messages

# def the response function (to get the answer as one block after generation)
def response(newMsg:str, chatHistory, instruction, temperature, max_tokens, model, stream=False):
	prompt = formatPrompt(newMsg=newMsg, chatHistory=chatHistory, instruction=instruction)
	response = APIcall(prompt=prompt, temperature=temperature, max_tokens=max_tokens, model=model)
	chatHistory.append([newMsg, response])
	return "", chatHistory

# def the streamResponse function, to stream the results as they are generated
def streamResponse(newMsg:str, chatHistory, instruction, temperature, max_tokens, model, stream = True):
	chatHistory.append([newMsg, ""])
	prompt = formatPrompt(newMsg=newMsg, chatHistory=chatHistory, instruction=instruction)
	stream = APIcall(prompt=prompt, temperature=temperature, max_tokens=max_tokens, model=model)
	for chunk in stream:
		if chunk != None:
			chatHistory[-1][1] += chunk
			yield "", chatHistory
		else:
			return "", chatHistory

# Define some components
model = gr.Dropdown(
	choices=["GPT-3.5", "GPT-4"],
	value="GPT-3.5",
	multiselect=False,
	label="Model",
	info="Choose the model you want to chat with.\nGo easy on GPT-4: it costs 500 times more than GPT 3.5!"
)
instruction = gr.Textbox(
	value=SYSTEM_PROMPT,
	label="System instructions",
	lines=4,)
temperature = gr.Slider(
	minimum=0,
	maximum=2,
	step=0.1,
	value=0.7,
	label="Temperature",
	info="The higher, the more random the results will be"
)
max_token = gr.Slider(
	minimum=64,
	maximum=2048,
	step=64,
	value=1024,
	label="Max Token",
	info="Maximum number of token the model will take into consideration"
)

# Build the app
with gr.Blocks(theme='Insuz/Mocha') as app:
	with gr.Row():
		with gr.Column(scale = 8, elem_classes=["float-left"]):
			gr.Markdown("# Private GPT")
			gr.Markdown("This chatbot is powered by the openAI GPT series.\
					The default model is `GPT-3.5`, but `GPT-4` can be selected in the advanced options.\
					\nAs it uses the openAI API, user data is not used to train openAI models (see their official [website](https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance)).")
			chatbot = gr.Chatbot() # Associated variable: chatHistory
			msg = gr.Textbox(label="Message")
			with gr.Row():
				with gr.Column(scale=4):
					Button = gr.Button(value="Submit")
				with gr.Column(scale=4):
					clearButton = gr.ClearButton([chatbot, msg])
			msg.submit(
				fn=streamResponse,
				inputs=[msg, chatbot, instruction, temperature, max_token, model],
				outputs=[msg, chatbot]
			)
			Button.click(
				fn=streamResponse,
				inputs=[msg, chatbot, instruction, temperature, max_token, model],
				outputs=[msg, chatbot]
			)
		with gr.Column(scale = 1, elem_classes=["float-right"]):
			with gr.Accordion(label="Advanced options", open=True):
				model.render()
				instruction.render()
				temperature.render()
				max_token.render()
gr.close_all()
app.queue().launch(auth=(AUTH_USERNAME, AUTH_PASSWORD))
# app.queue().launch()

# %%