当前位置:   article > 正文

LiJian-kaldi搭建在线语音识别系统 资料汇总_hclg是什么

hclg是什么

感谢视频制作者李健和视频上传者北洋村的热心分享
原视频在:https://www.bilibili.com/video/BV19a4y1h7cB
大家记得三连~

说明

Kaldi的资料比较少,对新手特别不友好,我也是无意中搜到了这个视频的资料,看完确实收获很大,学习的过程一方面是复现出作者的各种模型,另一方面,也想在心中形成kaldi的一个big picture。

但这个视频并无相关的学习资料,另外视频的知识点的索引也不全面,我分享的目的也是希望大家一起搜集资料,互相分享,互相促进,所以这篇文章也会不断更新。

已经搜集的资料在:度盘链接,密码: p2nj
主要包括作者提到的一些资料,有些比较难下载,我这里替大家下载好了:
在这里插入图片描述
注意:没有作者的代码源文件和数据集

知识点的笔记

目标:从无到有搭建起中文在线语音识别Demo

P1 准备kaldi的数据文件夹(四个基本文件)

本章节前置知识有:shell的基本工具:grep、sed、awk,linux指令的管道机制,kaldi源代码的基本结构、环境变量配置等,熟悉egs/wsj的utils和steps

本节主要讲述了训练模型前的基本准备,需要准备好四个文件:wav.scp、text、utt2spk和spk2utt,如下表所示:

需要准备的文件文件的作用文件内容示例模式
wav.scp语音文件id到语音wav文件的映射sentense_id /path/to/wavfile.wav<uterranceID> <full_path_to_audio_file>
text语音文件id到语音内容的映射sentense_id 今天天气很好<uterranceID> <text_transcription>
utt2spk语音文件id到说话人的id映射sentense_id speaker_id<uterranceID> <speakerID>
spk2utt说话人的id 到语音文件id的映射speaker_id sentense_id1 sentense_id2 sentense_id3<speakerID> <uterranceID_1> <uterranceID_2> <uterranceID_3> …
  • 其中spk2utt是1对多的关系,其余都是一对一的关系
  • spk2utt可以通过命令得到 ./utils/utt2spk_to_spk2utt.pl utt2spk > spk2utt
  • 一些数据集还需要说话人性别映射(spk2gender)数据
  • 作者比较硬核,直接用linux shell脚本来实现上述文件的制作
  • 因为不同的语音数据集涉及的处理流程不一致,所以我建议这里了解基本原理即可,不必纠结
  • 我个人习惯使用python脚本,python能很方便生成这些文件

P2 准备语言模型相关文件

作者继续准备data/local/dict目录下的文件:

需要准备的文件文件的作用文件内容示例模式
lexicon.txt发音字典(单词由什么发音音素构成的),有的数据集会提供你好 n i3 h ao3 (1-4代表声调,5代表轻声)<word> <phone 1> <phone 2> …
word.list单词集合(text出现的单词,已去重)今天 天气 很好<word>
silence_phones.txt音素集合(text出现的单词发音,已去重)SIL SPN<phone>
nonsilence_phones.txt音素集合(text出现的单词发音,已去重)ah ao<phone>
  • 对P1的text中的每行句子进行分词,分词使用的是python里面的mmseg包
  • lexicon是发音词典,一般数据集会提供,如果不提供需要自己生成,我分享的lexicon.txt就是来自aishell数据集
  • word.list 是把text分词后的单词去重后的集合,经过实测,貌似有些数据集是不需要生成这个的
  • phones.txt 是所有出现的音素集合,按照有无发音可以分成silence_phones和nonsilence_phones
  • 这部分同样可以用python来做,但是kaldi提供了不少脚本,更方便
  • 这节主要讲述分词,生成word.list和phones.txt在下一节(P3)还会提到
  • 部分数据集还需要生成lexiconp.txt,里面包含概率

这里部分效果如下所示:
lexicon.txt:
lexicon

分词的结果:
分词的结果

P3 数据集划分&建立语言模型&MFCC

本节作者继续讲述训练语言模型需要用的文件,还提到了不少的脚本:

  • kaldi数据划分的脚本(subset_data_dir.sh)
  • 验证训练文件的正确性脚本(fix_data_dir.sh)

然后作者继续生成,data/local/dict 目录下的文件,如下所示:

注意这里只是作者的习惯,有些数据集(aishell)使用了data/local/lang 和data/local/lm 等多个文件夹来保存这些文件)

