简介
我们先来简单说说Kaldi中用于建模的代码的思路,以及为什么这样设计。我们的目标是使Kaldi支持传统模型,也就是对角阵高斯混合模型 (GMM)和子空间高斯混合模型(SGMM),同时也要便于扩展到新的模型。在上一轮代码设计过程中,我们设计了一个虚基类,从其中衍生出GMM类和SGMM类,然后编写了一个命令行工具用于操作这两种模型。但是根据我们的经验,基类并不像事先想象的那样能派上大用场,因为这两种模型之间的差异太大(例如,它们支持的自适应算法不同)。为了构建我们想象中具有“普适性”的代码,使它能够处理不同模型类别,我们不得不不断的扩展基类。最终,我们的命令行工具已经很难修改和维护了。
在重设计代码的时候,我们决定使用更“现代化”的软件工程方法,不为了增强普适性而过于强调类的层级结构,而是专注于创建简单的、可复用的组件。例如,我们的解码器代码是很通用的,因为它的需求很少,它只要我们从简单的基类DecodableInterface中 创造一个衍生的实例。这个实例操作起来类似于由一个句子的声学似然度组成的矩阵(参见Kaldi工具中的解码器)。同时,每个命令行工具更简单易用,例如gmm-align用于给定对角GMM获得一句话的状态级对齐结果。总的想法是,要实现某种新技术只要编写一个新的命令行程序,而不是增加已有的命令行程序的复杂度。