2. 智能座舱基础
语音交互,说白了就是让机器听懂人话,再用人话回应你。这个领域我摸爬滚打了好几年,踩过的坑比写过的代码还多。今天咱们就把语音识别(ASR)、语音合成(TTS)和唤醒词设计这三个核心模块拆开揉碎了讲。
2.1 语音识别(ASR)原理
ASR 的目标很简单:把音频信号转成文字。但实现起来,远没你想的那么简单。
我习惯把 ASR 流程分成三个阶段:
- 前端信号处理:降噪、端点检测、特征提取
- 声学模型:把音频特征映射到音素(拼音的最小单位)
- 语言模型:结合上下文,把音素串成最合理的文字
核心要点:ASR 不是「听写」,而是「概率推理」。它输出的是概率最高的文字序列,不是绝对正确的答案。
举个例子。你说「我想去银行」,ASR 会先提取梅尔频率倒谱系数(MFCC)特征,然后声学模型判断出音素序列 "wo xiang qu yin hang",最后语言模型结合上下文,把 "yin hang" 映射成「银行」而不是「引航」。嗯,这里要注意,如果环境噪音大,语言模型的权重就得调高,否则容易出错。
我在项目中遇到过最头疼的问题,是远场识别。麦克风离人 3 米以上,信噪比急剧下降。后来我们用了波束成形(Beamforming)加多麦克风阵列,才把识别率从 60% 拉到 85% 以上。
| ASR 组件 | 输入 | 输出 | 常见技术 |
|---|---|---|---|
| 前端处理 | 原始音频 | 降噪后音频 / 特征向量 | VAD、MFCC、Beamforming |
| 声学模型 | 特征向量 | 音素概率分布 | CNN、RNN-T、Transformer |
| 语言模型 | 音素序列 | 文字序列 | N-gram、BERT、GPT |
实战技巧:测试 ASR 时,别只测安静环境。一定要在 50dB、65dB、80dB 三种噪音等级下分别跑一遍,才能暴露真实问题。
2.2 语音合成(TTS)原理
TTS 是 ASR 的逆过程——把文字转成语音。但这里有个悖论:机器合成的语音,要么像机器人,要么像真人但计算量巨大。
目前主流 TTS 架构分两派:
- 拼接合成:预录大量语音片段,按需拼接。音质高但死板,换个词就得重新录。
- 参数合成:用模型直接生成波形。灵活但容易有「电子音」。
我个人更倾向混合方案。前端用 Tacotron 或 FastSpeech 生成梅尔频谱,后端用 HiFi-GAN 或 WaveGlow 转成波形。这样既保证了自然度,又控制了延迟。
我记得有一次做车载语音,客户要求 TTS 延迟低于 200ms。我们试了各种模型,最后发现 WaveRNN 在 GPU 上能跑到 150ms,但 CPU 上直接崩到 800ms。后来做了模型量化 + 算子融合,才勉强达标。
避坑指南:我曾经在 TTS 测试中忽略了一个细节——语速。默认 1.0 倍速听起来正常,但用户实际使用时可能调快或调慢。调快 1.2 倍后,很多模型会出现「吞音」现象,比如「不知道」变成「不道」。这个一定要测。
TTS 的关键指标就三个:
- MOS 分(Mean Opinion Score):人耳主观评分,5 分满分,商用至少 4.0
- 实时率:合成 1 秒语音需要多少秒计算,低于 0.5 才算可用
- 首包延迟:从输入文字到听到第一个字的时间,建议 < 300ms
2.3 唤醒词与命令词设计
唤醒词就是「嘿 Siri」「小爱同学」这类词。命令词则是唤醒后说的「打开空调」「导航到公司」。
设计唤醒词,有几个硬规则:
- 音节数 3-5 个:太短容易误唤醒,太长用户嫌啰嗦
- 避免常见词:别用「你好」「开始」这种日常高频词
- 声学区分度:音素组合要独特,比如「小爱同学」的 /x/ /ai/ /t/ /ong/ /x/ /ue/ 组合在中文里很少见
命令词设计更讲究。我建议按「动词 + 对象 + 参数」的格式来:
# 命令词格式示例
打开 空调 26度
导航 到 北京西站
播放 周杰伦 的 七里香
为什么这么设计?因为 ASR 对短词的识别率远高于长句。把「帮我打开空调并设置到 26 度」拆成「打开 空调 26度」,识别率能从 70% 提升到 92%。
经验之谈:我做过一个智能家居项目,用户说「关灯」和「开灯」的误识别率高达 15%。后来我们把命令词改成「打开灯光」「关闭灯光」,虽然长了点,但误识别率降到了 2% 以下。你想想看,有时候牺牲一点自然度,换来的是可靠性。
下面这张图,是我自己总结的语音交互全链路结构:
2.4 唤醒词与命令词的测试要点
测试唤醒词,不能只测「唤醒率」。我列几个必测项:
- 唤醒率:正常说话时,10 次至少唤醒 9 次
- 误唤醒率:24 小时连续运行,误唤醒不超过 3 次
- 唤醒延迟:从说出唤醒词到系统响应,建议 < 500ms
- 抗噪唤醒:60dB 噪音下唤醒率不低于 80%
命令词测试更复杂。我习惯用「混淆矩阵」来评估:
| 实际命令 | 识别为「开灯」 | 识别为「关灯」 | 识别为其他 |
|---|---|---|---|
| 开灯 | 92% | 3% | 5% |
| 关灯 | 4% | 90% | 6% |
| 打开空调 | 2% | 1% | 97% |
你看,如果「开灯」和「关灯」的混淆率超过 5%,就得考虑换命令词了。
小技巧:测试命令词时,让不同口音的人来读。我遇到过「打开」读成「打改」的,ASR 直接懵了。后来我们在训练数据里加了 10% 的方言口音样本,才把这个问题解决。