FastASR——PaddleSpeech的C++實現

FastASR

基於PaddleSpeech所使用的conformer模型,使用C++的高效實現模型推理,在樹莓派4B等ARM平台運行也可流暢運行。

項目簡介

本項目僅實現了PaddleSpeech r1.01版本中conformer_wenetspeech-zh-16k預訓練模型。
這個預訓練模型採用了當下最先進的conformer模型,使用10000+小時的wenetspeech數據集訓練得到。
經過測試它識別效果很好,可以媲美許多商用的ASR軟體。

PaddleSpeech是基於python實現的,本身的性能已經很不錯了,即使在沒有GPU的個人電腦上運行,
也能滿足實時性的要求(如:時長為10s的語音,推理時間小於10s,即可滿足實時性)。

但是要把PaddleSpeech部署在ARM平台,會遇到兩個方面的困難。

  • 不容易安裝,需要自己編譯一些組件。
  • 執行效率很慢,無法滿足實時性的要求。

因此就有這個項目,它由純C++編寫,僅實現了模型的推理過程。

  • 語言優勢: 由於C++和Python不同,是編譯型語言,編譯器會根據編譯選項針對不同平台的CPU進行優化,更適合在不同CPU平台上面部署,充分利用CPU的計算資源。
  • 獨立: 實現不依賴於現有的深度學習框架如pytorch、paddle、tensorflow等。
  • 依賴少: 項目僅使用了兩個第三方庫libfftw3和libopenblas,並無其他依賴,所以在各個平台的可移植行很好,通用性很強。
  • 效率高:演算法中大量使用指針,減少原有演算法中reshape和permute的操作,減少不必要的數據拷貝,從而提升演算法性能。

快速上手

安裝依賴

安裝依賴庫libfftw3

sudo apt-get install libfftw3-dev libfftw3-single3

安裝依賴庫libopenblas

sudo apt-get install libopenblas-dev

編譯源碼

下載最新版的源碼

git clone //github.com/chenkui164/FastASR.git

編譯最新版的源碼

cd FastASR/
make

下載預訓練模型

從PaddleSpeech官網下載預訓練模型,如果之前已經在運行過PaddleSpeech,
則可以不用下載,它已經在目錄~/.paddlespeech/models/conformer_wenetspeech-zh-16k中。

wget -c //paddlespeech.bj.bcebos.com/s2t/wenetspeech/asr1_conformer_wenetspeech_ckpt_0.1.1.model.tar.gz

將壓縮包解壓wenetspeech目錄下

mkdir wenetspeech
tar -xzvf asr1_conformer_wenetspeech_ckpt_0.1.1.model.tar.gz -C wenetspeech

將用於Python的模型轉換為C++的,這樣更方便通過記憶體映射的方式直接讀取參數,加快模型讀取速度。

./convert.py wenetspeech/exp/conformer/checkpoints/wenetspeech.pdparams

查看轉換後的參數文件wenet_params.bin的md5碼,md5碼為9cfcf11ee70cb9423528b1f66a87eafd,表示轉換正確。

md5sum -b wenet_params.bin

同時我也把轉換好的wenet_params.bin上傳至github,可以直接下載,可能會有些慢。

wget -c  //github.com/chenkui164/FastASR/releases/download/V0.01/wenet_params.bin

如何使用

下載用於測試的wav文件

wget -c //paddlespeech.bj.bcebos.com/PaddleAudio/zh.wav 

執行程式

./fastasr zh.wav

程式輸出

Audio time is 4.996812 s.
Model initialization takes 0.163184s
result: "我認為跑步最重要的就是給我帶來了身體健康"
Model inference takes 0.462369s.

樹莓派4B上優化部署

由於深度學習推理過程,屬於計算密集型演算法,所以CPU的指令集對程式碼的執行效率會有重要影響。
從純數值計算角度來看,64bit的指令及要比32bit的指令集執行效率要提升1倍。
經過測試同樣的演算法在64bit系統上,確實是要比32bit系統上,執行效率高很多。

為樹莓派升級64位系統raspios

樹莓派官網下載最新的raspios 64位系統,
我下載的是沒有桌面的精簡版raspios_lite_arm64
當然也可以下載有桌面的版本raspios_arm64
兩者沒有太大差別,全憑個人喜好。

下載完成鏡像,然後燒寫SD卡,保證系統新做的系統能正常啟動即可。

重新編譯依賴庫

儘管兩個依賴庫fftw3和openblas都是可以通過sudo apt install直接安裝的,
但是軟體源上的版本是通用版本,是兼容樹莓派3B等老版本的型號,
並沒有針對樹莓派4B的ARM CORTEX A72進行優化,所以執行效率並不高。
因此我們需要針對樹莓派4B重新編譯,讓其發揮最大效率。


注意:以下編譯安裝步驟都是在樹莓派上完成,不使用交叉編譯!!!

安裝fftw3

下載源碼

wget -c //www.fftw.org/fftw-3.3.10.tar.gz

解壓

tar -xzvf fftw-3.3.10.tar.gz 
cd fftw-3.3.10/

配置工程,根據CPU選擇適當的編譯選項

./configure --enable-shared --enable-float --prefix=/usr

編譯和安裝

make -j4
sudo make install

安裝OpenBLAS

下載源碼

wget -c //github.com/xianyi/OpenBLAS/releases/download/v0.3.20/OpenBLAS-0.3.20.tar.gz

解壓

tar -xzvf OpenBLAS-0.3.20.tar.gz  
cd OpenBLAS-0.3.20

編譯和安裝

make -j4
sudo make PREFIX=/usr install

編譯和測試

編譯和下載預訓練模型的過程,請參考上文的 快速上手章節。

運行程式

./fastasr zh.wav

結果

Audio time is 4.996812 s.
Model initialization takes 10.288784s
result: "我認為跑步最重要的就是給我帶來了身體健康"
Model inference takes 4.900788s.

當第一次運行時,發現模型初始化時間就用了10.2s,
顯然不太合理,這是因為預訓練模型是在SD卡中,一個450M大小的文件從SD卡讀到記憶體中,主要受限於SD卡的讀取速度,所以比較慢。
得利於linux的快取機制,第二次運行時,模型已經在記憶體中,不用在從SD卡讀取了,所以只有重啟後第一次會比較慢。

第二次運行結果

Audio time is 4.996812 s.
Model initialization takes 0.797091s
result: "我認為跑步最重要的就是給我帶來了身體健康"
Model inference takes 4.916471s.

從結果中可以看出,當音頻文件為4.99s時,推理時間為4.91秒,推理時間小於音頻時間,剛剛好能滿足實時性的需求。