kaildi讲解

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章。

中文入门方式可以看《语音信号处理》韩纪庆(编)的语音识别章节;或者《模式分类》这本书的部分章节。

kaldi安装

简要说明:(运行环境centos7、ubuntu16.4、macos 10.13都能安装成功)
0、安装前你需要对你的 linux 进行配置,需要安装的软件apt-get、subversion、automake、autoconf、libtool、g++、zlib、libatal、wget,如何安装见《kaldi的全部资料_v0.7(未完成版本).pdf》。

1、git clone https://github.com/kaldi-asr/kaldi.git 选择某个路径,下载kaldi。

2、在命令行cd到kaldi路径下,cd到tool目录下,在命令行分别输入:

make -j nproc

extras/install_irstlm.sh

install_irstlm.sh是安装语言模型。

        extras/install_kaldi_lm.sh

install_kaldi_lm.sh 也是安装语言模型。


3. make 完后,在src目录下:在命令行分别输入:

./configure

make depend

make

make阶段是编译阶段,将下载的包编译为可执行文件,耗时较长,耐心等待。

ubuntu安装遇到问题最少,centos和macos上安装都会出现一些问题,得手动解决。

遇到过的error和解决方法:

  1. 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(不需要手动解压)。

  2. sudo make仍出现permission denied造成error。把文件夹的用户改成使用者。比如我的用户名叫work,chown -R work kaldi

  3. 如果多次make都遇到error,建议先make clean把编译过的全删掉,再重新装。

kaldi各文件解释

  • /egs:不同语料例子的执行脚本文件
  • /tools:存放asr过程中用到的库
  • /src:存放实际执行的c++算法

以aishell为例的ASR过程

命令行到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过程了。强烈建议逐行运行,运行当前行时,把其他暂时注释调,这样清楚看见每个阶段的过程。

过程简单说来就是:

  • 语料数据准备 下载语料库到本地/服务器的文件夹
  • 数据关系,词典、语言文件(text, wav.scp, utt2pk, spk2utt)准备,训练集、测试集、验证集准备
  • 单音素(或者其他模型)训练和解码
  • 构建解码图
  • 解码查看结果

数据准备

