kaldi lesson教程示例

创建示例目录

第一步:egs目录下创建lesson文件夹,lesson文件夹创建版本标识文件夹v1

mkdir lesson
cd lesson
mkdir v1

结果展示

(notebook) root@ai-PowerEdge-R740:/opt/asr/kaldi/egs# ls -l lesson/
total 4
drwxr-xr-x 2 root root 4096 5月  19 10:32 v1

为什么lesson下还要创建v1?

  • v1表示第一个版本,方便版本管理
  • 和path.sh返回目录一致, 后面会创建path.sh脚本。KALDI_ROOT为安装目录,如果不创建v1文件夹,这个路径需要修改一下。
    在这里插入图片描述

第二步:创建软链接到steps, utils,sid(声纹任务)

进入v1文件夹,使用下面命令创建软链接, 其中不是声纹识别相关任务,不需要创建sid的软链接

cd v1
ln -s ../../wsj/s5/steps/ .
ln -s ../../wsj/s5/utils/ .
ln -s ../../sre08/v1/sid .

使用软连接是为了节约磁盘空间,linux软连接相当于windows快捷方式。steps封装了语音识别各个阶段的标准化处理脚本,utils封装语音识别阶段用到工具和方法。
kaldi lesson教程示例_第1张图片

第三步:创建cmd.sh文件,设置运行方式,单机还是集群

vim cmd.sh
添加如下内容:

export train_cmd="run.pl"

run.pl指定本机运行,如果用集群,可以按照这种配置

export train_cmd="queue.pl --mem 2G"
export decode_cmd="queue.pl --mem 4G"
export mkgraph_cmd="queue.pl --mem 8G"

train_cmd是训练运行方式,decode_cmd是解码运行方式,mkgraph_cmd是构建计算图运行方式,通常情况下,一般只用到run.pl, 单机运行方式

第四步:创建path.sh环境变量文件

可以通过下面命令复制其它egs下path.sh到该目录下,也可以vim path.sh 然后复制下面内容进行创建

  • 方式1:vim path.sh, 复制下面内容到文件里,然后wq!保存
export KALDI_ROOT=`pwd`/../../..
[ -f $KALDI_ROOT/tools/env.sh ] && . $KALDI_ROOT/tools/env.sh
export PATH=$PWD/utils/:$KALDI_ROOT/tools/openfst/bin:$PWD:$PATH
[ ! -f $KALDI_ROOT/tools/config/common_path.sh ] && echo >&2 "The standard file $KALDI_ROOT/tools/config/common_path.sh is not present -> Exit!" && exit
1
. $KALDI_ROOT/tools/config/common_path.sh
export LC_ALL=C

  • 方式2:
cp ../../aishell/s5/path.sh .

详细解读下path.sh内容:

export KALDI_ROOT=pwd/../../.. 这行代码是添加kaldi安装目录到环境变量, 相当于在环境变量里添加/opt/asr/kaldi, 但是export是临时添加,机器重启之后会清掉这个环境变量。一般都选用临时添加kaldi运行环境变量。

[ -f $KALDI_ROOT/tools/env.sh ] && . $KALDI_ROOT/tools/env.sh 这行脚本是先判断env.sh文件是否存在,如果存在执行这个文件。env.sh用来导入python执行程序路径,通常指定python版本也在这个地方指定。具体修改python运行版本要去tools/python文件夹下。kaldi采用的python版本是python2,如果要用python3,可以修改python运行软连接指向python3执行程序。

(notebook) root@ai-PowerEdge-R740:/opt/asr/kaldi/egs/lesson/v1# more ../../../tools/env.sh
export PATH=/opt/asr/kaldi/tools/python:${PATH}
export PATH=/opt/asr/kaldi/tools/python:${PATH}
(notebook) root@ai-PowerEdge-R740:/opt/asr/kaldi/egs/lesson/v1# cd  ../../../tools/python/
(notebook) root@ai-PowerEdge-R740:/opt/asr/kaldi/tools/python# ls
python  python2
(notebook) root@ai-PowerEdge-R740:/opt/asr/kaldi/tools/python# ls -l
total 0
lrwxrwxrwx 1 root root 18 3月  10 22:50 python -> /usr/bin/python2.7
lrwxrwxrwx 1 root root 18 1月  24 08:02 python2 -> /usr/bin/python2.7

