NANInithin commited on
Commit
855ae1e
·
1 Parent(s): d3f0718

feat: debugging asr and minicpm

Browse files
Files changed (2) hide show
  1. app.py +2 -1
  2. app/services/minicpm.py +22 -6
app.py CHANGED
@@ -1275,7 +1275,8 @@ with gr.Blocks(title="CityQuest · AI") as demo:
1275
  with gr.Row():
1276
  with gr.Column():
1277
  gr.HTML("<div class='section-label'>Voice journal</div>")
1278
- d_audio = gr.Audio(sources=["microphone"], type="filepath", label="Record")
 
1279
  d_lang = gr.Dropdown(
1280
  ["en", "fr", "de", "it", "es", "pt", "el", "nl", "pl",
1281
  "zh", "ja", "ko", "vi", "ar"],
 
1275
  with gr.Row():
1276
  with gr.Column():
1277
  gr.HTML("<div class='section-label'>Voice journal</div>")
1278
+ d_audio = gr.Audio(sources=["microphone", "upload"], type="filepath",
1279
+ format="wav", label="Record or upload audio")
1280
  d_lang = gr.Dropdown(
1281
  ["en", "fr", "de", "it", "es", "pt", "el", "nl", "pl",
1282
  "zh", "ja", "ko", "vi", "ar"],
app/services/minicpm.py CHANGED
@@ -123,7 +123,22 @@ def warm() -> bool:
123
  return _get_llm() is not None
124
 
125
 
126
- def ask(question: str, context: str = "", max_tokens: int = 320) -> Optional[str]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  """In-game MiniCPM helper: answer a player's question (clue / explain a
128
  task / tell me about this place). Returns plain text, or ``None`` if the
129
  model is unavailable so the caller can show a graceful fallback."""
@@ -134,7 +149,7 @@ def ask(question: str, context: str = "", max_tokens: int = 320) -> Optional[str
134
  "You are CityQuest's friendly in-game guide for a real-world city "
135
  "adventure game. Give a short, warm, practical answer (2-4 sentences). "
136
  "Help with clues, understanding tasks, and local places. Never reveal "
137
- "winners or scores. Plain text only."
138
  )
139
  user = question if not context else f"Context:\n{context}\n\nQuestion: {question}"
140
 
@@ -145,8 +160,9 @@ def ask(question: str, context: str = "", max_tokens: int = 320) -> Optional[str
145
  {"role": "user", "content": user}],
146
  max_tokens=max_tokens, temperature=0.6, top_p=0.9,
147
  )
148
- text = (result["choices"][0]["message"]["content"] or "").strip()
149
- print(f"[minicpm] ask(chat) len={len(text)} preview={text[:80]!r}")
 
150
  if text:
151
  return text
152
  except Exception as e:
@@ -164,8 +180,8 @@ def ask(question: str, context: str = "", max_tokens: int = 320) -> Optional[str
164
  prompt, max_tokens=max_tokens, temperature=0.6, top_p=0.9,
165
  stop=["<|im_end|>", "<|im_start|>", "</s>"],
166
  )
167
- text = (out["choices"][0]["text"] or "").strip()
168
- print(f"[minicpm] ask(raw) len={len(text)} preview={text[:80]!r}")
169
  return text or None
170
  except Exception as e:
171
  print(f"[minicpm] ask(raw) failed: {type(e).__name__}: {e}")
 
123
  return _get_llm() is not None
124
 
125
 
126
+ def _strip_think(text: str) -> str:
127
+ """Remove MiniCPM5 reasoning blocks.
128
+
129
+ MiniCPM5 is a reasoning model that emits ``<think>…</think>`` before its
130
+ answer. Those tags render invisibly in Markdown (they look like HTML), so
131
+ we drop the whole block and keep only the final answer. Also handles an
132
+ unclosed ``<think>`` (answer was truncated by max_tokens).
133
+ """
134
+ import re
135
+ text = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL | re.IGNORECASE)
136
+ # If a think block was opened but never closed (truncation), drop the rest.
137
+ text = re.sub(r"<think>.*$", "", text, flags=re.DOTALL | re.IGNORECASE)
138
+ return text.strip()
139
+
140
+
141
+ def ask(question: str, context: str = "", max_tokens: int = 640) -> Optional[str]:
142
  """In-game MiniCPM helper: answer a player's question (clue / explain a
143
  task / tell me about this place). Returns plain text, or ``None`` if the
144
  model is unavailable so the caller can show a graceful fallback."""
 
149
  "You are CityQuest's friendly in-game guide for a real-world city "
150
  "adventure game. Give a short, warm, practical answer (2-4 sentences). "
151
  "Help with clues, understanding tasks, and local places. Never reveal "
152
+ "winners or scores. Plain text only. Do not show your reasoning."
153
  )
154
  user = question if not context else f"Context:\n{context}\n\nQuestion: {question}"
155
 
 
160
  {"role": "user", "content": user}],
161
  max_tokens=max_tokens, temperature=0.6, top_p=0.9,
162
  )
163
+ raw = (result["choices"][0]["message"]["content"] or "").strip()
164
+ text = _strip_think(raw)
165
+ print(f"[minicpm] ask(chat) raw_len={len(raw)} answer_len={len(text)} preview={text[:80]!r}")
166
  if text:
167
  return text
168
  except Exception as e:
 
180
  prompt, max_tokens=max_tokens, temperature=0.6, top_p=0.9,
181
  stop=["<|im_end|>", "<|im_start|>", "</s>"],
182
  )
183
+ text = _strip_think((out["choices"][0]["text"] or "").strip())
184
+ print(f"[minicpm] ask(raw) answer_len={len(text)} preview={text[:80]!r}")
185
  return text or None
186
  except Exception as e:
187
  print(f"[minicpm] ask(raw) failed: {type(e).__name__}: {e}")