1、首先在根目录下建立路径:/export/a05/xna/data然后下载数据集。这里下载数据集要在run.sh前面加sudo命令,这是路径的缘故。下载数据集用到的脚本是local/download_and_untar.sh 需要下载两个数据文件:data_aishell 和 resource_aishell.
2、数据准备阶段运行脚本:local/aishell_data_prep.sh 运行脚本后会产生 以下文件:

    spk2utt: 这里存放的是测试集好训练集中每个样例名称及其它下面的语音文件名称。这个文件在test下面则说明是test集的相关信息,如果在train 文件下则说明是train集的相关信息。文件内容如下所示(只展示部分样例):

    S0764 BAC009S0764W0121 BAC009S0764W0122 BAC009S0764W0123 BAC009S0764W0124 BAC009S0764W0125 BAC009S0764W0126 BAC009S0764W0127 BAC009S0764W0128 BAC009S0764W0129 BAC009S0764W0130 BAC009S0764W0131 BAC009S0764W0132 BAC009S0764W0133 BAC009S0764W0134 BAC009S0764W0135 BAC009S0764W0136 BAC009S0764W0137 BAC009S0764W0138 BAC009S0764W0139 BAC009S0764W0140 BAC009S0764W0141 BAC009S0764W0142 BAC009S0764W0143 BAC009S0764W0144 BAC009S0764W0145 BAC009S0764W0146 BAC009S0764W0147 BAC009S0764W0148 BAC009S0764W0149 BAC009S0764W0150 BAC009S0764W0151 BAC009S0764W0152 BAC009S0764W0153 BAC009S0764W0154
    S0765 BAC009S0765W0121 BAC009S0765W0122 BAC009S0765W0123 BAC009S0765W0124 BAC009S0765W0125 BAC009S0765W0126 BAC009S0765W0127 BAC009S0765W0128 BAC009S0765W0129 BAC009S0765W0130 BAC009S0765W0131 BAC009S0765W0132 BAC009S0765W0133 BAC009S0765W0134 BAC009S0765W0135 BAC009S0765W0136 BAC009S0765W0137 BAC009S0765W0138 BAC009S0765W0139 BAC009S0765W0140 BAC009S0765W0141 BAC009S0765W0142 BAC009S0765W0143 BAC009S0765W0144 BAC009S0765W0145 BAC009S0765W0146 BAC009S0765W0147 BAC009S0765W0148 BAC009S0765W0149 BAC009S0765W0150 BAC009S0765W0151 BAC009S0765W0152 BAC009S0765W0153 BAC009S0765W0154

    text :这里存放的是训练集和测试集中语音文本的信息,第一列是语音文件名,第二列是语音文件所对应的说话的内容,如下所示(只展示部分信息):

        BAC009S0764W0121 甚至 出现 交易 几乎 停滞 的 情况
        BAC009S0764W0122 一二 线 城市 虽然 也 处于 调整 中
        BAC009S0764W0123 但 因为 聚集 了 过多 公共 资源
        BAC009S0764W0124 为了 规避 三四 线 城市 明显 过剩 的 市场 风险
        BAC009S0764W0125 标杆 房企 必然 调整 市场 战略
        BAC009S0764W0126 因此 土地 储备 至关 重要
        BAC009S0764W0127 中原 地产 首席 分析 师 张大 伟 说
        BAC009S0764W0128 一 线 城市 土地 供应 量 减少

    transcripts.txt 这个文件是text文件的副本 。内容跟text文件的内容格式一样

    utt.list 这个文件是测试集和训练集中所有语音文件的名称

        BAC009S0764W0121
        BAC009S0764W0122
        BAC009S0764W0123
        BAC009S0764W0124
        BAC009S0764W0125
        BAC009S0764W0126
        BAC009S0764W0127
        BAC009S0764W0128
        BAC009S0764W0129
        BAC009S0764W0130
        BAC009S0764W0131
        BAC009S0764W0132
        BAC009S0764W0133
        BAC009S0764W0134
        BAC009S0764W0135
        BAC009S0764W0136
        BAC009S0764W0137
        BAC009S0764W0138
        BAC009S0764W0139

    utt2spk_all 这里放的是语音文件的详细信息。第一列是语音文件名称,第二列是语音文件类别,即说话人名称

    BAC009S0764W0121 S0764
    BAC009S0764W0122 S0764
    BAC009S0764W0123 S0764
    BAC009S0764W0124 S0764
    BAC009S0764W0125 S0764
    BAC009S0764W0126 S0764
    BAC009S0764W0127 S0764
    BAC009S0764W0128 S0764
    BAC009S0764W0129 S0764
    BAC009S0764W0130 S0764
    BAC009S0764W0131 S0764
    BAC009S0764W0132 S0764
    BAC009S0764W0133 S0764
    BAC009S0764W0134 S0764
    BAC009S0764W0135 S0764
    BAC009S0764W0136 S0764
    BAC009S0764W0137 S0764
    BAC009S0764W0138 S0764
    BAC009S0764W0139 S0764
    BAC009S0764W0140 S0764

    wav.flist 这个文件中放的是语音文件的详细地址和语音文件

        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0360.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0448.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0324.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0133.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0287.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0482.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0456.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0214.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0376.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0157.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0194.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0484.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0490.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0251.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0366.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0210.wav
        /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0263.wav

    wav.scp

    BAC009S0764W0121 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0360.wav
    BAC009S0764W0122 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0448.wav
    BAC009S0764W0123 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0324.wav
    BAC009S0764W0124 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0133.wav
    BAC009S0764W0125 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0287.wav
    BAC009S0764W0126 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0482.wav
    BAC009S0764W0127 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0456.wav
    BAC009S0764W0128 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0214.wav
    BAC009S0764W0129 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0376.wav
    BAC009S0764W0130 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0157.wav
    BAC009S0764W0131 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0194.wav
    BAC009S0764W0132 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0484.wav
    BAC009S0764W0133 /export/a05/xna/data/data_aishell/wav/test/S0766/BAC009S0766W0490.wav
 