export PATH=$PWD/utils/:$KALDI_ROOT/tools/openfst/bin:$PWD:$PATH 这样代码添加kaldi utils 和 openfst/bin目录下内容到环境变量

[ ! -f $KALDI_ROOT/tools/config/common_path.sh ] && echo >&2 "The standard file $KALDI_ROOT/tools/config/common_path.sh is not present -> Exit!" && exit
1

判断common_path.sh脚本是否存在,如果不存在,推出当前shell,然后输出执行错误结果1

上面四行脚本执行都没问题,执行 . $KALDI_ROOT/tools/config/common_path.sh这个脚本,这个脚本负责添加kaldi源代码编译后可执行文件的路径到环境变量中,我们在linux执行这些可执行文件,不在需要指定其所在路径,直接用文件名即可。有哪些可执行文件,参考common_path的文件内容,其按照不同的功能将可执行文件组织在不同的文件夹。

(notebook) root@ai-PowerEdge-R740:/opt/asr/kaldi/egs/lesson/v1# more ../../../tools/config/common_path.sh
# we assume KALDI_ROOT is already defined
[ -z "$KALDI_ROOT" ] && echo >&2 "The variable KALDI_ROOT must be already defined" && exit 1
# The formatting of the path export command is intentionally weird, because
# this allows for easy diff'ing
export PATH=\
${KALDI_ROOT}/src/bin:\
${KALDI_ROOT}/src/chainbin:\
${KALDI_ROOT}/src/featbin:\
${KALDI_ROOT}/src/fgmmbin:\
${KALDI_ROOT}/src/fstbin:\
${KALDI_ROOT}/src/gmmbin:\
${KALDI_ROOT}/src/ivectorbin:\
${KALDI_ROOT}/src/kwsbin:\
${KALDI_ROOT}/src/latbin:\
${KALDI_ROOT}/src/lmbin:\
${KALDI_ROOT}/src/nnet2bin:\
${KALDI_ROOT}/src/nnet3bin:\
${KALDI_ROOT}/src/nnetbin:\
${KALDI_ROOT}/src/online2bin:\
${KALDI_ROOT}/src/onlinebin:\
${KALDI_ROOT}/src/rnnlmbin:\
${KALDI_ROOT}/src/sgmm2bin:\
${KALDI_ROOT}/src/sgmmbin:\
${KALDI_ROOT}/src/tfrnnlmbin:\
${KALDI_ROOT}/src/cudadecoderbin:\
$PATH

export LC_ALL=C最后一行脚本是将linux环境设置成c语言运行环境,这样好处是我们使用kaldi编译的可执行文件时,可以当成linux命令来使用,cat, ls等。不得不说这个设计太让人叹服!!!。

执行 source path.sh 看看path.sh的威力吧,
kaldi lesson教程示例_第2张图片
如上图所示,是不是可以随意使用${KALDI_ROOT}/src/featbin:\源码下内容了,如果没有添加环境变量,得到是下面的结果
在这里插入图片描述
好了,path.sh内容介绍完,进入下一个环节,创建local, feats, data,目录

第五步:创建conf, local, feats, data, exp文件夹

创建conf和local文件夹,conf下面存放和提特征相关的配置文件,如设置采样频率,mel滤波个数等,一般有mfcc.conf和vad.conf文件。 local下面放的是这个工程相关的子脚本,前面介绍介绍utils/ steps/存放的是主脚本。

feats存放mfcc或者fbank特征数据,data存放数据list,如wav.scp, utt2spk, spk2utt等。exp存放是模型文件和训练相关中间结果。

