OpenAI Whisper论文笔记
OpenAI 收集了 68 万小时的有标签的语音数据,通过多任务、多语言的方式训练了一个 seq2seq (语音到文本)的 Transformer 模型,自动语音识别(ASR)能力达到商用水准。本文为李沐老师论文精读的学习笔记。本文的模型权重,推理代码及 API 均以开源,相关博客也介绍了一些有趣的例子。
Paper:https://cdn.openai.com/papers/whisper.pdf
Code:https://github.com/openai/whisper
Blog:https://openai.com/blog/whisper
在互联网上,可获取的带标注的语音数据有很多,如电影及其字幕,歌曲及其歌词等。语音数据似乎很容易通过爬虫收集。但是,目前并没有(公开的)大规模语音数据集。这是因为这些带标注的语音数据的版权问题很难处理。即使某些公司通过收集这些数据训练了大语音模型,也不会声明自己的数据是爬去自存在版权问题的作品,更不会将数据公开。在 Whisper 文章中,同样没有详细说明数据来源,只是介绍了数据清洗和筛选的方法。
本文标题为 Robust Speech Recognition via Large-Scale Weak Supervision ,其中 Large-Scale 是 OpenAI 的 “传统艺能”,也是最近学术界的一个火热方向。即“大力出奇迹”,大模型、大数据的训练。Weak Supervision 是指本文所用数据虽然是有标注的,但并不是为了训练模型专门进行的人工标注,所以是质量较低的标注,故称为 “弱监督”。
摘要
在摘要部分,作者指明,本文通过扩大语音识别弱监督数据的规模,达到 68 万小时,并在大规模数据上进行多语言、多任务的训练。得到了一个泛化性能很好的模型。该模型在常见语音识别数据集上,不需要微调,直接以 zero-shot 的方式进行测试,结果与在这些数据集上训练过的语音识别模型性能相当。
导言
最近的语音识别方面的进展是使用无标签的数据进行自监督预训练。如 Wav2Vec,收集了大量无标签的语音数据,通过对比学习的方式预训练语音编码器。在编码器预训练完成之后,再在标准的语音识别数据集上微调,得到的结果优于只在语音识别训练集训练的模型。自监督预训练使用到的无标签语音数据规模最多已经达到 100 万小时。
考虑在 NLP 领域常见的两类预训练方式:BERT,Transformer 编码器类 和 GPT,Transformer 解码器类。BERT 中,预测掩码掉的单词和预测下一个句子是为了训练编码器理解自然语言而构造的预训练任务,它们不是现实中真正要用的 NLP 任务。因此,BERT 类预训练方法需要在对应下游任务上进行微调。GPT 类的预训练任务标准的语言模型,预测句子的下一个单词。这种方式可以通过构造 prompt,实现 zero-shot 测试,无需微调。然而,在语音识别领域,这种方式预测的是下一帧音频,而非语音识别结果,故而也必须微调一个解码器。总之,在语音识别领域,如果没有文本标签,很难实现无需微调的预训练。(Wav2Vec-U 在无监督语音识别训练方面取得了一些相关进展,不需要微调。)
在语音识别领域,自监督预训练的方式可以训练一个不错的编码器,但是预训练阶段没有标签,无法训练解码器。因此在实际用于语音识别之前,还需要在有标签数据上进行微调,比较麻烦,并且容易造成过拟合。一个理想的语音识别系统,应当不需要根据不同的场景进行微调,即应该实现开箱即用。
既然需要有标签数据,那么在语音识别人工标注数据集上训练,不就能训练出无需微调的语音识别系统了吗?遗憾的是,目前人工标注的语音识别数据集规模都比较小,七个数据集加起来也只有 5000 小时左右。一个自然的思路是,在数据的质量和数量之间进行权衡。既然高质量的人工标注成本较高,得到的数据集规模较小,那么是否可以放宽对标注质量的要求,使用电影-字幕,歌曲-歌词等自然带标注的语音识别数据,从而扩大数据规模呢?本文的思路就是这样。
本文收集了 68 万小时的语音识别数据,除了数据的规模大幅上升之外,数据的多样性也更加丰富。在这 68 万小时的语音数据中,有 11.7 万小时涵盖了除英语外的其他 96 中语言,有 12.5 万小时是其他语言到英语的翻译数据。
方法
数据处理
数据部分是本文最核心的贡献。由于数据够多,模型够强,本文模型直接预测原始文本,而不经过任何标准化(standardization)。从而模型的输出就是最终识别结果,而无需经过反向的文本归一化(inverse text normalization)后处理。所谓文本归一化包括如将所有单词变小写,所有简写展开,所有标点去掉等操作,而反向文本归一化就是上述操作的反过程。在 Whisper 中,这些操作统统不用,因为数据足够多,可以覆盖所有的情况。
在本文收集的语音数据中,包含了不同环境、不同语言、不同说话人等多样的数据,这有助于训练出文件的语音识别系统。然而,文本标签的多样性对模型的学习是一种阻碍。为了解决这个问题,本文使用了几种自动过滤方法,来提高文本标签的质量。
首先,收集自互联网的语音识别数据,很有可能文本标签就是来自现有的语音识别系统的识别结果。之前有研究工作表明,在训练数据中混有机器生成的标签数据会损害模型的性能。为此,本文根据机器识别结果的一些特点,过滤掉了这些数据。 另外,本文对数据中语音所属语言和文本所属语言进行检测。如果文本是非英语的其他语言,则要求语音也必须是同种语言;如果文本是英语,则语音可以是任何语言(因为本文方法中有一个其他语言到英语的翻译任务)。 本文用一个语音识别模型在收集的数据上进行测试,发现在一些错误率极高的数据中,存在音频信息不完整、字幕声音不匹配等低质量数据,这些数据同样会被过滤掉。另外,可能在收集的数据中含有标准语音识别数据集中的内容,为了避免对测试结果产生影响,这部分数据同样需要去掉。
最后,将音频切分为 30s 的片段,配上对应文本,得到训练数据。
模型
Whisper 使用的模型改动不大,就是 Transformer 第一次提出时的 encoder-decoder 架构。
Whisper 的输出侧是声音信号,声音信号的预处理是将音频文件重采样到 16000 Hz,并计算出 80 通道的梅尔频谱,计算时窗口大小为 25ms,步长为 10ms。然后将数值归一化到 -1 到 1 之间,作为输入数据。可以认为是对于每一个时间点,提取了一个 80 维的特征。之前数据处理部分提到每个音频悲切氛围 30s 的片段,这里步长为 10,所以每 30 秒有 3000 个时间点。综上,对于一个 30 秒的音频数据,我们提取到形状为 3000x80 的特征。对应到 NLP 中,可以理解为句子长度为 3000,每个词的词嵌入维度为 80。
3000x80 的输入数据首先通过两个 1D 卷积层,得到 1500x80 的特征。后面的处理就是标准的 Transformer encoder-decoder结构了。将这个特征送入到 Transformer encoder 中,提取处的特征作为交叉注意力输入送给 decoder。decoder 每次预测下一个 token,其输入是对应多任务学习的一些预设 token 和 prompt。
多任务
语音识别系统除了识别出语音中的语言文本(转录)之外,还需要做一些其他的任务。比如是否有人在说话(voice activity detection, VAD)、谁在说话(speaker diarization),和反向文本归一化等。通常,在语音识别系统中,这些任务分别由不同的模型来处理,但在本文中,这通通由 Whisper 一个模型完成。多个语音任务由同一个模型完成,有利有弊。好处是 all-in-one 的模型听起来比较 fancy,比较符合我们对于语音识别系统的期待。坏处是多个任务中如果某几个性能相对较差,整个模型难以调试。而且,如果需求只是做某一个比较简单的任务(如 VAD),一般来说一个简单的模型就可以胜任,但是 Whisper 需要跑起整个大模型。
Whisper 模型共处理四个任务,如图左上所示。一是给定英文语音,转录成英文文本;二是给定其他语言语音,转录并翻译成英文文本;三是给定其他语言语音,转录成该语言文本;四是给定只有背景音乐的音频,识别出无人说话。
所有这些任务都由解码器预测的 token 序列表示,从而使得一个模型能够处理多个任务。这几个任务及模型输出 token 的关系可以从图中下方的图示中的 token 序列看出:在 START OF TRANSCRIPT token 之后,如果当前无人说话,则识别为 NO SPEECH 。如果有人说话,则识别出当前语音所属的语言 LANGUAGE TAG 。然后有两种可能的任务 TRANSCRIBE 还是翻译任务 TRANSLATE ,这两种任务又分为两种形式:带时间戳的和不带时间戳的,分别穿插或不穿插时间戳 token ,预测出文本 token。最后到达 EOT token,整个流程结束。
实验(选)
注意 Whisper 是没有在人工标注的语音识别数据集上训练的,即 zero-shot 的设定。而对比的方法都是在这些数据集上训练过的,因此,要达到与它们持平的性能也是不容易的。
语音识别常用的评估指标是词错误率(Word Error Rate, WER)。即预测结果和目标结果的编辑距离除以句长。
由于不同的数据集有不同的标注格式,如大小写、括号、数字间的逗号等。为了保证公平的对比,在测试 Whisper 性能时会进行手动的 text normalizer,来对齐测试数据集。当然,这在实际使用中是不需要的。
英文语音识别
下图展示了不同语音识别模型在 LibriSpeech dev-clean 上的性能(横轴)和在多个数据集上的平均性能(纵轴)。LibriSpeech 是一个比较干净、比较简单的数据集,因此相对于其他数据集,各模型在 LibriSpeech 数据集上的性能更好。可以看到,虽然很多有监督方法在该数据集上训练之后能够得到很低的错误率(~1.6%),但这些模型在多个数据集上测试的平均错误率却非常高(>20%),很可能是这些有监督方法过拟合了 LibriSpeech 数据集。而 Whisper 虽然在 LibriSpeech 上错误率没有特别低,但是在多数据集测试中错误率也不错。这足以说明 Whisper 优秀的泛化性能。
多语言语音识别
下表是各模型在多语言语音识别数据集上的性能。可以看到,在小数据集 MLS 上,Whisper 表现更好;而在更大的 VoxPopuli 上,在训练集上训练过的有监督方法性能更好。
下图是不同语言的语音识别错误率随训练数据量的变化。可以看到,整体上随着训练数据的增多, 错误率是会下降的。另外,观察到在相同训练数据量的情况下, ZH、KO,即中文、韩文等语言的错误率相对较高。这可能有两个原因,一是东亚语言与世界主流的英语、法语等差别较大,无法从多语言联合训练中受益,二是 Whisper 的 tokenizer 对于这类语言也不太友好。
多语言/多任务联合训练与仅英语训练对比
蓝线表示全部使用英语数据进行训练,橙线表示多语言、多任务联合训练的结果。可以看到,随着训练数据量的增加,多语言、多任务联合训练对英语本身的语音识别性能也是有帮助的。
总结
Whisper 通过弱监督预训练的方式,再加上大规模、多样性、多语言的训练数据,不需要自监督(self-supervised)和自训练(self-training),即可取得很好的性能。并且在处理任何语音识别任务时也不需要微调,可以以 zero-shot 的方式工作,大大提高了语音识别系统的稳健性。
笔者认为,Whisper 的意义在于指明了只要有大规模数据,通过一个简单的 Transformer encoder–decoder 架构就能训练出可靠的语音识别模型。并且开源了他们的训练权重。它的缺点也很明显,目前 Whisper 对推理基本无优化,Large 模型需要约 10 G 显存,速度也比较慢。不过在未来,肯定会有一系列工作从算法上或者从工程上来优化 Whisper 的推理部署。