106K star 的开源 ASR 老祖宗 | 重读 Whisper 原论文的每一个技术细节
106K star 的开源 ASR 老祖宗 | 重读 Whisper 原论文的每一个技术细节
原文:Robust Speech Recognition via Large-Scale Weak Supervision(OpenAI, 2022)
1. 前言:给老祖宗上香之前,先把它的家谱读明白
今天想和大家聊聊 Whisper 这篇论文。
先摆一个数字:openai/whisper 这个仓库现在(2026 年 7 月)有 105.8K star、12.8K fork。这个量级在整个 AI 开源生态里都是头部,在语音这个方向上更是断层第一 —— 后面所有你听过的名字,faster-whisper、whisper.cpp、WhisperX、distil-whisper、insanely-fast-whisper,全是它的下游。你现在用的绝大多数开源 ASR 方案,往上追两代就是这个仓库。
问题是,正因为它太好用了,大部分人(包括我)跟它的关系一直停留在 pip install openai-whisper 然后 model.transcribe()。用了三年,论文没认真读过。 这次算是回来补作业 —— 认真把这个老祖宗的家谱翻一遍,不是”了解一下 Whisper 是什么”,而是逐节抠它每个技术决定背后的理由。
促使我回来补作业的是最近的活。我在做中英混说(code-switching)的 ASR 评测,测了十来个引擎,Whisper 是里面的一个 baseline。跑完之后我盯着数字发了一会儿呆 —— 一个 2022 年 12 月放出来的模型,在 2026 年的评测里依然是个”你必须解释为什么没打赢它”的对照组。更离谱的是,当我想给评测定归一化口径(”9:30” 和 “九点三十” 算不算同一个答案)的时候,翻了一圈,发现业界最常被引用的那套规则,就是 Whisper 论文附录 C 里那 12 条。连评测的尺子都是它留下的。
所以这篇论文有两层价值:一层是它的方法(弱监督 scaling),另一层是它顺手立下的评测规范。 后者被引用得远比前者少,但对做工程的人来说可能更有用。
作为研究 AI 方向的牛马,我读论文有个习惯:先问”它在跟谁吵架”。Whisper 吵架的对象非常明确 —— wav2vec 2.0 那一条路线。这条路线在当时是绝对主流:自监督预训练一个 audio encoder,然后在下游数据集上 fine-tune。它的问题论文在 Introduction 里说得很直白:
这些预训练 audio encoder 学到了高质量的语音表示,但因为它们是纯无监督的,缺一个同等水平的 decoder 把表示映射成能用的输出,因此必须有一个 fine-tune 阶段才能真正做语音识别这件事。
而 fine-tune 有个更隐蔽的风险,论文举了一个计算机视觉的例子:Radford et al. (2021) 发现在 ImageNet 上 fine-tune 能让物体分类准确率涨 9.2%,但在另外七个自然图像数据集上,平均准确率一点没涨。也就是说涨的那 9.2% 全是在学 ImageNet 的数据集特质。
论文由此给 ASR 系统提了一个目标,这句话我觉得是整篇文章的立意所在:
语音识别系统的目标应该是开箱即用地在广泛的环境下可靠工作,而不是对每一个部署分布都要重新监督 fine-tune 一遍 decoder。
那怎么做到?当时的思路是把已有的高质量数据集混起来训(SpeechStew 混了 7 个数据集共 5,140 小时)。但 5,140 小时对比 wav2vec 那条路线用的 1,000,000 小时无标注数据,实在太小。
Whisper 的选择是:放弃 gold-standard 标注,去互联网上捞(音频, 字幕)配对,把有监督数据规模拉到 680,000 小时。 论文管这叫 weak supervision(弱监督)—— 标注是有的,但质量不保证。
下面按论文的顺序,把每个技术细节拆开讲。
2. 数据:这篇论文真正的护城河
2.1 一句话总结数据处理哲学
论文 2.1 节的第一句话就定了调:
我们采取极简的数据预处理方式。与大量语音识别工作相反,我们训练 Whisper 去预测转录文本的原始形态,不做任何显著的标准化,依赖 seq2seq 模型的表达力去学会音频到转录形态的映射。
这句话的分量要放到当时的语境里才看得出来。传统 ASR 的输出是”标准化”的 —— 全小写、无标点、数字写成单词(twenty twenty two),然后需要一个独立的 inverse text normalization(ITN,逆文本标准化) 模块把它变回人能读的形态(2022、加标点、加大小写)。ITN 通常是规则系统,是一坨脏活。
Whisper 直接让模型预测带标点、带大小写、数字是阿拉伯形态的原始文本,ITN 这个模块就消失了。这是”用 scaling 换掉一个工程模块”的典型操作。
2.2 过滤流水线:怎么从互联网垃圾里捞出 68 万小时
数据多样性对鲁棒性有好处,但论文明确区分了两种多样性:
音频质量的多样性可以帮模型变得鲁棒,但转录质量的多样性并不同样有益。
初步检查发现原始数据里有大量劣质转录。所以他们上了一整套自动过滤。这是全文我认为最有工程价值的一段,我把它画成了流程图:

