三条热词通道的机制拆解:bl speech 的参数面、生效模型范围与错配读数

写语音转写的调用时,我习惯把热词当效果开关:加一个参数,期待专名被认对,然后只看转写文本对不对。这一轮拆下来,参数面比想象中大,bl speech recognize 上有三个互不相同的入口,bl speech vocabulary 下面还有一组建表命令,三条通道的生效模型范围、取值约束、配错之后的行为都不一样。错配那一条我连试了三次,三次结果一样,和帮助文本写的相反。

帮助文本给的是每个 flag 的取值和范围,不给"配错之后返回里会露出什么"。这篇把这张映射表补出来,用的是阿里云百炼 CLI(bl 2.1.0)里的 bl speech 命令组。

取数口径先摆明:转写模型 qwen-audio-3.0-asr-flash,素材是我用语音合成现做的两段(不是真实录音),所有输出是 2026-10-14 我在自己电脑上跑出来的。语音识别有随机性,每条读数后面都跟着重复次数。工具在 CLI 安装页,一条 npm 命令。

一、基线:三个模型里只有一个会听错

热词有没有增量,得先有一个会听错的基线。我合成了一段塞满生僻专名的话:

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

bash 复制代码
bl speech recognize --url audio2.mp3 --model qwen-audio-3.0-asr-flash --language zh
模型 基线结果
fun-asr 全对
fun-asr-flash-2026-06-15 全对
qwen-audio-3.0-asr-flash 珞珈三号 → 洛家三号,其余全对

只有第三个模型听错,后面的对照都在它身上做。它的错本身不稳定:同一段合成音频连转三次,拿到过"洛家三号""洛家三号""洛嘉3号"三种写法。

对写代码的直接影响是:单次结果不能当判据,采样本身在抖。下面每条读数我都标了重复次数,你的实现里也应该把重复次数写进测试用例。

想用的第四个模型 qwen3-asr-flash 没跑起来,返回 HTTP 403 AllocationQuota.FreeTierOnly,口径是免费额度用尽、要续费用或者去控制台关掉"仅用免费额度"模式。余量数字我这边查不到(控制台会话过期),去控制台额度页看当天读数。

二、三条通道的参数面

通道 参数写法 要不要预建资源 取值约束 帮助文本写的生效范围 这段合成音频上的读数
预编译热词表 --vocabulary-id <表 ID> 要,先 vocabulary create 权重 1 到 5,帮助文本推荐 4;Qwen-Audio-3.0 系可用 50 的超级热词;--prefix 小写字母加数字、最长 10 位 建表 --model 与调用 --model 一致 1 次,珞珈三号修对
即时热词 --vocabulary '{"珞珈三号":4,"仇池":4}' 不要 权重口径同上 只对 Qwen-Audio-3.0-ASR-Flash 系列生效 1 次,修对
上下文词表 --context "珞珈三号 仇池" 不要 最长 400 字,必须含目标词本身 Qwen-Audio-3.0-ASR-Flash 与 Fun-ASR-Flash 1 次,修对

三条通道的写法:

bash 复制代码
bl speech vocabulary create --model qwen-audio-3.0-asr-flash --prefix hw1014a --words '{"珞珈三号":4,"仇池":4}'
bash 复制代码
bl speech recognize --url audio2.mp3 --model qwen-audio-3.0-asr-flash --language zh --vocabulary-id <表 ID>
bash 复制代码
bl speech recognize --url audio2.mp3 --model qwen-audio-3.0-asr-flash --language zh --vocabulary '{"珞珈三号":4,"仇池":4}'
bash 复制代码
bl speech recognize --url audio2.mp3 --model qwen-audio-3.0-asr-flash --language zh --context "珞珈三号 仇池"

建表返回一个 vocab- 开头的 ID,那是通道一的引用键。选型落到实现上就是三句话:词表长期不变、多个服务共用,建一次表反复引用;一次性的调用直接内联 JSON;手里只有一份词清单、不想给权重,用 --context。

表里三条通道各只有 1 次读数,够说明这条通道能把词修对,不够当稳定性结论。写进你们自己的测试用例之前,按第八节第 2 条重复跑。

三、错配 --vocabulary-id:与帮助文本相反的一组读数

这一节的现象我重复了三次。帮助文本对 --vocabulary-id 和建表时的 --model 写着同一句话:必须与之后 recognize 传的完全一致,否则热词表被静默忽略。

我按这句话设计了一次错配:另建一张表,建的时候声明给 fun-asr,然后喂给 qwen-audio-3.0-asr-flash。表的归属事后核过,bl speech vocabulary get --id <表 ID> 返回的 target_model 字段确实是 fun-asr。

bash 复制代码
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 的两条硬约束

第一条是范围:只对 Qwen-Audio-3.0-ASR-Flash 和 Fun-ASR-Flash 生效,别的模型上带了也白戴。第二条是内容形态,这条我专门验了:

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

参数里只有主题词,一个目标词都没有。连试两次,两次都还是洛家三号。帮助文本原话是"必须包含目标词本身,只写主题描述作用很小",这一条实测与它一致,可以当结论用。

也就是说 --context 是词表,不是话题提示器。想靠"告诉模型这段在讲什么"把专名救回来,这条路不通;400 字的上限要留给词本身。

