Spaces:
Running
Running
# %% [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" | |
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 | |
# Build the app | |
with gr.Blocks(theme='Insuz/Mocha') as app: | |
with gr.Row(): | |
with gr.Column(scale = 1): | |
with gr.Accordion(label="Advanced options", open=True): | |
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" | |
) | |
with gr.Column(scale = 8): | |
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] | |
) | |
gr.close_all() | |
app.queue().launch(auth=(AUTH_USERNAME, AUTH_PASSWORD)) | |
# app.queue().launch() | |
# %% | |