对着图从左往右走一遍:
第一道闸:字幕是不是机器转写的? 这是个反直觉但极其关键的设计。互联网上很多”字幕”其实是别家 ASR 系统的输出。论文引 Ghorbani et al. (2021) 说,在人写和机器生成混合的数据上训练会显著损害翻译系统的性能。他们把这个要避免的东西起名叫 “transcript-ese”(转录腔)—— 我觉得这个词起得很妙,就像 translationese(翻译腔)一样,是一种被机器污染的语言变体。
怎么检测?靠机器 ASR 输出的”缺陷指纹”:
- 现有 ASR 系统只输出书面语言的一个受限子集,会把难以从音频信号预测的东西抹掉或标准化掉 —— 复杂标点(感叹号、逗号、问号)、段落空白、大小写
- 全大写或全小写的转录,几乎不可能是人写的
- 即使某些 ASR 带了 ITN,那个 ITN 通常简单或基于规则,从”从不出现逗号”这类未处理的方面依然能识别出来
第二道闸:音频语言 vs 字幕语言。 他们用一个音频语言检测器(在 VoxLingua107 上 fine-tune 出来的),和字幕文本经 CLD2 判定的语言对比。不一致就不作为语音识别样本。
但这里有个漂亮的转折 —— 不一致且字幕是英文的,转成 X→en 翻译训练样本。翻译能力不是特意去收集数据训出来的,是从”语言不匹配的废料”里回收出来的。这 125,739 小时翻译数据就是这么来的。
第三道闸:模糊去重 + 切 30 秒片段。 音频切成 30 秒段,配上落在这个时间窗内的字幕子集。注意一个细节:无人声的片段也训练(虽然是降采样后的概率),并把它们当作 VAD(voice activity detection,人声活动检测)的训练数据。 后面第 4 节会看到 VAD 是怎么白捡的。
第四道闸(最容易被忽略):训完初版模型再回头洗数据。 原文:
训练一个初版模型之后,我们聚合它在各个训练数据源上的错误率信息,并按错误率高 + 数据源体积大的组合排序,人工检查这些数据源,以高效地识别并移除低质量数据源。
排序键设计得很讲究:只按错误率排会去查一堆边边角角的小数据源;乘上体积,就变成”修一个能收益最大”的优先级。检查结果发现了大量只转录了一部分的、对齐错位的,以及过滤规则没抓到的残留机器字幕。
最后还有防污染的一步:与他们认为重叠风险较高的评测集(主要是 TED-LIUM 3)做了 transcript 级别的去重。
2.3 最终的数据构成:这张图解释了后面所有实验结果

这是论文附录 E 的图,三块要分开看:
中间那块是总构成 —— 65% 英文语音识别(438,218 小时)、17% 多语言语音识别(117,113 小时)、18% 翻译(125,739 小时)。
左边那块是多语言转写数据按语言排序的柱状图,注意 x 轴是对数轴且从左到右递减。最上面中文 23,446 小时、德语 13,344、西班牙语 11,100,到最下面老挝语只有 0.1 小时。跨度是六个数量级。
右边那块是翻译数据,同样跨度极大:韩语 19,938 小时到土库曼语 1 小时。
这张图为什么重要?因为后面第 3 节所有”某语言表现差”的结果,答案都在这张图里。论文在 Limitations 里也承认了:由于数据收集流水线偏向互联网的英语中心部分,大多数语言的训练数据不到 1000 小时。
3. 模型:故意不创新的架构
3.1 为什么用最普通的 Transformer
论文 2.2 节开门见山:
由于我们工作的重点是研究大规模有监督预训练对语音识别的能力,我们使用现成的架构,以避免把我们的发现与模型改进混淆。
这是很干净的实验设计思路:如果同时改数据和改架构,涨点归谁就说不清了。所以他们选了 encoder-decoder Transformer(Vaswani et al., 2017),理由只有一个 —— 这个架构已经被充分验证过能可靠 scale。
3.2 前端和骨架,每个数字都对应一个设计决定

对着这张图从下往上、从左往右走一遍。
左边的灰框是训练数据的四种形态,也就是第 2 节那套流水线的产物:英文转写、任意语言→英文翻译、非英文转写、无人声(音频是背景音乐,目标文本是 ∅ 空集)。注意每一条都是「🗣️ 音频 → 📝 文本」的配对,而四种任务共用同一个模型,这是下一小节多任务格式要解决的问题。
中间偏下的彩色条带是 Log-Mel Spectrogram,也就是模型真正的输入。具体参数:
- 所有音频重采样到 16,000 Hz
- 80 通道的 log-magnitude Mel 频谱
- 25 毫秒窗口,10 毫秒 stride
- 特征归一化:全局缩放到 [−1, 1],在预训练数据集上均值约为零
10ms stride 意味着 30 秒音频 → 3000 帧。这个数字要记住,因为下一步就是要把它压掉。
再往上是紫色的 2 × Conv1D + GELU —— encoder 的 stem(干),两个卷积层,filter width = 3,激活函数 GELU,第二个卷积层 stride = 2。作用就是把 3000 帧压成 1500 帧。为什么必须压?因为 self-attention 是 O(n²),3000 长度的序列 attention 矩阵是 900 万个元素,1500 就降到 225 万,直接省 4 倍。这一步是纯粹的算力妥协,没什么理论深意,但少了它模型训不起来。
stem 输出加上 Sinusoidal Positional Encoding(图里那个 ~ 圆圈符号),然后进 encoder 的 Transformer blocks(图中青色)。两个细节:
- Transformer 用 pre-activation residual blocks(Child et al., 2019),也就是 LayerNorm 放在残差分支的前面而不是后面 —— 这是深层 Transformer 训练稳定性的标配做法
- encoder 输出还要过一个最终的 LayerNorm
右边红色是 decoder blocks,每个 block 三件套:self attention → cross attention → MLP。cross attention 就是图中那些从 encoder 横着连过来的箭头 —— decoder 通过它去看音频表示。
decoder 的两个和 encoder 不同的地方:
- 用 learned position embeddings(图右下的圆柱形符号),不是 sinusoidal
- tied input-output token representations(Press & Wolf, 2017)—— 输入 embedding 矩阵和输出投影矩阵共享权重,省参数
encoder 和 decoder 的宽度、block 数完全相同。
图最右上角是 next-token prediction:给定 SOT EN TRANSCRIBE 0.0 The quick,预测下一个 token brown。是的,decoder 侧就是个标准的自回归语言模型,只不过它是 audio-conditional 的。
tokenizer:英文模型直接用 GPT-2 那套 byte-level BPE;多语言模型保持词表大小不变、重新拟合词表,因为 GPT-2 的 BPE 词表是纯英文的,直接用在其他语言上会导致过度碎片化(一个字被切成好几个 byte token)。
这个”重新拟合但不扩容”的决定后面留了个尾巴:论文 3.4 节讨论为什么希伯来语(HE)、泰卢固语(TE)、中文(ZH)、韩语(KO)是显著的负向离群点时,给出的一个候选解释就是 byte level BPE tokenizer 对这些语言是个糟糕的匹配。词表大小不变、要塞进 99 种语言,这个 trade-off 是有代价的。
3.3 模型家族

