Repository navigation
fix(asr): force Qwen3-ASR language with the official prefix, not garbled task tokens - #1
Merged
msandroid merged 1 commit intoSep 24, 2026
Conversation
…led task tokens
Qwen3AsrManager put `taskTokens[lang]` in the system turn when a language was
given. Decoded with the Qwen3-ASR vocab (identical to the bundled vocab.json)
every entry was gibberish ("agnıs the Oper to essentially text." for Korean,
"...toPoints text." for Japanese — all 30 languages), and the official
qwen_asr package does not use the system turn for this anyway: it is context,
and a language is forced by appending `language {Name}<asr_text>` after the
assistant header.
- Qwen3AsrPrompt builds the official template (empty system turn) and appends
the forced-language prefix; the 30 token rows were generated with the
Qwen/Qwen3-ASR-0.6B tokenizer (fix_mistral_regex=True) and each decodes back
to exactly `language {Name}<asr_text>`
- language == nil produces the same tokens as before (auto-detect unchanged)
- Qwen3AsrPromptTests pin the auto/forced token layout and table invariants
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UDraWTxHPu3AegNzaFrowi
Owner
Author
|
Evidence it never ran against the code:
Status:
Generated by Claude Code |
msandroid
marked this pull request as ready for review
September 24, 2026 15:28
msandroid
merged commit Sep 24, 2026
408ebf8
into
translateblue/parakeet-ctc-ja-vocab
0 of 2 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why is this change needed?
When
Qwen3AsrManager.transcribe(language:)got a language, it puttaskTokens[lang]into the system turn. The comment says those are "Transcribe the audio to {Language} text.", but decoded with the Qwen3-ASR vocab (FluidInferencevocab.jsonis byte-identical toQwen/Qwen3-ASR-0.6B) every one of the 30 rows is gibberish:agnıs the Oper to English text.agnıs the Oper to essentially text.agnıs the Oper to(signal.sender text.agnıs the Oper toPoints text.The official
qwen_asrpackage doesn't use the system turn for this at all: the system turn is context (biasing text), and a language is forced by appendinglanguage {Name}<asr_text>right after<|im_start|>assistant\n(Qwen3ASRModel._build_text_prompt,force_language). TranslateBlue passes explicit hints for Korean and Cantonese, where Qwen3 is the tier-1 ASR, so every such session was injecting this noise.What changed
Qwen3AsrPrompt(new): builds the official template with an empty system turn and, when a language is given, appends the forced prefix. The 30 token rows were generated by tokenizing the official prompt with the Qwen/Qwen3-ASR-0.6B tokenizer (fix_mistral_regex=True, asqwen_asrloads it); each row decodes back to exactlylanguage {Name}<asr_text>(checked for all 30).Qwen3AsrManageruses it;taskTokens/buildPromptTokensare removed. Withlanguage == nilthe prompt tokens are unchanged, so auto-detect behaves as before.decodeTokensalready handles output with no<asr_text>, which is what forced decoding produces.Qwen3AsrPromptTests: pins the auto/forced token layout against the official tokenization and checks the table's invariants.Documentation/ASR/Qwen3-ASR.mdwording.Branching
Branched from
cf46be1, the commit TranslateBlue currently pins, so bumping the submodule to this fix doesn't pull in the later Canary / SenseVoice commits. Nothing underASR/Qwen3changed betweencf46be1and the branch head, so this merges cleanly intotranslateblue/parakeet-ctc-ja-vocab.Not verified
swift buildandswift test --filter "Qwen3AsrPromptTests|Qwen3AsrConfigTests"on a Mac.swift run -c release fluidaudiocli qwen3-transcribe <ko.wav> --language koon FLEURS ko/yue before and after this change.🤖 Generated with Claude Code
https://claude.ai/code/session_01UDraWTxHPu3AegNzaFrowi
Generated by Claude Code