近期,由于工作原因,笔者需要为公司开发一个领域适配的语音模型。从以往在NLP领域的工作来看,现如今预训练+微调机制已经在CV与NLP方向上充分证明了它的有效性,而语音作为AI研究经典方向之一自然也存在相应的研究。本文将介绍一个由Facebook AI Research(FAIR)于2020年提出的在语音方向里具有一定影响力的预训练模型——Wav2Vec2.0。
相关资源
- arXiv:https://arxiv.org/abs/2006.11477
- GitHub(FAIR):https://github.com/pytorch/fairseq
- Github(HuggingFace):https://github.com/huggingface/transformers/tree/main/src/transformers/models/wav2vec2
1.模型结构
Wav2Vec2由FeatureEncoder和Encoder两个模块组成,前者负责将一维的语音波形处理成若干个语音单元的向量表示;后者负责抽取并融合这些语音单元的上下文信息,最终输出这些语音单元的embedding。
1.1 FeatureEncoder
wav2vec2.0的FeatureEncoder由7层卷积层构成,结构如下图所示
对于参数的解析,知乎的xmdxcsj已经在文章自监督预训练(三)wav2vec 2.0原理进行过详细的说明,此处笔者直接引用这篇文章中的描述:
1 | 文章使用了7层的CNN,步长为(5,2,2,2,2,2,2),卷积核宽度为(10,3,3,3,3,2,2),假设输入语音的长度为(1,x): |
1.2 Encoder
Wav2vec2的Encoder由我们的老朋友——Transformer组成,base版本的tfm层数为12,large版为24。这里需要注意的是PositionEmbedding,wav2vec使用一个卷积层来作为PE,并将PE加到hidden_state中后传入Transformers。wav2vec2原文描述为:
1 | Instead of fixed positional embeddings which encode absolute positional information, we use a convolutional layer similar to which acts as relative positional embedding. |
这里其实存在一个问题——为什么使用卷积作为PE?
事实上,利用卷积PE替代传统的三角函数PE的做法自FAIR的另一个研究成果——《Transformers with convolutional context for ASR》。在这篇文章中,作者通过实验比对了多个PE的效果,最终卷积PE脱颖而出,被wav2vec2继承了下来。
2.预训练
2.1 有效性提升的关键——乘积量化
wav2vec2在预训练(或者说自监督学习)过程中引入了乘积量化(Product Quantization) ,这属于wav2vec2的一个创新点,也是它有效的重要原因之一。乘积量化模块的作用是将FeatureEncoder的输出离散化成为了一组数量有限的语音表示,对于乘积量化的解释,知乎这篇文章中已经给出了很通俗的解释,如下:
1 | From 知乎.量子纠缠态 <十三、如何又让马儿跑得好,又让马儿不吃草——wav2vec 2.0> |
2.2 损失函数
预训练损失函数为
它由两部分组成:
(1) Contrastive Loss
这部分损失函数来源于对比学习任务,模型需要从一组候选向量中预测出正确的语音表示。这里的q即经过乘积量化后的语音表示。
(2) Diversity Loss
这部分是多样性损失,主要是为了确保乘积量化时的离散语音表示的可用性。关于这一点,FAIR团队人员在这个issue中给出了官方解答
总结
预训练-微调模式继CV与NLP之后开始席卷语音领域,笔者在实践中也印证了wav2vec2.0在小规模数据集上fine-tune之后确实能达到非常好的效果。但凡事都是有代价的,正如预训练模型给CV、NLP带去的困扰那样,wav2vec2.0虽然效果喜人,但无奈太过笨重,要实现线上使用还需要进行一定的压缩与加速。总的来说,瑕不掩瑜,wav2vec2.0依然是一个非常适合低资源冷启动项目的基础模型。