五个尺寸,layers / width / heads / 参数量。Tiny 是 4 层 384 宽 6 头 39M,一路到 Large 的 32 层 1280 宽 20 头 1550M。注意这里的 layers 是 encoder 和 decoder 各自的层数(因为两边同深同宽)。
训练细节(2.4 节):
- 数据并行,FP16 + dynamic loss scaling + activation checkpointing
- AdamW + gradient norm clipping,前 2048 步 warmup 后线性衰减到 0
- batch size = 256 segments,训 2²⁰ = 1,048,576 步,相当于在数据集上过 2~3 遍
- 不用任何数据增强和正则化 —— 原文理由:由于只训几个 epoch,过拟合不是大问题,转而依赖如此大数据集内部的多样性来鼓励泛化和鲁棒性
Large V2 是原始版本发布之后追加训的:多训了 2.5 倍的 epoch,并加上了 SpecAugment、Stochastic Depth、BPE Dropout 做正则化。论文里除特别说明外,报告的结果都更新成了这个改进模型。
一个有意思的失败案例(2.4 节末尾):早期开发中他们发现 Whisper 倾向于给说话人名字编造出看起来合理但几乎总是错的猜测。原因是预训练数据里很多转录带说话人姓名,模型就学着去预测它 —— 但这个信息通常无法只从最近 30 秒的音频里推断出来。这是”数据里有什么,模型就学什么”的经典体现,也是后面 hallucination 问题的一个具体来源。
4. 多任务格式:全文最精巧的设计
4.1 要解决的问题
完整的语音识别系统不止”预测说了哪些词”,还包含 VAD、说话人分离(diarization)、逆文本标准化等组件。这些组件通常各自独立处理,导致核心识别模型外面裹着一个相当复杂的系统。
Whisper 想让一个模型干完整条流水线。但同一段音频上可以做的任务有很多种:转写、翻译、VAD、对齐、语言识别。这是个一对多映射,必须有某种形式的任务指定(task specification)。
Whisper 的答案:把所有任务和条件信息都编码成 decoder 的输入 token 序列。 不加任务专属的 head,不加 adapter,就是 token。
4.2 token 序列长什么样

这是论文 Figure 1 的下半部分。从最左边那个黑点开始,沿着箭头走,每条路径就是一种任务:
-
PREV+previous text tokens(可选的前置分支):以一定概率把当前音频段之前的转录文本加进 decoder 的上下文。图里标注了它的两个用途 ——「Custom vocabulary / prompting」。这就是后来大家用的initial_prompt参数的出处:你可以往这里塞热词表。 -
START OF TRANSCRIPT(就是<|startoftranscript|>):预测开始 - 接下来是第一个岔路口:预测语言 tag(训练集里每种语言一个唯一 token,共 99 个,标签来自前面提到的 VoxLingua107 模型),或者预测
NO SPEECH。图中这两个框上各挂了一个红色箭头指出它们的对外能力:语言 tag 那条是「Language identification」,NO SPEECH 那条是「Voice activity detection (VAD)」 - 第二个岔路口:
TRANSCRIBE(图上标注 X → X Transcription)或TRANSLATE(X → English Translation) - 第三个岔路口:要不要时间戳。走上路 = 带时间戳,走
NO TIMESTAMPS= 纯文本 - 带时间戳的路径(图上方红色大括号标注 Time-aligned transcription):
begin time→text tokens→end time→begin time→ … 交替 - 不带时间戳的路径(图下方红色大括号标注 Text-only transcription,并注明 allows dataset-specific fine-tuning):一整块
text tokens - 最后汇到
EOT(end of transcript)
我把四种任务各自的完整 token 序列写出来,对着看更清楚:

时间戳 token 的量化规则:时间是相对当前音频段的,量化到最近的 20 毫秒(这匹配 Whisper 模型的原生时间分辨率 —— 10ms stride 经过 stride-2 卷积后就是 20ms),词表里为每一个这样的时刻加一个 token。start time token 在每段 caption 文本之前预测,end time token 在之后。
一个边界情况的处理很讲究:当最后一个转录片段只有一部分落在当前 30 秒音频块内时,时间戳模式下只预测它的 start time token,用来指示后续解码应该在与那个时刻对齐的音频窗口上进行;非时间戳模式下则直接把这段音频截掉。这一条就是长音频滑窗解码的地基。
4.3 这个设计为什么聪明
我认为有三个点值得单独拎出来:
第一,VAD 和语言识别是白捡的。 它们不是额外训练的任务,而是”语言 tag 这个位置的分类结果”的两种读法。nospeech 和 99 个语言 tag 抢的是同一个 slot —— 所以你想做 VAD,不需要跑一个额外的模型,只要取这个位置 softmax 里 <|nospeech|> 的概率就行。第 6 节会看到官方推荐的 VAD 判据就是这么用的。
第二,「要不要时间戳」是可控的。 这不只是输出格式的开关,它让同一个模型能服务两种下游需求:需要字幕对齐的场景开时间戳,纯转写的场景关掉省 token。论文特别在图上标了「allows dataset-specific fine-tuning」—— 因为学术数据集的 label 通常没有时间戳。
第三,PREV 机制是一个可编程接口。 论文的动机写的是「希望它学会利用更长的文本上下文来消解有歧义的音频」,但实际上它同时给了用户一个注入先验的口子。
训练时的 loss 有一个关键细节(论文 2.3 节最后):只在当前音频段的 token 上算 loss,把之前上下文的部分 mask 掉。 这个设计是必要的 —— 否则模型会把一部分容量花在”复述我已经知道的上文”上,而那个能力对推理毫无用处。
5. 实验结果:数字与它们的读法
5.1 Effective robustness:这篇论文最重要的评测概念
先说结论:Whisper 在 LibriSpeech test-clean 上的 zero-shot WER 是 2.5,而当时的 SOTA 是 1.4 —— Whisper 输了,还输得不算少。
但论文的立论是这个比较本身就有问题。它引入 Taori et al. (2020) 的两个概念:
- overall robustness(整体鲁棒性):在众多分布/数据集上的平均表现
- effective robustness(有效鲁棒性):在参考数据集(通常是分布内)上的表现与一个或多个分布外数据集上的表现之间的差距
一个 effective robustness 高的模型,在分布外数据集上的表现好于由它在参考数据集上的表现所预期的水平,也就是逼近「在所有数据集上表现相同」这个理想。他们用 LibriSpeech 做参考数据集,用 12 个学术 ASR 数据集研究分布外行为。