需要准备的文件文件的作用文件内容示例
lexicon发音字典(单词由什么音素构成的)你情我愿 n i3 q ing2 uu uo3 vv van4
word.list单词集合(text出现的单词,已去重)今天 天气 很好 …
phones.txt音素集合(text出现的单词发音,已去重)ah ao …
nonesilence_phones.txt非静音音素集合不包括下面的silence_phones
silence_phones.txt静音音素集合SIL(静音) SPN(有声音但无法识别) NSN(非口语噪声) LAU(笑声)
optional_phones.txt填充词之间的静音音素SIL(词间静音)
extra_questions.txt构建音素的上下文决策树时会遇到的基本问题这里作者保持该文件为空
  • 准备好上述文件之后,运行指令(utils/prepare_lang.sh)生成需要用到的文件,这个比较重要(定位时间:2:07:10)这一步会生成L.fst文件(decode才需要,训练不需要,下面作者还会解释)
    运行如下指令:
utils/prepare_lang.sh data/local/dict "!SIL" data/lang_tmp data/lang
  • 1

data/local/dict就是我们刚才准备好的,data/lang_tmp是临时文件夹,data/lang是生成的文件目录,最终生成的 data/lang文件夹的内容如下所示:(定位时间:2:30:12
data/lang文件夹
生成的文件作者也解释了各个文件的作用,在定位时间:2:29:40
L.fst是lexicon的WFST格式(下一节会介绍), 已经把所有的音素转成了对应关系(解码图),该图的输入:音素组合,输出:词。是后续训练H、C、L解码图的一种,G训练的时候还用不到。
L_disambig.fst 目的是消除歧义,有同音字,加入#进行区分。
oov.txt是词汇表以外的词(Out of Vocabulary Words),oov.int是对应的id
phone.txt 存放了所有的音素和其编号 形如:<phone> <phone id>
typo HMM模型的参数,打开这个文件,我们可以发现静音音素有五个状态,非静音音素只有三个状态

另外:

  • 因为时间原因,作者通过egs/hkust的相关例子(定位时间:2:28:04)解释了整体的训练过程
  • 有了这个文件夹之后,就可以进一步训练模型了:
    训练模型
  • 作者在最后继续介绍了MFCC的使用方法(定位时间:2:33:00),使用的指令为:./steps/make_mfcc.sh --mfcc-config conf/mfcc.conf data/all exp/extract_mfcc mfcc,然而上述是二进制文件,无法直接读取,如果需要读取,可以用命令:copy-feats ark:raw_mfcc_all.1.ark ark,t:readark.txt

下面是MFCC提取的向量,维度是13维:
mfcc矩阵

P3这一节开始接触到了kaldi的HCLG,HCLG是WSFT格式的语音任务相关的表示,对于语音识别中用到的隐马尔科夫模型(H)、发音词典(L)、语言模型(G)以及上下文(C),都可以用 一个加权有限状态接收器(WFST)来表示。

下一节作者也会讲解,这里推荐一些资料供大家预习一下
1、WSFT的学习推荐阅读《Speech Recognition Algorithms Using Weighted Finite-StateTransducer》,这个文件我已经放到分享的文件中,着重了解什么是接收器,什么是转录器
2、 HCLG的学习建议阅读链接,整个HCLG的过程:构建语言模型(G.fst),发音词典模型(L.fst),以及合并的模型(LG.fst和CLG.FST),生成HMM模型(H.fst),最终合并、确定、最小化得到HCLG.fst。我的理解是,通过FST(有限状态转录机)的格式把语音识别各个模块组合到了一起,每组合一次,语音识别的功能就会多一个,方面语音解码的时候使用。

P4 使用srilm训练语言模型&WFST介绍

这一节的重点在怎么训练语言模型和WSFT
(1)语言模型,N-gram的原理可参考这篇博客:链接
(2)WSFT的推荐资料见上一节

知识点快速索引:

  • 使用kaldi并行提取train和test的MFCC,CMVN(倒谱归一化),并通过这个例子了解kaldi的流程
  • 演示kaldi怎么训练一个语言模型,n-gram,工具是srilm (定位时间:1:30:00
  • G.fsat介绍(定位时间:1:52:31
  • WSFT解码图(定位时间:1:54:00
  • 令牌(token passing)讲解:解码时候需要(定位时间:2:33:00

截至目前,已有的重要文件:
data/lang 发音词典(L):
data/local/lm 语言模型(G,只在解码时需要)

G.fst生成指令:在这里插入图片描述
G.fst可视化指令:
在这里插入图片描述
L.fst可视化指令:
在这里插入图片描述
组合L和G的命令:在utils/make_graph
在这里插入图片描述

P5 GMM-HMM算法&HCLG过程&训练脚本讲解

GMM+HMM的理论部分我建议学习李航老师的《统计学习方法(第二版)》,主要学习:HMM评价、解码和参数估计问题,视频的话建议学习李琳山老师的数字语音处理,b站上也有相关的视频。kaldi官方也有一个教程(链接)。DTW扩展阅读我推荐看王赟的知乎live,DTW是怎么过渡到GMM的(概率密度代替欧氏距离)。

  • DTW、动态规划算法(时间对齐问题)
  • GMM+HMM算法(定位时间:1:30:00)作者推荐看eecs e6870里面的PPT,见度盘分享4-5课
  • DNN和GMM的区别(定位时间:1:56:00):生成模型和判别模型
  • HCLG的举例过程(定位时间:2:07:00
    H: HMM,包括HMM的定义
    C: context,代表上下文关系
    L: lexicon,发声字典
    G: grammar,语法规则接收器
  • 作者讲解run.sh脚本(建议大家参见thchs30 run.sh即可,下一节刚开始的时候作者继续讲解了一些脚本流程) (定位时间:2:40:00

作者讲解HCLG的时候,一直在找LG.fst的可视化例子,我找了一个:
语料为:

语音 识别 技术
语音 识别 算法 公式
作战 防御 工事

LG.fst可视化为:
lg.fst
体会上图:输入音素,输出是句子

这里再推荐一篇结合kaldi的HCLG的文章:链接

P6 模型训练流程

  • 先训练GMM+HMM,最终会生成final.mdl文件
  • 训练DNN+HMM 大约需要训练三轮
  • 讲解了nnet3以及训练的参数设置(如下图)
    在这里插入图片描述
  • 基于Kaldi+GStreamer搭建线上的实时语音识别器(没找到pdf,截图,大家凑活看看,详细的直接到视频的后半部分看吧)pdf文章
    在这里插入图片描述
    在这里插入图片描述
    下面截图略

P7 模型实际部署过程

这节讲述了怎么使用GStreamer,搭建在安卓和网页上,可不看。

主要配置文件如下(yaml格式):
yaml格式
目录:(这就是部署的时候需要用到的模型文件)
目录
日志:(可以看出效果出来了,但是应该还是需要静一步处理的,最后俩字识别错了)
在这里插入图片描述

其他资料

因为作者没有提供自己数据库,我这里找到一个0-10英文发音的教程,教程比较通俗易懂,run.sh流程也不复杂,可以参考:
教程链接代码链接中文发音教程链接

实验过程

为了进一步消化作者提到的知识,继续学习LVCSR(大词汇连续语音识别) 相关知识,在kaldi-master/egs/thchs30/有一个清华大学王东老师的中文30小时语音的thchs30例子,基本上覆盖比较全面了,数据集也不大,新手对照run.sh里面练习就行。

也可以从aishell里面挑出10h-20h,练练手,在自己本机上也能快速跑一跑,一般机器估计训练个一天能出结果。

不建议新手参照librispeech学习,我不明白为啥《Kaldi语音识别实战》这本书要用这个数据集!!新手劝退!!这个数据集太大了(语料500小时+,数据集+训练中间文件文件夹轻轻松松就100GB了), 而且训练时间特别长,对机器性能要求也比较高,我用i9+16GB训练了3天都没出结果,最后内存消耗完了,程序被杀死了。我感觉要快速训练出来,肯定要上集群了。

其他建议

  • 建议安装在linux环境或者Mac电脑上,这两个都试过,安装环境非常方便,尽早动手安装,因为安装时间很耗时,第一次安装估计得花费几天时间,顺利的话最起码也要半天时间。最后一步可以用make -j 8 ,这个数字8就是你的cpu物理核心数量,也可以改为4或者其他
  • 如果只是单机运行,记得把cmd.sh中所有的queue改成run,不然会报错
  • 有时候脚本会遇到中断,需要重新运行,run.sh 没有记忆机制,已经跑过的脚本可以在run.sh里面手动注释了,避免再浪费时间跑一次
  • DNN训练是需要GPU的需要找一个能安装nvidia GPU的机器,不然会报错,检测这台机器能不能跑GPU可以运行nvidia-smi指令,可以找老的、带英伟达显卡的笔记本,笔者有一个2012年的笔记本,都能安装nvidia相关的驱动和cuda(最多到cuda9),显存2GB,自己测试足够了。
  • 这个视频虽然2017年,但是流程基本上都覆盖挺全的了,除了P1视频,其他的我觉得还是值得反复看几遍的。
  • 我也是初学kaldi,这方面资料真的太少了,希望大家踊跃交流吧!
  • 比较期待Daniel Povey大神的kaldi-pytorch项目,让熟悉python的人也能快速参与到语音领域。

总之,再次感谢作者分享!

如果有更好的资源和想法,欢迎在留言区讨论、分享,谢谢!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/366547
推荐阅读
相关标签
  

闽ICP备14008679号