五、错误码与拦截行为对照表

触发条件 返回 口径与处理
调 qwen3-asr-flash HTTP 403 AllocationQuota.FreeTierOnly 免费额度用尽;续费用或去控制台关掉"仅用免费额度"模式。余量去控制台额度页看,别写死在代码里
vocabulary delete 不带 --yes 命令被拦下,提示永久删除、不可撤销、加 --yes 重跑 高风险闸;脚本里要显式传 --yes,并把这个分支当失败处理
vocabulary get 一个已删的 ID 400 资源不存在 删除生效的复核信号
vocabulary get --vocabulary-id <id> 未知参数 get 与 delete 用 --id,recognize 才用 --vocabulary-id

六、参数名对照表

参数名不统一是这组命令里最容易抄错的地方,我自己在 get 上写成 --vocabulary-id 报过一次"未知参数"。

命令 参数 作用
bl speech vocabulary create --model / --prefix / --words 表的目标模型 / 前缀(小写字母加数字,最长 10 位)/ 词与权重的 JSON
bl speech vocabulary list 无 列出工作空间里的表
bl speech vocabulary get --id 查单张表,可读 target_model 字段
bl speech vocabulary delete --id / --yes 删除;不加 --yes 被拦
bl speech recognize --vocabulary-id 引用预编译热词表
bl speech recognize --vocabulary 即时热词 JSON,内联不建表
bl speech recognize --context 上下文词表,纯词无权重

七、资源纪律:别人的表只读,自建的表测完删

工作空间里原本有三张别人 09-09 建的表,我全程只 list 和 get,没有改也没有删。自己建的两张用了独立前缀,测完删掉,删完做两次复核:bl speech vocabulary list 里只剩那三张,bl speech vocabulary get --id <已删 ID> 返回 400 资源不存在。

共享工作空间里跑实验,这两步值得写进流程:用独立前缀让资源可辨识,删完用 list 加 get 双向确认。只跑 delete 不看复核,等于不知道删掉的是哪一张。

鉴权口径顺带记一句:合成音频、转写、建表删表都要 Key,list 和 get 同样要,这组命令没有完全免鉴权的那一档。Key 在 API Key 签发页 签发。

八、可以抄进代码的六条

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

九、读数汇总,和会变的部分

读数 值(2026-10-14) 命令
三模型基线(难句) 两家全对、一家珞珈三号 → 洛家三号 bl speech recognize --url <合成音频> --model <m> --language zh
听错那家的基线重复 三次三种写法:洛家三号 / 洛家三号 / 洛嘉3号 同上 ×3
三通道修复 各 1 次均修对 加 --vocabulary-id / --vocabulary / --context
--context 只写主题 两次仍错 --context "卫星工单项目组办事处"
错配 --vocabulary-id 三次全生效,与帮助文本相反 表 target_model=fun-asr,调用 --model 为 3.0
qwen3-asr-flash HTTP 403 AllocationQuota.FreeTierOnly 免费额度用尽口径
删除闸 不带 --yes 拦截,带 --yes 删除,复核为空 bl speech vocabulary delete --id <id>

会变的是模型在架名单、额度状态、热词表清单这三类,命令签名相对稳定。重跑一遍就有你当天的读数,映射表按你那次的返回重画一次即可。

下一轮我想把错配这件事换几个模型族组合再跑一遍,看能不能把"哪边是常态"这个问题查清楚;查清楚了再回来补第三节。

十、这次没覆盖的

字幕链路(识别加翻译加时间轴)是另一篇的事,这篇只共用 recognize 一条命令。实时流式识别(realtime 系列模型)不在范围内。真实带噪素材我手里没有,这一篇用的是合成音频,噪声环境下的表现以你自己那次为准。花费与额度走控制台账单页与额度页,查不到就不写数字。

你们的转写服务里热词是怎么下发的,每次调用内联 JSON,还是建一张长期表共用?另外错配 --vocabulary-id 这件事,你们在自己的模型组合上试过吗,我想知道三次全生效是不是只有我这边这样。

相关推荐
code_Bo2 小时前
从策划到上线:我和 AI 一起做了个微信记账小程序
前端·ai编程·cursor
森码2 小时前
一条 Prompt 在 Harness 中经过了谁?
agent
程序员大狐狸2 小时前
Ultra X7 358H 笔记本电脑,本地部署 Bonsai-2-27B,实测生成速度 11.6 tok/s
人工智能·llm
Behavior2 小时前
谷歌 Gemini 4 Argon正式开放:硬刚 GPT-6 与 Claude,这次谁更强?
llm·aigc·gemini
方方洛2 小时前
ai-agent教程-06-主流框架
人工智能·llm·agent
星始流年2 小时前
AI 时代,软件程序员未来 10—15 年的职业前景
前端·后端·ai编程
诺伦2 小时前
从一键分发到 AI 自动运营:内容矩阵工具三代技术架构拆解 | RiseClaw玄策
python·agent·架构设计·增长运营·ai自动运营·内容营销自动化
Captaincc3 小时前
# 实习生A视角来了 | 2024 年字节跳动前实习生 (Tian Keyu) 模型训练攻击事件:受害者陈述与证据整理
ai编程
源图客3 小时前
LiteLLM 介绍与部署
llm