这张图我认为是全文最值得盯着看的一张。逐个元素解释:
- x 轴:LibriSpeech dev-clean 上的 WER(分布内表现,越左越好)
- y 轴:Common Voice / CHiME-6 / TED-LIUM 三个数据集上的平均 WER(分布外表现)
- 黑色虚线
y = x:理想鲁棒性 —— 分布内外表现一致 - 蓝色点和蓝色回归线:有监督的 LibriSpeech 模型
- 紫色点和紫色回归线:zero-shot Whisper 模型(五个尺寸各一个点)
- 橙色点带误差棒:一个人类(Alec)的 zero-shot 表现,误差棒是 95% 置信区间
关键在于看斜率而不是看点的位置。蓝色线又高又陡:LibriSpeech 上从 1.5 走到 3.5,分布外 WER 从 24 飙到 46。紫色线又低又平:LibriSpeech 上从 2.6 走到 7.8,分布外 WER 只从 12 爬到 26.5。
最有说服力的地方在 x ≈ 2.6 附近:那里蓝色点的 y 值约 27,紫色点的 y 值约 12。同样的 LibriSpeech 成绩,分布外错误率差 2.25 倍。
而橙色那个人类点,落在紫色线上。论文的措辞是:zero-shot Whisper 模型的估计鲁棒性前沿包含了这位特定人类的 95% 置信区间。

这张表把上图具象化成数字。wav2vec 2.0 Large(no LM)vs Whisper Large V2,RER 是相对错误率下降:
- LibriSpeech Clean:两边都是 2.7,RER = 0.0 —— 参考数据集上打成平手
- Artie:24.5 → 6.2,RER 74.7%
- Common Voice:29.9 → 9.0,RER 69.9%
- Fleurs En:14.6 → 4.4,RER 69.9%
- CHiME6:65.8 → 25.5,RER 61.2%
- AMI SDM1:67.6 → 36.4,RER 46.2%(最小的一档,也是绝对 WER 最高的一档 —— 远场单麦克风会议录音,公认最难)
- 平均:29.3 → 12.8,RER 55.2%
这张表的结构就是论证本身:在参考集上打成平手(0.0%),在其他所有 12 个集上平均少错 55.2%。 这个差距不可能用”模型更好”解释,只能用”训练分布更宽”解释。
论文由此提出一个方法论建议:
这一发现建议强调 zero-shot 和分布外评测,特别是在试图与人类表现比较的时候,以避免由于误导性的比较而夸大机器学习系统的能力。
5.2 多语言:数据量决定一切

MLS(Multilingual LibriSpeech)上 Whisper zero-shot 拿到 7.3,好过 XLS-R (1B) 的 10.9 和 mSLAM-CTC (2B) 的 9.7。但 VoxPopuli 上 Whisper 是 13.6,输给几乎所有对手(Maestro 8.1、mSLAM 9.1、XLS-R 10.6)。
论文自己给的解释很诚实:VoxPopuli 上表现差可能是因为其他模型把这个分布作为无监督预训练数据的主要来源,并且该数据集有显著更多的监督数据可供 fine-tune。数据支撑:MLS 每种语言 10 小时训练数据,而 VoxPopuli 的每语言平均训练数据大约高 10 倍。
而且这两个 benchmark 都很窄 —— 只覆盖 15 种语言,几乎全在印欧语系,大部分是高资源语言。所以他们转到 Fleurs(102 种语言)做更广的分析:

- x 轴:该语言的转录音频小时数(对数轴,从 0.1 小时到 1M 小时)
- y 轴:Fleurs 上的 WER(对数轴)
- 每个点是一种语言,标着两字母语言代码
- 蓝线是线性拟合,浅蓝带是置信区间
- 左下角标着 r² = 0.83
r² = 0.83 是个很强的相关。 论文从拟合的回归系数推出一个好记的经验规律:训练数据每增加 16 倍,WER 减半。
再看离群点,这是这张图最有信息量的部分。右侧偏上的 ZH(中文):训练数据超过 20,000 小时(在图上位于 x 轴很右边),但 WER 还在 15 左右,明显在拟合线上方。KO(韩语) 同样。还有 HE(希伯来语)、TE(泰卢固语)。论文给的三个候选解释:
- 由于语言距离远,缺少迁移
- 我们的 byte level BPE tokenizer 对这些语言是个糟糕的匹配
- 数据质量的差异
第 2 条我前面提过 —— 词表大小不变塞 99 种语言的代价,在这里显形了。对做中文 ASR 的人来说这一条尤其值得注意:Whisper 在中文上表现不及其数据量应有的水平,一部分原因是 tokenizer 层面的,不是数据量能补回来的。
5.3 翻译:同一套分析,r² 却掉到 0.24

CoVoST2 的 X→en 子集,Whisper zero-shot 总分 29.1 BLEU,是新的 SOTA(对手 Maestro 25.2、mSLAM-CTC 24.8、XLS-R 22.1),而且没用 CoVoST2 的任何训练数据。
按资源分档看更有意思:
- High(高资源):36.2,输给 Maestro 的 38.2
- Mid:32.6,最优
- Low(低资源):25.2,最优,比 mSLAM 高出 6.7 BLEU
论文的归因:他们预训练数据集里有 68,000 小时的 X→en 翻译数据(针对这些语言),虽然噪声大,但远多于 CoVoST2 里 861 小时的训练数据。低资源档赢得最多、高资源档反而输,这个模式和”数据量驱动”的解释完全一致。

