語音識別開源工具PyTorch-Kaldi:兼顧Kaldi效率與PyTorch靈活性
機器之心原創
作者:Nurhachu Null
本文主要介紹用於語音識別的開源工具——PyTorch-Kaldi。
1 背景
傑出的科學家和工程師們一直在努力地給機器賦予自然交流的能力,語音識別就是其中的一個重要環節。人類對語音識別技術的研究從上世紀 50 年代開始就未曾停止。在長期的探索中,一次次重大的技術突破逐漸讓語音識別技術進入我們的日常生活。今天的 ASR 技術水平是前所未有的。高性能的語音識別給我們帶來了更多的生活體驗,我們擁有了可以對話的智能數字助手;它也在逐步改善相關領域的生產力水平。
和很多偉大技術的應用一樣,語音識別技術的背後也是很多模塊的組合。對其實現流程的改進往往會從一定程度上節省開發成本,並且加快技術迭代的速度。Pytorch-Kaldi 的出現就是基於這樣的動力。
1.1 語音識別系統的組成
圖 1. 語音識別系統的結構
一個典型的語音識別系統如圖 1 所示。它包含 4 個組成部分:信號處理和特徵提取、聲學模型、語言模型和解碼搜索。聲學模型是其中的核心部分,我們可以把它理解為說話聲音和語言發音之間的映射。而信號處理和特徵提取就是用於構建聲學模型的材料了,它主要依靠數字信號處理相關的技術。語言模型則可以被看作是語言先驗知識。語音識別的最終結果就是在聲學模型得分和語言模型得分上進行搜索得到的。具體的內容這裡不做展開。
在語音識別技術的發展史上,深度學習絕對是極具影響力的。可以說,沒有對深度學習的引入,就不會有今天如此先進的語音識別引擎。
1.2 業界的基本現狀
一個成功的語音識別系統真的是很難離開一眾優秀開源框架的支撐,比如:HTK,Julius,CMU-Sphinx,PWTH-ASR,LIA-ASR 以及 Kaldi。後來居上的 Kaldi 獨領風騷,擁有活躍的技術社區,被廣泛的應用在語音識別技術的研究和系統開發中。據筆者了解,很多國內語音公司的語音識別系統也有著對 Kaldi 或多或少的依賴。圖 2 是在本文寫作的時,GitHub 上 Kaldi 項目的「盛景」。
圖 2. kaldi-asr
但是,Kaldi 也有不盡如人意的地方,它依賴大量的腳本語言,而且核心演算法使用 C++編寫的,對聲學模型的更新就不是一件容易的事情了,尤其是在需要改變各種神經網路的結構時。即便是擁有豐富經驗的工程師,在調試的時候也會經歷巨大的痛苦。當然,儘管如此,Kaldi 還是一項偉大的工作。
有問題存在,便有了改進的需要。Yoshua Bengio 團隊成員 Mirco Ravanelli 等人開發了一個試圖繼承 Kaldi 的效率和 PyTorch 的靈活性的開源框架——PyTorch-Kaldi。相關的論文已經在 ICASSP 2019 上發表了,論文標題如圖 3 所示。
圖 3. PyTorch-Kaldi 論文首頁
1.3 Why pytorch-kaldi?
正如論文提到的一句話,「The PyTorch-Kaldi project aims to bridge the gap between Kaldi and PyTorch」,PyTorch-Kaldi 就是為了彌補 PyTorch 和 Kaldi 之間的鴻溝。在 PyTorch 中實現聲學模型,在 Kaldi 中執行特徵提取、標籤/對齊計算和解碼。這也再次從側面證明了 PyTorch 作為一個深度學習框架所具有的的卓越的靈活性和便利性。事實上,很多人都認為 PyTorch 比 TensorFlow 更加適合做研究工作。本文的第二部分將會重點介紹一下 PyTorch-Kaldi 開源工具。
2 PyTorch-Kaldi 簡介
PyTorch-Kaldi 項目的結構如圖 4 所示。正如前面所提到的,在這個項目中,PyTorch 和 Kaldi 在項目中的分工是比較明確的。主腳本 run_exp.py(後面稱其為主腳本)是用 Python 寫的,它負責管理 ASR 系統的所有階段,包括特徵和標籤提取、訓練、驗證、解碼和打分。目前版本(v0.2)的 PyTorch-Kaldi 實現了混合 DNN-HMM 的語音識別器。
圖 4. PyTorch-Kaldi 項目結構
2.1 配置文件
主腳本以 INI 格式的配置文件為輸入,這個配置文件在項目文檔中有著很詳細的描述。配置文件主要由以下 5 部分內容組成。
- [exp]:這部分指定了一些高級信息,例如用於實驗的文件夾、訓練迭代次數、隨機數種子,它也允許用戶指定實驗是在 CPU/GPU 或者多 GPU 上進行,下面是一個例子:
[exp]
cmd =
run_nn_script = run_nn
out_folder = exp/TIMIT_liGRU_fmllr
seed = 4234
use_cuda = True
multi_gpu = False
save_gpumem = False
n_epochs_tr = 24
- [dataset]:這部分指定了特徵和標籤。包括它們的存儲路徑、窗口的特徵以及數據集被分割成塊的數量。下面是一個例子:
[dataset1]
data_name = TIMIT_tr
fea = fea_name=mfcc
fea_lst=quick_test/data/train/feats_mfcc.scp
fea_opts=apply-cmvn --utt2spk=ark:quick_test/data/train/utt2spk ark:quick_test/mfcc/train_cmvn_speaker.ark ark:- ark:- | add-deltas --delta-order=2
ark:- ark:- |
cw_left=0
cw_right=0
fea_name=fbank
fea_lst=quick_test/data/train/feats_fbank.scp
fea_opts=apply-cmvn --utt2spk=ark:quick_test/data/train/utt2spk ark:quick_test/fbank/cmvn_train.ark
ark:- ark:- | add-deltas --delta-order=0 ark:- ark:- |
cw_left=0 cw_right=0
fea_name=fmllr fea_lst=quick_test/data/train/feats_fmllr.scp
fea_opts=apply-cmvn --utt2spk=ark:quick_test/data/train/utt2spk
ark:quick_test/data-fmllr-tri3/train/train_cmvn.ark
ark:- ark:- | add-deltas --delta-order=0
ark:- ark:- |
cw_left=0
cw_right=0
lab = lab_name=lab_cd
lab_folder=quick_test/dnn4_pretrain-dbn_dnn_ali
lab_opts=ali-to-pdf
lab_count_file=auto
lab_data_folder=quick_test/data/train/
lab_graph=quick_test/graph
lab_name=lab_mono
lab_folder=quick_test/dnn4_pretrain-dbn_dnn_ali
lab_opts=ali-to-phones --per-frame=true
lab_count_file=none
lab_data_folder=quick_test/data/train/
lab_graph=quick_test/graph
n_chunks = 5
- [architecture] 這部分描述神經網路模型,下面是一個例子:
2.2 語音特徵
- [model]:這部分定義了神經網路的結合方式,下面是一個例子:
[model]
model_proto = proto/model.proto
model = out_dnn1=compute(liGRU_layers,fmllr)
out_dnn2=compute(MLP_layers,out_dnn1)
out_dnn3=compute(MLP_layers2,out_dnn1)
loss_mono=cost_nll(out_dnn3,lab_mono)
loss_mono_w=mult_constant(loss_mono,1.0)
loss_cd=cost_nll(out_dnn2,lab_cd)
loss_final=sum(loss_cd,loss_mono_w)
err_final=cost_err(out_dnn2,lab_cd)
[forward]
forward_out = out_dnn2
normalize_posteriors = True
normalize_with_counts_from = lab_cd
save_out_file = False
require_decoding = True
- [decoding]:這部分定義了解碼參數,下面是一個例子:
[decoding]
decoding_script_folder = kaldi_decoding_scripts/
decoding_script = decode_dnn.sh
decoding_proto = proto/decoding.proto
min_active = 200
max_active = 7000
max_mem = 5000000 0
beam = 13.0
latbeam = 8.0
acwt = 0.2
max_arcs = -1
skip_scoring = false
scoring_script = local/score.sh
scoring_opts = "--min-lmwt 1 --max-lmwt 10"
norm_vars = False
2.2 語音特徵和標籤
語音特徵是使用 Kaldi 中的原生 C++庫進行提取的。PyTorch-Kaldi 的一個特點就是可以管理多個語音特徵流,用戶在實際開發的過程中可以定義使用多個特徵參數組合的模型。
用於訓練聲學模型的主要特徵來自於語音特徵和上下文無關的音素序列,這是通過 Kaldi 的音素決策樹生成的。
2.3 chunk 和 minibatch 的組成
PyTorch-Kaldi 將數據集分成了多個塊,每個塊中的樣本都是從整個語料庫中隨機抽樣得到的。然後再訓練的過程中每次迭代只使用一個小批量的數據,這也是神經網路優化的常用方法。
不過,小批量數據的聚集方式是由神經網路的結構決定的,對於普通的前饋模型而言,隨機選擇數據就行。但是對於 RNN 這類網路而言,minibatch 則必須由完整的句子組成。
2.4 DNN 聲學模型、解碼和打分
PyTorch-Kaldi 已經定義好了一些先進的神經網路模型,目前支持標準的 MLP、CNN、RNN、LSTM、GRU、Light GRU 等。實際上這部分就是神經網路模型的訓練和優化。
在進行基於 HMM 的解碼之前,聲學模型產生的聲學後驗概率與其先驗概率進行歸一化之後便和語言模型生成的語言概率,常用的語言模型就是 n-gram 模型。然後使用波束搜索演算法得到語音信號中的單詞序列。最後使用 NIST SCTK 工具計算字錯率(WER)。
原論文的實驗部分展示了使用 PyTorch-Kaldi 進行的多組語音識別相關的實驗,在一些數據集和任務上面還達到了目前最高的水平。
3 總結
就其整體架構和 Mirco Ravanelli 等人表現出來的「野心」來看,PyTorch-Kaldi 的潛力是比較大的。項目文檔中關於下一個版本的描述是這樣寫的:「The architecture of the toolkit will be more modular and flexible. Beyond speech recognition, the new toolkit will be suitable for other applications such as speaker recognition, speech enhancement, speech separation, etc.」。當然,這只是一個工具而已,如果沒有對語音識別技術的深刻理解,肯定是做不出更好東西的。許願:有更多的人力和資源積極地投入到這個領域,幫助讓 PyTorch-Kaldi 變得更好,或者打造出全新的比 PyTorch-Kaldi 更好的工具。
參考資料
[1] M. Ravanelli, T. Parcollet and Y. Bengio, "The Pytorch-kaldi Speech Recognition Toolkit," ICASSP 2019 - 2019 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP), Brighton, United Kingdom, 2019, pp. 6465-6469.doi: 10.1109/ICASSP.2019.8683713
[2] D. Yu and L. Deng, Automatic Speech Recognition – A Deep Learning Approach, Springer, 2015.
[3] Kaldi 文檔(kaldi-asr.org/doc/)(http://kaldi-asr.org/doc/%EF%BC%89)
[4] PyTorch-Kaldi Github 倉庫(https://github.com/mravanelli/pytorch-kaldi)(https://github.com/mravanelli/pytorch-kaldi%EF%BC%89)
[5] 王贇. 語音識別技術的前世今生(https://www.zhihu.com/lives/843853238078963712%EF%BC%89)(https://www.zhihu.com/lives/843853238078963712%EF%BC%89%EF%BC%89)
※50億美元:Facebook因泄露隱私接受史上最大罰單
※MIT發明10美元AI觸覺手套:識別物體,又能稱重,論文已上Nature
TAG:機器之心 |