“We can only see a short distance ahead, but we can see plenty there that needs to be done.”
―Alan Turing
Wenet简介
Wenet是出门问问语音团队联合西工大语音实验室开源的一款面向工业落地应用的语音识别工具包,该工具用一套简洁的方案提供了语音识别从训练到部署的一条龙服务,其主要特点如下:
- 使用conformer网络结构和C++TC/attention loss联合优化方法,具有业界一流的识别效果。
- 提供云上和端上直接部署的方案,最小化模型训练和产品落地之间的工程工作。
- 框架简洁,模型训练部分完全基于pytorch生态,不依赖于kaldi等安装复杂的工具。
- 详细的注释和文档,十分适合用于学习端到端语音识别的基础知识和实现细节。
Wenet在正式发布前已经在github获得数百个stars,其易用性深受用户好评
https://github.com/mobvoi/wenetgithub.com/mobvoi/wenet
- Wenet工具包介绍论文: https://arxiv.org/pdf/2102.01547.pdf
- Wenet核心算法U2介绍论文: https://arxiv.org/pdf/2012.05481.pdf
- U2算法解读 茶多酚老爹:调研报告|动态 Chunk Conformer 在线+离线混合 ASR 模型
和其他端到端语音识别工具包的区别
在网络设计上,Wenet借鉴了Espnet,opentransformer等优秀的语音开源项目,但Wenet的核心目标是为语音识别提供一套高性能易部署的工业级解决方案,所以相比Espnet,Wenet没有对各类序列转化任务进行统一抽象,完全聚焦于语音识别任务,同时对于常用的语音识别应用场景提出了一套效果极佳的端到端解决方案,而不去提供各类模型方案的大而全的集合。正因为这一明确的设计目标,Wenet在保持简洁易用的同时,在语音识别正确率、实时率和延时性都有着非常出色表现,可以直接在工业场景中落地应用。
模型结构
网络结构
Wenet网络结构设计借鉴Espnet的joint loss框架,这一框架采取Conformer Encoder + CTC/attention loss, 利用帧级别的CTC loss和label级别attention-based auto-regression loss联合训练整个网络。 这一框架是目前语音领域最流行的框架之一,在多个数据集和比赛上都取得了非常好的结果.
流式/非流式的统一结构。
近几年端到端的流式模型和非流式模型往往采用不同结构,一般流式方案可选用CTC,RNN-T,Monotonic Attention等方案,在非流式场景下,则通常使full-attention encoder decoder模型,牺牲流式特性的而获得更好的识别率。但是,在两种场景下使用两个结构不同的模型会增加模型训练和部署维护的成本,因此最近语音识别的一大研究热点是如何对流式/非流式的模型进行统一.
Wenet针对工业届的具体场景需求,兼顾流式响应速度和识别效果,采用了一套两遍解码的方案,用一个统一的模型结构同时有效的支持流式和非流式场景。
- CTC进行第一遍流式解码,该结果可作为流式结果实时返回。
- 多个候选结果再通过attention-based decoder做一遍teacher forcing rescoring,根据得分重新排序。得到更好的识别结果。
对Conformer的流式改进
原始Conformer结构中的self-attention需要对整个序列进行attention运算,不具备流式特点,同时convolution层也依赖于右侧固定长度上下文,且依赖的长度随着模型层数增多而增加。因此,都需要进行改进,保证只依赖有限长度的右侧上下文,从而支持流式推断。
对于self-attention层,常见流式改进方法有chunk法和windows法
- chunk法:将序列分成多个chunk,每帧在chunk内部做attention
- windows法:每帧和左右固定长度内的帧做attention,也叫look ahead方法
Wenet选择了chunk方案,这种方案可以保证对右侧依赖的长度与网络层数无关。在基于chunk的方案中,chunk的大小会影响着流式最大延时和模型识别率性能,大的chunk延时大但性能更好,小的chunk延时小但性能会变差。Wenet使用了一种新的动态chunk训练算法,可以使得模型的chunk大小动态可变,在运行时,可根据当前场景延时要求和识别率需求手动调整chunk大小,而无需重新训练模型。
而对于convolution层,Wenet使用一个左侧卷积,以支持流式推断。
解码算法
Wenet在训练时同时使用了帧级别deocder的CTC loss和label级别decoder的loss。因此在推断时可以使用多种不同的解码方式。目前Wenet支持四种解码算法
- CTC greedy beam search, 帧级别输出,解码过程不合并前缀,最终n-best上进行ctc序列处理。
- CTC prefix beam search , 帧级别的解码,合并相同的ctc序列前缀。
- Attention decoder beam search, 基于cross-attention的label级别解码。
- CTC + attention rescoring , 将CTC decoder的n-best结果,通过attention decoder进行重打分
CTC + attention rescoring方案可以利用CTC decoder的输出作为流式结果,在损失很小准确率的情况下支持场景的流式需求,并最终利用rescoring改进结果,得到一个识别率更高的最终结果。
考虑一个实时字幕上屏的场景,当演讲者说话时,可利用CTC decoder的实时输出结果将字幕实时上屏,让听众立刻看到当前演讲内容的文本,在一句话结束时,会对文本内容进行重打分纠正,最终显示和进行归档的文本是准确率更高的结果。手机/车载等语音助理也同样适用该模式。
模型训练
训练脚本
Wenet提供了aishell和librispeech的一键recipe示例,在aishell上可以达到目前业界最好的效果。
特征提取
Wenet的数据准备非常简单,只需wav.scp和text文件,即需要训练的音频文件列表和标注文本即可。提取特征在dataloader中利用torchaudio工具包完成,无需额外的特征提取步骤。
该方案一方面简化了pipeline,一方面可以在每个epoch动态使用不同的wav augmentatio方法.
目前Wenet中动态特征提取模式仅使用fbank特征。 在语音识别中,对于带调的语言如中文可加入pitch特征,不过在实验中发现,随着数据量的增大和使用更好的模型结构,往往仅用fbank也可达到很高的性能,
另外,Wenet也支持使用任意特征的方案,但是这种方案需要额外的特征准备步骤,将特征准备成kaldi的ark格式。
Wenet还支持一系列可选的augmentation算法,如speed perturbation,spec aug等方法。
分布式训练
Wenet目前可以支持在单机单卡和单机多卡上训练,后续会开放多机多卡的功能。
动态chunk训练
Wenet的提出了一套动态chunk的训练方法,该方法在训练时,随机为样本选择不同的chunk大小,从而允许一个模型可处理不同chunk大小的输入,当场景不需要流式识别是,可以使用整句长度作为chunk大小,以获得最佳识别性能。当场景需要流式识别时,可根据场景的特点自由选择chunk大小。
这种方案,在模型训练收敛速度上并不比使用全序列attention慢,甚至还可以加速模型的收敛。
模型部署
模型导出
Wenet模型全部由Torchscript编写,可以直接导出为支持libtorch运行时推断的模型,在运行时,利用libtorch导出的接口完成网络前向计算,而特征提取和解码算法则通过C++代码实现.
模型裁剪
目前Wenet使用dynamic量化来对模型进行压缩,该量化方法对代码结构破坏最小,而且也最为便捷。量化后的模型性能几乎没有损失。
实时率
实时率即处理时间/语音时长。更低的实时率意味着可以用更少的计算资源处理更多的语音,即能够为企业带来更低的服务器运营成本。通过模型量化,Wenet的实时率在服务器端和手机端均可以达到0.1以下。即处理10秒音频需要的时间不超过1秒。
延时性能
语音识别中存在多种延时需要考虑,如流式识别时用户感知到的实时回显的延时,如一句话说完后完成整句识别的延时。我们考虑三种延时:
L1: 模型结构带来的流式延时
L2: 重打分计算部分带来的延时
L3: 用户说话,到最终重打分后的结果之间的时间间隔。
Wenet的演示非常低,其不到0.4s的流式延时和0.14s的整句延时,使得用户在使用时几乎感受不到延时.
应用示例
Wenet提供了多个运行时应用示例,方便用户参考编写自己的应用
离线本地识别 ,这是嵌入式端Android平台上的离线流式语音识别app。该示例中使用aishell训练的U2 transformer模型,并对模型进行8bit的量化。
wenet_android_app_v01449 播放 · 1 赞同视频
文档和技术支持
Wenet本身的代码注释详细,便于初学者学习端到端语音识别的相关知识和实现技巧.
Wenet的官方英文文档请参考
Welcome to Wenet’s documentation!wenet-e2e.github.io/wenet/
后续我们还会陆续用中文撰写一些关于具体代码实现的介绍,方便学习者理解.
大家可以通过github issue提问和微信群讨论来交流Wenet的问题.
- Github issue
- 微信交流群,由于最近很多同学关注和使用Wenet,目前1群已经快满员,且无法通过二维码入群,所以又建立了交流2群,请大家扫码入群。
知乎为了防止恶意营销不能显示群二维码,大家可以在Wenet项目主页的Readme里找到二维码扫码进群。如果2群超过了200人不能扫码入群,可以加其中的个人微信,再入群。
未来工作
Wenet的核心目标是工业界的语音识别落地,在未来,会逐步开放多机多卡训练,实时率和延时等性能的优化方案,支持语言模型等功能。
另外,当一些学术界的热点研究效果达到能够在工业落地时,比如wav2vec 2.0,非自回归模型等方法,也会进行更新支持。
感谢
感谢每一位Wenet用户,你们的支持,是Wenet团队的小伙伴们最大的动力。非常感谢kaldi,espnet等开源语音项目为我们学习和应用语音识别铺平了道路,非常感谢西工大谢磊老师和aslp语音实验室的同学们的支持,非常感谢腾讯孙思宁博士对论文的修改,非常感谢在微信群中反馈建议以及在github提交issue和pr的各位同学。
千里之行始于足下,Wenet只是完成了从0到1,还有很长的路要走.
We will make this net better.
相关推荐: Wenet – 面向工业落地的E2E语音识别工具
“We can only see a short distance ahead, but we can see plenty there that needs to be done.” ―Alan Turing Wenet简介 Wenet是出门问问语…