kaldi005 -- 构图

本文详细介绍了Kaldi中的解码图构建过程,包括如何处理消歧符号、上下文相关性、权重处理等问题,以及如何确保解码图的随机性和确定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kaldi中的构图

 

首先,我们不能希望引入有限状态转换器以及它们如何用于语音识别。

为此,参见MohriPereiraRiley"Speech Recognition with Weighted Finite-State Transducers"Springer Handbook on SpeechProcessing and Speech Communication2008)。 我们使用的一般方法是在上面描述的,除了一些细节,特别是关于我们如何处理消歧符号以及如何处理重推权重不同之处。

 

解码图构建概述

 

解码图构建的总体规划是我们正在构建HCLG = H o C o L o G.这里

 

     G是编码语法或语言模型的接受机(即,其输入和输出符号是相同的)。

     L是词典其输出符号是字,其输入符号是音素

     C表示上下文相关性:其输出符号是phone,其输入符号表示上下文相关phone,即Nphone的窗口; 参考Phonetic context windows

     H包含HMM定义; 其输出符号表示上下文相关的phone,其输入符号是transitions-ids,它对pdf-id和其他信息编码(参见Integer identifiers used by TransitionModel

 

这是标准方法 然而,有很多细节要说明。我们希望确保输出被确定和最小化,为了使HCLG可以确定,我们必须插入消歧符号。 有关消歧符号的详细信息,请参见下面的 Disambiguation symbols

 

我们也希望尽可能确保HCLG是随机的; 在常规方法中,这通过权重前推操作完成(如果有的话)。 我们的确保随机性的方法是不同的,并且基于确保没有图构建步骤消除随机性; 请参阅保Preserving stochasticity and testing it 以了解详情。

 

如果我们在一行中总结我们的方法(显然,一行不能覆盖所有的细节),那么这行可能如下,其中asl ==“add-self-loops”rds ==“remove-disambiguation-symbols“H'没有自环的H

HCLG = aslminrdsdetH'o mindetC o mindetL o G)))))))

 

push-weights不是构图的一部分; 相反,我们的目的是确保图形创建的任何阶段都不会随机地停止结果,只要G是随机的。 当然,G通常不会很随机,因为Arpa语言模型与回退概率是用FST表示的,但至少我们的方法确保非随机性保持放置,不会比开始更糟; 这种方法避免了push-weights”操作失败或使事情变得更糟。

 

消歧符号

消歧符号是在词典中的音素序列末尾插入的符号#1,#2,#3等。 当音素序列是词典中另一个音素序列的前缀,或者出现在一个以上的单词中时,需要在其后加上这些符号之一。 需要这些符号以确保产品L o G是可确定的。 我们还在两个地方插入消歧符号。 我们在语言模型G中的退避弧上有一个符号#0; 这确保了G在删除epsilons之后是可确定的(因为我们的确定算法确实除去了epsilons)。 我们还有一个符号#-1代替出现在上下文FST C的左边的epsilons,在开始的话语(在我们开始输出符号之前)。 这是必要的,以解决一个相当微妙的问题,当我们有一个空的语音表示(例如句子符号的开始和结束<s></ s>)的话。

 

我们给出我们如何构建图的中间阶段(例如LGCLGHCLG是确定化的大纲;这对于确保我们的方法永远不会失败是重要的。通过可确定性,意味着在除去ε之后可以确定。一般的设置是:首先,我们规定G必须是可确定的。这就是为什么我们需要#0符号(G实际上是确定性的,因此可以确定)。那么我们希望L对于任何可确定的GL o G是可确定的。 [同样适用于C,右边是L o G而不是G]。有很多细节的理论仍然要充实,但我相信L有两个属性是足够的:

 

    必须有效

        等价地:L上的任何输入序列必须引发唯一的输出序列

        等价地:对于任何线性接收器AA o L是线性转换器或空的。

    L具有双胞胎属性,即不存在具有相同输入符号序列的两个状态,每个状态具有相同输入序列但不同权重或输出序列。

 

同样适用于C转换器。我们认为当前脚本和程序创建的转换器具有这些属性。

 

ContextFst对象

ContextFst对象(C)是动态创建的FST对象,它表示从上下文相关phone到上下文无关phone转换器。该对象的目的是为了避免我们必须在上下文中枚举所有可能的phone当上下文宽度(N)或phone索引大于正常时。构造函数ContextFst :: ContextFst需要在上下文宽度(N)和中心位置(P更进一步的介绍在Phonetic context windows;它们对应于三音系统的正常值分别为31。它还需要一个特殊符号的整数id,即后续符号(在上面给出的参考文献中称为“$”),FST在所有的音素可见之后输出N-P-1(这确保了上下文FST是输出确定性的)。除此之外,它需要phone整数ID和消歧符号的列表。 ContextFst输出端的词汇表包括一组phone和消歧符号加上后续符号。输入端的词汇是动态生成的(除了不使用的epsilon),对应于上下文中的phone,消歧符号和我们写为#-1的特殊符号,代替epsilon传统方法,但我们将其视为任何其他消歧符号(有必要确保我们偏好的意义上的可确定性,即除去epsilon)。后面的符号'$'在输入端没有任何对应(传统配方也是这样)。对应于输入侧的消歧符号的符号id不一定与用于相应符号的输出侧使用的整数标识符相同。 ContextFst对象具有一个函数ILabelInfo(),该函数返回对类型为std :: vector <std :: vector <int32>>的对象的引用,该对象使用户能够确定输入端每个符号的含义。该对象的正确解释将在The ilabel_info object中进一步描述。

 

有一个特殊的“Matcher”对象,称为ContextMatcher,用于涉及ContextFst的组合算法(MatcherOpenFst的组合算法用于弧查找的内容;更多解释请参阅OpenFst文档)。 ContextMatcher使ContextFst对象的使用更有效,通过避免分配比所需的更多的状态(问题是与正常匹配器相关的问题,每当我们想要任何一个状态的弧,我们必须分配从该状态出发的所有弧的目的状态)。 在组合的左手参数的类型为ContxtFst的情况下,有一个相关函数ComposeContextFst()执行FST组合; 它使用这个匹配器。 还有一个函数ComposeContext(),它类似,但是创建了ContextFst对象本身。

 

避免weight pushing

我们以与传统方法略有不同的方式处理整个weight pushing weight pushinglog半环中可以有助于加快搜索(weight pushing是一种FST操作,可以确保每个状态下的弧概率在适当的意义上合计为一)。 然而,在某些情况下,weight pushing可能会产生不良影响。 问题是统计语言模型,当表示为FST时,通常加起来多于一个,因为有些单词被计数两次(直接和通过退避弧)。

 

我们决定避免pushing weights,所以我们以不同的方式处理整个问题。首先,一个定义:我们称之为随机”FST,其权重为1,读者可以假设我们在谈论这里的log半环,而不是tropical半环,所以总和到一个实际上意味着和,而不是取最大值。我们确保图构建的每个阶段都具有如果前一个阶段是随机的,那么下一个阶段将是随机的。那就是:如果G是随机的,那LG就会随机;如果LG是随机的,那么detLG)将是随机的;如果detLG)是随机的,则mindetLG))将是随机的,依此类推。这意味着每个单独的操作必须在适当的意义上保持随机性。现在,很有可能以非常简单但不是非常有用的方式来做到这一点:例如,我们可以尝试push-weights算法,如果它似乎是失败的,因为原来的G fst总和多达一以上,然后我们惊恐地抛出我们的手,宣布失败。这不是很有帮助。

 

 