同样的分析换成翻译,r² 掉到了 0.24(识别是 0.83)。同样的方法、同样的模型,相关性弱这么多,说明翻译的表现被数据量之外的因素支配得更多。
论文怀疑这部分是由于翻译训练数据的噪声更大,源于语言识别环节的错误,然后举了一个我读完印象最深的例子:
威尔士语(CY)是一个显著的离群点,表现远差于预期 —— 在号称有 9,000 小时翻译数据的情况下只有 13 BLEU。这个巨大的威尔士语翻译数据量令人惊讶,在全部翻译数据里排到第 4,超过了法语、西班牙语、俄语这些世界上使用人数最多的语言。检查发现,绝大多数所谓的威尔士语翻译数据实际上是带英文字幕的英文音频,被语言识别系统误分类成了威尔士语,于是按照他们的数据集构建规则,被当成翻译训练数据而不是转写训练数据收进来了。
这个 case 值得所有做数据流水线的人抄在本子上。语言识别的一个错误分类,会顺着自动化规则被放大成 9000 小时的错误标签。 而且它在总量统计里看起来完全正常 —— 威尔士语排第 4,只有当你觉得”这不对,威尔士语凭什么排在法语前面”的时候才会去查。第 2.2 节那个”训完初版模型再洗数据”的步骤没能抓到它,因为这批数据的音频和文本其实是匹配的(都是英文),错的只是任务标签。
5.4 语言识别:一个被数据集设定坑了的结果

Fleurs 上 Whisper zero-shot 是 64.5%,输给有监督 SOTA 的 77.7%(mSLAM-CTC 2B)和 71.4%(w2v-bert-51)。论文承认不 competitive,但同时指出一个口径问题:
Whisper 数据集里 Fleurs 的 102 种语言中有 20 种完全没有训练数据,所以准确率的上界只有 80.4%。在 82 种重叠语言上,最好的 Whisper 模型达到 80.3% 准确率 —— 也就是说在它见过的语言里,几乎打满了上界。
这是一个读表时容易踩的坑:64.5 这个数字里,有 19.6 个百分点是结构性不可能的。
5.5 噪声鲁棒性

两个子图:左边加白噪声,右边加酒吧噪声(pub noise,来自 Audio Degradation Toolbox,模拟嘈杂餐厅或酒吧里的环境噪声和含混交谈)。x 轴是信噪比 SNR,从左往右递减(40dB 干净 → −10dB 极噪);y 轴是 LibriSpeech test-clean 的 WER,对数轴。
- 红色星星折线是 Whisper
- 绿色圆点是 NVIDIA STT 系列
- 蓝色三角是 wav2vec2-large-960h-lv60-self
- 其余细线是另外十来个 LibriSpeech 训练的模型
读法:在图的左侧(低噪声,40dB),红星在 2.5 左右,被绿点(1.5)和蓝三角(1.9)压在下面 —— 干净音频上 Whisper 不是最优的,这不意外,因为那些模型主要在 LibriSpeech 上训练。
但往右走,所有模型都快速退化,而红星的曲线更平。论文的结论:在 SNR 低于 10 dB 的加性酒吧噪声下,所有模型的表现都比 Whisper 模型更差。低噪声下第二好的模型(蓝色三角,只在 LibriSpeech 上 fine-tune 过)退化得更快。
这张图和 5.1 节那张 effective robustness 图讲的是同一件事的两个侧面:Whisper 的优势不在最优点上,在斜率上。
5.6 长音频转写
Whisper 在 30 秒块上训练,一次吞不下更长的音频。他们的做法是连续转写 30 秒段,并按模型预测的时间戳来移动窗口。论文强调:
我们观察到,基于模型预测的重复性和 log 概率来做 beam search 和温度调度是至关重要的,才能可靠地转写长音频。
七个长音频数据集,长度从几分钟到几小时:TED-LIUM3(拼接成完整 TED talk)、Meanwhile(Stephen Colbert 秀里术语密集的片段)、Rev16 和 Kincaid46(在线博客里被用作 ASR benchmark 的视频/播客)、Earnings-21/22(财报电话会议录音)、CORAAL(地区非裔美国人语言语料库的完整访谈)。

箱线图,每个数据集下 6 个箱子:Whisper(蓝)、Company A~D(4 家商业 ASR 服务)、NVIDIA STT CTC large(棕,开源里最好的)。箱子是逐样本 WER 的四分位数,箱上标注的数字是该数据集的聚合 WER。
逐个数据集读 Whisper 的数字和它的排位:
- TED-LIUM3:3.52,全场最低(对手 3.61 / 3.78 / 4.81 / 4.02 / 4.00)
- Meanwhile:5.09,第二名 8.23,领先 38% —— 论文特别点出这个数据集”术语密集(heavy with uncommon words)”
- Kincaid46:8.80,第二名 9.94
- Rev16:11.3,Company B 是 10.9,Whisper 第二
- Earnings-21:9.72,Company A 是 8.94、B 是 9.27,Whisper 第三
- Earnings-22:12.6,最低
- CORAAL:19.6,Company B 是 14.6,Whisper 第二,且和最差的 30.0 差距巨大
所以准确的说法是:Whisper 在多数数据集上优于被比较的模型,在所有数据集上优于最好的开源模型(NVIDIA STT),多数情况下也优于商业 ASR 系统。不是全胜。
论文还主动提了一个 caveat,我觉得这一句体现了作者的诚实:
我们注意到某些商业 ASR 系统有可能已经在这些公开可用的数据集上训练过,因此这些结果可能没有准确反映系统的相对鲁棒性。
5.7 和人类比