二、特征提取

1、特征提取用到的脚本是:step/make_mfcc.sh 在文件夹exp中会产生make_mfcc文件夹。在make_mfcc文件夹下会有test 和 train 文件夹,里面放的是特征提取的日志。正真对的提取的特征在kaldi-master/egs/aishell/v1/mfcc 中。下面将提取到的特征可视化:

~/kaldi-master/src/featbin/copy-feats ark:/home/gwp/kaldi-master/egs/aishell/v1/mfcc/raw_mfcc_train.2.ark ark,t:- |head

    1

运行结果:

    BAC009S0036W0279 [
    12.55563 -21.31167 11.26867 6.343046 15.55155 4.494844 20.27812 17.99247 18.88603 11.74063 1.810493 -4.666584 -0.2448959 -1.099169 1.787078 8.768214 -0.5345917 0.7129593 -1.881903 -0.184864
    11.32757 -20.03719 16.31762 6.122036 2.568633 0.9016883 4.645835 9.24137 4.62358 7.516443 11.05698 7.462651 1.606389 2.067619 7.471634 4.220415 -7.865553 -4.594973 -2.89533 2.004371
    11.91236 -24.09615 11.07287 10.10023 11.98197 8.601308 12.80181 20.9095 9.971997 -3.990842 -9.981028 -4.873005 12.09514 -0.05607986 -13.64925 2.12143 9.522418 10.41734 1.833998 2.004371
    13.08194 -23.40003 8.919159 8.774164 14.95662 18.35416 18.23913 16.04778 5.812117 -8.620422 -6.109185 -6.524362 4.739332 7.88231 4.0609 10.8672 7.427207 4.352102 0.8205705 0.7026639
    12.14628 -22.70391 9.506536 7.448099 19.12113 25.02716 16.8798 -1.454416 -6.327747 1.68997 9.730171 3.383781 3.17286 5.459522 3.68193 5.619738 -4.90952 1.926007 5.549899 6.6653
    11.91236 -19.61236 13.08912 7.890121 11.98197 16.81424 3.966171 13.13075 9.377729 3.729235 7.266272 22.1378 17.13299 0.987011 -1.784221 -2.556049 0.3034925 -2.488651 0.4827612 0.9393382
    12.84803 -17.27582 15.67192 10.76326 8.27466 12.19446 -10.80211 11.18606 13.53761 4.166221 9.202192 15.51031 1.463983 4.974965 8.608545 2.471261 4.074871 -1.730374 -1.206284 4.040326
    12.20475 -22.00779 10.87708 8.332142 17.93127 11.16785 8.044158 17.99247 18.29176 18.80422 15.70079 9.829611 -8.219662 -8.25178 4.43987 8.768214 -0.1155496 -3.246927 -2.89533 -1.427403
    11.7954 -22.00779 8.13599 7.448099 16.14648 11.68116 6.005165 17.02012 22.45164 9.555708 8.49822 6.042475 1.606389 -2.589295 -4.964538 1.071938 1.141577 2.896445 -8.269815 -1.604908

2、特征提取结束后还要运行脚本sid/compute_vad_decision.sh 进行数据预处理,进行VAD检测。VAD是语音激活检测算法,用于判断什么时候有语音输出,什么时候是静音状态。
3、如果在此数据出现异常重复等都可以运行脚本utils/fix_data_dir.sh 进行处理。

utils/fix_data_dir.sh data/所有data下的文件都可以进行处理。

之后会在 exp 文件夹下产生一个 mono 的目录,里面以 .mdl 结尾的就保存了模型的参数。使用下面的命令可以查看模型的内容。

$ gmm-copy --binary=false exp/mono/0.mdl - | less

构建单音素解码图:

  1. # Monophone decoding

  2. utils/mkgraph.sh data/lang_test exp/mono exp/mono/graph || exit 1;

mkgraph.sh主要生成了HCLG.fstwords.txt这两个重要的文件,后续识别主要利用了三个文件,分别是final.mdlHCLG.fstwords.txt

解码:分别针对开发集和测试集解码

  1. steps/decode.sh --cmd "$decode_cmd" --config conf/decode.config --nj 10 \

  2. exp/mono/graph data/dev exp/mono/decode_dev

  3. steps/decode.sh --cmd "$decode_cmd" --config conf/decode.config --nj 10 \

  4. exp/mono/graph data/test exp/mono/decode_test

解码的日志会保存在 exp/mono/decode_dev/log 和 exp/mono/decode_test/log 里。

Veterbi 对齐

  1. # Get alignments from monophone system.

  2. steps/align_si.sh --cmd "$train_cmd" --nj 10 \

  3. data/train data/lang exp/mono exp/mono_ali || exit 1;

之后就是和训练单音素一样,进行其他模型的训练解码,生成声学模型和语言模型,保存在/exp中。

查看结果:

输入下面的命令来查看结果

  1. # getting results (see RESULTS file)

  2. 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模型。

  • 首先用标准的13维MFCC加上一阶和二阶导数训练单音素GMM系统,采用倒谱均值归一化(CMN)来降低通道效应。然后基于具有由LDA和MLLT变换的特征的单音系统构造三音GMM系统,最后的GMM系统用于为随后的DNN训练生成状态对齐。
  • 基于GMM系统提供的对齐来训练DNN系统,特征是40维FBank,并且相邻的帧由11帧窗口(每侧5个窗口)连接。连接的特征被LDA转换,其中维度降低到200。然后应用全局均值和方差归一化以获得DNN输入。DNN架构由4个隐藏层组成,每个层由1200个单元组成,输出层由3386个单元组成。 基线DNN模型用交叉熵的标准训练。 使用随机梯度下降(SGD)算法来执行优化。 将迷你批量大小设定为256,初始学习率设定为0.008。
  • 被噪声干扰的语音可以使用基于深度自动编码器(DAE)的噪声消除方法。DAE是自动编码器(AE)的一种特殊实现,通过在模型训练中对输入特征引入随机破坏。已经表明,该模型学习低维度特征的能力非常强大,并且可以用于恢复被噪声破坏的信号。在实践中,DAE被用作前端管道的特定组件。输入是11维Fbank特征(在均值归一化之后),输出是对应于中心帧的噪声消除特征。然后对输出进行LDA变换,提取全局标准化的常规Fbank特征,然后送到DNN声学模型(用纯净语音进行训练)。
  1. train_mono.sh 用来训练单音子隐马尔科夫模型,一共进行40次迭代,每两次迭代进行一次对齐操作
  2. train_deltas.sh 用来训练与上下文相关的三音子模型
  3. train_lda_mllt.sh 用来进行线性判别分析和最大似然线性转换
  4. train_sat.sh 用来训练发音人自适应,基于特征空间最大似然线性回归
  5. nnet3/run_dnn.sh 用nnet3来训练DNN,包括xent和MPE
  6. 用chain训练DNN

aishell训练模型的词错误率wer和字错误率cer如下:

  1. %WER 44.23 [ 28499 / 64428, 1821 ins, 4610 del, 22068 sub ] exp/mono/decode_test/wer_13_0.0

  2. %WER 29.67 [ 19113 / 64428, 1567 ins, 2934 del, 14612 sub ] exp/tri1/decode_test/wer_14_0.5

  3. %WER 29.24 [ 18841 / 64428, 1557 ins, 2813 del, 14471 sub ] exp/tri2/decode_test/wer_15_0.5

  4. %WER 27.38 [ 17640 / 64428, 1764 ins, 2267 del, 13609 sub ] exp/tri3a/decode_test/wer_16_0.0

  5. %WER 23.44 [ 15102 / 64428, 1468 ins, 2110 del, 11524 sub ] exp/tri4a/decode_test/wer_15_0.5

  6. %WER 21.76 [ 14017 / 64428, 1383 ins, 1954 del, 10680 sub ] exp/tri5a/decode_test/wer_16_0.5

  7. %WER 17.43 [ 11233 / 64428, 1077 ins, 1675 del, 8481 sub ] exp/nnet3/tdnn_sp/decode_test/wer_16_0.5

  8. %WER 15.96 [ 10281 / 64428, 919 ins, 1672 del, 7690 sub ] exp/chain/tdnn_1a_sp/decode_test/wer_12_0.5

  9. %CER 34.13 [ 35757 / 104765, 783 ins, 3765 del, 31209 sub ] exp/mono/decode_test/cer_11_0.0

  10. %CER 19.56 [ 20496 / 104765, 910 ins, 1436 del, 18150 sub ] exp/tri1/decode_test/cer_13_0.5

  11. %CER 19.16 [ 20073 / 104765, 989 ins, 1211 del, 17873 sub ] exp/tri2/decode_test/cer_13_0.5

  12. %CER 17.24 [ 18060 / 104765, 780 ins, 1024 del, 16256 sub ] exp/tri3a/decode_test/cer_13_0.5

  13. %CER 13.58 [ 14227 / 104765, 640 ins, 716 del, 12871 sub ] exp/tri4a/decode_test/cer_14_0.5

  14. %CER 12.22 [ 12803 / 104765, 668 ins, 565 del, 11570 sub ] exp/tri5a/decode_test/cer_14_0.5

  15. %CER 8.44 [ 8838 / 104765, 331 ins, 510 del, 7997 sub ] exp/nnet3/tdnn_sp/decode_test/cer_14_0.5

  16. %CER 7.37 [ 7722 / 104765, 303 ins, 581 del, 6838 sub ] exp/chain/tdnn_1a_sp/decode_test/cer_11_1.0

在线识别

在kaldi 的工具集里有好几个程序可以用于在线识别。这些程序都位在src/onlinebin文件夹里,他们是由src/online文件夹里的文件编译而成(你现在可以用make ext 命令进行编译)。这些程序大多还需要tools文件夹中的portaudio 库文件支持,portaudio 库文件可以使用tools文件夹中的相应脚本文件下载安装。

  1. # 安装portaudio

  2. yum -y install *alsa*

  3. cd kaldi/tools/

  4. ./install_portaudio.sh

  5. # 编译在线识别工具

  6. cd src/

  7. make ext

  8. 或者进入kaldi/src/online和kaldi/src/onlinebin,分别make clean ,make就完美解决

服务器linux系统查看显卡信息:

root@poweredge:/joanna/kaldi/egs/aishell/online_demo# lspci -vnn | grep VGA -A 12
03:00.0 VGA compatible controller [0300]: Matrox Electronics Systems Ltd. Integrated Matrox G200eW3 Graphics Controller [102b:0536] (rev 04) (prog-if 00 [VGA controller])
    DeviceName: Embedded Video
    Subsystem: Dell Integrated Matrox G200eW3 Graphics Controller [1028:07e5]
    Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 16, NUMA node 0
    Memory at 91000000 (32-bit, prefetchable) [size=16M]
    Memory at 92808000 (32-bit, non-prefetchable) [size=16K]
    Memory at 92000000 (32-bit, non-prefetchable) [size=8M]
    Expansion ROM at 000c0000 [virtual] [disabled] [size=128K]
    Capabilities: [dc] Power Management version 3
    Kernel driver in use: mgag200
    Kernel modules: mgag200

17:00.0 PCI bridge [0604]: Intel Corporation Sky Lake-E PCI Express Root Port A [8086:2030] (rev 07) (prog-if 00 [Normal decode])

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