AI大语音(十一)——WFST解码器(上)(深度解析)

 点击上方“AI大道理”,选择“置顶”公众号

 

为了让识别出来的语音符合常规语言表达,引入了语言模型作为约束。

为了加速解码识别效率又引入了WFST解码机制。

解码本质:解码就是在网络中寻找最优路径。


解码方式多种多样,各有优缺点。

(注:on-the-fly Rescoring 归为动态解码有待商榷)

 

1 基于Viterbi的原始动态解码
无HCLG、一次解码

基于Viterbi的动态解码是最基础的解码。

线性词典:动态解码网络仅仅把词典编译为状态网络,构成搜索空间。编译的一般流程为:首先把词典中的所有单词并联构成并联网络;然后把单词替换为音素串;接着把每个音素根据上下文拆分为状态序列;最后把状态网络的首尾根据音素上下文一致的原则进行连接,构成回环。
编译出来的网络一般称为线性词典(Linear Lexicon)。

每个单词的状态序列保持严格独立,不同单词的状态之间没有节点共享,因此内存占用比较大,解码过程中的重复计算比较多。

将上图状态拉成直线,做为Y轴,X轴为时间T。

 

随着时间的推移,帧的移动,逐渐对齐到词的最后一个音素的最后一个状态,比如第7帧对齐到“北京”、“北极”、“南京”等词典中每个词的HMM的最后状态,对比累计概率,挑选出“北京”。继续进行下去,结合语言模型,加入语言模型概率,得到最优路径“北京是首都”,即解码结束。

可见,从状态序列到词序列的整个转化过程十分复杂,且词汇量很大的话,计算量很大,解码效率不高。

树型词典:一般把单词首尾发音相同的部分进行合并,称为树型词典(Tree Lexicon)。由于大量相同状态的节点被合并在一起,因此可以显著降低搜索空间的规模,减少解码过程的运算量。

 

(该方法基本不用)



2 基于WFST的Viterbi静态解码
HCLG、一次解码

 

 

为了加快解码速度,可以把动态知识源提取编译好,形成静态网络,在解码时直接调用。
从输入HMM状态序列,直接得到词序列及其相关得分。

用H、C、L、G分别表示上述HMM模型、三音子模型、字典和语言模型的WFST形式。

一般网络构建的流程为:

 

或者

 

声学得分依然还要根据输入特征单独计算,其他知识源词典、语言模型、上下文依赖不需要再考虑,已经融入整个静态网络中,通过网络的转移弧输入、输出、权重来整体代替。

由于静态网络已经把搜索空间全部展开,它只需要根据节点间的转移权重计算声学概率和累计概率即可,因此解码速度非常快。

 

基于WFST的Viterbi静态解码过程:

解码过程使用了令牌传播机制Token passing,其实就是viterbi解码的通用版本。

1)解码第一帧时,从状态节点0出发,首先进行ProcessEmitting处理的发射状态转移弧,节点0转移到节点3、2、6。接着ProcessNonemitting沿着虚线非发射转移弧将6传播到同一时刻下的状态节点1。

2)解码第二帧时首先切换Token列表,把cur_toks列表转变到pre_toks列表后,将cur_toks置空。然后再进行ProcessEmitting、ProcessNonemitting。

3)随着时间的推移,帧的进行,到达最后一帧,选择最低累计代价的Token,然后以次Token回溯最优路径。

 

其中:

Emitting Arc 表示发射转移弧,类似HMM的发射状态,观察值产生声学得分

aoustic_cost;

Nonemitting Arc表示非发射转移弧,类似HMM的非发射状态,不产生观察值,没有声学得分;

每条转移弧对应的权重为图代价graph_cost(语言模型得分、转移概率、发音词典)。

Swap(prev_toks,cur_toks) :

直到最后一帧,选择最低累计代价的Token,根据该Token回溯最优路径。

 

 

3 基于WFST的Lattice静态解码
HCLG、一次解码

 

Viterbi解码识别只保留一条最优路径,若要保存多种候选识别结果,就需要Lattice。

(灵魂的拷问:为什么要保存多种候选结果呢?viterbi识别出一条最优路径不够吗?

AI大语音:不能保证viterbi给的最优路径就是真正的对的路径,错误的路径一样可能成为viterbi算法跑出来的最优路径)

 

