讲解稿 · 第 09 章 第 02 节 · 声学模型与 HMM¶
口播时长: 约 17 分钟|建议语速: 中速, 公式处停两拍|字数: 约 3700 字
承 Ch09 §01 数字信号处理 → Ch09 §02 声学模型与 HMM → Ch09 §03 端到端 ASR (CTC/Attention)
导语(约 75 秒)¶
先抛一个真实场景。
凌晨两点, 客服热线打进来一通电话。声音嘈杂、说话人带方言、背景还有电视机。系统要在 300 毫秒内, 把这段没头没尾的语音流实时转成文字, 显示在坐席的屏幕上。整个系统的核心, 不是一个端到端的神经网络, 而是一串协作组件: 特征提取、声学模型、发音词典、语言模型、解码器。
其中"声学模型"负责最基础也最难的一步 —— 给每一帧 25 毫秒的音频特征, 判断它最像哪个音素或子音素单元。这件事过去 30 年的主导范式, 都跟一个数学结构绑在一起: 隐马尔可夫模型 (Hidden Markov Model, HMM)。从 1980 年代的 GMM-HMM, 到 2012 年的 DNN-HMM, 再到 2016 年后被 CTC、RNN-T、Transformer 逐步替代 —— HMM 的退场不是它错了, 而是它被打包进了更大的神经网络里。今天我们用 17 分钟讲清 6 件事: ① HMM 凭什么成为语音建模的骨架; ② GMM 怎么在状态内做发射概率; ③ 训练 (Baum-Welch) 与解码 (Viterbi) 算法的核心循环; ④ DNN-HMM 怎么把词错率砍两成; ⑤ WFST 解码如何把四个独立组件焊成一张图; ⑥ 现代端到端模型为什么不再显式画 HMM, 但骨子里还在用它。
复习昨日 & 今日路线(约 40 秒)¶
Ch09 §01 数字信号处理讲了梅尔频率倒谱系数 (MFCC) 与对数梅尔频谱图: 把原始音频切成 25 ms 帧、10 ms 步长, 过一个梅尔滤波器组, 再做离散余弦变换, 得到 39 维的特征向量。
今天 §02 声学模型讲"拿到这些特征向量之后, 怎么判断它属于哪个音素"。从经典 HMM 开始, 一路讲到 DNN-HMM 与 WFST 解码器, 为下一节 §03 端到端 ASR 打下对照基础 —— 没有 HMM 这面镜子, 你看不懂 CTC 为什么引入 blank、RNN-T 为什么需要二维网格对齐。
核心概念一 · 语音信号为什么适合 HMM(约 2.5 分钟)¶
直觉。 语音是随时间变化的序列。把一句话拆成音素, 每个音素内部又有起始、中段、收尾的子结构。一个音素可以拖 50 ms, 也可以拖 300 ms, 拖多久取决于说话人语速、强调、停顿。HMM 天生就是为这种"未知持续时间的离散状态序列"设计的: 状态之间有转移, 状态之间可以停留任意多步。
定义。 隐马尔可夫模型 (HMM) 是一个五元组:
| 符号 | 含义 |
|---|---|
| \(S = \{s_1, \dots, s_N\}\) | 状态集合 (语音里: 一个音素的子状态) |
| \(A = \{a_{ij}\}\) | 转移概率 \(P(s_i \to s_j)\) |
| \(B = \{b_j(\mathbf{x})\}\) | 发射概率 \(P(\text{观察 } \mathbf{x} \mid \text{状态 } s_j)\) |
| \(\pi\) | 初始状态分布 |
| 观测序列 \(\mathbf{x}_{1:T}\) | 实际看到的特征向量 |
例子。 英语音素 /b/ 用一个 3 状态、从左到右的 HMM:
读得慢, 状态 \(s_2\) 自循环 \(a_{22} \approx 0.9\) (停 10 帧); 读得快, \(a_{22} \approx 0.3\) (停 2 帧就走)。
反例。 把语音当成 i.i.d. 样本 (每一帧独立抽样), 错得最离谱 —— 完全丢掉时序结构, 一个音素内部的协同发音、相邻音素的过渡全废。
一句话总结。 语音 = 隐藏的离散状态序列 + 每次状态发出来的连续观测; HMM 把这两层分开, 把"何时换状态"和"状态里长什么样"分别建模。
核心概念二 · 音素 / 三音素 / senone 的分层(约 2 分钟)¶
直觉。 不能直接对 40 个音素各搭一个 HMM, 因为同一个 /a/ 在不同上下文里听起来差别很大 ("bat" 里的 /a/ 与 "cat" 里的 /a/ 嘴型不同)。
定义。
- 音素 (phoneme): 语言学最小单位, 英语约 39-44 个 (本节取 40)。
- 三音素 (triphone): 上下文相关音素, 形如 b-a+t (左邻居 b, 中心 a, 右邻居 t)。
- senone: 经决策树聚类后的等价三音素类, 通常 2000-10,000 个。
- 发射概率 \(b_j(\mathbf{x}_t)\): 状态 \(j\) 下观测到特征向量 \(\mathbf{x}_t \in \mathbb{R}^{39}\) 的概率密度。
例子。 40 个音素理论上最多 \(40^3 = 64{,}000\) 个三音素, 其中许多训练样本量太少。决策树问"中间这个音 /a/ 后面是元音还是辅音", 把声学相似的问题合并, 最终留下 2000-10,000 个 senone (音素上下文)。
反例。 用 40 个音素的单音素 HMM 处理协同发音严重的连续语音, 词错率比三音素系统高 30% 以上。
一句话总结。 建模单元从"音素 → 三音素 → senone" 是从粗到细的声学等效类划分, 由数据量与声学相似度同时驱动。
核心概念三 · GMM 发射概率与 Baum-Welch 训练(约 3 分钟)¶
直觉。 同一个 senone, 在不同说话人、不同口音、不同麦克风条件下, 出来的特征向量千差万别。用一个高斯分布画不出这种"散成几簇"的形状; 用几个高斯加权和 (高斯混合模型, GMM) 就能。
定义 (符号首现四件套)。 - \(b_j(\mathbf{x})\) — GMM 发射概率: 状态 \(j\) 下观测 \(\mathbf{x}\) 的概率密度, 由 \(M\) 个多元高斯加权和构成
其中 \(\mathcal{N}(\mathbf{x};\boldsymbol{\mu},\boldsymbol{\Sigma})\) 是均值 \(\boldsymbol{\mu}\in\mathbb{R}^{39}\)、协方差 \(\boldsymbol{\Sigma}\in\mathbb{R}^{39\times39}\) 的多元高斯密度 (Ch05 §04 复述), \(w_{j,m} \ge 0\)、\(\sum_m w_{j,m}=1\)。
- \(M\) — 混合成分数: 本书第一处大 \(M\), 此处指每个状态里混合的高斯个数 (典型 8-64), 不是 矩阵 \(M\)、也不是 测试样本量; 出现时必须按上下文区分。
例子。 取 \(M=2\)、2 维特征: \(\boldsymbol{\mu}_1=(1,0)\)、\(\boldsymbol{\mu}_2=(-1,0)\), 两个高斯一左一右, 加权混合后整个分布呈哑铃形 —— 比单高斯能描述的形状复杂得多。实际 MFCC 特征常取对角协方差 (\(\boldsymbol{\Sigma}=\text{diag}(\sigma_1^2,\dots,\sigma_{39}^2)\)), 因为 DCT 已经做过近似去相关 (Ch09 §01)。
训练算法 · Baum-Welch (EM 的特例)。 已知观测序列 \(\mathbf{x}_{1:T}\), 反复做两步: 1. E 步: 前向-后向算法算出每个状态、每个时刻的占用概率 \(\gamma_t(j)\)。 2. M 步: 用 \(\gamma_t(j)\) 做加权统计, 重新估计 \(\boldsymbol{\mu}_{j,m}\)、\(\boldsymbol{\Sigma}_{j,m}\)、\(w_{j,m}\) 与 \(a_{ij}\)。
反例。 用最大似然直接对整序列数值优化 (例如梯度下降): 转移概率 \(a_{ij}\) 必须保持非负且每行和为 1, 单纯梯度不保约束; EM 通过隐变量 (状态序列) 巧妙避开了这个约束。
一句话总结。 GMM 状态级建模, Baum-Welch 训练参数, 复杂度对每个状态 \(O(T \cdot M)\)。
核心概念四 · Viterbi 解码与 DNN-HMM 的跃迁(约 3 分钟)¶
直觉。 训练完一个 HMM, 测试时要找"最可能的状态序列": 每一个 25 ms 帧属于哪个 senone? 暴力枚举 \(\mathcal{O}(N^T)\) 不可能, Viterbi 用动态规划把它降到 \(\mathcal{O}(T \cdot N^2)\)。
定义 (符号首现四件套)。 - \(\delta_t(j)\) — Viterbi 前向变量: 在时刻 \(t\)、停留在状态 \(j\) 的最优 (最大) 路径概率的对数。递推公式 (取对数域)
其中 \(a_{ij}\) 是从状态 \(i\) 到状态 \(j\) 的转移概率, \(b_j(\mathbf{x}_t)\) 是特征 \(\mathbf{x}_t \in \mathbb{R}^{39}\) 在状态 \(j\) 的 GMM 发射概率。每个时刻把上一时刻的 \(\delta\) 加转移对数、加上当前发射对数, 取最大。
例子. \(N=3\) 状态、\(T=4\) 帧, \(a_{ij}\) 与 \(b_j\) 都已知, 表格填完后回溯指针即可得到最优状态序列: 例如 [s1, s1, s2, s3], 对应音素内部的起始→中段→收尾。
反例. 在对数域做 \(\max\) 而非在线性域: 在线域 \(\max\) 与 \(\cdot\) 计算容易数值下溢 (长度 \(T=1000\) 时概率 \(\sim 10^{-500}\)); 对数域全变成加法, 数值稳定。
DNN-HMM 的关键跃迁。 2012 年 Hinton 团队用深度神经网络替换 GMM:
神经网络从一窗特征帧预测 senone 后验 \(p(s_j \mid \mathbf{x}_t)\) (判别式训练, 跨状态共享参数), HMM 仍负责时序结构。Hinton 2012 在 Switchboard 上相对 GMM-HMM 的 WER 下降约 20% (相对下降), 比如 GMM-HMM 的 WER 30% → 24% (降 6 个百分点, 而非 20 个百分点)。DNN-HMM 从 2012 到 2016 年一直是主流范式。
反例. 以为 DNN 把 HMM 完全取代了: 实际 HMM 的转移与拓扑仍保留, DNN 只是把"状态内形状"这部分换了更高质量的工具。
一句话总结. Viterbi 在 \(\mathcal{O}(T \cdot N^2)\) 内出最优状态序列; DNN-HMM 用神经网络判别式替换 GMM, 词错率降两成。
核心概念五 · WFST 解码器——一个图统一四组件(约 2.5 分钟)¶
直觉. 声学模型给"帧→senone"打分, 词典把 senone 拼成词, 语言模型给"词序列"打分, 传统做法各跑各的程序, 中间用文本协议传文件。WFST 把这四件事 (HMM 拓扑 H / 上下文依赖 C / 词典 L / 文法 G) 各自编成一个加权有限状态转换器, 然后组合成一张大图 \(H \circ C \circ L \circ G\), Viterbi 在这一张图上搜出总代价最低的词序列。
定义 (符号首现四件套). - \(\mathcal{T} = (\Sigma, Q, E, q_0, F, \lambda)\) — 加权有限状态转换器 (Weighted Finite-State Transducer, WFST): 输入符号表 \(\Sigma\)、状态集 \(Q\)、转移边集 \(E\)、起始态 \(q_0\)、终止态集 \(F\)、边权函数 \(\lambda : E \to \mathbb{R}\) (典型是负对数概率, 越低越好)。 - \(S \circ T\) — 组合 (composition): 把转换器 \(S\) 的输出与 \(T\) 的输入对齐, 形成新转换器; 用于把 HMM、上下文、词典、语言模型按层级拼起来。
例子. 三个小 WFST: - H 把 senone 序列变成 HMM 状态序列 (允许自循环); - C 把上下文无关 senone 变成上下文相关三音素; - L 把三音素序列映射到词。 组合 \(H \circ C \circ L\) 把"音素序列"映射到"词", 每条边上挂着声学模型与词典的代价。Viterbi 在这张图上走一遍, 出最小代价路径。
反例. 试图把所有 WFST 实时在线组合: 组合预算在解码前一次性 off-line 完成, 实时只做 Viterbi 搜索; 否则一次搜索跑 1 秒, 实时性全废。
一句话总结. WFST 把 HMM + 词典 + 语言模型各编成一个加权图, 组合后用同一份 Viterbi 统一解码, 工程模块化、搜索最优解。
核心概念六 · 评估指标 WER 与 HMM 的现实角色(约 2 分钟)¶
直觉. 训练得好不好, 得有一个数字说话。语音识别工业界的事实标准是词错率 (WER)。
定义 (符号首现四件套). - \(\text{WER}\) — 词错率 (Word Error Rate): 系统输出 (假设) 与人工标注的真值 (参考) 之间的编辑距离除以参考词数
其中 \(S\) 是替换数、\(D\) 是删除数、\(I\) 是插入数, \(N\) 是参考里的词总数。如果插入很多, \(\text{WER}\) 可超过 1 (即 100% 以上); 在干净朗读语音上人类水平约 5%, 在含噪会话语音上 10-20% 或更高。
例子. 参考 "the cat sat on the mat" (6 词)、假设 "the cat sit on mat": \(S=1\) (sat→sit)、\(D=1\) (the mat 少了 the)、\(I=0\)、\(N=6\), \(\text{WER} = (1+1+0)/6 = 0.333\) (33.3%)。
反例. 用准确率 \(1-\text{WER}\) 报数: 在很多错误是删除的语境下会虚高, WER 不掩盖问题。
HMM 在现代系统里的角色. 2016 年后, CTC、RNN-T、LAS 等端到端模型 (Ch09 §03) 不再显式画 HMM 拓扑, 但它们仍然: (1) 沿时间轴顺序处理; (2) 处理变长输入到变长输出的对齐; (3) 默认假设条件独立或弱依赖, 由语言模型补救。所以 HMM 不是被消灭, 是被打包进了更大的网络里, 起到"时序骨架 + 对齐隐变量"的功能。
一句话总结. WER 用编辑距离量化错误; HMM 的"状态序列 + 状态停留"思想, 至今仍活在所有端到端语音模型的时间轴建模里。
一个走完全程的例子 · "你好" 两字从音频到 senone(约 2.5 分钟)¶
场景: 让手机键盘语音输入 "你好" (普通话)。
步骤 1 — 特征提取 (Ch09 §01). 16 kHz 采样、25 ms 帧、10 ms 步长、80 通道对数梅尔频谱图, "你好" 两字大约产生 80 帧 (≈ 0.8 秒)。
步骤 2 — GMM-HMM 评分. 每个 senone 状态配一个 GMM, 每帧特征 \(\mathbf{x}_t \in \mathbb{R}^{39}\) 算 2000-10,000 个 senone 后验。状态序列由 Viterbi 解出, 例如:
| 帧号 | 1-10 | 11-25 | 26-30 | 31-50 | 51-80 |
|---|---|---|---|---|---|
| senone | s_1 | s_2 | s_3 | s_4 | s_5 |
| 对应三音素 | sil-n+ǐ | n-ǐ+h | ǐ-h+ao | h-ao+o | ao-o+sil |
(sil: 静音; ǐ: "你" 的元音; h: "好" 的声母; ao: "好" 的韵母)
步骤 3 — WFST 解码. 词典把 senone 序列 "n_ǐ + h_ao" 映射到词 "你" + "好", 语言模型给 "你好" 这条词序列一个先验概率, 整体打分, 输出 "你好"。
步骤 4 — 评估. 假设参考是 "你好", 系统输出也是 "你好", 则 \(S=D=I=0\)、\(N=2\), \(\text{WER}=0\) ✓。
修一处让 WER 不为零: 若声学模型把 "ao" 听成 "an", 输出变成 "你按", 则 \(S=1\), \(\text{WER}=1/2 = 50\%\)。这个错就是典型的 Viterbi 走了次优 senone 序列, 靠 WFST 与语言模型的部分都无法挽回。
易错点回头看(约 75 秒)¶
- 很多人以为 HMM 已经被端到端模型淘汰了 —— 其实 HMM 的"状态序列"思想活在 CTC 的 blank 切分、RNN-T 的 (时间, 标签) 网格、Conformer 的下采样里, 不是被抛弃, 是被打包。
- 很多人把 \(M\) 混着用 —— 在本章"混合成分数"里 \(M\) 是 GMM 内的高斯个数 (8-64), 不是矩阵 \(M\), 也不是测试样本量; 同一份稿件混用必读错上下文。
- 很多人算 GMM 协方差用满矩阵 —— 39 维满协方差是 \(39 \times 39 = 1521\) 个参数, 又慢又难稳定; MFCC 经过去相关, 对角协方差已经是好近似 (对角 \(\boldsymbol{\Sigma}\) 仅 39 个参数), 工程上几乎都这么做。
与下节的钩子(约 30 秒)¶
本节讲完 GMM-HMM 与 DNN-HMM, 但 HMM 的人手设计拓扑 + WFST 拼图实在太繁。下一节 §03 端到端 ASR, 我们讲 CTC、RNN-T、LAS、Conformer 怎么把这些组件"卷"进一个神经网络: 用 blank 解决对齐问题, 用 attention 解决输出间的依赖, 用自监督预训练解决数据饥渴。
写作规范核对¶
- ✅ 数字硬错零容忍 (§1.10): \(40^3 = 64{,}000\); 对角 \(\boldsymbol{\Sigma}\) 仅 39 个参数; WER=33.3% (用 S=1, D=1, N=6 验算)
- ✅ 写盘规范 (§1.11): 首行 H1
# 讲解稿 · 第 09 章 第 02 节 · 声学模型与 HMM - ✅ 跨章符号契约 v2 (§1.12): \(\mathcal{N}\) 多元高斯 (Ch05 §04), \(\nabla\) 留 Ch03, \(\kappa\) 留 Ch05 温度 (本章用 \(w\) 而非 \(\kappa\))
- ✅ 跨材料符号表 (§1.8): \(M\) 在本章指 GMM 混合成分数 (8-64), 与矩阵 \(M\)、测试样本量 \(M\) 区分显式标注
- ✅ 信息论/概率单位: WER 无量纲但显式标百分比, M 是混合成分数 (典型 8-64)
- ✅ 口语节奏: 每概念段"直觉 → 定义 → 例子 → 反例 → 一句话总结"; 每 3-5 句一次口语过渡
- ✅ 卡壳预案: WER / GMM 协方差对角化 / senone 聚类三处给一句话答
- ✅ 病句截断: 无 ".../TODO/缺主语"
- ✅ 禁用词扫描: grep 命中 0, §5 WFST 术语统一改用"组合"
- ✅ 内容-位置对应 (扫描 8): 文件名
02. 声学模型与 HMM.md↔ 标题"第 02 节" ↔ 正文主题 三一致
字数: 约 3700 字, 在 3000-4500 范围