除了conf, local外,其它三个文件夹在准备阶段可以不用创建,后续主脚本执行过程中会创建的。

(notebook) root@ai-PowerEdge-R740:/opt/asr/kaldi/egs/lesson/v1# mkdir -p local conf data exp feats

综上,创建目录示例就已经完成了,看看现在lesson工程下目录内容

(notebook) root@ai-PowerEdge-R740:/opt/asr/kaldi/egs/lesson/v1# ls
cmd.sh  conf  data  exp  feats  local  path.sh  steps  utils

编写脚本run.sh

下面内容都围绕run.sh的内容展开,run.sh的参考模板如下,下面争取把每个环节内容填满。

#!/usr/bin/env bash
set -eo pipifail
. ./path.sh
. ./cmd.sh
# Set global env info
# Data preparation
# Feature extraction
# Mono training
# Graph compilation
# Decoding

run.sh前四行基本都是固定不变,脚本中"."是执行的意思,相当于source. 首先声明set -eo pipifail,这个脚本主要用来控制后续脚本如果有运行异常或者错误的立即退出当前脚本的运行,shell脚本运行时从前往后进行,如果前面的脚本运行错误,后续的脚本也能正常运行,但是后面脚本运行往往依赖前面脚本的运行结果,所以设置set -eo pipifail,一旦遇到有运行错误的脚本或者管道符执行错误则退出当前运行。
. ./path.sh, . ./cmd.sh 分别执行环境变量脚本和设置运行方式的脚本,这个两个脚本已经重点介绍过了。

Set global env info

指定源数据目录,数据下载目录,脚本执行控制指针,训练数据,特征数据,如下面这段代码。

data=/data/cn-celeb1
data_url=https://openslr.magicdatatech.com/resources/82
stage=1
stop_stage=10
train_data=data/mfcc/train
featdir=feats/mfcc
. tools/parse_options.sh

如果在运行run时候修改这些变量的值,这需要添加. tools/parse_options.sh这行代码,他的作用是允许运行脚本中修改变量的默认值, 如 bash run.sh --stage 2 --stop_stage 20。

Data preparation

数据准备阶段主要是下载数据,如果已经手动下载数据了,可以跳过这个步骤。
这阶段要掌握的就是如何根据自己实际问题修改download_and_untar.sh脚本。


# Data preparation
if [ $stage -le 1 ] && [ $stop_stage -ge 1 ]; then
        for part in cn-celeb; do
                local/download_and_untar.sh $data $data_url $part
        done
fi

download_and_untar.sh的用法如下,这个脚本主要完成数据下载和解压,详细内容没什么好分析的,用法如下: 其中尖括号是必填参数,中括号中是可选参数。

download_and_untar.sh [--remove-archive] <data-base> <url-base> <corpus-part>

带上–remove-archive参数下载解压完成之后会删掉下载压缩包。data-base参数是下载数据存放的路径,如果不存在文件夹需要事先创建这个文件夹,url-base是数据集去除文件名的url, 如cn-celeb的数据集完整urll为https://www.openslr.org/resources/82/cn-celeb.tgz,那么url-base=https://www.openslr.org/resources/82
,corpus-part=cn-celeb, 所以如果我们要下载cn-celeb,cn-celeb2-part1,cn-celeb2-part1这三个数据集,他们url-base都一样,只需要指定为相应问文件夹名即可,具体操作就是修改这个脚本里面list为list="cn-celeb cn-celeb2-part1 cn-celeb-part2",download_and_untar.sh脚本可以参考cslt写的这个
kaldi lesson教程示例_第3张图片
注释54-67行代码, 由于重新下载时需要判断原有文件是否完整,不完整删除重新下载。
kaldi lesson教程示例_第4张图片
重点:download_and_untar.sh
- 修改list
- 注释54-67行脚本

这个阶段主要内容就是这些,基本上就是在这个模板进行修改。

你可能感兴趣的:(kaldi,语音识别)