来源 | 极链AI云(性价比最高的共享GPU算力平台,双十一活动新人注册可领取268元大礼包,价值150+小时的GPU免费使用时长,领取地址:https://cloud.videojj.com/)

本文取名高阶解码器技术,一是文章假定读者已有语音识别、WFST(Weighted Finite State Transducer)和解码器的基础知识,二是文章关注解码器在实际应用中的问题和实际需求,当然也略有博人眼球的嫌疑。本文写作过程中,得到吕航博士的指正和支持,特此感谢。

文章中重点关注如下三类高阶解码器技术,这里先简单介绍下这三类技术的基本概念,后文会展开详细介绍。

动态图和Rescoring:使用动态图(on-the-fly Composition)和Rescoring技术支持更大更高阶的语言模型,从而进一步提升语音识别率。
个性化解码:在解码过程中引入用户的一些信息(如联系人等),从而做个性化的解码。
热词增强(Contextual Biasing):在解码过程中,提高给定一个或多个词(热词)的概率,使这些特定词更容易被识别出来。
本文先简单回顾基本的解码器静态构图算法,再分别介绍动态图和Rescoring、个性化解码和热词增强,文中所有的算法均基于WFST框架。

静态图
在基于WFST框架的语音识别解码器静态构图中,使用WFST的Compose算法组合各个层次的信息,最终生成解码图HCLG, H/C/L/G分别表示不同层级的FST,其中:
H表示HMM层级的FST,输入为senone状态,输出为context-dependent phone。
C表示Context层级的FST,语音识别中的音素建模时考虑当前音素的上一个音素和下一个音素,C的输入为context-dependent phones,输出为phone。
L表示Lexicon层级的FST,对单个的词来讲,输入为该词的phone序列,输出为该词。
G表示Grammar层级的FST,一般Grammar用n-gram的语言模型表示,arpa的语言模型可以表示为等价的FST的形式,输入输出均为词。

从H->C->L->G,低层次的FST的输出粒度刚好对应高一层次FST的输入粒度,通过Compose HCL*G(*表示Compose),即可将HMM/Context/Lexicon/Grammar所有层次的信息构建在一个FST HCLG中,该HCLG输入为语音识别声学模型的建模单元senone,输出为词。

解码时,解码器直接使用已经构建好的HCLG,该HCLG已经全部展开,称之为静态图。

在某些特定应用中,例如电话号码、航班号、车牌号等特定场景中,用来构建n-gram的语料或为该领域生成的语料很难覆盖全部的情况,而且最终的n-gram中对不同的电话号码/航班号/车牌号也可能会有不同的概率。一个常用的技巧是,在n-gram的语料中使用特殊符号表示该场景并构建G1,然后为该场景构建一个class的FST G2(考虑该场景实体的所有情况,并表示成FST的形式),最后使用fstreplace算法在G1中将该特殊符号替换为G2,从而得到最终的G。

动态图和Rescoring
在一般的语音识别系统的HCLG中,G(语言模型)的大小对最终的HCLG的大小起主要作用。实际使用中,静态图HCLG会有如下问题:
静态图HCLG自身占用空间大,难以使用大的语言模型,其在解码运行过程中占用内存也大,难以在移动端直接使用HCLG。
静态图HCLG构建过程速度慢,消耗内存高。
例如,典型的,1G的n-gram生成的HCLG在10G以上,而为了生成该10G的HCLG,又需要五六十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和其动态展开的部分,一般情况下也是远小于静态图HCLG的大小,所以动态图也起到了节省内存的作用。

那动态图有什么问题呢?可以看到静态图HCLG线下直接构图,解码时直接使用。相比之下,动态图HCL/G要在解码时动态的做Compose,也就加大了解码时的计算量,所以解码速度会相对降低。当然HCL/G和HCLG相比,本身就属于以时间换空间的策略。一般的,通过优化,可以控制HCL/G的解码实时率在可接受的范围内。优化的核心是加快HCL/G的动态Compose。在OpenFST中,最有效的方法是使用Label Reachability Filter对Compose进行优化,该算法要求对HCL中的olabel进行顺序调整,转换成一个olabel_lookahead类型的FST,同时G中的ilabel也要做相应的调整,从而提升on-the-fly Composition的效率(这部分可以进一步参考https://robin1001.github.io/2019/07/23/fst/)。OpenFST可以通过如下命令进行转换。
fstconvert --fst_type=olabel_lookahead --save_relabel_opairs=relabel.txt HCL.fst HCLr.fst
fstrelabel --relabel_ipairs=relabel.txt G.fst Gr.fst

Kaldi中在https://github.com/kaldi-asr/kaldi/pull/3616支持了动态图解码,其在librispeech上的实验结果如下表所示。可以看到,在该实验上,和静态图相比,动态图能取得与之相当的WER,整体图大小只有静态图的四分之一,但解码速度相比静态图要慢。
FST FST size WER RTF
static HCLG 476M HCLG 4.86 0.18
dynamic HCL/G 48M HCL + 77M G 4.86 0.29

第二种是Rescoring,其思路是在构建时使用小的LM1构建G1,使用G1构建静态图HCLG1,然后使用小的LM1和大的LM2构建G2(G2中LM的weight为LM2的weight减去LM1的weight)。解码时根据HCLG1和G2的使用方式,又可以做进一步细分:
常规Rescoring:利用HCLG1先全部解码,生成lattice或者nbest,然后在G2上做lattice和nbest的Rescoring。
on-the-fly Rescoring:使用HCLG1做解码,在解码过程中,每当解码出word时,立即再加上G2中的LM weight,所以称之为on-the-fly Rescoring。Kaldi中的BigLM Decoder即为on-the-fly Rescoring。

个性化解码
语音识别在实际应用中,有的场景需要用到用户个人的相关信息做个性化的解码,特别是在设备端的语音识别系统中,经常会有这样的需求。例如,在手机端的语音助手中,当用户说打电话给某某某,其中某某某是用户通讯录中的联系人名,这时就需要在解码中动态引入用户的通讯录信息,从而做个性化的解码,举例来说,假设A的通讯录中有“彬彬”,B的通讯录中有“斌斌”,当用户说打电话给Bin Bin时,识别系统应该给A返回"彬彬",给B返回"斌斌"。

一个很自然的想法是类似静态图中的class FST,如下图所示,先构建通用文法的FST G_ R O O T , 电 话 号 码 中 联 系 人 使 用 特 殊 符 号 ROOT,电话号码中联系人使用特殊符号 ROOT使CONTACTS表示,为每个用户的通讯录也构建相应的class FST G_KaTeX parse error: Expected group after '_' at position 26: …解码的时候直接使用通用文法的G_̲ROOT和用户相关的G_$CONTACTS进行Replace操作从而得到解码时的G(其中e是CONTACTS首尾的标记)。

在这里插入图片描述
在实际应用中,还会有如下问题:
如何给class中实体分配合理的一个概率,例如通讯录有10000条联系人,如何设定联系人的概率以保证合理的识别率?
class中存在OOV(例如生僻的英文人名),即HCL中不存在该词,HCL中无法输出该词,即使Repalce后的G中存在该词,也无法解码出该词,该怎么办?

"Improved recognition of contact names in voice commands“这篇文章中对这两个问题进行了细节的研究和讨论。

对于问题1,文章中考虑了3种概率,如下图所示,其中c表示class,P_c表示该class总共有多少条实体。第一种是直接给定每条概率都是1,缺点是没有做概率的归一化;第二种是做均匀归一,这样概率做了归一化,概率随实体总数的增加是线性下降的,所以当通讯录非常大时,每条实体分配到的概率很低,例如通讯录10000条时,每条仅得到1/10000的概率,解码时很容易被解码器裁剪掉;第三种是在第二种的基础上加入两个超参,以避免方法二中的问题,文章中比较好的配置是alpha=0,beta=0.5,概率随实体总数的增加下降的速度是远小于线性速度,例如当通讯录是10000条时,每条实体的概率是1/100。
在这里插入图片描述
对于问题2,文章中是在HCL构建中将每个单音素也当作一个词加入词表和词典,以保证HCL能够输出单个的音素。对于OOV,先做G2P以生成其发音序列,然后在构建class的FST中以单音素序列作为输入,该OOV词作为输出构建class FST。例如,假设class中有2个词,book和buuk,其中book在HCL中已经存在,buuk为OOV,在HCL中不存在,buuk的G2P生成的音素序列为b u k. 则该class的FST表示为如下图所示。即对于OOV,在HCL中结构上保证输出单音素,在class FST中以单音素作为输入,也就保证了最终能够解码和识别class中的OOV。
在这里插入图片描述
热词增强(Contextual Biasing)
在一些语音识别场景中,我们需要根据上下文对特定类型的词或者短语做增强,以提高其识别率和用户体验。例如,在预订机票的对话交互中,可能存在如下典型流程:

人:我想预定一张机票?
Agent:请问您要到哪里?
人:bulabula(大概率说一个城市地名,如北京、上海等,需要增强城市名识别)
Agent:请问您几点出发?
人:bulabula(大概率说一个时间,需要增强时间的识别)
Agent:我看有适合您的航班XXX,需要预定吗?
人:bulabula(大概率说要/不要/要预定/不预定等等,需要增强下这些词的识别)

可以看到,在不同的交互环节,都需要根据上下文对不同的词或者短语做增强,以提高检出率。

一个直观的想法是解码的过程中,当解码碰到这些词或者短语的时候,动态的给其一个概率上的奖励。如何奖励?如何和现有系统结合?如何处理OOV?文章"Bringing contextual information to google speech recognition"对这些问题进行了讨论。

如何奖励?对于任意的一个热词短语,我们都可以根据词典对其进行分词,此时其变成一个词序列,那就要考虑在解码过程中,当解码到该词序时如何处理。考虑到解码过程中,词是一个一个解码出来的,所以也是逐渐和该词序列去匹配的。文中直接给出两种方案。
方案1,奖励与匹配上的词序列长度相关,如下式:
在这里插入图片描述
方案2,当解码结果和词序列中的unigram可以匹配上的时候,给p1奖励,和bigram以上可以匹配的时候,给p2的奖励,如下所示:
在这里插入图片描述
如何和现有系统结合?上述的奖励这个过程和策略也可以用FST的等价形式表示出来,这时相当于我们又有一个contextual biasing的FST,假设我们把该FST当作一个类似大语言模型Rescoring的FST,则可以等价的使用on-the-fly Rescoring的方法在contextual biasing FST做Rescore。

如何处理OOV?参考个性化解码中的OOV,在个性化解码中,我们处理的是class中的OOV,该class的LM概率已经覆盖,通过Replace后其LM概率也就天然存在了。但对热词增强来讲,其OOV在G中根本不曾出现。文章中给出的解决方案是,我们在构建LM的时候,也构建一个$UNKNOWN的class,并且仅给其一定的unigram的概率,在解码时,我们从给定的要增强的热词集合中提取OOV,并使用该class进行Replace,这样即在G中给了OOV一定的概率,解决了该问题。对于OOV的发音,处理方法同个性化解码中的OOV。

文章中的主要实现结果如下表所示,其中绿色框起来的是含有热词的测试集,neg和anti是不含热词用做回归的测试集,可以看到文中提出的方法在含有热词的测试集上,性能有显著进步,在回归测试集上,也保证了识别率不下降。
在这里插入图片描述
参考资料
Aleksic, Petar, et al. “Improved recognition of contact names in voice commands.” 2015 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP). IEEE, 2015.
Aleksic, Petar, et al. “Bringing contextual information to google speech recognition.” (2015).
Hall, Keith, et al. “Composition-based on-the-fly rescoring for salient n-gram biasing.” (2015).
https://robin1001.github.io/2019/07/23/fst/
https://github.com/kaldi-asr/kaldi/pull/3616

来源 | 极链AI云(性价比最高的共享GPU算力平台,双十一活动新人注册可领取268元大礼包,价值150+小时的GPU免费使用时长,领取地址:https://cloud.videojj.com/)

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