Jiaqi-hkust commited on
Commit
b44b983
·
verified ·
1 Parent(s): 3abeae0

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +38 -42
app.py CHANGED
@@ -197,70 +197,66 @@ def _history_to_messages(history):
197
 
198
  # ==========================================
199
  @gpu_decorator
200
- def respond(user_msg, history, temp, tokens):
201
  """
202
- user_msg: {'text': '...', 'files': ['...']}
203
- history: List[List[str | None]] <- 这是旧版格式
204
  """
205
- files = user_msg.get("files", [])
206
- text = user_msg.get("text", "")
207
 
208
- # 1. 更新 UI History (先让用户在界面上看到自己的输入)
209
- # -------------------------------------------------
210
 
211
- # 先处理图片:每张图片作为一个单独的 (path, None) 元组添加到历史
212
- # Gradio Chatbot 会自动识别路径并显示图片
213
- for f in files:
214
- history.append([f, None])
215
 
216
- # 再处理文本
 
217
  if text:
218
- # 如果有文本,添加 (text, None),准备让机器人回复这一条
219
- history.append([text, None])
220
- elif not text and files:
221
- # 如果只有图片没文本,添加一个空的占位符,让机器人回复图片
222
- # 注意:这里我们用 (None, None) 可能会报错,用 ("(image uploaded)", None) 或者
223
- # 更常见的做法是:最后一项的 user 部分必须非空才能看起来正常,
224
- # 但我们可以在下面立即生成回复填补 bot 部分。
225
- pass
226
 
227
- # 此时 history 已经更新了用户的输入
 
 
 
 
 
 
 
 
 
228
  yield history, gr.MultimodalTextbox(value=None, interactive=False)
229
 
230
- # 2. 调用模型
231
- # -------------------------------------------------
232
  try:
233
  handler = get_model_handler()
234
 
235
- # Tuple 历史转换为模型能懂的 Messages 列表
236
- # 注意:我们需要把刚才加入的“只有用户部分”的消息也转进去
237
- messages = _history_to_messages(history)
 
 
 
238
 
239
- # 在界面上为机器人的回复预留位置
240
- # 如果最后一条是 [user_content, None],我们把它改成 [user_content, ""]
241
- if history and history[-1][1] is None:
242
- history[-1][1] = ""
243
- else:
244
- # 如果万一没有对应行,加一行
245
- history.append([None, ""])
246
-
247
- # 流式生成
248
  full_response = ""
249
- for chunk in handler.predict(messages, temp, tokens):
250
  full_response += chunk
251
- history[-1][1] = full_response # 更新最后一行机器人的回复
 
252
  yield history, gr.MultimodalTextbox(interactive=False)
253
 
254
  except Exception as e:
255
  import traceback
256
  traceback.print_exc()
257
- err_msg = f"❌ Error: {str(e)}"
258
- if history and history[-1][1] is None:
259
- history[-1][1] = err_msg
260
  else:
261
- history.append([None, err_msg])
 
262
  yield history, gr.MultimodalTextbox(interactive=True)
263
 
 
264
  yield history, gr.MultimodalTextbox(interactive=True)
265
 
266
  def create_chat_ui():
@@ -280,7 +276,7 @@ def create_chat_ui():
280
  elem_id="chatbot",
281
  label="Chat",
282
  avatar_images=(None, "https://api.dicebear.com/7.x/bottts/svg?seed=Qwen"),
283
- height=650,
284
  )
285
 
286
  chat_input = gr.MultimodalTextbox(
 
197
 
198
  # ==========================================
199
  @gpu_decorator
200
+ def respond(user_input, history, temp, tokens):
201
  """
202
+ user_input: MultimodalTextbox 返回的字典 {'text': '...', 'files': [...]}
203
+ history: 这里的 history 是 Gradio 自动维护的 [{'role': 'user', ...}, ...] 列表
204
  """
 
 
205
 
206
+ # 1. 构建当前用户的消息对象
207
+ user_content = []
208
 
209
+ # 处理图片
210
+ files = user_input.get("files", [])
211
+ for file_path in files:
212
+ user_content.append({"type": "image", "image": file_path})
213
 
214
+ # 处理文本
215
+ text = user_input.get("text", "")
216
  if text:
217
+ user_content.append({"type": "text", "text": text})
 
 
 
 
 
 
 
218
 
219
+ # 如果没有内容,直接返回
220
+ if not user_content:
221
+ yield history, gr.MultimodalTextbox(interactive=True)
222
+ return
223
+
224
+ # 2. 将用户消息加入历史
225
+ # 注意:history 必须是 [{'role': 'user', 'content': [...]}, ...] 格式
226
+ history.append({"role": "user", "content": user_content})
227
+
228
+ # 立即更新 UI,清空输入框
229
  yield history, gr.MultimodalTextbox(value=None, interactive=False)
230
 
 
 
231
  try:
232
  handler = get_model_handler()
233
 
234
+ # 3. 预先加入一个空的助手消息,用于流式显示
235
+ history.append({"role": "assistant", "content": ""})
236
+
237
+ # 4. 调用模型
238
+ # 我们传入 history 的副本(不包含刚才加的空 assistant),以免污染
239
+ input_messages = copy.deepcopy(history[:-1])
240
 
 
 
 
 
 
 
 
 
 
241
  full_response = ""
242
+ for chunk in handler.predict(input_messages, temp, tokens):
243
  full_response += chunk
244
+ # 实时更新最后一条消息的内容
245
+ history[-1]["content"] = full_response
246
  yield history, gr.MultimodalTextbox(interactive=False)
247
 
248
  except Exception as e:
249
  import traceback
250
  traceback.print_exc()
251
+ # 出错时显示错误信息
252
+ if history and history[-1]["role"] == "assistant":
253
+ history[-1]["content"] += f"\n❌ Error: {str(e)}"
254
  else:
255
+ history.append({"role": "assistant", "content": f"❌ Error: {str(e)}"})
256
+
257
  yield history, gr.MultimodalTextbox(interactive=True)
258
 
259
+ # 最后恢复输入框
260
  yield history, gr.MultimodalTextbox(interactive=True)
261
 
262
  def create_chat_ui():
 
276
  elem_id="chatbot",
277
  label="Chat",
278
  avatar_images=(None, "https://api.dicebear.com/7.x/bottts/svg?seed=Qwen"),
279
+ height=650
280
  )
281
 
282
  chat_input = gr.MultimodalTextbox(