14. 语音识别怎样训练:从声音到文字的对齐
前面的篇章都在训练读文字、写文字的模型。资料助手接上麦克风以后,小林对着手机说“年假怎么申请”,最先工作的是语音识别(ASR,Automatic Speech Recognition):把一段声音变成文字。它的训练和大语言模型有一个根本差别:输入是每秒成千上万个采样点,输出只有几个字,而训练数据只告诉你“这段音频说的是这句话”,没告诉你哪一小段声音对应哪个字。这一篇先把声音变成模型能吃的特征并算清数量,再看 CTC、Transducer、注意力编解码三种方法怎样解决这个“对不上”的问题,最后看 Whisper 的弱监督大数据和 wav2vec 2.0 的自监督预训练。读完你应该能判断一个语音识别模型属于哪一类、为什么有的能边说边出字、有的要等说完,以及训练一个可用的识别器要多少标注数据。
一句 5 秒的提问有多少个数
麦克风记录的是气压随时间的起伏。语音识别常用 16 kHz 采样,也就是每秒记 16,000 个数。小林这句话说了 5 秒:
text
采样点数 = 采样率 × 时长 = 16,000 × 5 = 80,000 个数直接把 8 万个数喂给模型并不划算:单个采样点几乎不携带“这是哪个音”的信息,区分“年”和“连”靠的是一小段时间里各个频率的能量分布。所以先做特征提取,Whisper 的论文给出了一套典型口径:
text
窗长 25 ms → 16,000 × 0.025 = 400 个采样点
步长 10 ms → 16,000 × 0.010 = 160 个采样点
每秒帧数 ≈ 1 ÷ 0.010 = 100 帧
5 秒 ≈ 500 帧(严格按 (80,000 − 400) ÷ 160 + 1 ≈ 498 帧,实现里常补边凑整)每一帧是一段 25 ms 的短窗,相邻两帧错开 10 ms,所以有 15 ms 重叠,保证一个音不会正好被切在两帧的缝里。对每帧做傅里叶变换得到频谱,再用 80 个按 Mel 刻度排布的滤波器把频谱压成 80 个数。Mel 刻度模仿人耳:低频分得细、高频分得粗。最后取对数,把动辄差上千倍的能量压到相近的数量级。结果叫 log-Mel 特征:
text
5 秒提问的特征 = 500 帧 × 80 维 = 40,000 个数图里最后一步是神经网络编码器。Whisper 的编码器入口有两层卷积,第二层步长为 2,帧率从每秒 100 降到 50,5 秒就是 250 帧。到这里问题就清楚了:编码器给出 250 个向量,标注是“年假怎么申请”6 个字。训练数据里没有“第 31 到 58 帧是‘年’”这样的信息,人工逐帧标注又贵得不现实。语音识别训练的核心,就是在不知道对齐的情况下也能算出损失。
数字的细节因模型而异:Whisper large-v3 把 Mel 频带从 80 个改成了 128 个,wav2vec 2.0 直接从原始波形用卷积提特征。但“每秒几十到一百帧、一句话几百帧对几个字”这个量级关系基本不变,它决定了下面三种方法的设计。
三种对齐方法
早期的语音识别先用另一套模型强行算出每帧对应哪个音素(强制对齐),再逐帧训练分类器,流程长、误差会传下去。现在主流的端到端方法有三种思路,同一句话放在一起比较:
CTC:每帧出一个符号,再合并
CTC(Connectionist Temporal Classification,连接时序分类,Graves 等人 2006 年提出)让编码器在每一帧都输出一个符号:要么是一个字,要么是一个特殊的 blank,表示“这一帧不出字”。得到逐帧序列后,先合并相邻的重复字,再删掉 blank:
text
逐帧输出:年 年 _ 假 _ _ 怎 么 _ 申 请 _
合并重复:年 _ 假 _ 怎 么 _ 申 请 _
删掉 blank:年假怎么申请blank 还有一个作用:“看看”这样连续相同的字必须写成“看 _ 看”,否则会被合并成一个。能折叠成“年假怎么申请”的逐帧写法有成千上万种,CTC 的损失把所有这些路径的概率加起来,要求这个总和越大越好。路径虽多,但相邻帧之间的转移规则很简单,可以用动态规划在“帧数 × 文本长度”的表格里一次算完,不需要知道真正的对齐。
CTC 的代价来自一个假设:每一帧的输出只看声音,互相之间条件独立。模型在第 40 帧写“年”时,并不知道第 20 帧写了什么。这让它计算快、天然适合流式,但缺少文字上下文,同音字和专有名词容易写错,实际系统常在解码时加外部语言模型或热词。
Transducer:让输出看见已经写出的字
Transducer(常称 RNN-T,Graves 2012 年提出)在 CTC 的编码器旁边加了一个预测网络,它读已经输出的文字,作用类似一个小语言模型;再用一个 joiner(联合网络)把“第 t 帧听到了什么”和“已经写到第 u 个字”合起来,给出下一步的分布。每一步要么输出一个字(送回预测网络,停在同一帧再试),要么输出 blank(前进到下一帧)。
它同样对所有可能的路径求和来训练,但输出不再相互独立,弥补了 CTC 最大的短板;同时又是逐帧推进的,说一个字出一个字,因此成了手机输入法、会议实时字幕这类流式识别的主流结构。训练成本是另一回事:joiner 要为每个“帧 × 已输出字数”的组合算一次整张词表的分布。
text
T = 250 帧,U = 6 个字,词表 V = 5,000(示意值)
joiner 输出 = T × (U + 1) × V = 250 × 7 × 5,000 ≈ 875 万个数 / 条
一批 32 条、FP32 存储:875 万 × 32 × 4 字节 ≈ 1.1 GB,只是这一个张量句子更长、词表更大时这个三维张量增长很快,所以 Transducer 训练框架普遍要做裁剪或分块计算。CTC 只有“帧数 × 词表”这一层,便宜得多。
注意力编解码:先听完,再像写文章一样逐字生成
第三种思路干脆不显式处理对齐。编码器一次读完整段音频(Whisper 每次读 30 秒),解码器像语言模型一样逐个预测下一个字,每一步用交叉注意力在全部编码器帧里查找“现在该听哪一段”。损失就是普通的交叉熵,和训练大语言模型预测下一个 token 完全相同。
这种结构上下文能力最强,还能把翻译、语种识别、时间戳当成不同的输出格式一起学。代价有两个:要等整段音频才能开始解码,流式需要额外改造;对齐完全靠注意力学,没对上时解码器会凭语言习惯继续写,出现重复或凭空编造的句子,第 15 篇会专门讨论这种幻觉。
| 方法 | 训练损失 | 输出之间 | 流式 | 典型代表 |
|---|---|---|---|---|
| CTC | 所有对齐路径求和 | 条件独立 | 天然支持 | wav2vec 2.0 微调头、很多端侧模型 |
| Transducer | 所有对齐路径求和 | 依赖已输出文字 | 天然支持 | 流式输入法、实时字幕 |
| 注意力编解码 | 逐字交叉熵 | 依赖已输出文字 | 需要改造 | Whisper |
实际系统常常混用,例如训练时同时加 CTC 和注意力两个损失,让 CTC 帮注意力更快学会单调对齐。
编码器与解码方式的两个变体
三种方法说的是“怎样对齐”,编码器本身用什么结构是另一维度。Conformer(2020)在 Transformer 层里插入卷积模块:自注意力负责全句范围的依赖,卷积负责几十毫秒内的局部声学模式。这两种依赖在语音里同时存在,所以 Conformer 成了 CTC 和 Transducer 模型里最常见的编码器。
中文场景常见的 Paraformer(2022,阿里达摩院,开源在 FunASR 工具包中)则改的是解码方式。它属于非自回归模型:先用一个 CIF 预测器根据声学信息估计这句话有几个字,并为每个字汇总出一个声学向量,再让解码器一次性并行输出全部字,不用一个个往后写。论文在 AISHELL 公开集和 2 万小时工业数据上报告,精度接近自回归 Transformer,速度快 10 倍以上。代价是字与字之间的依赖建模弱于自回归,论文为此加了一个按“字猜错多少”调整训练的采样器。
Whisper:用 68 万小时弱监督数据换鲁棒性
传统做法是用几百到几千小时人工精标的录音训练。Whisper(OpenAI,2022)换了思路:从互联网收集带字幕的音频,共 680,000 小时,其中 117,000 小时覆盖英语以外的 96 种语言,另有 125,000 小时是“外语音频 → 英文文本”的翻译数据。这些字幕没有经过逐句人工校对,所以叫弱监督:数量极大,但有错字、有不对齐、甚至有别的识别系统自动生成的字幕。论文专门写了启发式规则来剔除机器生成的字幕,否则模型会学到别家系统的错误习惯。
弱标注换来的是鲁棒性。精标数据集大多在安静环境里朗读,模型换到嘈杂会议室、电话录音就明显变差;Whisper 见过各种口音、噪声和录音设备,开箱即用时更稳。后续的 large-v3 走得更远:按官方模型卡,它用了 100 万小时弱标注音频,加 400 万小时由 large-v2 自动转写的伪标注音频,参数约 15.5 亿,相比 large-v2 错误率降低 10%—20%。用上一代模型给海量无标注音频打标签再训练下一代,和第 13 篇讲的蒸馏是同一个思路。
伪标注也会把上一代的错误一起传下去。对资料助手来说,这意味着 Whisper 在通用中文上可用,但“钉钉审批”“OKR”这类训练数据里少见的组合,以及公司特有的项目代号,仍可能写错,这是下一篇微调要处理的问题。
wav2vec 2.0:先听大量无标注录音
有标注的语音贵,无标注的语音便宜。自监督预训练先让模型只听声音、自己出题自己学,再用少量标注数据微调。wav2vec 2.0(Meta,2020)的做法和第 07 篇的“预测被遮住的内容”类似:卷积网络把波形变成隐向量,随机遮住一部分时间步,再让 Transformer 根据上下文,从若干候选中挑出被遮住位置的真实量化向量(对比学习:正确答案的得分要高过干扰项)。
论文的结果说明了这条路线的价值:在 5.3 万小时无标注音频上预训练后,只用 10 分钟有标注数据微调,LibriSpeech 测试集的词错误率就到了 4.8%(干净子集)和 8.2%(较难子集);用 1 小时标注数据,就超过了此前用 100 小时标注数据的最好结果。微调时通常在预训练编码器上接一个 CTC 输出层。
10 分钟这个结果有前提:英文朗读语料、预训练和测试数据风格接近、评测集相对干净。换到中文会议录音、方言或领域术语,所需标注量会多得多,它证明的是“预训练大幅降低了对标注的依赖”,而不是任何场景 10 分钟都够。
数据规模与标注成本
把常见的数据量级放在一起,能看出不同路线依赖什么:
| 数据 | 规模 | 标注方式 |
|---|---|---|
| AISHELL-1 | 约 178 小时,400 名说话人,安静室内朗读 | 人工精标,常用作中文入门基准 |
| WenetSpeech | 1 万多小时标注 + 2400 多小时弱标注 + 约 1 万小时无标注 | 视频字幕经 OCR 对齐,播客用识别系统生成候选 |
| Whisper 原版 | 68 万小时 | 互联网字幕,弱监督 |
| Whisper large-v3 | 100 万小时弱标注 + 400 万小时伪标注 | 字幕 + 上一代模型自动转写 |
人工精标的成本远高于音频时长本身:转写员要反复回听含糊处、查专有名词、统一数字和标点写法,再由第二个人抽检,转写 1 小时音频花的人工远不止 1 小时,倍数取决于噪声、口音和规范的严格程度。这也是为什么大模型都在想办法用弱标注、伪标注和自监督绕开人工标注,而企业自己的微调数据往往只有几小时到几十小时,必须精挑细选。
一个不该从零训练的判断标准:如果目标只是让通用识别器在公司场景里更准,从头训练一个识别器需要上万小时数据和对应的算力,几乎总是不划算;在已有的 Whisper、Paraformer 或 Conformer 模型上微调,或者先用热词和后处理,成本低几个数量级。
声音先按 16 kHz 采样,再按 25 ms 窗、10 ms 步长变成每秒约 100 帧的 log-Mel 特征,一句话几百帧对几个字,训练要在不知道逐帧对齐的情况下算损失。CTC 用 blank 和合并规则对所有路径求和,快但输出彼此独立;Transducer 加上预测网络和 joiner,保留流式又能看见上文,代价是训练显存;注意力编解码像语言模型一样逐字生成,上下文最强但要等整段音频,还可能幻觉。Whisper 用海量弱标注和伪标注换鲁棒性,wav2vec 2.0 用自监督把标注需求降到很低。通用模型听不准公司内部的词和口音时,下一步就是语音识别微调。识别器在部署时怎样流式运行、怎样接进整条语音链路,见推理系列的语音与多模态推理。
