From 217fdd2234519f2cb052c9a0789008f964c9e6b4 Mon Sep 17 00:00:00 2001 From: Tai An Date: Sun, 19 Jul 2026 13:00:23 -0700 Subject: [PATCH] fix(qwen-asr): map ISO language codes to the names Qwen3-ASR expects (#10959) request.language usually carries an ISO 639-1 code (e.g. "de"), which OpenAI-compatible clients such as Home Assistant / wyoming_openai send, but qwen_asr.validate_language() only accepts full English names ("German") and raises ValueError otherwise. Normalize the requested language: accept full names case-insensitively, translate ISO codes (with optional region suffix like "de-DE") to the expected name, and pass anything unrecognised through so qwen_asr still reports it clearly. Fixes #10958 Signed-off-by: Tai An --- backend/python/qwen-asr/backend.py | 53 ++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/backend/python/qwen-asr/backend.py b/backend/python/qwen-asr/backend.py index d576200a4..ea5e877f2 100644 --- a/backend/python/qwen-asr/backend.py +++ b/backend/python/qwen-asr/backend.py @@ -40,6 +40,55 @@ def is_int(s): _ONE_DAY_IN_SECONDS = 60 * 60 * 24 MAX_WORKERS = int(os.environ.get('PYTHON_GRPC_MAX_WORKERS', '1')) +# Languages Qwen3-ASR understands, spelled the way its validate_language() +# expects (full English names). Used to accept case-insensitive names and to +# leave anything already valid untouched. +_QWEN_ASR_SUPPORTED_LANGUAGES = ( + "Chinese", "English", "Cantonese", "Arabic", "German", "French", "Spanish", + "Portuguese", "Indonesian", "Italian", "Korean", "Russian", "Thai", + "Vietnamese", "Japanese", "Turkish", "Hindi", "Malay", "Dutch", "Swedish", + "Danish", "Finnish", "Polish", "Czech", "Filipino", "Persian", "Greek", + "Romanian", "Hungarian", "Macedonian", +) + +# OpenAI-compatible clients (Home Assistant / wyoming_openai, Whisper tooling, +# ...) send ISO 639-1 codes such as "de", but qwen_asr only accepts the full +# names above. Map the codes for every supported language to its name. +_LANGUAGE_CODE_TO_NAME = { + "zh": "Chinese", "en": "English", "yue": "Cantonese", "ar": "Arabic", + "de": "German", "fr": "French", "es": "Spanish", "pt": "Portuguese", + "id": "Indonesian", "it": "Italian", "ko": "Korean", "ru": "Russian", + "th": "Thai", "vi": "Vietnamese", "ja": "Japanese", "tr": "Turkish", + "hi": "Hindi", "ms": "Malay", "nl": "Dutch", "sv": "Swedish", + "da": "Danish", "fi": "Finnish", "pl": "Polish", "cs": "Czech", + "fil": "Filipino", "tl": "Filipino", "fa": "Persian", "el": "Greek", + "ro": "Romanian", "hu": "Hungarian", "mk": "Macedonian", +} + + +def _normalize_language(language): + """Translate an ISO language code into the name Qwen3-ASR expects. + + ``request.language`` typically carries an ISO 639-1 code ("de", "de-DE"), + but ``qwen_asr.validate_language`` only accepts full English names + ("German"). Names that are already valid (in any case) are returned with + their canonical spelling, and anything unrecognised is passed through + unchanged so qwen_asr keeps raising its own descriptive error. + """ + if not language: + return language + key = language.strip() + if not key: + return language + lowered = key.lower() + # Already a full language name (compare case-insensitively). + for name in _QWEN_ASR_SUPPORTED_LANGUAGES: + if lowered == name.lower(): + return name + # ISO code, optionally with a region/script suffix like "de-DE" / "zh_CN". + code = lowered.replace("_", "-").split("-", 1)[0] + return _LANGUAGE_CODE_TO_NAME.get(code, key) + class BackendServicer(backend_pb2_grpc.BackendServicer): def Health(self, request, context): @@ -299,7 +348,7 @@ class BackendServicer(backend_pb2_grpc.BackendServicer): language = None if request.language and request.language.strip(): - language = request.language.strip() + language = _normalize_language(request.language.strip()) ctx = "" if request.prompt and request.prompt.strip(): @@ -374,4 +423,4 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description="Run the gRPC server.") parser.add_argument("--addr", default="localhost:50051", help="The address to bind the server to.") args = parser.parse_args() - serve(args.addr) + serve(args.addr) \ No newline at end of file