随手记两件反直觉的事:同一段合成音频三次三种错法,配错模型的热词表照样生效

最近在搞语音转文字,顺手把热词的三条通道各试了一遍。本来只想确认"哪条通道能修对专名",结果记下的是两件跟我直觉相反的事,写在下面。

先说个语境。这周 Hacker News 上有两篇语音转文字的帖子排着队上首页,一篇是 10-08 的,一个 16.9 MB 的端侧转写工具,961 分;另一篇是 10-13 的,有人把一个嵌入模型改造成语音转文字,397 分。热闹归热闹,做过客服通话或会议转写的人都知道,卡人的从来不是"能不能转",是产品名、人名、地名永远听错。"珞珈"听成"洛家",同音不同字,后面全跟着错。

工具是阿里云百炼的 CLI。CLI 就是命令行工具,不开网页,在终端敲一行字让平台干活,百炼那个叫 bl,我是在 GitHub 上翻它的仓库时看到这组 speech 命令的。ASR 是语音识别,声音进去文字出来;热词表是你提前递给它的一张清单,意思是"这些词请按我给的字形写",每个词能带一个权重,权重越高越倾向于照你写的出。

专有名词永远听错:热词三条通道各试一遍

读数都是 2026-10-14 我在自己电脑上敲出来的,bl 2.1.0。合成音频两段是我用语音合成现做的,不是真实通话,这点先说清楚,带噪环境上的表现以你自己那次为准。工作空间里别人建的热词表我只看不碰,自己建的两张测完就删。

一、先要有一段会听错的音频

热词有没有用,得先有个"听错"的基线。我合成了一句故意塞满生僻专名的话:

请把 XQ-7734 号工单转给岑巩县的冉雍,抄送珞珈三号项目组的仇池和濮阳办事处。

三个模型各转一遍:fun-asr 全对,fun-asr-flash-2026-06-15 全对,qwen-audio-3.0-asr-flash 把珞珈三号转成了洛家三号,其余全对。只有第三个会错,实验就在它身上做。

反直觉的第一件在这儿。同一段合成音频连着转三次,我拿到的是"洛家三号""洛家三号""洛嘉3号"三种写法。不是同一个错重复三遍,是三次里换了字形。我原来以为专名听错是个稳定现象,错就固定错成那一个,拿一次结果当结论完全够了。实际上语音识别有随机性,"我试了一次生效/没生效"这种话一句都站不住,后面每条结论我都标了重复次数。

顺带记一条:我本想加第四个模型 qwen3-asr-flash 做对照,跑不了,返回 HTTP 403 AllocationQuota.FreeTierOnly,提示免费额度用尽、要续费用或去控制台关掉"仅用免费额度"模式。剩多少我看不到,控制台会话过期了。这类数字你去控制台额度页看当天读数,别抄文章里的。

三模型基线与三通道修复结果矩阵

二、三条通道各试一次,都修对了

在会听错的那个模型上,三条通道各跑一次,各 1 次都把珞珈三号修对了。

第一条是预编译热词表,先建一张表,把词和权重写进去:

bl speech vocabulary create --model qwen-audio-3.0-asr-flash --prefix hw1014a --words '{"珞珈三号":4,"仇池":4}'

--prefix 只能用小写字母和数字、最长 10 位;权重 1 到 5,帮助文本推荐 4,Qwen-Audio-3.0 系还能用 50 的超级热词。建完拿到一个 vocab- 开头的 ID,转写时带上:

bl speech recognize --url audio2.mp3 --model qwen-audio-3.0-asr-flash --language zh --vocabulary-id <表 ID>

第二条是即时热词,不建表,词直接塞进这次调用:

bl speech recognize --url audio2.mp3 --model qwen-audio-3.0-asr-flash --language zh --vocabulary '{"珞珈三号":4,"仇池":4}'

第三条是上下文词表,不给权重只给词:

bl speech recognize --url audio2.mp3 --model qwen-audio-3.0-asr-flash --language zh --context "珞珈三号 仇池"

三条的生效模型范围不一样,这是选通道时唯一真正要看的:--vocabulary-id 支持面最宽,含 Fun-ASR 与 Paraformer;--vocabulary 只对 Qwen-Audio-3.0-ASR-Flash 系列生效,别的模型上带了也白戴;--context 只对 Qwen-Audio-3.0-ASR-Flash 和 Fun-ASR-Flash 生效,且最长 400 字。

