Skip to content

Commit 8d9b34b

Browse files
authored
fix(server): report detected transcription language (#3400)
1 parent 6c3b47c commit 8d9b34b

2 files changed

Lines changed: 54 additions & 3 deletions

File tree

funasr/bin/_server_app.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@
2626
logger = logging.getLogger("funasr.server")
2727

2828

29+
_LANGUAGE_TAG_RE = re.compile(r"<\|(zh|en|yue|ja|ko)\|>")
30+
31+
32+
def extract_language_from_asr_text(text):
33+
"""Extract a SenseVoice language code before special tokens are removed."""
34+
if not isinstance(text, str):
35+
return None
36+
match = _LANGUAGE_TAG_RE.search(text)
37+
return match.group(1) if match else None
38+
39+
40+
def resolve_transcription_language(requested_language, result):
41+
"""Prefer the caller's language hint, then backend detection, else unknown."""
42+
if requested_language and requested_language.strip().lower() != "auto":
43+
return requested_language
44+
detected_language = result.get("language")
45+
if isinstance(detected_language, str) and detected_language:
46+
return detected_language
47+
return "unknown"
48+
49+
2950
def _split_text_for_openai_segments(text: str, max_chars: int = 80):
3051
"""Split unsegmented ASR text into readable OpenAI-compatible cues."""
3152
text = text.strip()
@@ -255,7 +276,9 @@ def _process_fallback(model_name, audio_path, language=None):
255276
if language:
256277
kwargs["language"] = language
257278
result = model.generate(**kwargs)
258-
text = re.sub(r'<\|[^|]*\|>', '', result[0]["text"]).strip()
279+
raw_text = result[0]["text"]
280+
detected_language = extract_language_from_asr_text(raw_text)
281+
text = re.sub(r'<\|[^|]*\|>', '', raw_text).strip()
259282
segments = []
260283
if "sentence_info" in result[0]:
261284
for s in result[0]["sentence_info"]:
@@ -267,7 +290,12 @@ def _process_fallback(model_name, audio_path, language=None):
267290
})
268291
if not segments and text:
269292
segments = build_openai_fallback_segments(text, duration)
270-
return {"text": text, "segments": segments, "duration": duration}
293+
return {
294+
"text": text,
295+
"segments": segments,
296+
"duration": duration,
297+
"language": detected_language,
298+
}
271299

272300
# Pre-load
273301
if app.state.model_path:
@@ -322,7 +350,7 @@ async def transcribe(
322350
if response_format == "verbose_json":
323351
return JSONResponse({
324352
"task": "transcribe",
325-
"language": language or "zh",
353+
"language": resolve_transcription_language(language, result),
326354
"duration": result.get("duration", 0),
327355
"text": result["text"],
328356
"segments": [

tests/test_server_app_openai_segments.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,29 @@ def test_fallback_segments_keep_short_text_single_cue(monkeypatch):
103103
]
104104

105105

106+
def test_extract_language_from_sensevoice_text(monkeypatch):
107+
module = load_server_app(monkeypatch)
108+
109+
assert module.extract_language_from_asr_text("<|en|><|NEUTRAL|><|Speech|>hello") == "en"
110+
assert module.extract_language_from_asr_text("<|yue|> nei hou") == "yue"
111+
assert module.extract_language_from_asr_text("plain transcript") is None
112+
113+
114+
def test_resolve_transcription_language_prefers_request_then_detection(monkeypatch):
115+
module = load_server_app(monkeypatch)
116+
117+
assert module.resolve_transcription_language("ja", {"language": "en"}) == "ja"
118+
assert module.resolve_transcription_language("auto", {"language": "en"}) == "en"
119+
assert module.resolve_transcription_language(None, {"language": "ko"}) == "ko"
120+
assert module.resolve_transcription_language(None, {}) == "unknown"
121+
122+
123+
def test_resolve_transcription_language_does_not_default_to_chinese(monkeypatch):
124+
module = load_server_app(monkeypatch)
125+
126+
assert module.resolve_transcription_language(None, {}) != "zh"
127+
128+
106129
def test_default_fun_asr_nano_uses_requested_modelscope_hub(monkeypatch):
107130
module = load_server_app(monkeypatch)
108131
DummyAutoModel = install_dummy_funasr(monkeypatch)

0 commit comments

Comments
 (0)