Lattice解码需要保存多条搜索路径,Token间需要有链表信息。

前向链接ForwardList与转移弧不同,用来链接前后两帧之间的发射转移弧之间的Token,或同一时刻非发射转移弧之间的Token。

令牌列表TokenList每帧一个,可以和帧索引建立关联。

 

基于WFST的Lattice静态解码过程:

 

 

问题与解决:

在HCLG中,G的大小对最终的HCLG的大小起主要作用。

静态图HCLG问题:

1)静态图HCLG自身占用空间大,难以使用大的语言模型,其在解码运行过程中占用内存也大,难以在移动端直接使用HCLG。

2)   静态图HCLG构建过程速度慢,消耗内存高。

 

为了解决该问题,有两种方法:

1)on-the-fly Composition;

2)Rescoring(常规Rescoring、on-the-fly Rescoring)。

 

 

4 on-the-fly Composition
HCL/G、一次解码、动态解码

on-the-fly Composition动态解码思路是把HCLG分开成HCL和G,称之为HCL/G。构图时分别构建HCL和G,分别构建的HCL和G。因为不是完全展开的图,这两个图的大小远比其展开的静态图HCLG小,这样就节省了空间。
另一方面无需再进行HCL和G的Compose这一过程,而这一步恰恰是静态图HCLG构建过程中最为耗时的一步,所以又节省了构图时间。
在解码时,分别加载HCL和G,然后根据解码动态的对HCL和G进行按需动态Compose,而无需完全Compose展开。

动态图有什么问题呢?
动态图HCL/G要在解码时动态的做Compose,也就加大了解码时的计算量,所以解码速度会相对降低。

 

5 Rescoring
HCLG1和G2、二次解码

 

Rescoring,其思路是在构建时使用小的LM1构建G1,使用G1构建静态图HCLG1,然后使用小的LM1和大的LM2构建G2(G2中LM的weight为LM2的weight减去LM1的weight)。解码时根据HCLG1和G2的使用方式,又可以做进一步细分:

1)常规Rescoring:利用HCLG1先全部解码,生成lattice或者nbest,然后在G2上做lattice和nbest的Rescoring。

2)on-the-fly Rescoring:使用HCLG1做解码,在解码过程中,每当解码出word时,立即再加上G2中的LM weight,所以称之为on-the-fly Rescoring。Kaldi中的BigLM Decoder即为on-the-fly Rescoring。

 

6 总结

 

基于Voiterbi的原始动态解码词典一旦很大,计算量就会很大,解码速度很慢。

为了加速解码速度,一方面可以进行剪枝处理,在解码中选出最优路径,超过剪枝阈值的路径则直接删除,不再后续运算。

另一方面可以把知识源预先编译成一个静态网络,在解码中直接使用。其中一般基于WFST的Viterbi静态解码得到的一条最优路径可能并不是实际上真正的最优路径,为了得到更多的候选结果使用基于WFST的Lattice静态解码。

静态解码HCLG占用空间大,难以使用大的语言模型,HCLG在构建过程中速度慢,消耗内存高。

为了解决静态一次解码的问题,可以进行on-the-fly composition动态解码和rescoring解码。

 

 

 

 

 

下期预告

AI大语音(十二)——WFST解码器(下)(深度解析)

往期精选

AI大语音(十)——N-gram语言模型
AI大语音(九)——基于GMM-HMM的连续语音识别系统
AI大语音(八)——GMM-HMM声学模型
AI大语音(七)——基于GMM的0-9语音识别系统
AI大语音(六)——混合高斯模型(GMM)
AI大语音(五)——隐马尔科夫模型(HMM)
AI大语音(四)——MFCC特征提取
AI大语音(三)——傅里叶变换家族
AI大语音(二)——语音预处理
AI大语音(一)——语音识别基础

——————

浅谈则止,细致入微AI大道理

扫描下方“AI大道理”,选择“关注”公众号

 

—————————————————————

​     

—————————————————————

 

投稿吧   | 留言吧

 

 

 

posted on 2020-11-17 23:35  AI大道理  阅读(1031)  评论(0编辑  收藏  举报

导航