ginipick commited on
Commit
0e0c015
ยท
verified ยท
1 Parent(s): d9c0fb0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -121
app.py CHANGED
@@ -32,13 +32,8 @@ except Exception as e:
32
  print("Continuing with limited functionality...")
33
 
34
  # ----------------------- Global Variables ----------------------- #
35
- VOICE_CHOICES = {
36
- '๐Ÿ‡บ๐Ÿ‡ธ Female (Default)': 'af',
37
- '๐Ÿ‡บ๐Ÿ‡ธ Bella': 'af_bella',
38
- '๐Ÿ‡บ๐Ÿ‡ธ Sarah': 'af_sarah',
39
- '๐Ÿ‡บ๐Ÿ‡ธ Nicole': 'af_nicole'
40
- }
41
- TTS_ENABLED = False # ๊ธฐ๋ณธ์ ์œผ๋กœ TTS ๋ชจ๋“ˆ ์ดˆ๊ธฐํ™” ์‹คํŒจ ์‹œ ๋น„ํ™œ์„ฑํ™”
42
 
43
  # ----------------------- Model and Tokenizer Initialization ----------------------- #
44
  model_name = "deepseek-ai/DeepSeek-R1-Distill-Llama-8B"
@@ -56,16 +51,8 @@ def init_models():
56
  return model
57
 
58
  # ----------------------- Kokoro TTS Initialization ----------------------- #
59
- try:
60
- import sys
61
- sys.path.append('Kokoro-82M')
62
- from models import build_model
63
- from kokoro import generate
64
-
65
- TTS_ENABLED = True
66
- except Exception as e:
67
- print(f"Warning: Could not initialize Kokoro TTS: {str(e)}")
68
- TTS_ENABLED = False
69
 
70
  # ----------------------- Web Search Functions ----------------------- #
71
  def get_web_results(query, max_results=5):
@@ -82,19 +69,18 @@ def get_web_results(query, max_results=5):
82
  return []
83
 
84
  def format_prompt(query, context):
 
85
  current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
86
- context_lines = '\n'.join([f'- [{res["title"]}]: {res["snippet"]}' for res in context])
87
- return f"""You are an intelligent search assistant. Answer the user's query using the provided web context.
88
  Current Time: {current_time}
89
 
90
- Important: For election-related queries, please distinguish clearly between different election years and types (presidential vs. non-presidential). Only use information from the provided web context.
91
-
92
  Query: {query}
93
 
94
  Web Context:
95
  {context_lines}
96
 
97
- Provide a detailed answer in markdown format. Include relevant information from sources and cite them using [1], [2], etc. If the query is about elections, clearly specify which year and type of election you're discussing.
98
  Answer:"""
99
 
100
  def format_sources(web_results):
@@ -144,96 +130,36 @@ def generate_answer(prompt):
144
  )
145
  return tokenizer.decode(outputs[0], skip_special_tokens=True)
146
 
