fix(qwen): 去掉字幕里的 language Chinese / asr_text 模板残留 - #442
Conversation
Qwen3-ASR sometimes emits chat-template crumbs such as language Chinese<asr_text> into cue text. Sanitize at the worker and engine exits, and drop empty leftover cues.
问题用 Qwen3-ASR 转写时会出现三类脏输出:
真实课字幕里的脏形态例如: 变更内容
验证
已有字幕文件不会自动改写,需要重新转写才会变干净。 |
buxuku
left a comment
There was a problem hiding this comment.
发现
-
[P1] 多语种场景会静默删除合法的单词字幕
main/helpers/engines/qwenText.ts:78-83和 worker 中的extraResources/sherpa/worker/sherpa-worker.js:313-318将所有不含汉字、没有空格、非白名单/公式格式的 2 到 24 字符英文 token 判定为幻听。例如:
Welcome -> '' computer -> '' English -> ''worker 会先删除 segment,主进程无法恢复。项目英文和中文资源文案都将 Qwen3-ASR 描述为 “multilingual” (
renderer/public/locales/*/resources.json:181-182),但这条规则没有使用 source language 做 gating。英文视频中常见的单词字幕会直接消失。建议只在明确选择中文时启用该规则,或结合模型语言/置信度判断,并补充
Welcome、computer等合法英文单词测试。 -
[P2]
language Chinese的常见变体仍会残留到字幕qwenText.ts:101-106的 header 正则要求语言名首字母大写,且不能带句末标点或引号;它运行在stripCueDecorations()之前。以下输入都会被保留:language chinese language Chinese. "language Chinese" language Chinese:后续的单 token 判定只对含空格的文本直接放行,因此无法补救。worker 版本也有相同问题 (
sherpa-worker.js:333-340)。这会使 PR 主要修复目标在真实输出带标点时失效。 -
[P2] JSON 修复器会把非法 JSON 静默改写成另一份合法数据
extraResources/sherpa/vendor/json-result.js:37-44会删除字符串外所有非法 C0 控制字符,而不是拒绝损坏结果。例如:{"a":1<vertical-tab>2} -> {"a":12}parseJsonResult()随后成功返回{ a: 12 }。这不仅容忍了 native 输出,还改变了数据语义并隐藏了原生结果损坏;该 parser 通过OfflineRecognizer对所有 sherpa 引擎生效,不只 Qwen。建议只处理已知的尾部 NUL,字符串外的内部非法控制字符应继续抛错,并增加结构损坏测试。
-
[P2] 控制字符被“转义后再还原”,最终仍会写入 SRT
json-result.js:29-30,67-68将裸控制字符转成 JSON escape,但JSON.parse会把它们还原成真实字符。之后qwenEngine.ts:144-153和formatSrtContent()原样写入字幕文件。因此 NUL 会进入
.srt文件,换行会改变 cue 的文本结构。PR 当前测试还明确要求保留 NUL (scripts/test-sherpa-json-result.cjs:8-12)。如果目标只是避免JSON.parse崩溃,这个行为需要明确记录;如果目标是生成干净字幕,则应在写文件前删除或替换 C0 字符。 -
[P2] 新增核心路径没有被 CI 覆盖,worker 实现也没有直接测试
package.json:41只注册了test:sherpa-json,但.github/workflows/ci.yml:36-61没有运行它;当前 PR 的 GitHub 状态也是no checks reported。此外,
qwenText.ts:12-109与sherpa-worker.js:248-340是两份手工复制的 sanitizer,现有 TypeScript 单测只覆盖前者,未覆盖生产 worker 的 segment 丢弃逻辑。两边未来漂移时,CI 不会发现。
问题
用 Qwen3-ASR 转写时会出现三类脏输出:
字幕里时不时冒出
language Chinese,有时还带着<asr_text>。这是 Qwen3-ASR 的聊天模板漏进正文。模型每段先报语种,再跟听写内容,sherpa-onnx 把整段解码原文交出来,SmartSub 原先原样写入 SRT。
转写直接报
SyntaxError: Bad control character in string literal in JSON at position 59。原生识别结果是一段 JSON 字符串。Qwen 正文里偶尔带未转义的换行、Tab、NUL 等 C0 控制字符,
JSON.parse直接炸掉,整段字幕失败。静音/幻听时整条 cue 变成英文碎片,例如
demand、detract.、imageUrl、Finds.。这不是模板前缀,是模型在无语音段乱吐拉丁词。只剥
<asr_text>去不掉。真实课字幕里的脏形态例如:
变更内容
sanitizeQwenAsrText,剥掉语种头、<asr_text>和偶发 markdown 星号;剥完为空的 cue 丢弃p/DXY/EX1)、数学符号名(sigma)和口语短回应(OK)保留language is important)不会被误删qwenEngine写 SRT 前清洗qwen3_asr同步剥一层json-result.js,解析原生 JSON 前把字符串里的裸控制字符转义;decodeAsync/getResult都走这条路径验证
npm run test:engines:810 passed, 0 failednpm run test:sherpa-json:4 passed已有字幕文件不会自动改写,需要重新转写才会变干净。