第四章 语音识别(ASR)基础:ASR架构、声学模型与语言模型、端到端识别模型
各位同学,欢迎来到第四章。这一章我们聊聊语音识别,也就是ASR。说实话,ASR是整个座舱语音交互系统的“耳朵”。耳朵不好使,后面说啥都白搭。
我在做座舱项目时,最头疼的就是用户说“打开空调”,系统识别成“打开窗户”。这种低级错误,往往不是算法不行,而是架构设计上就埋了坑。今天我们就从根上把ASR捋一遍。
4.1 传统ASR架构:三件套
传统的ASR系统,说白了就是三个模块串在一起:声学模型、语言模型、解码器。我习惯叫它“三件套”。
- 声学模型:把音频信号转成音素(比如“a”、“b”这些基本发音单元)。
- 语言模型:判断哪些词串在一起更像人话。比如“我要去机场”比“我要去鸡场”概率高。
- 解码器:把声学模型和语言模型的输出综合起来,找到最可能的文字序列。
你想想看,这三个模块是独立训练的。声学模型只管“听”,语言模型只管“猜”。最后解码器把它们拼起来。这种架构有个好处:每个模块可以单独优化。但坏处也很明显——误差会累积。
核心要点:传统ASR的瓶颈不在单个模型,而在模块之间的“信息损耗”。声学模型输出一个概率分布,语言模型再叠一层概率,解码器做搜索时,很多细节就丢了。
4.2 声学模型:从GMM到DNN
声学模型这块,我经历过好几个时代。最早是GMM(高斯混合模型),后来是DNN(深度神经网络),再后来是CNN、RNN、Transformer。
GMM时代,我记得每个音素都要手工设计特征。MFCC(梅尔频率倒谱系数)是标配。那时候调参调得我头秃。一个简单的“静音检测”就能折腾一周。
后来DNN来了,事情简单了很多。你只需要把原始音频特征扔进去,网络自己学。我在项目中用过的一个经典结构是这样的:
# 伪代码:DNN声学模型结构
输入层: 40维MFCC特征(每帧)
隐藏层1: 1024个神经元,ReLU激活
隐藏层2: 1024个神经元,ReLU激活
隐藏层3: 512个神经元,ReLU激活
输出层: 音素个数(比如40个),Softmax
嗯,这里要注意:DNN虽然强,但它对时序关系不敏感。你想想看,语音是连续的,前后帧有依赖。DNN只看当前帧,容易“断章取义”。
所以后来大家开始用RNN/LSTM。LSTM能记住前面几帧的信息,识别率明显提升。我在一个车载项目里,把DNN换成LSTM后,准确率从85%跳到了92%。
个人经验:声学模型训练时,数据增强特别重要。我习惯加一些噪声、混响、变速。座舱环境里,风噪、路噪、空调声都很常见。不加噪声训练,实车测试时识别率会掉10个点以上。
4.3 语言模型:N-gram与神经网络
语言模型的任务,是给词序列打分。比如“打开空调”得分高,“打开空条”得分低。
传统做法是N-gram。N-gram统计的是“前N-1个词出现后,下一个词的概率”。比如2-gram(bigram)就是看“打开”后面跟“空调”的概率。
N-gram简单、快、可解释。但有个问题:它只能看到局部上下文。比如“我想听周杰伦的《七里香》”,N-gram很难捕捉到“周杰伦”和“七里香”之间的远距离关系。
后来神经网络语言模型(NNLM)出现了。RNNLM、LSTM LM、Transformer LM,一个比一个强。它们能建模长距离依赖,效果明显好于N-gram。
我在座舱项目里,用的是“N-gram + 神经网络”的混合方案。N-gram做快速解码,神经网络做重打分。这样既保证了实时性,又提升了准确率。
| 模型类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| N-gram | 速度快、可解释性强 | 无法建模长距离依赖 | 实时性要求高的场景 |
| RNNLM | 能建模长距离依赖 | 训练慢、推理慢 | 离线重打分 |
| Transformer LM | 并行计算、效果最好 | 资源消耗大 | 云端大模型 |
避坑指南:我曾经在项目里直接用了开源的通用语言模型,结果在座舱场景下效果很差。因为用户说的都是“导航到XXX”、“播放XXX”,这些短语在通用语料里出现频率低。后来我专门收集了座舱语料,微调了语言模型,准确率才上来。
4.4 端到端识别模型:一步到位
传统ASR的“三件套”虽然经典,但太复杂了。每个模块都要单独训练、调优、部署。而且模块之间的接口设计不好,容易出问题。
端到端模型,说白了就是“输入音频,直接输出文字”。中间没有声学模型、语言模型、解码器的区分。一个神经网络搞定所有。
主流的端到端模型有三种:
- CTC(连接时序分类):最早期的端到端方案。它假设每一帧的输出是独立的,然后通过“空白符”处理对齐问题。CTC简单,但效果一般。
- RNN-T(循环神经网络转录器):Google提出的方案。它不假设帧独立,而是用“预测网络”来建模语言信息。RNN-T在流式识别中表现很好。
- Transformer/Conformer:基于自注意力机制。效果最好,但计算量大。适合离线场景。
我在座舱项目里,最终选的是RNN-T。原因很简单:座舱需要实时识别。用户说“导航到天安门”,系统得在说完之前就开始出结果。RNN-T天然支持流式解码,延迟低。
# 伪代码:RNN-T模型结构示意
class RNNTModel(nn.Module):
def __init__(self):
self.encoder = Encoder() # 声学编码器
self.prediction = Prediction() # 语言预测网络
self.joiner = Joiner() # 联合网络
def forward(self, audio_features):
# 编码器处理音频
encoded = self.encoder(audio_features)
# 预测网络处理已输出的文本
predicted = self.prediction(prev_tokens)
# 联合网络输出最终概率
output = self.joiner(encoded, predicted)
return output
核心要点:端到端模型虽然方便,但也不是万能的。它对数据量的要求很高。传统ASR可能几万小时数据就够了,端到端模型往往需要几十万小时。座舱场景下,如果数据不够,我建议还是用传统方案或者混合方案。
4.5 实际项目中的选择建议
说了这么多,到底怎么选?我给大家一个参考:
- 资源受限(车机芯片弱):传统ASR(GMM/DNN + N-gram)。轻量、快速、可裁剪。
- 资源中等(有GPU但不大):混合方案。DNN/LSTM声学模型 + N-gram解码 + 神经网络重打分。
- 资源充足(云端或高端车机):端到端模型(RNN-T或Conformer)。效果好,但需要大量数据。
我个人习惯是:先跑一个传统ASR做基线,然后逐步替换成端到端。这样每一步都有对比,出了问题也知道是哪一步导致的。
小技巧:不管选哪种方案,一定要做“热词”优化。座舱场景里,“导航”、“空调”、“音乐”这些词出现频率极高。把它们加入语言模型或解码器的热词列表,能显著提升用户体验。
好了,这一章就到这里。下一章我们聊聊语音合成(TTS),也就是让车机“开口说话”。到时候我会分享一些让合成语音更自然的技巧,敬请期待。