147
- @spaces.GPU(duration=60)
148
- def generate_speech_with_gpu(text, voice_name='af'):
149
- try:
150
- device = 'cuda'
151
- TTS_MODEL = build_model('Kokoro-82M/kokoro-v0_19.pth', device)
152
- VOICEPACK = torch.load(f'Kokoro-82M/voices/{voice_name}.pt', weights_only=True).to(device)
153
-
154
- clean_text = ' '.join([line for line in text.split('\n') if not line.startswith('#')])
155
- clean_text = clean_text.replace('[', '').replace(']', '').replace('*', '')
156
-
157
- max_chars = 1000
158
- if len(clean_text) > max_chars:
159
- sentences = clean_text.split('.')
160
- chunks = []
161
- current_chunk = ""
162
- for sentence in sentences:
163
- if len(current_chunk) + len(sentence) < max_chars:
164
- current_chunk += sentence + "."
165
- else:
166
- if current_chunk:
167
- chunks.append(current_chunk)
168
- current_chunk = sentence + "."
169
- if current_chunk:
170
- chunks.append(current_chunk)
171
- else:
172
- chunks = [clean_text]
173
-
174
- audio_chunks = []
175
- for chunk in chunks:
176
- if chunk.strip():
177
- chunk_audio, _ = generate(TTS_MODEL, chunk.strip(), VOICEPACK, lang='a')
178
- if isinstance(chunk_audio, torch.Tensor):
179
- chunk_audio = chunk_audio.cpu().numpy()
180
- audio_chunks.append(chunk_audio)
181
-
182
- if audio_chunks:
183
- final_audio = np.concatenate(audio_chunks) if len(audio_chunks) > 1 else audio_chunks[0]
184
- return (24000, final_audio)
185
- return None
186
-
187
- except Exception as e:
188
- print(f"Error generating speech: {str(e)}")
189
- import traceback
190
- traceback.print_exc()
191
- return None
192
-
193
- def process_query(query, history, selected_voice='af'):
194
  try:
195
  if history is None:
196
  history = []
197
 
 
198
  web_results = get_web_results(query)
199
  sources_html = format_sources(web_results)
200
 
 
201
  current_history = history + [[query, "*Searching...*"]]
202
  yield {
203
- answer_output: gr.Markdown("*Searching & Thinking...*"),
204
  sources_output: gr.HTML(sources_html),
205
  search_btn: gr.Button("Searching...", interactive=False),
206
- chat_history_display: current_history,
207
- audio_output: None
208
  }
209
 
 
210
  prompt_text = format_prompt(query, web_results)
211
  answer = generate_answer(prompt_text)
212
  final_answer = answer.split("Answer:")[-1].strip()
213
 
214
- if TTS_ENABLED:
215
- try:
216
- yield {
217
- answer_output: gr.Markdown(final_answer),
218
- sources_output: gr.HTML(sources_html),
219
- search_btn: gr.Button("Generating audio...", interactive=False),
220
- chat_history_display: history + [[query, final_answer]],
221
- audio_output: None
222
- }
223
- audio = generate_speech_with_gpu(final_answer, selected_voice)
224
- except Exception as e:
225
- print(f"Error in speech generation: {str(e)}")
226
- audio = None
227
- else:
228
- audio = None
229
-
230
  updated_history = history + [[query, final_answer]]
231
  yield {
232
  answer_output: gr.Markdown(final_answer),
233
  sources_output: gr.HTML(sources_html),
234
  search_btn: gr.Button("Search", interactive=True),
235
- chat_history_display: updated_history,
236
- audio_output: audio if audio is not None else gr.Audio(value=None)
237
  }
238
  except Exception as e:
239
  error_message = str(e)
@@ -242,10 +168,9 @@ def process_query(query, history, selected_voice='af'):
242
 
243
  yield {
244
  answer_output: gr.Markdown(f"Error: {error_message}"),
245
- sources_output: gr.HTML(sources_html),
246
  search_btn: gr.Button("Search", interactive=True),
247
- chat_history_display: history + [[query, f"*Error: {error_message}*"]],
248
- audio_output: None
249
  }
250
 
251
  # ----------------------- Custom CSS for Bright UI ----------------------- #
@@ -260,7 +185,7 @@ css = """
260
  #header {
261
  text-align: center;
262
  padding: 2rem 0;
263
- background: #f0f8ff;
264
  border-radius: 12px;
265
  color: #333333;
266
  margin-bottom: 2rem;
@@ -385,20 +310,6 @@ css = """
385
  border: 1px solid #e0e0e0;
386
  }
387
 