Kincaid46 里选 25 段录音,覆盖念稿和即兴的广播、电话和 VoIP 通话、会议等多种录制条件。横轴 10 个箱子:Whisper、A~D(同上的 4 家商业 ASR)、E(一家计算机辅助的人工转写服务)、F~I(4 家纯人工转写服务)。图下方的括号标出了分组:左边 5 个是 ASR,E 单独标为 computer-assisted,右边 4 个是 human transcription。
聚合 WER:
- Whisper 8.81
- 商业 ASR:A 9.66、B 9.74、C 10.9、D 12.2 —— 全部落后于 Whisper
- E(计算机辅助人工)7.61 —— 全场最低,比 Whisper 好 1.15 个百分点
- F~I(纯人工)8.14、8.65、8.96、10.5
纯人工那四家里,有两家(8.96、10.5)比 Whisper 差。论文的措辞很克制:纯人类的表现只比 Whisper 好不到一个百分点(a fraction of a percentage point)。
这里有个细节值得注意:为什么要拿人类来比?因为由于含混或不清晰的语音以及标注错误,每个数据集都有不同程度的不可约错误(irreducible error),光看 ASR 系统之间的 WER,很难判断每个数据集还剩多少提升空间。人类的成绩就是那把标尺。
6. 消融实验:哪些东西真的有用
6.1 模型规模

四个子图,x 轴都是模型参数量(38M → 1549M),淡蓝细线是单个数据集/语言,粗蓝线是平均,橙色虚线单独标出 Large V2(因为它包含了小模型没有的若干改动):
- English Speech Recognition:12 个数据集平均 WER,18.5 → 9.5,Large V2 到 ~8.8
- Multilingual Speech Recognition (Fleurs):67 种语言平均 WER,79 → 39,Large V2 到 ~33
- X→En Translation (CoVoST2):21 种语言平均 BLEU,2.5 → 25.5,Large V2 到 ~29
- Language Identification (Fleurs):102 种语言准确率,45 → 61,Large V2 到 ~64.5
论文的结论:随规模增大,表现在所有任务上都可靠改善,除了英文语音识别在从 768M 到 1.5B 时呈现出收益递减。而 Whisper 的鲁棒性随规模持续提升 —— 这否证了”在弱监督数据上训练,模型会饱和在数据集固有质量水平上”这个担忧,也否证了”随算力增加模型会学去利用数据集特质”的担忧。
顺便说一句,第 1 个子图那个”英文识别在 768M 之后趋平”的现象,论文猜测原因是接近人类水平表现时的饱和效应 —— 呼应了 5.7 节的结果。
6.2 数据集规模:这张表适合贴在墙上

从 3,405 小时(全量的 1/200)到 681,070 小时(全量),每档翻倍:
| 数据量(h) | 英文 WER↓ | 多语言 WER↓ | X→En BLEU↑ |
|---|---|---|---|
| 3,405 | 30.5 | 92.4 | 0.2 |
| 6,811 | 19.6 | 72.7 | 1.7 |
| 13,621 | 14.4 | 56.6 | 7.9 |
| 27,243 | 12.3 | 45.0 | 13.9 |
| 54,486 | 10.9 | 36.4 | 19.2 |
| 681,070 | 9.9 | 29.2 | 24.8 |
三列的形状完全不同,值得分开读:
英文 WER:3,000 → 13,000 小时快速改善(30.5 → 14.4),13,000 → 54,000 之间明显放缓(14.4 → 10.9),从 54,000 到全量(又是 12.5 倍)只再降 1 个点。
多语言 WER:到 54,000 小时都遵循幂律趋势,之后偏离,从 36.4 只再改善 7 个点到 29.2。
X→En BLEU:在 7,000 小时或更少的音频上训练时,翻译表现几乎是零(0.2 → 1.7)—— 存在一个明显的能力涌现门槛。然后到 54,000 小时之前大致呈对数线性改善,之后也进入递减。
论文对”全量数据收益递减”给了两个方向截然不同的解读,并明确说无法区分:
- 数据没吃完:当前最好的 Whisper 模型相对数据集规模而言是训练不足(under-trained)的,用更长训练和更大模型可以进一步改善
- 数据吃到底了:我们正在接近语音识别从数据集规模 scaling 中能获得的性能改进的终点
原文:「需要进一步分析来刻画语音识别的 scaling law,以便在这些解释之间做决定。」这个问题据我所知到现在也没有被干净地回答。
6.3 多任务/多语言迁移:小模型有害,大模型有益

- x 轴:花在英文语音识别上的训练 FLOPs(对数轴,10e19 → 10e22)
- y 轴:11 个英文语音识别数据集的平均 WER
- 蓝色点/线:English Only 模型
- 橙色点/线:Multilingual and Multitask 模型
- 阴影带是 95% bootstrap 置信区间
关键是两条线交叉了。在图的左侧(低算力),橙线在蓝线上方 —— 联合训练更差。往右走,两条线在 10e20 附近交叉,之后橙线在蓝线下方 —— 联合训练更好,而且橙线斜率更陡。
这里有个方法论细节必须说清楚,否则这张图会被读错。论文做了一个校正:
我们对花在英文语音识别任务上的 FLOPs 数量做了调整,因为在联合训练设定下只有 65% 的算力花在这个任务上;否则分析会被”任务上的训练不足”所混淆,相比同尺寸的纯英文模型不公平。
也就是说 x 轴不是”总算力”,是”折算到英文识别上的有效算力”。没有这个校正,联合模型会因为分心而看起来更差,那就说不清是”负迁移”还是”算力被分走了”。
结论:对于用中等算力训练的小模型,确实存在跨任务和跨语言的负迁移 —— 联合模型表现不如同等算力的纯英文模型。但联合模型 scale 得更好,在他们最大的实验里超过了纯英文对手,展示出正迁移。而且在最大规模下,即使不校正每任务算力,联合模型也略微超过纯英文模型。
这个结论对做多语言/多任务系统的人很实用:小规模实验上观察到的负迁移,不能直接外推到大规模。 如果 Whisper 团队只在 1e19 FLOPs 规模上做消融,他们会得到”多任务联合训练有害”的结论然后放弃这条路。
6.4 文本标准化:这一节被引用得太少了
我在开头说这篇论文有第二层价值,就是指这里。
由于他们的文本标准化器是和 Whisper 一起开发的,用来折掉无关紧要的词形错误,存在一个风险:这个标准化器可能过拟合到了 Whisper 的特性上,而不是在处理转写中的一般性差异。 为了检查,他们把自己的标准化器和 FairSpeech 项目独立开发的一个做了对比。

