你可以使用 egs/thchs30/s5/run.sh
脚本下载数据(后面将会讲到),也可以在这里下载数据包:
http://www.openslr.org/18/
这个数据集包含以下内容:
数据集 | 音频时长(h) | 句子数 | 词数 |
---|---|---|---|
train(训练) | 25 | 10000 | 198252 |
dev(开发) | 2:14 | 893 | 17743 |
test(测试) | 6:15 | 2495 | 49085 |
还有训练好的语言模型 word.3gram.lm 和 phone.3gram.lm 以及相应的词典 lexicon.txt,位于 data_thchs30/lm_word/word.3gram.lm
, data_thchs30/lm_phone/phone.3gram.lm
。
其中dev的作用是在某些步骤与train进行交叉验证的,如 local/nnet/run_dnn.sh
同时用到exp/tri4b_ali
和 exp/tri4b_ali_cv
。
训练和测试的目标数据也分为两类:word(词)和phone(音素)。
1、修改 cmd.sh:
把原脚本注释掉,修改为本地运行
export train_cmd=run.pl
export decode_cmd="run.pl --mem 4G"
export mkgraph_cmd="run.pl --mem 8G"
export cuda_cmd=run.pl
# export cuda_cmd="run.pl --gpu 1"
2、修改 run.sh
路径为 data_thchs30 所在文件夹;建议填写绝对路径;
#corpus and trans directory
thchs=/Users/xx/xx/kaldi-trunk/egs/thchs30/s5/data1
3、执行训练
sh run.sh
大概有几个过程:
thchs
字段用来设置数据地址;local/download_and_untar.sh $th
这个命令对应的三行 取消注释就好。#!/usr/bin/env bash
. ./cmd.sh ## You'll want to change cmd.sh to something that will work on your system.
## This relates to the queue.
. ./path.sh
H=`pwd` #exp home
n=8 #parallel jobs
#corpus and trans directory
thchs=/Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1
#you can obtain the database by uncommting the following lines
#[ -d $thchs ] || mkdir -p $thchs || exit 1
#echo "downloading THCHS30 at $thchs ..."
#local/download_and_untar.sh $thchs http://www.openslr.org/resources/18 data_thchs30 || exit 1
#local/download_and_untar.sh $thchs http://www.openslr.org/resources/18 resource || exit 1
#local/download_and_untar.sh $thchs http://www.openslr.org/resources/18 test-noise || exit 1
local/thchs-30_data_prep.sh
主要工作是从 $thchs/data_thchs30
(下载的数据)三部分分别生成
#data preparation
#generate text, wav.scp, utt2pk, spk2utt
local/thchs-30_data_prep.sh $H $thchs/data_thchs30 || exit 1;
/egs/thchs30/s5/data/dev $ head *
==> word.txt <==
A11_101 七十 年代 末 我 外出 求学 母亲 叮咛 我 吃饭 要 细嚼慢咽 学习 要 深 钻 细 研
A11_119 陈云 同志 同时 要求 干部 认真学习 业务 精通 业务 向 一切 业务 内 行人 学习
A11_124 另外 女单 中国队 还有 韩晶 娜 和 尧 燕 奥运 排名 第六 七位 也 可 与 高手 一 搏
A11_132 得到 李公朴 噩耗 闻一多 怒 愤 填 膺 拍案而起 怒斥 反动派 卑鄙无耻
A11_170 据 印度 官员 透露 双方 讨论 了 印度 控制 的 克什米尔 地区 目前 的 紧张 局势 问题
...
A11_203 开滦 矿务局 后 吕 家 坨 矿 张 文友 张 文富 两兄弟 同 超产 同 立功 同 当 劳动模范
与word.txt相同
==> text <==
A02_033 与 王伟 四平市 货车 司机 杜 大平 岳 玉杰 装卸工 刘 春山 一同 追赶 逃跑 的 案犯
A02_058 特 别是 跨 省区 电网 超 计划 用电 不仅 损害 自己 也 损害 别人 损害 电网 损害 国家
A02_085 胡耀邦 与 杨勇 确 系 嫡亲 姨 表兄弟 耀邦 的 母亲 刘 明伦 与 杨勇 的 母亲 刘 世珍 是 同胞 姐妹
A02_092 揭阳 成为 外商 投资 新 热点 建 市 一年 引进 外资 十 五亿 美元
...
A02_206 上等 糖果 香烟 药品 等 用 玻璃纸 包装 除了 美观 外 还有 保护 物品 的 绝妙 作用
==> phone.txt <==
A02_033 vv v3 uu uang2 uu ui3 s iy4 p ing2 sh ix4 h uo4 ch e1 s iy1 j i1 d u4 d a4 p ing2 vv ve4 vv v4 j ie2 zh uang1 x ie4 g ong1 l iu2 ch un1 sh an1 ii i4 t ong2 zh ui1 g an3 t ao2 p ao3 d e5 aa an4 f an4
A02_058 t e4 b ie2 sh ix4 k ua4 sh eng3 q v1 d ian4 uu uang3 ch ao1 j i4 h ua4 ii iong4 d ian4 b u4 j in3 s un3 h ai4 z iy4 j i3 ii ie3 s un3 h ai4 b ie2 r en2 s un3 h ai4 d ian4 uu uang3 s un3 h ai4 g uo2 j ia1
A02_085 h u2 ii iao4 b ang1 vv v3 ii iang2 ii iong3 q ve4 x i4 d i2 q in1 ii i2 b iao3 x iong1 d e5 ii iao4 b ang1 d e5 m u3 q in1 l iu2 m ing2 l un2 vv v3 ii iang2 ii iong3 d e5 m u3 q in1 l iu2 sh ix4 zh en1 sh ix4 t ong2 b ao1 j ie3 m ei4
...
A02_206 sh ang4 d eng3 t ang2 g uo3 x iang1 ii ian1 ii iao4 p in3 d eng3 ii iong4 b o1 l i5 zh ix3 b ao1 zh uang1 ch u2 l e5 m ei3 g uan1 uu uai4 h ai2 ii iu3 b ao3 h u4 uu u4 p in3 d e5 j ve2 m iao4 z uo4 ii iong4
==> wav.scp <==
A02_033 /Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1/data_thchs30/dev/A2_33.wav
A02_058 /Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1/data_thchs30/dev/A2_58.wav
A02_085 /Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1/data_thchs30/dev/A2_85.wav
...
A02_206 /Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1/data_thchs30/dev/A2_206.wav
如 句子ID 为 A02_033,说话人为 A02
==> utt2spk <==
A02_033 A02
A02_058 A02
A02_085 A02
A02_092 A02
...
A02_206 A02
==> spk2utt <==
A02 A02_033 A02_058 A02_085 A02_092 A02_103 A02_108 A02_116 A02_119 A02_167 A02_206
A04 A04_004 A04_010 A04_026 A04_048 A04_052 A04_074 A04_125 A04_140 A04_157 A04_182 A04_197 A04_204 A04_209 A04_210 A04_235 A04_240 A04_243
A06 A06_000 A06_003 A06_011 A06_016 A06_020 A06_041 A06_077 A06_078 A06_089 A06_108 A06_109 A06_128 A06_138 A06_141 A06_145 A06_171 A06_205 A06_212 A06_231 A06_247
...
A14 A14_010 A14_037 A14_063 A14_068 A14_076 A14_082 A14_112 A14_139 A14_148 A14_150 A14_159 A14_181 A14_191 A14_202 A14_203 A14_225 A14_241 A14_249
#produce MFCC features
rm -rf data/mfcc && mkdir -p data/mfcc && cp -R data/{train,dev,test,test_phone} data/mfcc || exit 1;
for x in train dev test; do
#make mfcc
steps/make_mfcc.sh --nj $n --cmd "$train_cmd" data/mfcc/$x exp/make_mfcc/$x mfcc/$x || exit 1;
#compute cmvn
steps/compute_cmvn_stats.sh data/mfcc/$x exp/mfcc_cmvn/$x mfcc/$x || exit 1;
done
#copy feats and cmvn to test.ph, avoid duplicated mfcc & cmvn
cp data/mfcc/test/feats.scp data/mfcc/test_phone && cp data/mfcc/test/cmvn.scp data/mfcc/test_phone || exit 1;
prepare_lang.sh
: 构建字典 L.fst文件,来准备语言模型。data/lang
目录,是 Kaldi 的标准语言文件夹。format_lm.sh
: 格式化语言模型(把 arpa 的 language model 转换成 FST格式)$thchs/data_thchs30/lm_word/lexicon.txt
,词典;data/graph/lang
:输出,G.fst语言模型# 数据准备:准备发音词典L.fst和训练3-gram语言模型G.fst。
#prepare language stuff
# 建立一个庞大的词汇库,包括单词的训练和解码
#build a large lexicon that invovles words in both the training and decoding.
(
# 制作词图
echo "make word graph ..."
# 在pwd下创建文件夹
cd $H; mkdir -p data/{dict,lang,graph} && \
# 将语音数据库目录的相应文件拷贝到dict目录
cp $thchs/resource/dict/{extra_questions.txt,nonsilence_phones.txt,optional_silence.txt,silence_phones.txt} data/dict && \
# 将两个目录的lexicon.txt文件输出到 data_thchs30/lm_word/lexicon.txt,同时过滤掉带或的行,并且删除相同的重复信息
cat $thchs/resource/dict/lexicon.txt $thchs/data_thchs30/lm_word/lexicon.txt | \
grep -v '' | grep -v '' | sort -u > data/dict/lexicon.txt || exit 1;
# 调用 utils 下的 prepare_lang.sh 构建字典 L.fst文件,来准备语言模型。
utils/prepare_lang.sh --position_dependent_phones false data/dict "" data/local/lang data/lang || exit 1;
# 将 word.3gram.lm 压缩为 word.3gram.lm.gz 并保留文件
gzip -c $thchs/data_thchs30/lm_word/word.3gram.lm > data/graph/word.3gram.lm.gz || exit 1;
# 格式化语言模型
utils/format_lm.sh data/lang data/graph/word.3gram.lm.gz $thchs/data_thchs30/lm_word/lexicon.txt data/graph/lang || exit 1;
)
这里使用的 prepare_lang.sh | format_lm.sh 和上面相似,输入输出略微不同。
# make_phone_graph
(
echo "make phone graph ..."
# 创建文件夹
cd $H; mkdir -p data/{dict_phone,graph_phone,lang_phone} && \
# 将语音数据库的目录的相应文件拷贝到dict目录
cp $thchs/resource/dict/{extra_questions.txt,nonsilence_phones.txt,optional_silence.txt,silence_phones.txt} data/dict_phone && \
# 将 lexicon.txt 文件输出到 data/dict_phone/lexicon.txt,同时过滤掉带的行,并且删除相同的重复信息
cat $thchs/data_thchs30/lm_phone/lexicon.txt | grep -v '' | sort -u > data/dict_phone/lexicon.txt && \
echo " sil " >> data/dict_phone/lexicon.txt || exit 1;
# 构建字典 L.fst文件,来准备语言模型。
utils/prepare_lang.sh --position_dependent_phones false data/dict_phone "" data/local/lang_phone data/lang_phone || exit 1;
# 将 phone.3gram.lm 压缩为 phone.3gram.lm.gz 并保留文件
gzip -c $thchs/data_thchs30/lm_phone/phone.3gram.lm > data/graph_phone/phone.3gram.lm.gz || exit 1;
# 调用utils下的format_lm.sh来格式化语言模型,就是把arpa的language model 转换成 FST格式。
# 输入1: data/lang_phone,语言文件夹;
# 输入2:data/graph_phone/word.3gram.lm.gz,ARPA格式的语言模型;
# 输入3:$thchs/data_thchs30/lm_phone/lexicon.txt,词典;
# 输出:data/graph_phone/lang,G.fst语言模型
utils/format_lm.sh data/lang_phone data/graph_phone/phone.3gram.lm.gz $thchs/data_thchs30/lm_phone/lexicon.txt \
data/graph_phone/lang || exit 1;
)
# monophone
steps/train_mono.sh --boost-silence 1.25 --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/mono || exit 1;
# test monophone model
local/thchs-30_decode.sh --mono true --nj $n "steps/decode.sh" exp/mono data/mfcc &
# monophone_ali
steps/align_si.sh --boost-silence 1.25 --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/mono exp/mono_ali || exit 1;
。
--boost-silence 1.25
:在对齐过程中提高静音的比例;data/mfcc/train
:输入,标注文本text;data/lang
:输入,词典 L.fst;exp/mono
:输入,模型,tree文件;#triphone
steps/train_deltas.sh --boost-silence 1.25 --cmd "$train_cmd" 2000 10000 data/mfcc/train data/lang exp/mono_ali exp/tri1 || exit 1;
# 解码测试部分,可以看到该代码和单音素的解码测试是一样的,只是少了–mono选项
#test tri1 model
local/thchs-30_decode.sh --nj $n "steps/decode.sh" exp/tri1 data/mfcc &
# 利用第一行训练得到的三音素模型来做强制对齐。代码也是和单音素时是一样的,只是输出模型的变化
#triphone_ali
steps/align_si.sh --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/tri1 exp/tri1_ali || exit 1;
train_deltas.sh
, 训练与上下文相关的三音子模型Usage: steps/train_deltas.sh
#num-leaves
:叶子节点数目;train_lda_mllt.sh
, 用来进行线性判别分析 和 最大似然线性转换# 最大似然线性变换
# 用来做特征调整并训练新模型
#lda_mllt
steps/train_lda_mllt.sh --cmd "$train_cmd" --splice-opts "--left-context=3 --right-context=3" 2500 15000 data/mfcc/train data/lang exp/tri1_ali exp/tri2b || exit 1;
# 解码测试
#test tri2b model
local/thchs-30_decode.sh --nj $n "steps/decode.sh" exp/tri2b data/mfcc &
# 根据模型对数据进行对齐
#lda_mllt_ali
steps/align_si.sh --nj $n --cmd "$train_cmd" --use-graphs true data/mfcc/train data/lang exp/tri2b exp/tri2b_ali || exit 1;
# 说话人自适应训练
# 对特征进行FMLLR,而后训练GMM模型
#sat
steps/train_sat.sh --cmd "$train_cmd" 2500 15000 data/mfcc/train data/lang exp/tri2b_ali exp/tri3b || exit 1;
# 对自适应模型的解码及测试
#test tri3b model
local/thchs-30_decode.sh --nj $n "steps/decode_fmllr.sh" exp/tri3b data/mfcc &
# 根据FMLLR模型对数据进行对齐,可以看出核心任务是 对特征码本做FMLLR,以达到说话人自适应的目的
#sat_ali
steps/align_fmllr.sh --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/tri3b exp/tri3b_ali || exit 1;
# quick 模型训练
#quick
steps/train_quick.sh --cmd "$train_cmd" 4200 40000 data/mfcc/train data/lang exp/tri3b_ali exp/tri4b || exit 1;
# 对quick训练得到的模型进行解码测试
#test tri4b model
local/thchs-30_decode.sh --nj $n "steps/decode_fmllr.sh" exp/tri4b data/mfcc &
# 采用quick训练得到的模型对数据进行对齐
#quick_ali
steps/align_fmllr.sh --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/tri4b exp/tri4b_ali || exit 1;
# 对开发数据集进行对齐
#quick_ali_cv
steps/align_fmllr.sh --nj $n --cmd "$train_cmd" data/mfcc/dev data/lang exp/tri4b exp/tri4b_ali_cv || exit 1;
# dnn模型训练,采用DNN来训练一个声学模型
#train dnn model
local/nnet/run_dnn.sh --stage 0 --nj $n exp/tri4b exp/tri4b_ali exp/tri4b_ali_cv || exit 1;
# dae模型训练,通过对语音数据添加噪声来得到有噪音的数据,而后调用 nnet1/train_dnn.sh来对其进行训练,训练细节和dnn部分一样
#train dae model
#python2.6 or above is required for noisy data generation.
#To speed up the process, pyximport for python is recommeded.
local/dae/run_dae.sh $thchs || exit 1;
2023-01-25(周三、初四)