WeNet是一个端到端语音识别模型,由于其优越的特性,成为近几年语音识别领域的热门模型。WeNet模型是一种CTC和attention结构的混合体,以Conformer或Transformer作为encoder,并使用attention decoder对CTC的输出进行重新打分(rescore)。此外,为了在统一的模型中实现流式与非流式推理,该网络还引入了基于动态块的注意力机制,使得attention可以关注不同长度的上下文。
WeNet论文共两篇,对应WeNet模型结构的两个版本。论文链接如下:
WeNet: Production Oriented Streaming and Non-streaming End-to-End Speech Recognition Toolkit
WeNet 2.0: More Productive End-to-End Speech Recognition Toolkit
开源工程地址:https://github.com/wenet-e2e/wenet
1. 模型结构
在WeNet 1中,模型结构如下:
在WeNet 2中,增加了从右向左的注意力机制,模型结构如下:
WeNet模型主要由三部分组成:Shared Encoder、CTC Decoder和Attention Decoder。
Shared Encoder对输入序列进行信息提取,支持Transformer和Conformer两种网络,其中,Conformer网络的效果更优。与Transformer相似,Conformer由多个Conformer Block堆叠而成,每个Block又由Conv、Self-Attention、Residual、ReLU、Feed-Forward层组成。
CTC通过引入Blank输出单元,可以处理输入和输出之间不等长以及时间同步的问题。通过对输出的连续相同字符进行合并,以及移除Blank字符,得到最终的解码结果。
Attention Decoder与Transformer中的Decoder一样,是一个在目标序列上的自回归模型(也就是输入之前的输出单元,预测下一个输出单元),并在做自回归运算时,会利用Encoder的输出信息做Cross Attention,从而使其能够利用输入序列的信息。这样,可以不必显式对齐输入和输出,而是让网络隐式地去学习二者之间的对齐关系。
在解码时,同时使用CTC和AED的输出,可以提高识别率,但是由于AED本身是非流式的解码,在Wenet中,先使用CTC进行第一遍流式解码,再用AED对CTC的B-best结果进行Rescoring,根据得分重新排序,得到最好的识别结果。
整体模型结构可参考:
2. Subsampling
在语音识别中,一定时间范围内的语音信号是相似的,多个连续帧对应的是同一个发音。并且,端到端的语音识别,其建模单元一般是一个时间延续较长的粗粒度的单元,比如建模一个中文汉字,加入其用时0.2s,以10ms帧移计算,对应20帧,如果将20帧的信息合并为5帧,在进行帧同步输出时不会出现丢字问题,同时还可以减少后续Encoder网络的前向计算、CTC loss和AED cross-attention计算的开销。
WeNet中使用的是2D CNN实现输入的下采样。2D卷积将输入看成是通道数为1,高度为F(FBank的特征维度),宽度为T(帧数)的一张图。
3. Shared Encoder
Shared Encoder用于为声学特征建模,它由多个Transformer层或Conformer层组成。原始的Conformer结构中的self-attention需要对整个序列做attention运算,无法处理流式数据。而卷积操作也依赖于右侧固定长度上下文,且依赖的长度随着模型层数增多而增多。因此,原始结构需要针对流式数据进行改进。WeNet中采用Chunk方法进行改进,也就是把序列分成多个Chunk,每帧在Chunk内部做attention。Chunk的大小会影响流式数据的延时和模型识别率,大chunk的延时较大,但效果较好;小chunk的延时较小,但性能较差。WeNet中使用动态chunk,可根据场景的延时要求和识别率要求,手动调整chunk的大小,从而兼容流式和非流式数据。
常见的Attention范围如下:
为了增加模型鲁棒性,在训练中,会使用随机chunk size大小进行训练。在解码过程中,则根据场景需要以及延迟、性能需求等,选择固定的chunk size进行解码。
Conformer在Transformer的基础上引入了卷积,可以同时兼顾全局特征和局部特征,因而是目前语音识别任务效果最好的模型之一。需要说明的是,WeNet中使用的是因果卷积(Causal Convolution),即不依赖右侧上下文。
Shared Encoder具体结构如下:
4. CTC Decoder
CTC的基本原理示意图:
CTC在此先不展开讲,后面准备再开一篇单独讲。
在WeNet实现中,CTC部分比较简单,包含CTC Decoder和CTC Loss两部分。CTC Decoder只对Encoder的输出做了一次线性运算,并计算log_softmax,CTC Loss部分则是直接使用torch.nn.CTCLoss。
5. Attention-based Decoder
WeNet提供了单向Attention based Decoder和双向Attention based Decoder。该模块的输入是当前已经产生的输出序列,并在此基础上生成新的输出。跟Encoder中的Attention不同的是,在Decoder中,除了要做Self-Attention,还要与Encoder的输出做Cross-Attention。
Decoder结构如下:
6. 整体流程
WeNet网络的整体工作流程如下:
这张图非常直观地展示出WeNet的工作流程,感谢算法大神贡献的图。
以上笔记的参考资料除了两篇WeNet论文, 主要参考了Chao Yang的博客:
Wenet网络设计与实现 | Chao Yangz
在此表示感谢。