- y 轴:13 个数据集,按下方效果差异排序
- x 轴:相对于 FairSpeech 标准化器的相对 WER 降幅(%),注意从左往右递减,右边红色竖线是 0(无差异)
- 蓝色箱:开源模型
- 橙色箱:Whisper 模型
读法:如果某个数据集上橙箱明显比蓝箱更靠左,说明他们的标准化器给 Whisper 的优惠比给别人的多,那就是过拟合的证据。
结果:大多数数据集上两个箱子重叠得很好(CORAAL、CommonVoice、AMI-SDM1、Artie、Fleurs 等基本都贴在 0 附近)。但有三个数据集橙箱明显更靠左 —— WSJ、CallHome、Switchboard,他们的标准化器把 Whisper 模型的 WER 降低得显著更多,最大接近 50%。
论文诚实地追查了原因,并且解释得很具体:
降幅差异可以追溯到 ground truth 使用的不同格式,以及两个标准化器惩罚它们的方式。例如在 CallHome 和 Switchboard 上,我们的标准化器没有惩罚常见英文缩写的差异,比如 “you’re” 对 “you are”;而在 WSJ 上,我们的标准化器标准化了数值和货币表达的书面形式与口语形式,比如 “sixty-eight million dollars” 对 “$68 million”。
附录 C 里给出了完整的 12 条英文标准化规则,我列一下(这个清单可以直接当工程 checklist 用):
- 去掉方括号
[ ]之间的短语 - 去掉圆括号
( )之间的短语 - 去掉这些词:hmm, mm, mhm, mmm, uh, um
- 去掉撇号
'前的空白字符 - 把英文的标准或非正式缩写形式还原成原形
- 去掉数字之间的逗号
- 去掉后面不跟数字的句点
- 去掉符号和音调符号(Unicode category 以 M/S/P 开头的字符),但保留句点、百分号和货币符号(下一步要用)
- 检测数字和货币的数值表达,替换成阿拉伯数字形式 —— 例如 “Ten thousand dollars” → “$10000”
- 英式拼写转美式拼写
- 去掉不属于任何数值表达的剩余符号
- 连续空白字符压成一个空格
非英文语言,他们承认缺乏为所有语言构建这类标准化器的语言学知识,所以只做基础处理:去括号内容、把 M/S/P 类字符替换成空格(在 NFKC 归一化的字符串上判定)、转小写、压缩空白。另外,对不用空格分词的语言(中文、日文、泰文、老挝文、缅甸文),在每个字符之间插入一个空格,实际上等于在测字错误率(CER)。
最后论文自己给了一个很到位的声明:
我们注意到上述方案是不完美的,有时会产生意外和非预期的输出。我们不主张上述过程得到的文本格式在任何意义上更”正确”。相反,上述流程的设计目标是更好地区分无害的措辞差异和真正的转写错误。
这段话我觉得应该刻在每个 ASR 评测报告的第一页。评测口径不是”正确”与否的问题,是”你想测什么”的问题 —— 而这个选择会改变排名。我自己做混说评测时踩过这个坑:同一批模型,开不开填充词过滤(嗯/呃/那个),排名会变。
6.5 长音频解码的启发式规则
Whisper 的长音频转写依赖时间戳 token 的准确预测来决定把 30 秒窗口往后移多少,任一窗口内转写不准都可能负面影响后续窗口的转写。所以他们攒了一套启发式规则专门避开长音频的失败模式:

七个数据集 + 平均列,从贪心解码开始逐项累加:
| 配置 | 平均 WER |
|---|---|
| Greedy decoding only | 11.0 |
| + Beam search | 10.6 |
| + Temperature fallback | 10.6 |
| + Voice activity detection | 10.2 |
| + Previous text conditioning | 10.0 |
| + Initial timestamp constraint | 10.0 |
每条规则的具体参数(4.5 节):

