前言

本项目将分三个阶段分支,分别是入门级 、进阶级 和最终级 分支,当前为最终级的V2版本,如果想使用最终级的V1版本,请在这个分支r1.x。PPASR中文名称PaddlePaddle中文语音识别(PaddlePaddle Automatic Speech Recognition),是一款基于PaddlePaddle实现的语音识别框架,PPASR致力于简单,实用的语音识别项目。可部署在服务器,Nvidia Jetson设备,未来还计划支持Android等移动设备。

别忘了star

源码地址:https://github.com/yeyupiaoling/PPASR

在线使用

1. 在AI Studio平台训练预测

2. 在线使用Dome

本项目使用的环境:

  • Anaconda 3
  • Python 3.8
  • PaddlePaddle 2.4.0
  • Windows 10 or Ubuntu 18.04

项目快速了解

  1. 本项目支持流式识别模型deepspeech2conformersqueezeformer,每个模型又分online(在线)和offline(离线),对应的是流式识别和非流式识别。
  2. 本项目支持两种解码器,分别是集束搜索解码器ctc_beam_search和贪心解码器ctc_greedy,集束搜索解码器ctc_beam_search准确率更高,但不支持Windows。
  3. 下面提供了一系列预训练模型的下载,下载预训练模型之后,需要把全部文件复制到项目根目录,并执行导出模型才可以使用语音识别。

视频讲解

  • 知识点讲解(哔哩哔哩)
  • 流式识别的使用讲解(哔哩哔哩)

快速使用

这里介绍如何使用PPASR快速进行语音识别,前提是要安装PPASR,命令python -m pip install ppasr -U。执行过程不需要手动下载模型,全部自动完成。

  1. 短语音识别
from ppasr.predict import PPASRPredictorpredictor = PPASRPredictor(model_tag='conformer_online_fbank_wenetspeech')wav_path = 'dataset/test.wav'
result = predictor.predict(audio_data=wav_path, use_pun=False)
score, text = result['score'], result['text']
print(f"识别结果: {text}, 得分: {int(score)}")
  1. 长语音识别
from ppasr.predict import PPASRPredictorpredictor = PPASRPredictor(model_tag='conformer_online_fbank_wenetspeech')wav_path = 'dataset/test_long.wav'
result = predictor.predict_long(audio_data=wav_path, use_pun=False)
score, text = result['score'], result['text']
print(f"识别结果: {text}, 得分: {score}")
  1. 模拟流式识别
import time
import wavefrom ppasr.predict import PPASRPredictorpredictor = PPASRPredictor(model_tag='conformer_online_fbank_wenetspeech')# 识别间隔时间
interval_time = 0.5
CHUNK = int(16000 * interval_time)
# 读取数据
wav_path = 'dataset/test.wav'
wf = wave.open(wav_path, 'rb')
data = wf.readframes(CHUNK)
# 播放
while data != b'':start = time.time()d = wf.readframes(CHUNK)result = predictor.predict_stream(audio_data=data, use_pun=False, is_end=d == b'')data = dif result is None: continuescore, text = result['score'], result['text']print(f"【实时结果】:消耗时间:{int((time.time() - start) * 1000)}ms, 识别结果: {text}, 得分: {int(score)}")
# 重置流式识别
predictor.reset_stream()

模型下载

  1. conformer预训练模型列表:
使用模型 数据集 预处理方式 语言 测试集字错率(词错率) 下载地址
conformer_online WenetSpeech (10000小时) fbank 中文 0.03579(aishell_test)
0.11081(test_net)
0.16031(test_meeting)
点击下载
conformer_online WenetSpeech (10000小时)+中文语音数据集 (3000+小时) fbank 中文 0.02923(aishell_test)
0.11876(test_net)
0.18346(test_meeting)
点击下载
conformer_online aishell (179小时) fbank 中文 0.04936 点击下载
conformer_offline aishell (179小时) fbank 中文 0.04343 点击下载
conformer_online Librispeech (960小时) fbank 英文 点击下载
conformer_offline Librispeech (960小时) fbank 英文 点击下载
  1. deepspeech2预训练模型列表:
使用模型 数据集 预处理方式 语言 测试集字错率(词错率) 下载地址
deepspeech2_online WenetSpeech (10000小时) fbank 中文 0.05379(aishell_test) 点击下载
deepspeech2_online aishell (179小时) fbank 中文 0.11367 点击下载
deepspeech2_offline aishell (179小时) fbank 中文 0.09385 点击下载
deepspeech2_online Librispeech (960小时) fbank 英文 点击下载
deepspeech2_offline Librispeech (960小时) fbank 英文 0.11035 点击下载

说明:

  1. 这里字错率或者词错率是使用eval.py程序并使用集束搜索解码ctc_beam_search方法计算得到的,min_duration为1.0,max_duration为20.0。
  2. 没有提供预测模型,需要把全部文件复制到项目的根目录下,执行export_model.py导出预测模型。

有问题欢迎提 issue 交流

快速预测

  • 下载作者提供的模型或者训练模型,然后执行导出模型,使用infer_path.py预测音频,通过参数--wav_path指定需要预测的音频路径,完成语音识别,详情请查看模型部署。
python infer_path.py --wav_path=./dataset/test.wav

输出结果:

-----------  Configuration Arguments -----------
alpha: 1.2
beam_size: 10
beta: 0.35
cutoff_prob: 1.0
cutoff_top_n: 40
decoding_method: ctc_greedy
enable_mkldnn: False
is_long_audio: False
lang_model_path: ./lm/zh_giga.no_cna_cmn.prune01244.klm
mean_std_path: ./dataset/mean_std.npz
model_dir: ./models/infer/
to_an: True
use_gpu: True
use_tensorrt: False
vocab_path: ./dataset/zh_vocab.txt
wav_path: ./dataset/test.wav
------------------------------------------------
消耗时间:132, 识别结果: 近几年不但我用书给女儿儿压岁也劝说亲朋不要给女儿压岁钱而改送压岁书, 得分: 94

数据准备

  1. download_data目录下是公开数据集的下载和制作训练数据列表和词汇表的,本项目提供了下载公开的中文普通话语音数据集,分别是Aishell,Free ST-Chinese-Mandarin-Corpus,THCHS-30 这三个数据集,总大小超过28G。下载这三个数据只需要执行一下代码即可,当然如果想快速训练,也可以只下载其中一个。注意: noise.py可下载可不下载,这是用于训练时数据增强的,如果不想使用噪声数据增强,可以不用下载。
cd download_data/
python aishell.py
python free_st_chinese_mandarin_corpus.py
python thchs_30.py
python noise.py

注意: 以上代码只支持在Linux下执行,如果是Windows的话,可以获取程序中的DATA_URL单独下载,建议用迅雷等下载工具,这样下载速度快很多。然后把download()函数改为文件的绝对路径,如下,我把aishell.py的文件单独下载,然后替换download()函数,再执行该程序,就会自动解压文件文本生成数据列表。

# 把这行代码
filepath = download(url, md5sum, target_dir)
# 修改为
filepath = "D:\\Download\\data_aishell.tgz"
  1. 如果开发者有自己的数据集,可以使用自己的数据集进行训练,当然也可以跟上面下载的数据集一起训练。自定义的语音数据需要符合以下格式,另外对于音频的采样率,本项目默认使用的是16000Hz,在create_data.py中也提供了统一音频数据的采样率转换为16000Hz,只要is_change_frame_rate参数设置为True就可以。

    1. 语音文件需要放在dataset/audio/目录下,例如我们有个wav的文件夹,里面都是语音文件,我们就把这个文件存放在dataset/audio/
    2. 然后把数据列表文件存在dataset/annotation/目录下,程序会遍历这个文件下的所有数据列表文件。例如这个文件下存放一个my_audio.txt,它的内容格式如下。每一行数据包含该语音文件的相对路径和该语音文件对应的中文文本,他们之间用\t隔开。要注意的是该中文文本只能包含纯中文,不能包含标点符号、阿拉伯数字以及英文字母。