我的选法是按词表寿命:长期不变、几个服务共用,建一次表反复用;临时一两次调用,直接塞 json;手里只有一份词清单不想管权重,走 context。

三、反直觉的第二件:配错模型的那张表,三次都生效了

帮助文本对 --vocabulary-id 和建表时的 --model 都写着"必须与之后 recognize 传的完全一致,否则热词表被静默忽略"。我按这句话的理解去验:另建一张表,建的时候声明给 fun-asr 用,事后用 bl speech vocabulary get --id <表 ID> 核实过,target_model 字段确实是 fun-asr,然后把它喂给 qwen-audio-3.0-asr-flash:

bl speech recognize --url audio2.mp3 --model qwen-audio-3.0-asr-flash --language zh --vocabulary-id <fun-asr 的表>

我预期是"照旧听错",因为帮助文本说会被忽略。实际连试三次,三次都把珞珈三号修对了,没有被忽略。

反方向(3.0 的表喂给 fun-asr)我没法观察,fun-asr 基线本来就全对,修没修看不出来。所以这条我只能记到这儿:帮助文本说的"错配静默忽略"在我这个组合上没复现,连试三次都生效;哪边是常态、是不是模型族之间互通,我没查明,也不打算猜。

留一句实操:别依赖"配错会自动忽略"这句话做兜底设计。建表的 --model 和调用的 --model 写成一样,是最不需要解释的做法。

三条通道的生效模型范围与两条边界

四、还有一条边界,跟帮助文本一致

把 context 的参数换成主题描述,不写词本身:

bl speech recognize --url audio2.mp3 --model qwen-audio-3.0-asr-flash --language zh --context "卫星工单项目组办事处"

连试两次,两次都还是洛家三号。帮助文本原话是"必须包含目标词本身,只写主题描述作用很小",实测一致。我原来隐隐觉得给个话题方向多少有点用,没有。这条通道不是话题提示器,是词表。

五、建表删表的纪律,和一个参数名的坑

删表这条有闸:

bl speech vocabulary delete --id <表 ID>

不带确认参数直接跑会被拦下来,提示该操作永久删除、不可撤销、加 --yes 重跑。我把自己建的两张删掉之后做了两次复核:bl speech vocabulary list(无参数)里只剩别人 09-09 建的三张表,一张没碰;再 get 已删的那个 ID,返回 400 资源不存在。删干净了,也没动别人的东西。

参数名不统一,抄命令时留意:get 和 delete 都叫 --id,recognize 那边叫 --vocabulary-id。我一开始在 get 上写成 --vocabulary-id,报的是"未知参数"。

六、记下来的六条,和这篇没写的

  1. 先跑基线,确认你的合成音频和模型组合真的会听错再上热词,全对的组合加热词没有可测量的增量
  2. 识别有随机性,任何通道结论至少重复两次
  3. 长期词表走 vocabulary create + --vocabulary-id;临时调用走 --vocabulary;只有词清单走 --context
  4. --context 必须含目标词本身,写主题没用(实测两次仍错)
  5. 建表与调用的 --model 保持一致;"错配静默忽略"我这次没复现(连试三次都生效),别拿它当兜底
  6. 删表有高风险闸,不加 --yes 会被拦;删完 list + get 双重复核

没写的:字幕那条链路是另一篇的事;实时流式识别(realtime 系列模型)不在本包;带噪通话我没素材,合成音频上的结论不外推到噪声音频;花费与额度去控制台看,我这边会话过期了,查不了也不编数字。

合成音频、转写、建表删表都要 Key,list 和 get 同样要 Key,没有完全免鉴权的那一档。API Key 在密钥管理页签创建,地域选北京;想自己走一遍的话 CLI 安装页在这,也可以先去百炼首页看看平台侧长什么样。

会变的:模型在架名单、额度状态、热词表清单。重跑一遍就有当天读数,结论以你那次为准,别抄我的快照。

posted @ 2026-10-14 15:21  新的白白酱  阅读(20)  评论(0)    收藏  举报