对着图走一遍:
- Beam search,5 个 beam,用 log 概率作为打分函数 —— 目的是减少贪心解码中更频繁出现的重复循环
- 温度 fallback:从 T = 0 开始(即总是选概率最高的 token),当两个信号任一命中时把温度增加 0.2,最高到 1.0:
- 生成 token 的平均 log 概率低于 −1(模型自己对结果没信心)
- 生成文本的 gzip 压缩率高于 2.4(文本重复到了能被高效压缩的程度 —— 这是个很聪明的循环检测器,不用写规则去匹配重复模式,直接用压缩率当”重复度”的代理指标)
- 前文条件:把前一个窗口的转写文本作为 prev 提供给模型,但只在当前温度低于 0.5 时才做。这个条件很关键 —— 高温意味着当前窗口的输出本身就不可信,把它传下去会污染后续窗口,错误会级联
- VAD:他们发现只用
<|nospeech|>token 的概率不足以区分一个段落有没有语音,把 nospeech 概率阈值 0.6 和平均 log 概率阈值 −1 组合起来,才使 Whisper 的 VAD 更可靠 - 初始时间戳约束:为了避免模型忽略输入前几个词的失败模式,把初始时间戳 token 约束在 0.0 到 1.0 秒之间
从表看,Beam search 贡献 0.4,Temperature fallback 在平均上是 0.0(但看单列,它在 Meanwhile 上从 5.71 没变、在 Kincaid46 上 9.42 没变 —— 它的作用是防灾而不是提分,只在触发失败模式的样本上起作用,会被平均掉),VAD 贡献 0.4,前文条件贡献 0.2,初始时间戳约束在平均上 0.0。总共 11.0 → 10.0。
论文对这套东西的定位说得很直白:
增加这些干预中的每一个通常都会整体降低 WER,但在数据集上并不均匀。这些启发式规则作为一个针对模型噪声预测的 workaround,需要更多研究来进一步改善长音频解码的可靠性。
用了 workaround 这个词。 这是我最欣赏这篇论文的地方之一 —— 没有把一堆调出来的阈值包装成”我们提出了一个新颖的解码框架”。
7. 局限:论文自己承认的问题
第 6 节 Limitations 里,我觉得最值得关注的是解码策略这一段:
随着我们 scale Whisper,我们观察到更大的模型在减少感知类错误(比如混淆发音相似的词)上取得了稳定可靠的进展。许多剩余的错误,特别是在长音频转写中,性质上似乎更顽固,且明显不是人类式的/感知性的。它们是 seq2seq 模型、语言模型、以及文本-音频对齐的失败模式的组合,包括卡在重复循环里、不转写音频段落开头或结尾的前几个词、或者完全的幻觉 —— 模型输出一段与实际音频完全无关的转写。
这段话把错误分成了两类,这个分类我认为比任何单一指标都有用:
- 感知类错误(同音词混淆):scaling 能解决
- 生成类错误(重复循环、掉头尾、幻觉):scaling 不解决,因为它们来自 seq2seq/LM 侧而不是听觉侧
这解释了为什么第 6.5 节那套启发式是必需的 —— 它们全都是在治第二类病。论文猜测在高质量监督数据集上 fine-tune、或者用强化学习更直接优化解码表现,可能进一步减少这些错误。
其他几条:
- 低资源语言数据太少:数据集因为收集流水线的偏向而非常英语中心,大多数语言不到 1000 小时。而 Figure 3 的 r² = 0.83 说明这条路很明确 —— 有针对性地给这些稀有语言加数据,即使总数据量只小幅增加,也能大幅改善平均识别表现
- 没研究 fine-tune:本文只研究 zero-shot 迁移,但对很多有高质量监督数据的领域,fine-tune 大概能进一步改善
- 不清楚鲁棒性来自 encoder 还是 decoder:他们怀疑 Whisper 的鲁棒性部分来自它强大的 decoder(一个音频条件语言模型),但目前不清楚收益来自训练 encoder、decoder、还是两者。可以通过训练一个无 decoder 的 CTC 模型来消融,或者研究把 wav2vec 2.0 这类现有 encoder 配上语言模型后表现如何变化
- 没有辅助训练目标:Whisper 明显偏离了大多数近期 SOTA 系统,因为它缺少无监督预训练或自训练方法。虽然他们没发现这些是达到好表现的必需品,但纳入它们也许能进一步改善结果
8. 读完之后我自己的几个 take
第一,这篇论文最硬的贡献是数据流水线,不是模型。 模型是”现成的 encoder-decoder Transformer”,作者自己都强调是为了避免混淆变量才刻意不创新的。真正难复现的是第 2.2 节那四道闸 —— 尤其是”检测机器生成字幕”和”训完初版模型再按错误率×体积排序洗数据”。这两件事没有论文可以引用,是纯手工活。这也是为什么 Whisper 好复现架构、难复现效果。
第二,effective robustness 这个评测框架的价值超过 Whisper 本身。 「在参考集上打平,在其他 12 个集上平均少错 55.2%」这种论证结构,比”我在 benchmark X 上刷到了 SOTA”有说服力得多。我做混说评测时借了这个思路:先在共同交集上排名,再单独看每家在难子集上掉多少,两个数字一起看才有意义。
第三,Figure 9 那个交叉点是个方法论警告。 小规模实验上多任务联合训练是负迁移,大规模上是正迁移。如果只在小规模做消融就下结论,会把一条正确的路线砍掉。这个陷阱在 MoE 领域也有同构的版本 —— 小规模上 sparse 打不过 dense,规模上去了才反过来。规模是会改变结论的方向,不只是改变数值。
第四,威尔士语那 9000 小时是我读到的最好的数据质量案例。 一个语言识别的误分类,被自动化规则放大成了 9000 小时的错误标签,而且在总量统计里看起来完全正常(排第 4)。自动化流水线不会犯随机错误,它会犯系统性错误 —— 而系统性错误在聚合统计里是隐形的。唯一发现它的方式是有人觉得”威尔士语凭什么排在法语前面”然后去查了。
第五,附录 C 那 12 条应该成为常识。 做 ASR 评测的人如果不定归一化口径,报出来的 WER/CER 数字基本没有可比性。而口径的选择本身会改变排名 —— 论文自己在 4.4 节展示了同一批模型换个标准化器 WER 能差 50%。任何一份 ASR 评测报告的第一节都应该是口径声明,不是结论。
第六,一个我没想到的细节:中文在 Figure 3 里是负向离群点。 训练数据量排第一(23,446 小时),但 WER 明显高于拟合线预期。论文给的候选解释里,byte-level BPE tokenizer 对中文是糟糕匹配这一条最值得注意 —— 因为这不是加数据能补的。做中文 ASR 的话,这一条比”Whisper 中文数据最多”重要。
扯一句题外话。这篇论文的核心逻辑是”用规模换掉工程复杂度”—— ITN 模块被 scaling 换掉了,VAD 和语言识别被 token 格式换掉了。这个思路在别的方向上也在反复出现:手工设计的模块被自动化流程和规模取代。我这几年主要做的 NAS / AutoML 和 LLM 效率优化,本质上也在同一个方向上使劲,只是换了个入口 —— 不是”把模块塞进模型让它自己学”,而是”把设计模块这件事本身自动化掉”。
我们把这方面的积累整理成了一本书,《动手学 AutoML:从 NAS 到大语言模型优化实战》。ASR 不在书的覆盖范围内(书讲的是搜索空间、搜索策略、架构评估,以及 LLM 架构自动化、压缩剪枝量化、LLM 驱动的 AutoML 这些),所以这里不硬扯关系 —— 只是如果你读这篇文章时对”哪些设计决定其实可以交给搜索”这个问题起了兴趣,那本书讲的就是这件事。
欢迎评论区交流,有讲错的地方也请指出来。