dataset/audio/wav/0175/H0175A0171.wav   我需要把空调温度调到二十度
dataset/audio/wav/0175/H0175A0377.wav   出彩中国人
dataset/audio/wav/0175/H0175A0470.wav   据克而瑞研究中心监测
dataset/audio/wav/0175/H0175A0180.wav   把温度加大到十八
  1. 最后执行下面的数据集处理程序,详细参数请查看该程序。这个程序是把我们的数据集生成三个JSON格式的数据列表,分别是manifest.test、manifest.train、manifest.noise。然后建立词汇表,把所有出现的字符都存放子在vocabulary.txt文件中,一行一个字符。最后计算均值和标准差用于归一化,默认使用全部的语音计算均值和标准差,并将结果保存在mean_std.npz中。以上生成的文件都存放在dataset/目录下。数据划分说明,如果dataset/annotation存在test.txt,那全部测试数据都使用这个数据,否则使用全部数据的1/500的数据,直到指定的最大测试数据量。
python create_data.py

训练模型

  • 训练流程,首先是准备数据集,具体看数据准备部分,重点是执行create_data.py程序,执行完成之后检查是否在dataset目录下生成了manifest.testmanifest.trainmean_std.npzvocabulary.txt这四个文件,并确定里面已经包含数据。然后才能往下执行开始训练。

  • 执行训练脚本,开始训练语音识别模型,详细参数请查看该程序。每训练一轮和每10000个batch都会保存一次模型,模型保存在models/<use_model>_<feature_method>/epoch_*/目录下,默认会使用数据增强训练,如何不想使用数据增强,只需要将参数augment_conf_path设置为None即可。关于数据增强,请查看数据增强部分。如果没有关闭测试,在每一轮训练结果之后,都会执行一次测试计算模型在测试集的准确率,注意为了加快训练速度,默认使用的是ctc_greedy解码器,如果需要使用ctc_beam_search解码器,请设置decoder参数。如果模型文件夹下包含last_model文件夹,在训练的时候会自动加载里面的模型,这是为了方便中断训练的之后继续训练,无需手动指定,如果手动指定了resume_model参数,则以resume_model指定的路径优先加载。如果不是原来的数据集或者模型结构,需要删除last_model这个文件夹。

# 单卡训练
python3 train.py
# 多卡训练
python -m paddle.distributed.launch --gpus '0,1' train.py

训练输出结果如下:

............
[2021-09-17 08:41:16.135825] Train epoch: [24/50], batch: [5900/6349], loss: 3.84609, learning rate: 0.00000688, eta: 10:38:40
[2021-09-17 08:41:38.698795] Train epoch: [24/50], batch: [6000/6349], loss: 0.92967, learning rate: 0.00000688, eta: 8:42:11
[2021-09-17 08:42:04.166192] Train epoch: [24/50], batch: [6100/6349], loss: 2.05670, learning rate: 0.00000688, eta: 10:59:51
[2021-09-17 08:42:26.471328] Train epoch: [24/50], batch: [6200/6349], loss: 3.03502, learning rate: 0.00000688, eta: 11:51:28
[2021-09-17 08:42:50.002897] Train epoch: [24/50], batch: [6300/6349], loss: 2.49653, learning rate: 0.00000688, eta: 12:01:30======================================================================
[2021-09-17 08:43:01.954403] Test batch: [0/65], loss: 13.76276, cer: 0.23105
[2021-09-17 08:43:07.817434] Test epoch: 24, time/epoch: 0:24:30.756875, loss: 6.90274, cer: 0.15213
======================================================================
  • 在训练过程中,程序会使用VisualDL记录训练结果,可以通过以下的命令启动VisualDL。
visualdl --logdir=log --host=0.0.0.0
  • 然后再浏览器上访问http://localhost:8040可以查看结果显示,如下。

评估

执行下面这个脚本对模型进行评估,通过字符错误率来评价模型的性能,详细参数请查看该程序。

python eval.py --resume_model=models/conformer_online_fbank/best_model/

输出结果:

······
W0918 10:33:58.960235 16295 device_context.cc:404] Please NOTE: device: 0, GPU Compute Capability: 7.5, Driver API Version: 11.0, Runtime API Version: 10.2
W0918 10:33:58.963088 16295 device_context.cc:422] device: 0, cuDNN Version: 7.6.
100%|██████████████████████████████| 45/45 [00:09<00:00,  4.50it/s]
评估消耗时间:10s,字错率:0.095808

导出模型

训练保存的或者下载作者提供的模型都是模型参数,我们要将它导出为预测模型,这样可以直接使用模型,不再需要模型结构代码,同时使用Inference接口可以加速预测,详细参数请查看该程序。

python export_model.py --resume_model=models/conformer_online_fbank/best_model/

输出结果:

·····
[2021-09-18 10:23:47.022243] 成功恢复模型参数和优化方法参数:models/conformer_online_fbank/best_model/model.pdparams预测模型已保存:models/conformer_online_fbank/infer

本地预测

我们可以使用这个脚本使用模型进行预测,如果如何还没导出模型,需要执行导出模型操作把模型参数导出为预测模型,通过传递音频文件的路径进行识别,通过参数--wav_path指定需要预测的音频路径。支持中文数字转阿拉伯数字,将参数--to_an设置为True即可,默认为True。

python infer_path.py --wav_path=./dataset/test.wav

输出结果:

·····
消耗时间:101, 识别结果: 近几年不但我用书给女儿儿压岁也劝说亲朋不要给女儿压岁钱而改送压岁书, 得分: 94

长语音预测

通过参数--is_long_audio可以指定使用长语音识别方式,这种方式通过VAD分割音频,再对短音频进行识别,拼接结果,最终得到长语音识别结果。

python infer_path.py --wav_path=./dataset/test_long.wav --is_long_audio=True

输出结果:

······
======================================================================
初始化解码器...
language model: is_character_based = 1, max_order = 5, dict_size = 0
初始化解码器完成!
======================================================================
最终结果,消耗时间:4788, 得分: 7, 识别结果: ,作品一行,那时已经上了有的1种数,不知在干了已知的知识,他的干的,增长是正常高像是加一人公式的,1项以内其五行之,把所有
的压制呢,一律向上而且仅仅靠拢,也像是加以人工事的成为1束结果行协议出,它的宽大的意思也是天天向上几乎没有学生的,更不用说到垂直的,它的皮光滑而有银色的运圈,演出淡青色,这
是一方的风雪的压迫下却保持着一定的体力的1种数,哪怕只有往来粗细吧,他是努力向上发展找到这2张餐厅总不折不挠对抗的西北风,这个就是白杨树西北极普通的1种数,2个决不是平行的
数,没有图书的姿态没有区域盘旋的求知,也许你要说它不美丽,如果每只专职不说或横行以出之类而言,那么白杨树算不得数中的女子,但是它却是唯一按政治不严肃也不缺乏综合,更不用
提他的坚强不屈与挺拔,它是15中的伟丈夫,当你在积雪初中的高原上走过,看见平坦的大地上傲然挺立这么1回1排白杨树,难道你就直接着数只是数,难道你就不想让他的铺子严肃坚强不
屈,至少也是真的北方的农民,难道你就1点儿也不联想到,在第1后的广大土地上,让数以坚强不屈就像白杨树一样偶然挺立的首位他们家乡的哨兵,难道你就不更原1点想到这样知识界也
好紧团结力求上进的反映数依然象征了今天在华北平原纵横绝上用血写出新中国历史的那种精神和意志,欢迎光临普通话学习网三达6点

模拟实时识别

这里提供一个简单的实时识别例子,如果想完整使用实时识别,可以使用infer_gui.py中的录音实时识别功能。在--real_time_demo指定为True。

python infer_path.py --wav_path=./dataset/test.wav --real_time_demo=True

输出结果:

······
======================================================================
初始化解码器...
language model: is_character_based = 1, max_order = 5, dict_size = 0
初始化解码器完成!
======================================================================
【实时结果】:消耗时间:19ms, 识别结果: , 得分: -15
【实时结果】:消耗时间:22ms, 识别结果: , 得分: -15
【实时结果】:消耗时间:24ms, 识别结果: 近几年, 得分: -8
【实时结果】:消耗时间:31ms, 识别结果: 近几年不, 得分: -10
【实时结果】:消耗时间:34ms, 识别结果: 近几年不但我用, 得分: -7
【实时结果】:消耗时间:43ms, 识别结果: 近几年不但我用输给女儿, 得分: -4
【实时结果】:消耗时间:46ms, 识别结果: 近几年不但我用输给女儿压岁, 得分: -6
【实时结果】:消耗时间:51ms, 识别结果: 近几年不但我用输给女儿压岁也, 得分: -7
【实时结果】:消耗时间:52ms, 识别结果: 近几年不但我用输给女儿压岁也劝说, 得分: -6
【实时结果】:消耗时间:68ms, 识别结果: 近几年不但我用输给女儿压岁也劝说亲朋不, 得分: -6
【实时结果】:消耗时间:85ms, 识别结果: 近几年不但我用输给女儿压岁也劝说亲朋不要给女儿, 得分: -3
【实时结果】:消耗时间:152ms, 识别结果: 近几年不但我用输给女儿压岁也劝说亲朋不要给女儿压岁, 得分: -6
【实时结果】:消耗时间:76ms, 识别结果: 近几年不但我用输给女儿压岁也劝说亲朋不要给女儿压岁钱, 得分: -3
【实时结果】:消耗时间:91ms, 识别结果: 近几年不但我用输给女儿压岁也劝说亲朋不要给女儿压岁钱而改, 得分: -7
【实时结果】:消耗时间:134ms, 识别结果: 近几年不但我用输给女儿压岁也劝说亲朋不要给女儿压岁钱而改送压, 得分: -6
【实时结果】:消耗时间:163ms, 识别结果: 近几年不但我用输给女儿压岁也劝说亲朋不要给女儿压岁钱而改送压岁书, 得分: -2
【实时结果】:消耗时间:102ms, 识别结果: 近几年不但我用输给女儿压岁也劝说亲朋不要给女儿压岁钱而改送压岁书, 得分: -2

Web部署

在服务器执行下面命令通过创建一个Web服务,通过提供HTTP接口来实现语音识别。启动服务之后,如果在本地运行的话,在浏览器上访问http://localhost:5000,否则修改为对应的 IP地址。打开页面之后可以选择上传长音或者短语音音频文件,也可以在页面上直接录音,录音完成之后点击上传,播放功能只支持录音的音频。支持中文数字转阿拉伯数字,将参数--to_an设置为True即可,默认为True。

python infer_server.py

打开页面如下:

GUI界面部署

通过打开页面,在页面上选择长语音或者短语音进行识别,也支持录音识别,同时播放识别的音频。默认使用的是贪心解码策略,如果需要使用集束搜索方法的话,需要在启动参数的时候指定。

python infer_gui.py

打开界面如下:

相关项目

  • 基于PaddlePaddle实现的声纹识别:VoiceprintRecognition-PaddlePaddle
  • 基于PaddlePaddle静态图实现的语音识别:PaddlePaddle-DeepSpeech
  • 基于Pytorch实现的语音识别:MASR

参考资料

  • https://github.com/PaddlePaddle/PaddleSpeech
  • https://github.com/jiwidi/DeepSpeech-pytorch
  • https://github.com/wenet-e2e/WenetSpeech

