前言
PPASR是飞桨社区开发者夜雨飘零开发的一款基于飞桨实现的语音识别工具,简单实用,可识别中文语音,可部署在服务器、Nvidia Jetson设备,未来还计划支持Android等移动设备。
使用环境:
Anaconda 3
Python 3.7
飞桨PaddlePaddle核心框架2.2.0
Windows 10 or Ubuntu 18.04
源码地址:https://github.com/yeyupiaoling/PPASR
模型下载
本项目在各个公开数据集上的字错率见下表:
说明:aishell数据集已经固定好训练数据和测试数据,其他数据集是按照项目设置的固定比例划分训练数据和测试数据。
快速预测
下载预训练模型或者自行训练模型,然后执行模型导出。
使用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
数据准备
本项目使用了公开的中文普通话语音数据集,分别是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"
如果开发者有自己的数据集,可以使用自己的数据集进行训练,当然也可以跟上面下载的数据集一起训练。自定义的语音数据需要符合以下格式,本项目默认使用的音频的采样率是16000Hz,在create_data.py中也提供了统一音频数据的采样率转换为16000Hz,只要is_change_frame_rate参数设置为True就可以。
1)语音文件需要放在dataset/audio/目录下。
2)把数据列表文件存在dataset/annotation/目录下,程序会遍历这个文件下的所有数据列表文件。
dataset/audio/wav/0175/H0175A0171.wav 我需要把空调温度调到二十度 dataset/audio/wav/0175/H0175A0377.wav 出彩中国人 dataset/audio/wav/0175/H0175A0470.wav 据克而瑞研究中心监测 dataset/audio/wav/0175/H0175A0180.wav 把温度加大到十八
3)执行数据处理。该脚本将数据集生成三个JSON格式的数据列表,分别是manifest.test、manifest.train、manifest.noise。然后建立词汇表,把所有出现的字符都存放子在vocabulary.txt文件中,一行一个字符。最后计算均值和标准差用于归一化,默认使用全部的语音计算均值和标准差,并将结果保存在mean_std.npz中。
以上生成的文件都存放在dataset/目录下。数据划分说明,如果dataset/annotation存在test.txt,那全部测试数据都使用这个数据,否则使用全部数据的1/500的数据,直到指定的最大测试数据量。
python create_data.py
训练模型
执行训练脚本,开始训练语音识别模型。每训练一轮和每10000个batch都会保存一次模型,模型保存在models/
# 单卡训练
python3 train.py
# 多卡训练
python -m paddle.distributed.launch --gpus '0,1' train.py
训练输出结果如下:
----------- Configuration Arguments -----------
alpha: 2.2
augment_conf_path: conf/augmentation.json
batch_size: 32
beam_size: 300
beta: 4.3
cutoff_prob: 0.99
cutoff_top_n: 40
dataset_vocab: dataset/vocabulary.txt
decoder: ctc_greedy
lang_model_path: lm/zh_giga.no_cna_cmn.prune01244.klm
learning_rate: 5e-05
max_duration: 20
mean_std_path: dataset/mean_std.npz
min_duration: 0.5
num_epoch: 65
num_proc_bsearch: 10
num_workers: 8
pretrained_model: None
resume_model: None
save_model_path: models/
test_manifest: dataset/manifest.test
train_manifest: dataset/manifest.train
use_model: deepspeech2
------------------------------------------------
............
[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/deepspeech2/best_model
输出结果:
----------- Configuration Arguments -----------
alpha: 2.2
batch_size: 32
beam_size: 300
beta: 4.3
cutoff_prob: 0.99
cutoff_top_n: 40
dataset_vocab: dataset/vocabulary.txt
decoder: ctc_beam_search
lang_model_path: lm/zh_giga.no_cna_cmn.prune01244.klm
mean_std_path: dataset/mean_std.npz
num_proc_bsearch: 10
num_workers: 8
resume_model: models/deepspeech2/best_model/
test_manifest: dataset/manifest.test
use_model: deepspeech2
------------------------------------------------
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 infer_path.py --wav_path=./dataset/test.wav
输出结果:
----------- Configuration Arguments -----------
dataset_vocab: dataset/vocabulary.txt
mean_std_path: dataset/mean_std.npz
resume_model: models/deepspeech2/epoch_50
save_model: models/deepspeech2/
use_model: deepspeech2
------------------------------------------------
[2021-09-18 10:23:47.022243] 成功恢复模型参数和优化方法参数:
models/deepspeech2/epoch_50/model.pdparams
预测模型已保存:
models/deepspeech2/infer
本地预测
可以使用这个脚本进行预测,通过参数--wav_path指定需要预测的音频路径。支持中文数字转阿拉伯数字,将参数--to_an设置为True即可。
python infer_path.py --wav_path=./dataset/test.wav
输出结果:
----------- Configuration Arguments -----------
alpha: 2.2
beam_size: 300
beta: 4.3
cutoff_prob: 0.99
cutoff_top_n: 40
decoder: ctc_beam_search
is_long_audio: False
lang_model_path: lm/zh_giga.no_cna_cmn.prune01244.klm
model_dir: models/deepspeech2/infer/
real_time_demo: False
to_an: True
use_gpu: True
use_model: deepspeech2
vocab_path: dataset/vocabulary.txt
wav_path: ./dataset/test.wav
------------------------------------------------
消耗时间:101, 识别结果: 近几年不但我用书给女儿儿压岁也劝说亲朋不要给女儿压岁钱而改送压岁书, 得分: 94
长语音预测
通过参数--is_long_audio可以指定使用长语音识别方式,这种方式通过VAD分割音频,再对短音频进行识别,拼接结果,最终得到长语音识别结果。
python infer_path.py --wav_path=./dataset/test_vad.wav --is_long_audio=True
输出结果:
----------- Configuration Arguments -----------
alpha: 2.2
beam_size: 300
beta: 4.3
cutoff_prob: 0.99
cutoff_top_n: 40
decoding_method: ctc_greedy
is_long_audio: 1
lang_model_path: ./lm/zh_giga.no_cna_cmn.prune01244.klm
model_dir: ./models/deepspeech2/infer/
to_an: True
use_gpu: True
vocab_path: ./dataset/zh_vocab.txt
wav_path: dataset/test_vad.wav
------------------------------------------------
Web部署
在服务器执行以下命令通过创建一个Web服务,提供HTTP接口来实现语音识别。启动服务之后,如果在本地运行的话,在浏览器上访问http://localhost:5000,否则修改为对应的 IP地址。打开页面之后可以选择上传长音或者短语音音频文件,也可以在页面上直接录音,录音完成之后点击上传,播放功能只支持录音的音频。支持中文数字转阿拉伯数字,将参数--to_an设置为True即可,默认为True。
python infer_server.py
打开页面如下:
GUI界面部署
在页面上选择长语音或者短语音进行识别,也支持录音识别,同时播放识别的音频。默认使用的是贪心解码策略,如果需要使用集束搜索方法的话,需要在启动参数的时候指定。
python infer_gui.py
打开界面如下:
相关项目
基于飞桨框架实现的声纹识别:
https://github.com/yeyupiaoling/VoiceprintRecognition-PaddlePaddle
基于飞桨框架静态图实现的语音识别:
https://github.com/yeyupiaoling/PaddlePaddle-DeepSpeech
参考资料
https://github.com/PaddlePaddle/PaddleSpeech
https://github.com/jiwidi/DeepSpeech-pytorch
https://github.com/wenet-e2e/WenetSpeech
关注公众号,获取更多技术内容~