同一批数据训练,误触发差 5 倍:唤醒词模型的训练随机性
同一个唤醒词、同一份负样本、同一套训练配方,唯一不同的是随机种子——一次重训得到 2.74 次/小时的误触发,另一次得到 14.20。5 倍的差距,只来自初始化和数据顺序。这篇记录我们的生产数据,以及对应的解法:现在每轮重训产出 5 个候选模型,让用户自己挑。
先上数据
我们的误触发优化是一个自动闭环:拿刚训好的模型去扫公开语料,把它打高分的非关键词片段挖出来当困难负样本,再全量重训(这套机制的细节见之前那篇误触发排查文章)。以前一轮重训只产出一个模型;现在每轮重训用 5 个不同的种子各训一个候选,所有候选在同一个评估集上测两个指标——每小时误触发和召回变化。
下面是 7 条生产链路的真实数据,覆盖 5 种语言,每行一个关键词,候选按误触发升序排列(关键词做了匿名,都是真实用户的词):
| 语言 | R0(次/时) | 5 个候选(次/时,升序) | 最好/最差 |
|---|---|---|---|
| en | 104.4 | 4.46 / 4.69 / 5.84 / 6.10 / 10.86 | 2.4× |
| en | 49.5 | 3.05 / 3.68 / 5.21 / 7.44 / 9.52 | 3.1× |
| en | 44.6 | 4.83 / 5.35 / 5.39 / 6.02 / 8.48 | 1.8× |
| zh | 74.5 | 3.51 / 10.08 / 11.02 / 14.41 / 16.85 | 4.8× |
| ja | 330.9 | 5.12 / 7.35 / 9.90 / 11.64 / 13.04 | 2.5× |
| fr | 222.7 | 4.51 / 7.25 / 9.02 / 10.75 / 15.21 | 3.4× |
| de | 265.3 | 2.74 / 3.89 / 4.46 / 4.79 / 14.20 | 5.2× |
每一轮重训都比 R0 基线降了 90% 以上——这是机制本身的功劳。但候选之间的差距稳定在 2~5 倍,五种语言无一例外。只训一个模型,等于闭眼抽签。
方差从哪来
端侧唤醒词模型很小,我们的只有 3 万参数左右。小模型、小参数量、大量彼此不同的极小值点——种子决定你落进哪一个。在我们的场景里,三件事把它放大:
- 困难负样本是小子集、大影响。重训数据 = 原正样本 + 通用负样本 + 几千条挖掘片段。挖掘片段承载了修正决策边界的大部分梯度信号,批量顺序的微小变化会改变每条片段对边界的影响强度。
- 这个指标是重尾的。每小时误触发次数由少数几个声音主导——一句电视广告词就可能贡献每小时 20 次触发。某个候选恰好站在这条边界的"对的一侧",数字就是成倍地动,不是百分之几地动。
- 推理端没有平均可做。所有候选用的是同一个评估集、同一条评估管线,所以这个差距是模型的真实差距,不是测量噪声。
两条走不通的路
挑幸运种子。种子 A 在关键词甲上跑出 2.7,换个关键词乙再用它——没有保证。种子到结果的映射在不同数据集、不同关键词之间不稳定,"好种子"不可迁移。我们验证过。
模型集成。5 个模型的分数取平均,方差基本消掉。但这类模型要跑在 ESP32-S3 和 Android 上,预算是一部设备上的一枚 100KB 模型、几毫秒推理。集成把内存和算力乘 5,这个设备类别付不起。
我们上线的方案
一轮重训产出 5 个候选,全部在同一评估集上测完,控制台把 5 个候选连同双指标(误触发/小时、召回变化)一起列出来,用户挑一个下载。
"为什么不让服务器直接选最好的"——这个问题的诚实答案才是有意思的部分。服务器确实排了序,但依据是公开语料。我们的评估集是通用语音,用户家不是。哪个候选最好,取决于部署环境里有什么声音、用户怎么权衡误触发和召回。上面表格里就有现成的例子:法语关键词有个候选误触发 7.25,看着不错,直到你注意到它的召回相对 R0 掉了 7 个点——对一台偶尔用一次的设备,这个交换可以接受;对一个全天候待命的唤醒词,不行。这是用户的决策,不是服务器的决策。
自己训练模型的话,四条实操建议
- 不要相信单次训练的误触发数字。对比两个配方之前,先用不同种子重训一遍——种子解释的差异可能比你的改动还大。
- 候选在固定评估集上测,误触发旁边永远放上召回。只赢误触发的候选,可能在悄悄变聋。
- 部署端跑不动集成的话,离线训 N 个候选选一个——这是穷人的集成,花的是训练时间,不是运行时开销。
- 盯尾部不只是均值:德语那行最差候选(14.20)是最好的 5 倍。配方合理之后,"选"比"调"更值钱。
局限
5 个候选共享同一份数据——这样降的是种子方差,不是数据方差。评估语料仍是公开语音,20~30 小时的留出集对个位数触发率的分辨率也比较粗。每轮重训 5 倍的训练算力是真实成本;我们付这个成本,是因为 100KB 的模型训起来不贵,而用户对一个乱触发的设备的耐心很贵。
训练一个唤醒词,看看你的候选模型