PPASR流式与非流式语音识别相关推荐

  1. 完美解释:wenet-流式与非流式语音识别统一模型

    Unified Streaming and Non-streaming Two-pass End-to-end Model for Speech Recognition[1] ,本文以该篇论文为主线, ...

  2. 操作系统中抢占式和非抢占式内核的区别

    编排 | strongerHuang 微信公众号 | 嵌入式专栏 操作系统分为抢占式内核和非抢占式内核,通常RTOS都是抢占式内核. 下面就来讲讲抢占式内核和非抢占式内核的内容. 非抢占式内核 非抢占 ...

  3. 非抢占式优先级调度算法_华为鸿蒙操作系统内核真面目之抢占式和非抢占式内核...

    华为鸿蒙操作系统内核真面目之抢占式和非抢占式内核 众所周知华为鸿蒙操作系统内核是Linux内核.而Linux内核即是抢占式内核也是非抢占式内核.设置软件优先级在优先级在0-99之间是抢占式优先级.设置 ...

  4. 侵入式与非侵入式链表

    侵入式与非侵入式链表 非侵入式链表 非侵入式链表中数据保存在节点中,结点链接域存的是下一个结点的内存首地址 template<typename T> struct ListNode {Li ...

  5. java 非侵入式_非侵入式设计 和侵入式设计 意思?

    非侵入式系介绍DI用语,我得理解是两个组件(类,接口)之间,比较独立,不深入到另一个类内部,哪位大虾能点拨一二? 关于"侵入式"和"非侵入式"设计 有读者讲&q ...

  6. 侵入式及非侵入式概念

    注:此篇博客的内容主要摘录自其他人的博客,并加以整理,下述会给出详细出处. 侵入式与非侵入式设计:在学框架时,经常会遇到侵入式设计与非侵入式设计?究竟是什么意思? 参考侵入式与非侵入式概念. 这两种设 ...

  7. 侵入式与非侵入式概念

    1.侵入式与非侵入式设计:在学框架时,经常会遇到侵入式设计与非侵入式设计?究竟是什么意思? 个人感觉,这两种设计,主要是基于系统扩展性以及依赖性来说的.比如说:①当我们用Struts2框架做系统时,A ...

  8. 脑机接口科普0009——侵入式与非侵入式的优缺点

    本文禁止转载!!!! 在上文脑机接口科普0008--侵入式与非侵入式_sgmcy的博客-CSDN博客中,我们科普了三个术语,EEG, ECoG,LFP.并且,我们做个一个简单的划分归类,我们把EEG划 ...

  9. 五种网络IO模型:阻塞式IO 非阻塞式IO IO复用(IO multiplexing) 信号驱动式IO 异步IO

    文章目录 五种网络IO模型 举例说明 阻塞式I/O模型 非阻塞式I/O I/O多路复用 信号驱动式I/O 异步I/O 比较结果 总结 同步 异步 阻塞 非阻塞 阻塞/非阻塞: 同步/异步: 举例子:小 ...

最新文章

  1. 简单定制自己的Centos系统(第三版)
  2. 成功解决ValueError: attempted relative import beyond top-level package
  3. 成功解决 OSError: [WinError 193] %1 不是有效的 Win32 应用程序
  4. mysql bin log日志
  5. 我看objective-C --不要把objC当做c/c++的超集
  6. 前端小知识点(7):正则前瞻
  7. %3cphp和%3c php_phpcmsv9后台登录绕过
  8. android系统打印功能实现,Android实现系统打印功能
  9. 或许是比力扣 leetcode 更好的选择?推荐两个编程算法宝藏网站
  10. Java - HashMap源码解析
  11. 第7章非线性系统的分析-7.1非线性系统的基本概念
  12. python读取大智慧数据_大智慧数据格式
  13. 装了冰点还原如何修改计算机ip,如何改变冰点还原企业控制台的IP地址
  14. 腾讯云TDSQL-C云原生数据库技术
  15. 10个优秀免费高清素材图库相册:各类美图应有尽有
  16. 为什么都说阿里P7的晋升是道坎?
  17. 中职计算机专业英语说课稿,中职英语基础模块说课
  18. NHANES数据库的介绍及使用(二)
  19. 腾讯轻量云FREEBSD11.1安装panabit cloud
  20. Win 10 亮度调节选项消失

热门文章

  1. tableViewCell、collectionViewCell、组头组尾等总结
  2. ghost还原固态硬盘_高级格式化_固态硬盘到底能不能使用Ghost软件?终于说明白了...
  3. 主引导记录MBR的结构和作用
  4. Python技能树及 CSDN MarkDown编辑器测评
  5. GEP基因表达式编程
  6. 如虎添翼 7 个转场技巧
  7. 狂神说Spring学习笔记————(一发入魂)
  8. 在office中插入特殊符号方框带√
  9. 计算机科学类专升本复习之“C语言结构体”详解(初稿)
  10. 衡量连通图连通性一些指标(r-reachable, r-robust)