388
- .voice-selector {
389
- margin-top: 1rem;
390
- background: #ffffff;
391
- border-radius: 8px;
392
- padding: 0.5rem;
393
- border: 1px solid #cccccc;
394
- }
395
-
396
- .voice-selector select {
397
- background: #ffffff !important;
398
- color: #333333 !important;
399
- border: 1px solid #cccccc !important;
400
- }
401
-
402
  footer {
403
  text-align: center;
404
  padding: 1rem 0;
@@ -413,7 +324,7 @@ with gr.Blocks(title="AI Search Assistant", css=css) as demo:
413
 
414
  with gr.Column(elem_id="header"):
415
  gr.Markdown("# ๐Ÿ” AI Search Assistant")
416
- gr.Markdown("### Powered by DeepSeek & Real-time Web Results with Voice")
417
 
418
  with gr.Column(elem_classes="search-container"):
419
  with gr.Row(elem_classes="search-box"):
@@ -424,19 +335,12 @@ with gr.Blocks(title="AI Search Assistant", css=css) as demo:
424
  container=False
425
  )
426
  search_btn = gr.Button("Search", variant="primary", scale=1)
427
- voice_select = gr.Dropdown(
428
- choices=list(VOICE_CHOICES.items()),
429
- value='af',
430
- label="Select Voice",
431
- elem_classes="voice-selector"
432
- )
433
 
434
  with gr.Row(elem_classes="results-container"):
435
  with gr.Column(scale=2):
436
  with gr.Column(elem_classes="answer-box"):
437
  answer_output = gr.Markdown()
438
- audio_output = gr.Audio(label="Voice Response")
439
- with gr.Accordion("Chat History", open=False, elem_classes="accordion"):
440
  chat_history_display = gr.Chatbot(elem_classes="chat-history")
441
  with gr.Column(scale=1):
442
  with gr.Column():
@@ -457,13 +361,13 @@ with gr.Blocks(title="AI Search Assistant", css=css) as demo:
457
 
458
  search_btn.click(
459
  fn=process_query,
460
- inputs=[search_input, chat_history, voice_select],
461
- outputs=[answer_output, sources_output, search_btn, chat_history_display, audio_output]
462
  )
463
  search_input.submit(
464
  fn=process_query,
465
- inputs=[search_input, chat_history, voice_select],
466
- outputs=[answer_output, sources_output, search_btn, chat_history_display, audio_output]
467
  )
468
 
469
  if __name__ == "__main__":
 
32
  print("Continuing with limited functionality...")
33
 
34
  # ----------------------- Global Variables ----------------------- #
35
+ # ์Œ์„ฑ ๊ด€๋ จ ๋ณ€์ˆ˜๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
36
+ # VOICE_CHOICES = { ... } --> ์ œ๊ฑฐ
 
 
 
 
 
37
 
38
  # ----------------------- Model and Tokenizer Initialization ----------------------- #
39
  model_name = "deepseek-ai/DeepSeek-R1-Distill-Llama-8B"
 
51
  return model
52
 
53
  # ----------------------- Kokoro TTS Initialization ----------------------- #
54
+ # ์Œ์„ฑ ๊ธฐ๋Šฅ ์ œ๊ฑฐ: TTS ์ดˆ๊ธฐํ™” ๊ด€๋ จ ์ฝ”๋“œ๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
55
+ TTS_ENABLED = False
 
 
 
 
 
 
 
 
56
 
57
  # ----------------------- Web Search Functions ----------------------- #
58
  def get_web_results(query, max_results=5):
 
69
  return []
70
 
71
  def format_prompt(query, context):
72
+ """์›น ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๊ฐ„๊ฒฐํ•˜๊ณ  ์š”์•ฝ๋œ ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•˜๋„๋ก ํ”„๋กฌํ”„ํŠธ๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค."""
73
  current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
74
+ context_lines = '\n'.join([f'- {res["title"]}: {res["snippet"]}' for res in context])
75
+ return f"""You are an intelligent search assistant. Your task is to provide a concise, clear summary answer to the user's query based solely on the provided web context.
76
  Current Time: {current_time}
77
 
 
 
78
  Query: {query}
79
 
80
  Web Context:
81
  {context_lines}
82
 
83
+ Please provide a summary answer in markdown format, including citations such as [1], [2], etc. in your answer if needed.
84
  Answer:"""
