kaldi是一个开源的语音识别工具箱,是基于c++、perl、shell编写的,可以在windows和unix 平台上编译。
教程网页:http://www.kaldi-asr.org/doc/ 里面可以查阅语音/说话人识别实现过程、kaldi的数据结构、命令的使用说明等。还有网上的dan的ppt。
kaldi下载:https://github.com/kaldi-asr/kaldi。
英文:《Speech and Language Processing》第9、10章。
中文入门方式可以看《语音信号处理》韩纪庆(编)的语音识别章节;或者《模式分类》这本书的部分章节。
简要说明:(运行环境centos7、ubuntu16.4、macos 10.13都能安装成功)
0. 安装前你需要对你的 linux 进行配置,需要安装的软件apt-get、subversion、automake、autoconf、libtool、g++、zlib、libatal、wget,如何安装见《kaldi的全部资料_v0.7(未完成版本).pdf》。
git clone https://github.com/kaldi-asr/kaldi.git 选择某个路径,下载kaldi。
在命令行cd到kaldi路径下,cd到tool目录下,在命令行分别输入:
make -j nproc
extras/install_irstlm.sh
install_irstlm.sh是安装语言模型。
3. make 完后,在src目录下:在命令行分别输入:
./configure
make depend
make
make阶段是编译阶段,将下载的包编译为可执行文件,耗时较长,耐心等待。
ubuntu安装遇到问题最少,centos和macos上安装都会出现一些问题,得手动解决。
遇到过的error和解决方法:
make过程中,openfst-1.6.7.tar.gz没有解压完全,因此自动又解压一遍,生成openfst-1.6.7.tar.gz.1,因此要把原openfst-1.6.7.tar.gz删掉(rm openfst-1.6.7.tar.gz
),openfst-1.6.7.tar.gz.1重命名为openfst-1.6.7.tar.gz(mv openfst-1.6.7.tar.gz.1 openfst-1.6.7.tar.gz
)。再次make(不需要手动解压)。
sudo make仍出现permission denied造成error。把文件夹的用户改成使用者。比如我的用户名叫work,chown -R work kaldi
。
如果多次make都遇到error,建议先make clean把编译过的全删掉,再重新装。
命令行到kaldi路径下,输入
cd egs/aishell/s5
首先改cmd的配置:
vim cmd.sh
改为:
export train_cmd=run.pl #"queue.pl --mem 2G"
export decode_cmd="run.pl --mem 4G" #"queue.pl --mem 4G"
export mkgraph_cmd="run.pl --mem 8G" #"queue.pl --mem 8G"
export cuda_cmd="run.pl --gpu 1"
原文件的queue是基于集群的,这里我们用本机/服务器跑,因此改为run.sh。
:wq保存后,输入:
vim run.sh
看见data=/export/a05/xna/data
改成想存放语料的路径,返回后,新建对应的文件夹。之后输入
./run.sh
就开始进行asr过程了。强烈建议逐行运行,运行当前行时,把其他暂时注释调,这样清楚看见每个阶段的过程。
过程简单说来就是:
这里是简单的介绍,具体细节可以参考kaldi入门详解 aishell2步骤解释(二)
vim run.sh
查看run.sh脚本,这里逐行解释:
local/download_and_untar.sh $data $data_url data_aishell || exit 1;
local/download_and_untar.sh $data $data_url resource_aishell || exit 1;
local/aishell_prepare_dict.sh $data/resource_aishell || exit 1;
local/aishell_data_prep.sh $data/data_aishell/wav $data/data_aishell/transcript || exit 1;
Phone Sets, questions, L compilation
utils/prepare_lang.sh --position-dependent-phones false data/local/dict \
"" data/local/lang data/lang || exit 1;
其中,数据关系保存在/data里,文件解释如下:
# Now make MFCC plus pitch features.
# mfccdir should be some place with a largish disk where you
# want to store MFCC features.
mfccdir=mfcc
for x in train dev test; do
steps/make_mfcc_pitch.sh --cmd "$train_cmd" --nj 10 data/$x exp/make_mfcc/$x $mfccdir || exit 1;
steps/compute_cmvn_stats.sh data/$x exp/make_mfcc/$x $mfccdir || exit 1;
utils/fix_data_dir.sh data/$x || exit 1;
done
分为两步,先通过steps/make_mfcc.sh提取MFCC特征,再通过steps/compute_cmvn_stats.sh计算倒谱均值和方差归一化。
生成了两个文件夹:mfcc 和 exp/make_mfcc,其中 mfcc 里主要保存了提取的特征,而 exp/make_mfcc 里保存了日志,即 .log 文件。
在 steps/make_mfcc.sh 里用到的最主要的命令就是 compute-mfcc-feats 和 copy-feats,其在 src 里编译好的。
mfcc 目录里主要是 .ark 和 .scp 文件,其中 .scp 文件里的内容是语音段和特征对应,而真正的特征保存在 .ark 文件里。用下面的命令可以看清楚
copy-feats ark:mfcc/raw_mfcc_train.1.ark ark,t:-
steps/train_mono.sh --cmd "$train_cmd" --nj 10 \
data/train data/lang exp/mono || exit 1;
之后会在 exp 文件夹下产生一个 mono 的目录,里面以 .mdl 结尾的就保存了模型的参数。使用下面的命令可以查看模型的内容。
$ gmm-copy --binary=false exp/mono/0.mdl - | less
# Monophone decoding
utils/mkgraph.sh data/lang_test exp/mono exp/mono/graph || exit 1;
mkgraph.sh
主要生成了HCLG.fst
和words.txt
这两个重要的文件,后续识别主要利用了三个文件,分别是final.mdl
、HCLG.fst
、words.txt
。
steps/decode.sh --cmd "$decode_cmd" --config conf/decode.config --nj 10 \
exp/mono/graph data/dev exp/mono/decode_dev
steps/decode.sh --cmd "$decode_cmd" --config conf/decode.config --nj 10 \
exp/mono/graph data/test exp/mono/decode_test
解码的日志会保存在 exp/mono/decode_dev/log 和 exp/mono/decode_test/log 里。
# Get alignments from monophone system.
steps/align_si.sh --cmd "$train_cmd" --nj 10 \
data/train data/lang exp/mono exp/mono_ali || exit 1;
之后就是和训练单音素一样,进行其他模型的训练解码,生成声学模型和语言模型,保存在/exp中。
输入下面的命令来查看结果
# getting results (see RESULTS file)
for x in exp/*/decode_test; do [ -d $x ] && grep WER $x/cer_* | utils/best_wer.sh; done 2>/dev/null
总结:aishell的/s5/run.sh文件运行了gmm+hmm hybrid模型以及dnn+hmm hybrid模型。
aishell训练模型的词错误率wer和字错误率cer如下:
%WER 44.23 [ 28499 / 64428, 1821 ins, 4610 del, 22068 sub ] exp/mono/decode_test/wer_13_0.0
%WER 29.67 [ 19113 / 64428, 1567 ins, 2934 del, 14612 sub ] exp/tri1/decode_test/wer_14_0.5
%WER 29.24 [ 18841 / 64428, 1557 ins, 2813 del, 14471 sub ] exp/tri2/decode_test/wer_15_0.5
%WER 27.38 [ 17640 / 64428, 1764 ins, 2267 del, 13609 sub ] exp/tri3a/decode_test/wer_16_0.0
%WER 23.44 [ 15102 / 64428, 1468 ins, 2110 del, 11524 sub ] exp/tri4a/decode_test/wer_15_0.5
%WER 21.76 [ 14017 / 64428, 1383 ins, 1954 del, 10680 sub ] exp/tri5a/decode_test/wer_16_0.5
%WER 17.43 [ 11233 / 64428, 1077 ins, 1675 del, 8481 sub ] exp/nnet3/tdnn_sp/decode_test/wer_16_0.5
%WER 15.96 [ 10281 / 64428, 919 ins, 1672 del, 7690 sub ] exp/chain/tdnn_1a_sp/decode_test/wer_12_0.5
%CER 34.13 [ 35757 / 104765, 783 ins, 3765 del, 31209 sub ] exp/mono/decode_test/cer_11_0.0
%CER 19.56 [ 20496 / 104765, 910 ins, 1436 del, 18150 sub ] exp/tri1/decode_test/cer_13_0.5
%CER 19.16 [ 20073 / 104765, 989 ins, 1211 del, 17873 sub ] exp/tri2/decode_test/cer_13_0.5
%CER 17.24 [ 18060 / 104765, 780 ins, 1024 del, 16256 sub ] exp/tri3a/decode_test/cer_13_0.5
%CER 13.58 [ 14227 / 104765, 640 ins, 716 del, 12871 sub ] exp/tri4a/decode_test/cer_14_0.5
%CER 12.22 [ 12803 / 104765, 668 ins, 565 del, 11570 sub ] exp/tri5a/decode_test/cer_14_0.5
%CER 8.44 [ 8838 / 104765, 331 ins, 510 del, 7997 sub ] exp/nnet3/tdnn_sp/decode_test/cer_14_0.5
%CER 7.37 [ 7722 / 104765, 303 ins, 581 del, 6838 sub ] exp/chain/tdnn_1a_sp/decode_test/cer_11_1.0
参考资料:
1.解读thchs30/s5/run.sh的主要步骤:https://blog.csdn.net/BBZZ2/article/details/72884979
2.kaldi的语音识别数据timit例子详解:https://blog.csdn.net/DanyHgc/article/details/75222517