2. 唤醒词技术基础
各位好,这一章我们聊聊声学前端处理。说白了,就是麦克风采集到声音之后,到唤醒词模型开始工作之前,中间那一整套信号处理流程。
很多同学觉得唤醒率低就是模型不行,调一调网络结构就好了。我刚开始做唤醒词的时候也这么想,结果被现实狠狠教育了一回——模型在安静环境下跑得挺好,一到嘈杂环境就崩了。后来我才明白,声学前端处理才是唤醒率的第一道防线。
核心观点:唤醒率提升,70%靠前端,30%靠模型。前端处理不好,模型再强也白搭。
麦克风阵列:不止是多个麦克风
先说说麦克风阵列。很多人觉得,麦克风阵列不就是把几个麦克风焊在一起嘛。其实没那么简单。
麦克风阵列的核心价值在于空间信息。单个麦克风只能听到声音,但多个麦克风可以知道声音从哪个方向来。这个信息对后续的波束成形至关重要。
常见的阵列拓扑有这么几种:
| 阵列类型 | 麦克风数量 | 适用场景 | 优缺点 |
|---|---|---|---|
| 线性阵列 | 2-8个 | 智能音箱、电视 | 结构简单,水平方向定位好,垂直方向差 |
| 环形阵列 | 4-8个 | 智能音箱、会议设备 | 360°覆盖,算法复杂度适中 |
| 球形阵列 | 16个以上 | 专业会议、机器人 | 全空间覆盖,成本高,算法复杂 |
我个人习惯在智能音箱项目上用6麦环形阵列。为什么是6个?因为4个在某些角度会有盲区,8个成本上去了但收益边际递减。6麦是个不错的平衡点。
工程经验:麦克风间距很关键。间距太小,低频方向性差;间距太大,高频会出现空间混叠。一般建议间距在15-25mm之间,具体根据目标频段调整。
波束成形:把耳朵转向说话的人
波束成形,说白了就是让麦克风阵列"听"某个方向的声音,同时抑制其他方向的声音。你可以想象成用手在耳朵后面拢着听人说话。
波束成形有两种主流方法:
- 固定波束成形(Delay-and-Sum):简单粗暴,对每个麦克风的信号做时延补偿后相加。优点是计算量小,适合资源受限的嵌入式设备。缺点是抑制能力有限。
- 自适应波束成形(MVDR、GSC):根据实际信号环境动态调整权重。抑制能力强,但计算量大,而且对误差敏感。
我在项目中遇到过一个问题:用MVDR做波束成形,在实验室效果很好,但到了用户家里,因为麦克风位置有偏差,性能直接崩了。后来我改用GSC结构,加了一个阻塞矩阵来抑制干扰,鲁棒性好了很多。
避坑指南:我曾经在量产项目上吃过亏——麦克风阵列的安装公差没控制好,导致波束指向偏移。后来我们在产线上加了校准流程,每个设备出厂前都要做一次麦克风灵敏度校准和相位校准。这个步骤不能省。
回声消除(AEC):别让音箱自己吵自己
回声消除,英文叫Acoustic Echo Cancellation。你想想看,智能音箱在播放音乐的时候,你说"小爱同学",麦克风同时录到了你的声音和音箱播放的音乐。如果不做回声消除,唤醒词模型会被音乐干扰,甚至把音乐里的某个音节误识别成唤醒词。
AEC的核心原理是自适应滤波。系统知道音箱在播放什么(参考信号),通过自适应滤波器估计回声路径,然后从麦克风信号中减去回声成分。
一个典型的AEC流程是这样的:
参考信号(音箱播放的音频)
↓
自适应滤波器(模拟回声路径)
↓
估计的回声信号
↓
麦克风信号 - 估计的回声信号 = 干净的近端信号
↓
双端检测(判断是否只有回声,还是同时有近端说话)
这里有个关键问题——双端检测。当用户和音箱同时发声时,自适应滤波器不能更新,否则会发散。我见过不少项目,AEC在双端场景下直接炸了,回声反而被放大。
关键参数:AEC的收敛速度、稳态失调、双端检测的灵敏度,这三个参数需要仔细调优。收敛太快容易不稳定,收敛太慢又跟不上环境变化。一般建议收敛时间控制在200-500ms。
噪声抑制(NS):把背景噪声压下去
噪声抑制,就是去掉环境中的背景噪声。风扇声、空调声、马路上的车流声,这些都会干扰唤醒词识别。
传统的噪声抑制方法有:
- 谱减法:估计噪声谱,从信号谱中减去。简单,但容易产生"音乐噪声"。
- 维纳滤波:基于统计模型,效果比谱减法好,但计算量大一些。
- 基于深度学习的NS:用神经网络做噪声抑制,效果最好,但需要额外的模型和算力。
我个人建议,在唤醒词场景下,优先用传统方法。为什么?因为唤醒词模型本身就是一个神经网络,如果前端再用一个神经网络做NS,延迟和算力都吃不消。传统方法虽然效果差一点,但延迟低、资源少。
工程技巧:噪声抑制不要做得太狠。过度抑制会导致语音失真,反而降低唤醒率。我一般把NS的抑制量控制在6-12dB之间,既能去掉大部分背景噪声,又不会明显损伤语音质量。
整体流程与工程实践
好了,我们把上面几个模块串起来,看看完整的声学前端处理流程:
嗯,这里要注意,每个模块都会引入延迟。麦克风阵列采集有延迟,波束成形有计算延迟,AEC有滤波器收敛延迟,NS有帧处理延迟。这些延迟累加起来,如果超过50ms,用户就会感觉到"说了唤醒词之后反应慢半拍"。
我一般要求整个声学前端的处理延迟控制在30ms以内。怎么做到?
- 用低延迟的滤波器设计,比如分块自适应滤波
- 减少帧长,比如从20ms降到10ms
- 优化算法实现,用定点运算代替浮点运算
重要提醒:模块之间的级联顺序不能乱。一定是先波束成形,再做AEC,最后做NS。如果先做AEC再做波束成形,回声路径会变得非常复杂,AEC根本收敛不了。这个顺序我踩过坑,大家记住就好。
工程实践中的常见问题
最后,我总结几个工程实践中经常遇到的问题,供大家参考:
- 麦克风一致性差:同一批次的麦克风,灵敏度和相位可能有差异。建议在产线上做校准,或者用算法做在线补偿。
- 非线性失真:音箱的功放和喇叭会产生非线性失真,导致AEC效果变差。可以在参考信号路径上加一个非线性处理器。
- 风噪:户外场景下,风直接吹到麦克风上会产生低频噪声。可以用高通滤波器或者风噪检测算法来处理。
- 多设备干扰:家里多个智能设备同时唤醒,互相干扰。这个需要设备间的协同机制,属于更高层的问题。