85
 
86
  def format_sources(web_results):
 
130
  )
131
  return tokenizer.decode(outputs[0], skip_special_tokens=True)
132
 
133
+ # ----------------------- Process Query and Output Summary ----------------------- #
134
+ def process_query(query, history):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  try:
136
  if history is None:
137
  history = []
138
 
139
+ # ์›น ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๊ฐ€์ ธ์˜ค๊ธฐ
140
  web_results = get_web_results(query)
141
  sources_html = format_sources(web_results)
142
 
143
+ # ์ค‘๊ฐ„ ์ƒํƒœ ํ‘œ์‹œ
144
  current_history = history + [[query, "*Searching...*"]]
145
  yield {
146
+ answer_output: gr.Markdown("*Searching & Summarizing...*"),
147
  sources_output: gr.HTML(sources_html),
148
  search_btn: gr.Button("Searching...", interactive=False),
149
+ chat_history_display: current_history
 
150
  }
151
 
152
+ # ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ: ์›น ๊ฒฐ๊ณผ๋ฅผ ์š”์•ฝํ•˜๋Š” ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑ
153
  prompt_text = format_prompt(query, web_results)
154
  answer = generate_answer(prompt_text)
155
  final_answer = answer.split("Answer:")[-1].strip()
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  updated_history = history + [[query, final_answer]]
158
  yield {
159
  answer_output: gr.Markdown(final_answer),
160
  sources_output: gr.HTML(sources_html),
161
  search_btn: gr.Button("Search", interactive=True),
162
+ chat_history_display: updated_history
 
163
  }
164
  except Exception as e:
165
  error_message = str(e)
 
168
 
169
  yield {
170
  answer_output: gr.Markdown(f"Error: {error_message}"),
171
+ sources_output: gr.HTML(""),
172
  search_btn: gr.Button("Search", interactive=True),
173
+ chat_history_display: history + [[query, f"*Error: {error_message}*"]]
 
174
  }
175
 
176
  # ----------------------- Custom CSS for Bright UI ----------------------- #
 
185
  #header {
186
  text-align: center;
187
  padding: 2rem 0;
188
+ background: #e3f2fd;
189
  border-radius: 12px;
190
  color: #333333;
191
  margin-bottom: 2rem;
 
310
  border: 1px solid #e0e0e0;
311
  }
312
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  footer {
314
  text-align: center;
315
  padding: 1rem 0;
 
324
 
325
  with gr.Column(elem_id="header"):
326
  gr.Markdown("# ๐Ÿ” AI Search Assistant")
327
+ gr.Markdown("### Powered by DeepSeek & Real-time Web Results")
328
 
329
  with gr.Column(elem_classes="search-container"):
330
  with gr.Row(elem_classes="search-box"):
 
335
  container=False
336
  )
337
  search_btn = gr.Button("Search", variant="primary", scale=1)
 
 
 
 
 
 
338
 
339
  with gr.Row(elem_classes="results-container"):
340
  with gr.Column(scale=2):
341
  with gr.Column(elem_classes="answer-box"):
342
  answer_output = gr.Markdown()
343
+ with gr.Accordion("Chat History", open=False):
 
344
  chat_history_display = gr.Chatbot(elem_classes="chat-history")
345
  with gr.Column(scale=1):
346
  with gr.Column():
 
361
 
362
  search_btn.click(
363
  fn=process_query,
364
+ inputs=[search_input, chat_history],
365
+ outputs=[answer_output, sources_output, search_btn, chat_history_display]
366
  )
367
  search_input.submit(
368
  fn=process_query,
369
+ inputs=[search_input, chat_history],
370
+ outputs=[answer_output, sources_output, search_btn, chat_history_display]
371
  )
372
 
373
  if __name__ == "__main__":