awacke1 commited on
Commit
fbd3a0e
·
verified ·
1 Parent(s): c54308c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +170 -0
app.py ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import edge_tts
3
+ import asyncio
4
+ import tempfile
5
+ import os
6
+ from huggingface_hub import InferenceClient
7
+ import re
8
+ from streaming_stt_nemo import Model
9
+ import torch
10
+ import random
11
+ import pandas as pd
12
+ from datetime import datetime
13
+ import base64
14
+ import io
15
+ import json
16
+
17
+ default_lang = "en"
18
+ engines = { default_lang: Model(default_lang) }
19
+
20
+ def transcribe(audio):
21
+ lang = "en"
22
+ model = engines[lang]
23
+ text = model.stt_file(audio)[0]
24
+ return text
25
+
26
+ HF_TOKEN = os.environ.get("HF_TOKEN", None)
27
+
28
+ def client_fn(model):
29
+ if "Mixtral" in model:
30
+ return InferenceClient("mistralai/Mixtral-8x7B-Instruct-v0.1")
31
+ elif "Llama" in model:
32
+ return InferenceClient("meta-llama/Meta-Llama-3-8B-Instruct")
33
+ elif "Mistral" in model:
34
+ return InferenceClient("mistralai/Mistral-7B-Instruct-v0.2")
35
+ elif "Phi" in model:
36
+ return InferenceClient("microsoft/Phi-3-mini-4k-instruct")
37
+ else:
38
+ return InferenceClient("microsoft/Phi-3-mini-4k-instruct")
39
+
40
+ def randomize_seed_fn(seed: int) -> int:
41
+ seed = random.randint(0, 999999)
42
+ return seed
43
+
44
+ system_instructions1 = """
45
+ [SYSTEM] Answer as Real Jarvis JARVIS, Made by 'Tony Stark.'
46
+ Keep conversation friendly, short, clear, and concise.
47
+ Avoid unnecessary introductions and answer the user's questions directly.
48
+ Respond in a normal, conversational manner while being friendly and helpful.
49
+ [USER]
50
+ """
51
+
52
+ # Initialize an empty DataFrame to store the history
53
+ history_df = pd.DataFrame(columns=['Timestamp', 'Request', 'Response'])
54
+
55
+ def save_history():
56
+ history_df.to_json('chat_history.json', orient='records')
57
+
58
+ def load_history():
59
+ global history_df
60
+ try:
61
+ history_df = pd.read_json('chat_history.json', orient='records')
62
+ except FileNotFoundError:
63
+ history_df = pd.DataFrame(columns=['Timestamp', 'Request', 'Response'])
64
+ return history_df
65
+
66
+ def models(text, model="Mixtral 8x7B", seed=42):
67
+ global history_df
68
+
69
+ seed = int(randomize_seed_fn(seed))
70
+ generator = torch.Generator().manual_seed(seed)
71
+
72
+ client = client_fn(model)
73
+
74
+ generate_kwargs = dict(
75
+ max_new_tokens=300,
76
+ seed=seed
77
+ )
78
+ formatted_prompt = system_instructions1 + text + "[JARVIS]"
79
+ stream = client.text_generation(
80
+ formatted_prompt, **generate_kwargs, stream=True, details=True, return_full_text=False)
81
+ output = ""
82
+ for response in stream:
83
+ if not response.token.text == "</s>":
84
+ output += response.token.text
85
+
86
+ # Add the current interaction to the history DataFrame
87
+ new_row = pd.DataFrame({
88
+ 'Timestamp': [datetime.now().strftime("%Y-%m-%d %H:%M:%S")], # Convert to string
89
+ 'Request': [text],
90
+ 'Response': [output]
91
+ })
92
+ history_df = pd.concat([history_df, new_row], ignore_index=True)
93
+ save_history()
94
+
95
+ return output
96
+
97
+ async def respond(audio, model, seed):
98
+ user = transcribe(audio)
99
+ reply = models(user, model, seed)
100
+ communicate = edge_tts.Communicate(reply)
101
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp_file:
102
+ tmp_path = tmp_file.name
103
+ await communicate.save(tmp_path)
104
+ return tmp_path, gr.Audio.update(interactive=True)
105
+
106
+ def display_history():
107
+ return load_history()
108
+
109
+ def download_history():
110
+ csv_buffer = io.StringIO()
111
+ history_df.to_csv(csv_buffer, index=False)
112
+ csv_string = csv_buffer.getvalue()
113
+ b64 = base64.b64encode(csv_string.encode()).decode()
114
+ href = f'data:text/csv;base64,{b64}'
115
+ return gr.HTML(f'<a href="{href}" download="chat_history.csv">Download Chat History</a>')
116
+
117
+ DESCRIPTION = """ # <center><b>JARVIS⚡</b></center>
118
+ ### <center>A personal Assistant of Tony Stark for YOU
119
+ ### <center>Voice Chat with your personal Assistant</center>
120
+ """
121
+
122
+ with gr.Blocks(css="style.css") as demo:
123
+ gr.Markdown(DESCRIPTION)
124
+ with gr.Row():
125
+ select = gr.Dropdown([
126
+ 'Mixtral 8x7B',
127
+ 'Llama 3 8B',
128
+ 'Mistral 7B v0.3',
129
+ 'Phi 3 mini',
130
+ ],
131
+ value="Mistral 7B v0.3",
132
+ label="Model"
133
+ )
134
+ seed = gr.Slider(
135
+ label="Seed",
136
+ minimum=0,
137
+ maximum=999999,
138
+ step=1,
139
+ value=0,
140
+ visible=False
141
+ )
142
+
143
+ input_audio = gr.Audio(label="User", sources="microphone", type="filepath")
144
+ output_audio = gr.Audio(label="AI", type="filepath", autoplay=True)
145
+
146
+ # Add a DataFrame to display the history
147
+ history_display = gr.DataFrame(label="Query History")
148
+
149
+ # Add a download button for the history
150
+ download_button = gr.Button("Download History")
151
+ download_link = gr.HTML()
152
+
153
+ def process_audio(audio, model, seed):
154
+ response, audio_update = asyncio.run(respond(audio, model, seed))
155
+ return response, audio_update, display_history()
156
+
157
+ input_audio.change(
158
+ fn=process_audio,
159
+ inputs=[input_audio, select, seed],
160
+ outputs=[output_audio, input_audio, history_display]
161
+ )
162
+
163
+ # Connect the download button to the download function
164
+ download_button.click(fn=download_history, outputs=[download_link])
165
+
166
+ # Load history when the page is refreshed
167
+ demo.load(fn=display_history, outputs=[history_display])
168
+
169
+ if __name__ == "__main__":
170
+ demo.queue(max_size=200).launch(share=True)