我们想保持更强烈的随机性,也就是说:首先测量G,最小和最大值在所有状态下,这些状态之间的(弧度概率加上最后一个概率)的总和。 这就是我们的程序“fstisstochastic”。 如果G是随机的,这两个数字都将是一个(你实际上会从程序中看到零,因为实际上我们在log空间中操作;这就是log半环意思)。 我们想在以下意义上保持随机性:这个最小和最大不会变得更糟”; 也就是说,他们永远不会远离这个 事实上,当我们有一种以本地的方式保存随机性的算法时,这是自然而然的。

我们需要保存随机性的各种算法,包括:

 

·  Minimization

·  Determinization

·  Epsilon removal

·  Composition (with particular FSTs on the left)

 

还有一个或两个次要算法需要保留随机性,如添加一个后续符号循环。最小化自然地保持随机性,只要我们不作为其一部分的任何weight pushing(我们使用我们的程序“fstminimizeencoded”而没有weight pushing)。只要我们在保持随机性的进行确定即可保持随机性(这意味着log半环;这就是为什么我们使用我们的程序fstdeterminizestar和选项-determinize-in-log = true)。关于epsilon的删除:首先,我们有自己的版本的epsilon删除“RemoveEpsLocal()fstrmepslocal),这不能保证删除所有的epsilons,但是保证永远不会炸毁。这种算法在FST算法中是不寻常的,因为对于我们需要做的和保持随机性,它需要同时跟踪两个半环。也就是说,如果它在tropical半环保持相等性log半环中保持随机性,这是我们实际需要的,它实际上必须同时知道两个半字。这似乎是一个边缘的情况,半环的概念有点分解。左侧的词与词汇L,上下文FST CH转换器(编码HMM结构)的组合都必须保持随机性。我们来讨论一下这个摘要:我们问,当组合A o B时,A必须有足够的属性,以便每当B随机时,A o B将随机?这些属性是:

对于可能出现在B的输入上的任何符号序列,A输出必须接受该序列(即A必须可以输出该序列),并且:

对于任何这样的符号序列(例如S),如果我们未加权线性FST SA做组合,则结果将是随机的。

 

这些属性对于CLH是至关重要的,至少对所有是归一化(即如果任何一个给定的单词的词法权重相加一个,并且如果H中的HMM适当的归一化,而且我们不使用概率标度)。 然而,在实践中,在我们的构图中,我们使用HMM中的转换概率的概率标度(类似于声级)。 这意味着构图最后阶段通常不会保留随机性。 此外,如果我们使用统计语言模型,G通常不会是随机的。 在这种情况下我们所做的是,我们开始测量偏离随机性(使用程序fstisstochastic)多少,在随后的构图阶段(除了最后一个),我们验证非随机性不会比起初更糟糕。

<think>我们正在讨论如何为KaldiSherpa-ONNX语音识别模型生成关键词文件(keyword.txt)。根据引用内容,Sherpa是一个基于下一代Kaldi和ONNXRuntime的开源项目,支持离线语音识别。关键词文件通常用于在语音识别中提升特定词汇的识别准确率。在Kaldi和Sherpa-ONNX中,关键词文件(keyword.txt)通常包含需要被识别的关键词列表,每行一个词。这个文件用于构建有限状态转换器(FST)来增强关键词的识别。步骤:1.创建一个文本文件,每行一个关键词。2.文件名通常为`keywords.txt`(注意:用户问题中写的是keyword.txt,但通常使用复数形式keywords.txt,不过具体名称取决于实际使用)。但是,仅仅提供关键词列表是不够的,我们还需要将其转换为模型可以使用的格式(通常是FST)。Sherpa-ONNX可能提供了工具来将关键词列表编译成所需的二进制格式。根据引用[2]中提到的sherpa-ncnn项目(虽然用户询问的是sherpa-onnx,但两者可能有相似之处),我们可能需要使用Sherpa提供的工具来生成关键词的FST。在Kaldi中,通常使用以下步骤生成关键词的FST:-创建一个词汇表文件(vocab),包含所有关键词。-使用fstmake命令生成FST。然而,在Sherpa-ONNX中,具体步骤可能有所不同。由于Sherpa-ONNX是较新的项目,我们需要参考其官方文档。根据Sherpa-ONNX的GitHub页面(https://github.com/k2-fsa/sherpa-onnx),我们可以找到相关工具。具体步骤(以Sherpa-ONNX为例):1.创建一个关键词列表文件,例如`keywords.txt`,内容如下(每行一个关键词):helloworldsherpa2.使用Sherpa-ONNX提供的工具`k2-fsa/onnx/bin/sherpa-onnx-keyword-spotter`(具体工具名称可能有所不同,请以实际为准)来生成关键词模型。但是,在Sherpa-ONNX中,关键词识别(KeywordSpotting)通常是在运行时加载关键词列表,而不是预先生成一个单独的文件。因此,我们可能需要直接提供关键词列表文件给识别程序。实际上,在Sherpa-ONNX的示例中,关键词识别是通过命令行参数直接指定关键词列表的。例如,在实时麦克风输入的示例中,我们可以这样运行:./bin/sherpa-onnx-keyword-spotter\--tokens=/path/to/tokens.txt\--encoder=/path/to/encoder.onnx\--decoder=/path/to/decoder.onnx\--joiner=/path/to/joiner.onnx\--keywords-file=keywords.txt\--num-threads=1其中,`--keywords-file`参数指定了关键词列表文件(每行一个词)。因此,生成关键词文件实际上就是创建一个文本文件,每行一个关键词。注意:关键词文件中的词必须在模型的词汇表中(即tokens.txt中)。如果关键词不在词汇表中,则无法识别。总结:1.创建一个文本文件,例如`keywords.txt`。2.每行写一个关键词。3.确保这些关键词在模型的词汇表(tokens.txt)中存在。4.在运行关键词识别程序时,通过`--keywords-file`参数指定这个文件。如果用户需要的是在构建语言模型时加入关键词(例如在解码图中加入关键词),那么可能需要更复杂的步骤(如构建一个包含关键词的FST)。但根据Sherpa-ONNX的示例,它支持直接通过关键词文件进行关键词识别,而无需重新编译整个模型。因此,对于Sherpa-ONNX,生成关键词文件非常简单:只需按格式创建文本文件即可。相关问题:1.如何确保关键词在模型的词汇表中?2.如果关键词不在词汇表中,有什么解决办法?3.如何测试关键词识别的效果?4.Sherpa-ONNX支持多少个关键词?5.关键词识别对识别准确率有什么影响?6.除了关键词文件,还需要其他配置吗?请注意:以上回答基于Sherpa-ONNX的一般使用方式,具体细节请参考其官方文档。</think>### 为 Kaldi Sherpa-ONNX 生成关键词文件 (keyword.txt) 在 Kaldi Sherpa-ONNX 中,`keyword.txt` 是用于**关键词唤醒**或**特定词识别**的配置文件,其生成步骤如下: #### 1. **创建关键词列表文件** 创建一个纯文本文件(如 `keywords.txt`),每行一个关键词: ``` 你好 打开灯光 停止 退出 ``` > ⚠️ 注意: > - 关键词需在语音模型的**词汇表范围内**(参考模型的 `tokens.txt`) > - 避免过长短语(建议 1-4 个词) > - 文件编码需为 **UTF-8 无 BOM** #### 2. **生成 keyword.txt 格式** Sherpa-ONNX 要求 `keyword.txt` 包含**关键词权重**(重要性系数),格式为: ``` 关键词1 权重值 关键词2 权重值 ``` 示例: ```txt 你好 1.5 打开灯光 2.0 停止 1.0 退出 1.0 ``` > 📌 权重说明: > - 默认权重 = 1.0 > - 更高权重(如 2.0)提升该词识别优先级 > - 权重范围建议 [0.5, 3.0] #### 3. **在 Sherpa-ONNX 中使用** 运行时通过参数加载关键词文件: ```bash ./sherpa-onnx \ --tokens=path/to/tokens.txt \ --encoder=path/to/encoder.onnx \ --decoder=path/to/decoder.onnx \ --joiner=path/to/joiner.onnx \ --keywords-file=path/to/keyword.txt \ # 加载关键词 --max-active-paths=4 \ # 并行解码路径数 ... ``` #### 4. **验证效果** - 测试命令(实时麦克风输入): ```bash ./sherpa-onnx-microphone \ --keywords-file=keyword.txt \ --keywords-threshold=0.25 \ # 触发阈值(需调整) ... ``` - 调整参数: - `--keywords-threshold`:降低阈值(如 0.1)提高敏感度 - `--keywords-score`:控制误触发率 #### 注意事项 1. **模型兼容性**:仅适用于支持**关键词唤醒**的 Sherpa-ONNX 模型(需确认模型训练方式)[^1] 2. **权重优化**:通过测试集调整权重,平衡召回率与误触发率 3. **实时性要求**:嵌入式设备需简化关键词数量(建议 ≤20 个词) 4. **非关键词处理**:通用语音识别仍需完整语言模型 > 💡 提示:Sherpa-ONNX 的**流式识别架构**特别适合关键词唤醒场景[^1],其 FST(有限状态转换器)会优先处理关键词路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值