WeNet:面向生产的流和非流端到端语音识别工具包
原文链接:WeNet: Production Oriented Streaming and Non-streaming End-to-End Speech Recognition Toolkit
1.摘要
- WeNet : 一个开源的语音识别工具包,旨在通过新的双通道方法 U2 统一流式和非流式端到端(E2E)语音识别。
- 动机: 缩小E2E语音识别模型的研究与部署之间的差距。
- 架构: 基于Transformer或Conformer编码器的混合连接时序分类(CTC)和注意力模型。
- 关键特性: 动态chunk-based attention策略,实现流式和非流式统一。
2.WeNet的主要特性
- 生产优先设计: 易于在实际场景中部署。
- 统一解决方案: 在一个模型中集成流式和非流式语音识别,减少开发和部署工作量。
- 可移植运行时: 支持多种平台,包括服务器(x86)和嵌入式(ARM Android)。
- 轻量化: 不依赖于Kaldi,完全使用PyTorch生态系统。
3.模型架构
U2框架
统一的双通道联合CTC/AED模型。
-
Shared Encoder: 多层Transformer或Conformer层,负责提取输入语音的特征。
-
CTC Decoder: 将编码器输出转换为CTC激活的线性层。
-
Attention Decoder: 多个Transformer解码器层。
-
Training: 结合CTC和AED损失。
-
Decoding Modes:
- Attention
- CTC Greedy Search
- CTC Prefix Beam Search
- Attention Rescoring
Training
联合训练 :同时优化CTC和AED(Attention Encoder-Decoder)损失函数。损失函数如下:
L = λ L C T C + ( 1 − λ ) L A E D L=λL_{CTC}+(1−λ)L_{AED} L=λLCTC+(1−λ)LAED
其中, λ λ λ是一个权重因子,用于平衡CTC损失和AED损失。
动态chunk训练:在训练过程中,输入语音被分割成多个chunk。每个chunk独立处理,并通过调整chunk大小来模拟不同的实时性要求。
分布式训练:使用PyTorch的DistributedDataParallel进行多GPU训练,以加速训练过程和处理大规模数据。
Decoding
在解码阶段,U2模型采用了多种解码策略来提高识别精度和效率,主要包括CTC贪婪搜索、CTC前缀束搜索、Attention解码器以及Attention重评分。
- Attention:在AED(Attention Encoder-Decoder)模型中,采用标准的自回归波束搜索方法进行解码。能够捕捉长距离依赖和上下文信息,适合高精度的离线语音识别任务。
- CTC Greedy Search(CTC贪婪搜索):在模型的CTC(Connectionist Temporal Classification)部分,采用CTC贪婪搜索方法进行解码。直接选择每个时间步长上CTC输出中概率最高的标签。简单快速,计算复杂度低。精度较低,因为忽略了长距离依赖和上下文信息。
- CTC Prefix Beam Search(CTC前缀束搜索):在模型的CTC部分,应用CTC前缀波束搜索算法,生成n-best候选序列。相比贪婪搜索提高了精度,能够捕捉更多潜在的候选序列。计算复杂度较高,解码速度较慢。
- Attention Rescoring(Attention重评分):结合CTC前缀束搜索和Attention解码器。首先在模型的CTC部分应用CTC前缀波束搜索,生成n-best候选序列,然后在AED解码器中对这些候选序列进行重评分。兼顾了CTC的快速解码能力和Attention的高精度,通过重评分进一步提高了识别精度。整体计算复杂度较高,但相比单纯的Attention解码器有所优化。
4.系统设计
- Data Preparation: 使用Torchaudio进行实时特征提取。
- Training:
- 实时特征提取。
- 联合CTC/AED训练。
- 使用PyTorch的DistributedDataParallel进行分布式训练。
- Decoding: 提供Python工具进行验证和调试。
- Export: 使用TorchScript导出模型,直接部署在LibTorch上。
- Runtime: 支持x86和Android平台,提供C++ API库和演示。
5.实验
数据集: AISHELL-1,包含150小时的普通话语音语料。特征提取采用80维的FBANK特征,并且加上3维的音高特征(基频(F0)、音高概率和音高标准差),总共83维。
Unified model evaluation:
- Non-Streaming Model (M1): 完全注意力模型。
- Unified Model (M2): 动态chunk策略,评估了不同chunk大小。
- Decoding Modes: Attention Rescoring表现最佳,具有最低的延迟。
Runtime Benchmark
实验平台
- 云端服务器 (x86平台): 使用4核Intel Xeon E5-2620 v4 @ 2.10GHz CPU,16GB内存。由于云服务需要并行处理,每个语音片段仅使用一个线程来避免性能下降。
- 移动设备 (ARM Android平台): 使用4核Qualcomm Snapdragon 865 CPU,8GB内存。每个语音片段也仅使用一个线程。
量化 (Quantization)
量化对比了量化前后CER (Character Error Rate) 的变化。结果表明,无论是否进行量化,CER几乎没有变化。下表展示了AISHELL-1测试集上的量化前后CER对比:
实时因子 (RTF)
RTF (Real-Time Factor) 表示的是处理音频所需的时间和音频时长的比值。实验表明,随着chunk大小减小,RTF增大。同时,量化可在设备端带来约两倍的速度提升,并在服务器端带来轻微的改进。
延迟 (Latency)
延迟基准测试使用WebSocket服务器/客户端模拟真实流式应用,只在服务器x86平台上进行。评估了以下三种延迟:
- 模型延迟 (L1): 由模型结构引入的等待时间。对于基于chunk的解码,平均等待时间理论上为chunk的一半。总模型延迟计算公式为(chunk/2 * 4 + 6) * 10(ms),其中4是子采样率,6是编码器中前两个CNN层引入的lookahead,10是帧移。
- 重评分延迟 (L2): 第二遍注意力重评分的时间成本。
- 最终延迟 (L3): 用户感知的延迟,即用户停止说话到获得识别结果的时间差。当ASR服务器接收到语音结束信号时,首先转发剩余语音进行CTC搜索,然后进行第二遍注意力重评分,因此重评分成本是最终延迟的一部分。
结果显示,不同chunk大小的重评分成本几乎相同,因为重评分计算与chunk大小无关。此外,最终延迟主要由重评分成本主导,这意味着可以通过减少重评分成本来进一步降低最终延迟。最终延迟随着chunk大小从4到8再到16略有增加。
15,000-hour Task
使用了一个来自不同领域的15,000小时的普通话数据集,以展示模型在工业级数据集上的能力。
模型架构:
- 共享编码器:使用了Conformer(Wenet)。Conformer在transformer的基础上增加了卷积模块,可以捕捉局部和全局上下文信息,从而在不同的ASR任务中获得更好的效果。特别地,因果卷积用于Conformer的chunk训练,并且在80维的FBANK特征上增加了额外的3维音高特征。
- 编码器结构:主结构与之前实验保持一致,只是将transformer层更换为12层Conformer层,每层具有4个多头注意力头。每层Conformer使用384维的注意力维度和2048维的前馈维度。
- 其他技术:使用了累积梯度以稳定训练,每4步更新一次参数。最终模型通过平均训练过程中评估集上损失较低的前10个最佳模型来获得。
训练了一个全上下文的Conformer CTC模型和一个使用动态chunk训练的U2模型。三个测试集包括AISHELL-1、电视领域和对话领域。U2模型在注意力重评分数解码模式下工作,而Conformer模型在注意力解码模式下工作。
结果表明,U2模型在整体上与Conformer基线模型取得了相当的效果,甚至在使用全注意力进行推理时在AISHELL-1测试集上表现更好。chunk大小为16时,CER(字符错误率)并没有明显变差。
对AISHELL-1任务表现更好的原因进行了分析。由于AISHELL-1中的平均话语时长比其他两个测试集要长,因此需要更强的全局信息建模能力。U2模型可以使用注意力解码器来重评分CTC假设,这使得其更适合AISHELL-1任务。
知识细化
动态分块训练 (Dynamic Chunk Training)
论文链接:Unified Streaming and Non-streaming Two-pass End-to-end Model for Speech Recognition (arxiv.org)
论文提出了一种动态分块训练技术,用于统一流式和非流式模型,并实现延迟控制。U2模型在Shared Encoder是流式时才能实现流式功能。标准Transformer编码器层使用全自注意力机制(full self-attention),如下图(a)所示,每个时间t的输入依赖于整个输入。如下图(b)所示,最简单的流式处理方法是让时间t的输入只看到自身和之前的输入,即左注意力(left attention),但这种方法相比全上下文模型有很大的性能下降。另一种常见技术是限制时间t的输入只看到有限的右上下文t+1, t+2, ..., t+W(W是每层编码器的右上下文),整个上下文通过所有编码器层累积。
文中采用了一种分块注意力机制(chunk attention),如图2©所示,将输入按固定块大小C分成多个块,每个块的输入[t+1, t+2, ..., t+C],每个块依赖于自身和之前所有的块。编码器的整体延迟取决于块大小,易于控制和实现。可以使用固定块大小训练模型,称为静态分块训练(static chunk training),并用相同的块进行解码。
文中进一步提出了动态分块训练(dynamic chunk training)。训练时对不同批次使用不同的动态块大小,动态块大小范围为从1到最大语句长度的均匀分布,即注意力从左上下文注意力到全上下文注意力变化,模型在不同块大小下捕捉不同的信息,学习如何在提供不同有限右上下文时做出准确预测。将块大小从1到25称为流式块(streaming chunk),最大语句长度的块为非流式块(none streaming chunk)。
如公式2所示,每批次训练过程中x从0到1.0采样, l m a x l_{max} lmax为当前批次的最大语句长度,U为均匀分布。块大小分布改变,一半是全块用于非流式,另一半从1到25用于流式。实验结果表明,这种方法简单而有效,动态块大小训练的模型性能与静态分块训练相当。除了批次级别的方法,还尝试了epoch级别的方法------前半部分epoch使用全块,后半部分epoch使用流式块或交替使用。这些策略没有成功。