# 前言
本項目將分三個階段分支,分別是入門級 、進階級 和最終級 分支,當前爲最終級的V2版本,如果想使用最終級的V1版本,請在這個分支r1.x。PPASR中文名稱PaddlePaddle中文語音識別(PaddlePaddle Automatic Speech Recognition),是一款基於PaddlePaddle實現的語音識別框架,PPASR致力於簡單,實用的語音識別項目。可部署在服務器,Nvidia Jetson設備,未來還計劃支持Android等移動設備。
別忘了star
源碼地址:https://github.com/yeyupiaoling/PPASR
在線使用¶
2. 在線使用Dome
3. 在線運行
本項目使用的環境:
- Anaconda 3
- Python 3.8
- PaddlePaddle 2.4.0
- Windows 10 or Ubuntu 18.04
項目快速瞭解¶
- 本項目支持流式識別模型
deepspeech2、conformer、squeezeformer,每個模型又分online(在線)和offline(離線),對應的是流式識別和非流式識別。 - 本項目支持兩種解碼器,分別是集束搜索解碼器
ctc_beam_search和貪心解碼器ctc_greedy,集束搜索解碼器ctc_beam_search準確率更高,但不支持Windows。 - 下面提供了一系列預訓練模型的下載,下載預訓練模型之後,需要把全部文件複製到項目根目錄,並執行導出模型纔可以使用語音識別。
視頻講解¶
快速使用¶
這裏介紹如何使用PPASR快速進行語音識別,前提是要安裝PPASR,命令python -m pip install ppasr -U。執行過程不需要手動下載模型,全部自動完成。
- 短語音識別
from ppasr.predict import PPASRPredictor
predictor = PPASRPredictor(model_tag='conformer_streaming_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)}")
- 長語音識別
from ppasr.predict import PPASRPredictor
predictor = PPASRPredictor(model_tag='conformer_streaming_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}")
- 模擬流式識別
import time
import wave
from ppasr.predict import PPASRPredictor
predictor = PPASRPredictor(model_tag='conformer_streaming_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 = d
if result is None: continue
score, text = result['score'], result['text']
print(f"【即時結果】:消耗時間:{int((time.time() - start) * 1000)}ms, 識別結果: {text}, 得分: {int(score)}")
# 重置流式識別
predictor.reset_stream()
模型下載¶
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 | 英文 | 點擊下載 |
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指定需要預測的音頻路徑,完成語音識別,詳情請查看模型部署。
```shell script
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`可下載可不下載,這是用於訓練時數據增強的,如果不想使用噪聲數據增強,可以不用下載。
```shell script
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就可以。- 語音文件需要放在
dataset/audio/目錄下,例如我們有個wav的文件夾,裏面都是語音文件,我們就把這個文件存放在dataset/audio/。 - 然後把數據列表文件存在
dataset/annotation/目錄下,程序會遍歷這個文件下的所有數據列表文件。例如這個文件下存放一個my_audio.txt,它的內容格式如下。每一行數據包含該語音文件的相對路徑和該語音文件對應的中文文本,他們之間用\t隔開。要注意的是該中文文本只能包含純中文,不能包含標點符號、阿拉伯數字以及英文字母。
```shell script
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
python create_data.py
訓練模型¶
-
訓練流程,首先是準備數據集,具體看數據準備部分,重點是執行
create_data.py程序,執行完成之後檢查是否在dataset目錄下生成了manifest.test、manifest.train、mean_std.npz、vocabulary.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。
```shell script
python infer_path.py –wav_path=./dataset/test.wav
輸出結果:
·····
消耗時間:101, 識別結果: 近幾年不但我用書給女兒兒壓歲也勸說親朋不要給女兒壓歲錢而改送壓歲書, 得分: 94
## 長語音預測
通過參數`--is_long_audio`可以指定使用長語音識別方式,這種方式通過VAD分割音頻,再對短音頻進行識別,拼接結果,最終得到長語音識別結果。
```shell script
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。
```shell script
python infer_server.py
打開頁面如下:

## GUI界面部署
通過打開頁面,在頁面上選擇長語音或者短語音進行識別,也支持錄音識別,同時播放識別的音頻。默認使用的是貪心解碼策略,如果需要使用集束搜索方法的話,需要在啓動參數的時候指定。
```shell script
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