重要提示
您正在查看 NeMo 2.0 文档。此版本对 API 和新库 NeMo Run 进行了重大更改。我们目前正在将 NeMo 1.0 中的所有功能移植到 2.0。有关先前版本或 2.0 中尚不可用的功能的文档,请参阅 NeMo 24.07 文档。
ASR 语言建模和定制#
语言模型已被证明有助于提高 ASR 模型的准确性。NeMo 支持以下两种将语言模型融入 ASR 模型的方法
可以在同一个 ASR 模型上同时使用这两种方法。
N-gram 语言建模#
在这种方法中,N-gram LM 在文本数据上进行训练,然后用于与波束搜索解码融合,以找到最佳候选。NeMo 中的波束搜索解码器支持使用 KenLM 库 (kpu/kenlm) 训练的语言模型。波束搜索解码器和 KenLM 库在 NeMo 中默认未安装。您需要安装它们才能使用波束搜索解码和 N-gram LM。请参阅 scripts/asr_language_modeling/ngram_lm/install_beamsearch_decoders.sh,了解如何安装它们。或者,您可以构建 Docker 镜像 scripts/installers/Dockerfile.ngramtools,其中包含所有必要的依赖项。
NeMo 支持用于 N-gram LM 的基于字符和基于 BPE 的模型。N-gram LM 可以与 ASR 模型之上的波束搜索解码器一起使用,以生成更准确的候选。波束搜索解码器会将 N-gram LM 生成的分数纳入其分数计算,如下所示
final_score = acoustic_score + beam_alpha*lm_score + beam_beta*seq_length
其中 acoustic_score 是声学编码器预测的分数,lm_score 是 LM 估计的分数。参数 ‘beam_alpha’ 决定了给予 N-gram 语言模型的权重,而 ‘beam_beta’ 是一个惩罚项,用于解释分数中的序列长度。较大的 ‘beam_alpha’ 值会更多地强调语言模型,而较少地强调声学模型。‘beam_beta’ 的负值会惩罚较长的序列,鼓励解码器偏向较短的预测。相反,‘beam_beta’ 的正值则偏向较长的候选。
训练 N-gram LM#
使用 KenLM 训练 N-gram 语言模型的脚本可以在以下位置找到:scripts/asr_language_modeling/ngram_lm/train_kenlm.py。
此脚本使用 KenLM 库训练 N-gram 语言模型,然后可以将其与 ASR 模型之上的波束搜索解码器一起使用。此脚本还支持字符级和 BPE 级编码和模型,这些编码和模型可以从模型类型中自动检测出来。
您可以使用以下命令训练 N-gram 模型
python train_kenlm.py nemo_model_file=<path to the .nemo file of the model> \
train_paths=<list of paths to the training text or JSON manifest files> \
kenlm_bin_path=<path to the bin folder of KenLM library> \
kenlm_model_file=<path to store the binary KenLM model> \
ngram_length=<order of N-gram model> \
preserve_arpa=true
train_paths 参数允许使用各种输入类型,例如文本文件列表、JSON 清单或目录,作为训练数据。如果文件的扩展名不是 .json,则假定数据格式为纯文本。对于纯文本格式,每行应包含一个样本。对于 JSON 清单,文件必须在每行包含 JSON 格式的样本,如下所示
{"audio_filepath": "/data_path/file1.wav", "text": "The transcript of the audio file."}
此代码从每行中提取 text 字段以创建训练文本文件。训练 N-gram 模型后,它将存储在 kenlm_model_file 指定的路径中。
以下是训练脚本的参数列表
参数 |
类型 |
默认值 |
描述 |
nemo_model_file |
str |
必需 |
ASR 模型的 .nemo 文件路径,或用于提取分词器的预训练 NeMo 模型名称。 |
train_paths |
List[str] |
必需 |
训练文件或文件夹的列表。文件可以是纯文本文件或“.json”清单或“.json.gz”。 |
kenlm_model_file |
str |
必需 |
用于存储 KenLM 二进制模型文件的路径。 |
kenlm_bin_path |
str |
必需 |
KenLM 的 bin 文件夹的路径。它是 KenLM 安装位置下的名为 bin 的文件夹。 |
ngram_length** |
int |
必需 |
指定 N-gram LM 的阶数。 |
ngram_prune |
List[int] |
[0] |
用于剪枝 N-gram 的阈值列表。示例:[0,0,1]。请参阅 https://kheafield.com/code/kenlm/estimation 上的 Pruning 部分 |
cache_path |
str |
|
用于保存分词文件的缓存路径。 |
preserve_arpa |
bool |
|
是否在构建 BIN 文件后保留中间 ARPA 文件。 |
verbose |
int |
1 |
详细级别。 |
..note:: 建议您为基于 BPE 的模型使用 6 作为 N-gram 模型的阶数。更高的阶数可能需要重新编译 KenLM 以支持它们。
通过波束搜索解码和 N-gram LM 进行评估#
NeMo 的波束搜索解码器能够使用 KenLM 的 N-gram 模型来找到最佳候选。使用波束搜索解码和 N-gram 模型评估 ASR 模型的脚本可以在 scripts/asr_language_modeling/ngram_lm/eval_beamsearch_ngram_ctc.py 中找到。
此脚本有大量可能的参数覆盖;因此,建议您使用 python eval_beamsearch_ngram_ctc.py --help
来查看完整的参数列表。
您可以使用以下命令评估 ASR 模型
python eval_beamsearch_ngram_ctc.py nemo_model_file=<path to the .nemo file of the model> \
input_manifest=<path to the evaluation JSON manifest file \
kenlm_model_file=<path to the binary KenLM model> \
beam_width=[<list of the beam widths, separated with commas>] \
beam_alpha=[<list of the beam alphas, separated with commas>] \
beam_beta=[<list of the beam betas, separated with commas>] \
preds_output_folder=<optional folder to store the predictions> \
probs_cache_file=null \
decoding_mode=beamsearch_ngram \
decoding_strategy="<Beam library such as beam, pyctcdecode or flashlight>"
它可以通过设置参数 --decoding_mode
在以下三种模式下评估模型
greedy:仅执行贪婪解码,不执行波束搜索解码。
beamsearch:执行波束搜索解码,但不使用 N-gram 语言模型。最终结果等效于将 LM 的权重 (beam_beta) 设置为零。
beamsearch_ngram:使用 N-gram LM 执行波束搜索解码。
在 beamsearch
模式下,评估是使用不带任何语言模型的波束搜索解码执行的。性能以词错误率 (WER) 和字符错误率 (CER) 表示。此外,当在候选者中选择最佳候选者时,也会报告最佳 WER/CER。这可以作为预测候选质量的指标。
该脚本最初加载 ASR 模型,并将模型编码器的输出预测为对数概率。此部分在由 –device 指定的设备上分批计算,该设备可以是 CPU (–device=cpu) 或单个 GPU (–device=cuda:0)。此部分的批大小由 --acoustic_batch_size
指定。使用尽可能大的批大小可以加快对数概率的计算速度。此外,您可以使用 –use_amp 来加速计算并允许更大的 –acoustic_batch_size 值。目前,多 GPU 支持不适用于计算对数概率。但是,使用 --probs_cache_file
可以提供帮助。此选项将模型编码器生成的对数概率存储在 pickle 文件中,允许您在将来的运行中跳过第一步。
以下是评估脚本的重要参数列表
波束搜索的宽度 (--beam_width
) 指定波束搜索解码器将考虑的顶部候选或预测的数量。较大的波束宽度会产生更准确但更慢的预测。
注意
eval_beamsearch_ngram_ctc.py
脚本包含用于 CTC 波束解码的完整子配置。因此,可以通过 decoding
子配置转发各种波束搜索库(如 flashlight
和 pyctcdecode
)的参数。
要了解有关使用 N-gram LM 评估 ASR 模型的更多信息,请参阅此处的教程:使用波束搜索和外部语言模型重打分的离线 ASR 推理 Offline ASR Inference with Beam Search and External Language Model Rescoring
波束搜索引擎#
NeMo ASR CTC 支持多种波束搜索引擎进行解码。默认引擎是 beam,它是 OpenSeq2Seq 解码库。
OpenSeq2Seq (beam
)#
基于 CPU 的波束搜索引擎,非常高效,支持字符和子词模型。它需要提供字符/子词 KenLM 模型。
上面描述了此解码库的配置。
Flashlight (flashlight
)#
Flashlight 是一个 C++ 库,用于 ASR 解码,在 flashlight/flashlight 中提供。它是一个基于 CPU 和 CUDA 的波束搜索引擎,非常高效,支持字符和子词模型。它需要 ARPA KenLM 文件。
它支持多项高级功能,例如基于词典的解码、无词典解码、波束剪枝阈值等。
@dataclass
class FlashlightConfig:
lexicon_path: Optional[str] = None
boost_path: Optional[str] = None
beam_size_token: int = 16
beam_threshold: float = 20.0
unk_weight: float = -math.inf
sil_weight: float = 0.0
# Lexicon-based decoding
python eval_beamsearch_ngram_ctc.py ... \
decoding_strategy="flashlight" \
decoding.beam.flashlight_cfg.lexicon_path='/path/to/lexicon.lexicon' \
decoding.beam.flashlight_cfg.beam_size_token = 32 \
decoding.beam.flashlight_cfg.beam_threshold = 25.0
# Lexicon-free decoding
python eval_beamsearch_ngram_ctc.py ... \
decoding_strategy="flashlight" \
decoding.beam.flashlight_cfg.beam_size_token = 32 \
decoding.beam.flashlight_cfg.beam_threshold = 25.0
PyCTCDecode (pyctcdecode
)#
PyCTCDecode 是一个 Python 库,用于 ASR 解码,在 kensho-technologies/pyctcdecode 中提供。它是一个基于 CPU 的波束搜索引擎,对于纯 Python 库来说效率相当高,并且支持字符和子词模型。它需要提供字符/子词 KenLM ARPA/BINARY 模型。
它具有高级功能,例如单词提升,这对于转录定制非常有用。
@dataclass
class PyCTCDecodeConfig:
beam_prune_logp: float = -10.0
token_min_logp: float = -5.0
prune_history: bool = False
hotwords: Optional[List[str]] = None
hotword_weight: float = 10.0
# PyCTCDecoding
python eval_beamsearch_ngram_ctc.py ... \
decoding_strategy="pyctcdecode" \
decoding.beam.pyctcdecode_cfg.beam_prune_logp = -10. \
decoding.beam.pyctcdecode_cfg.token_min_logp = -5. \
decoding.beam.pyctcdecode_cfg.hotwords=[<List of str words>] \
decoding.beam.pyctcdecode_cfg.hotword_weight=10.0
超参数网格搜索#
带有 N-gram LM 的波束搜索解码具有三个主要超参数:beam_width、beam_alpha 和 beam_beta。模型的准确性取决于这些参数的值,特别是 beam_alpha 和 beam_beta。要执行网格搜索,您可以为每个参数指定一个值或值列表。在这种情况下,它将对这三个超参数的所有组合执行波束搜索解码。例如,以下参数集将导致 212=4 个波束搜索解码
python eval_beamsearch_ngram_ctc.py ... \
beam_width=[64,128] \
beam_alpha=[1.0] \
beam_beta=[1.0,0.5]
用于 Transducer 模型(RNNT 和 HAT)的波束搜索 ngram 解码#
您还可以找到一个类似的脚本,用于使用波束搜索解码和 N-gram 模型评估 RNNT/HAT 模型:scripts/asr_language_modeling/ngram_lm/eval_beamsearch_ngram_transducer.py
python eval_beamsearch_ngram_transducer.py nemo_model_file=<path to the .nemo file of the model> \
input_manifest=<path to the evaluation JSON manifest file \
kenlm_model_file=<path to the binary KenLM model> \
beam_width=[<list of the beam widths, separated with commas>] \
beam_alpha=[<list of the beam alphas, separated with commas>] \
preds_output_folder=<optional folder to store the predictions> \
probs_cache_file=null \
decoding_strategy=<greedy_batch or maes decoding>
maes_prefix_alpha=[<list of the maes prefix alphas, separated with commas>] \
maes_expansion_gamma=[<list of the maes expansion gammas, separated with commas>] \
hat_subtract_ilm=<in case of HAT model: subtract internal LM or not (True/False)> \
hat_ilm_weight=[<in case of HAT model: list of the HAT internal LM weights, separated with commas>] \
神经重打分#
当使用神经重打分方法时,神经网络用于对候选进行评分。候选是 ASR 模型解码器预测的文本转录。波束搜索解码(波束宽度为 K)生成的 Top K 个候选被提供给神经语言模型进行排名。语言模型为每个候选分配一个分数,该分数通常与波束搜索解码的分数相结合,以生成最终分数和排名。
训练神经重打分器#
使用 Transformer 训练此类语言模型的示例脚本可以在 examples/nlp/language_modeling/transformer_lm.py 中找到。它训练一个 TransformerLMModel
,可以用作 ASR 系统的神经重打分器。有关语言模型训练的完整文档,请访问
../nlp/language_modeling
您还可以使用 Hugging Face 库中的预训练语言模型,例如 Transformer-XL 和 GPT,而不是训练自己的模型。此脚本不支持 BERT 和 RoBERTa 等模型,因为它们被训练为掩码语言模型。因此,它们对于开箱即用地对句子进行评分效率不高或效果不佳。
评估#
给定训练好的 TransformerLMModel .nemo 文件或预训练的 HF 模型,可以使用 scripts/asr_language_modeling/neural_rescorer/eval_neural_rescorer.py 中提供的脚本来重新评分通过 ASR 模型获得的波束。您需要 .tsv 文件,其中包含声学模型和波束搜索解码生成的候选,才能使用此脚本。候选可以是仅波束搜索解码的结果,也可以是与 N-gram LM 融合的结果。您可以通过为 scripts/asr_language_modeling/ngram_lm/eval_beamsearch_ngram_ctc.py 指定 –preds_output_folder 来生成此文件。
神经重打分器将使用 rescorer_alpha 和 rescorer_beta 的两个参数来重新评分波束/候选,如下所示
final_score = beam_search_score + rescorer_alpha*neural_rescorer_score + rescorer_beta*seq_length
参数 rescorer_alpha 指定神经重打分器模型的重要性,而 rescorer_beta 是一个惩罚项,用于解释分数中的序列长度。这些参数与波束搜索解码器和 N-gram 语言模型中的 beam_alpha 和 beam_beta 具有类似的效果。
使用以下步骤评估神经 LM
获取包含波束及其对应分数的 .tsv 文件。分数可以来自常规波束搜索解码器,也可以与 N-gram LM 分数融合。对于给定的波束大小 beam_size 和评估示例的数量 num_eval_examples,它应包含 (num_eval_examples x beam_size) 行,格式为 beam_candidate_text t score。此文件可以由 scripts/asr_language_modeling/ngram_lm/eval_beamsearch_ngram_ctc.py 生成
通过 scripts/asr_language_modeling/neural_rescorer/eval_neural_rescorer.py 重新评分候选。
python eval_neural_rescorer.py
--lm_model=[path to .nemo file of the LM or the name of a HF pretrained model]
--beams_file=[path to beams .tsv file]
--beam_size=[size of the beams]
--eval_manifest=[path to eval manifest .json file]
--batch_size=[batch size used for inference on the LM model]
--alpha=[the value for the parameter rescorer_alpha]
--beta=[the value for the parameter rescorer_beta]
--scores_output_file=[the optional path to store the rescored candidates]
候选及其新分数存储在 –scores_output_file 指定的文件中。
以下是评估脚本的参数列表
参数 |
类型 |
默认值 |
描述 |
lm_model |
str |
必需 |
ASR 模型的 ‘.nemo’ 文件路径,或 Hugging Face 预训练模型的名称,如 ‘transfo-xl-wt103’ 或 ‘gpt2’。 |
eval_manifest |
str |
必需 |
评估清单文件(.json 清单文件)的路径。 |
beams_file |
str |
必需 |
包含候选及其分数的波束文件 (.tsv) 的路径。 |
beam_size |
int |
必需 |
解码器生成的波束宽度(候选数量)。 |
alpha |
float |
None |
参数 rescorer_alpha 的值。不传递值将启用 rescorer_alpha 的线性搜索。 |
beta |
float |
None |
参数 rescorer_beta 的值。不传递值将启用 rescorer_beta 的线性搜索。 |
batch_size |
int |
16 |
用于计算分数的批大小。 |
max_seq_length |
int |
512 |
输入的最大序列长度(以 token 为单位)。 |
scores_output_file |
str |
None |
用于存储重新评分波束的可选文件。 |
use_amp |
bool |
|
如果可用,是否使用 AMP 计算分数。 |
device |
str |
cuda |
将 LM 模型加载到其上以计算分数的设备。它可以是 ‘cpu’、‘cuda’、‘cuda:0’、‘cuda:1’ 等 |
超参数线性搜索#
超参数线性搜索脚本还支持对参数 alpha 和 beta 进行线性搜索。如果未提供这两个参数中的任何一个,则执行线性搜索以找到该参数的最佳值。当使用线性搜索时,最初将 beta 设置为零,并找到 alpha 的最佳值,然后使用该值固定 alpha,并进行另一次线性搜索以找到 beta 的最佳值。如果已指定这两个参数中的任何一个,则跳过对该参数的搜索。在每次搜索参数后,还会显示不同参数值的 WER% 图。
建议首先在验证集上对两个参数使用线性搜索,方法是不为 –alpha 和 –beta 提供任何值。然后检查 WER 曲线,并确定每个参数的最佳值。最后,在测试集上评估最佳值。
单词提升#
Flashlight 解码器支持在使用 KenLM 二进制文件和相应词典的 CTC 解码期间进行单词提升。单词提升仅在词典解码模式下有效,在无词典模式下不起作用。它允许您通过手动增加或减少发出特定单词的概率来偏置解码器以支持某些单词。如果您有不常见的或特定于行业的术语,并且希望确保正确转录这些术语,这将非常有用。
有关更多信息,请访问 word boosting
要在 NeMo 中使用单词提升,请创建一个简单的制表符分隔的文本文件。每行应包含要提升的单词,后跟一个制表符,然后是要提升的单词的分数。
例如
nvidia 40
geforce 50
riva 80
turing 30
badword -100
正分数会在 LM 解码步骤中将单词提升得更高,因此它们会更频繁地出现,而负分数会抑制单词,因此它们会更少地出现。建议的提升分数范围为 +/- 20 到 100。
提升文件可以很好地处理词汇表内单词和 OOV 单词,因此您可以指定 IV 和 OOV 单词以及相应的分数。
然后,您可以在解码期间将此文件传递给 Flashlight 配置对象
# Lexicon-based decoding
python eval_beamsearch_ngram_ctc.py ... \
decoding_strategy="flashlight" \
decoding.beam.flashlight_cfg.lexicon_path='/path/to/lexicon.lexicon' \
decoding.beam.flashlight_cfg.boost_path='/path/to/my_boost_file.boost' \
decoding.beam.flashlight_cfg.beam_size_token = 32 \
decoding.beam.flashlight_cfg.beam_threshold = 25.0
组合 N-gram 语言模型#
在组合 N-gram LM 之前,请使用 scripts/installers/install_opengrm.sh 安装所需的 OpenGrm NGram 库。或者,您可以使用 Docker 镜像 scripts/installers/Dockerfile.ngramtools,其中包含所有必要的依赖项。
或者,您可以使用以下位置的 Docker 镜像:scripts/asr_language_modeling/ngram_lm/ngram_merge.py,其中包括所有必要的依赖项。
此脚本插值两个 ARPA N-gram 语言模型,并创建一个 KenLM 二进制文件,该文件可以与 ASR 模型之上的波束搜索解码器一起使用。您可以为每个模型 (–ngram_a 和 –ngram_b) 分别指定权重 (–alpha 和 –beta):alpha * ngram_a + beta * ngram_b。此脚本支持字符级和 BPE 级编码和模型,这些编码和模型可以从模型类型中自动检测出来。
要组合两个 N-gram 模型,您可以使用以下命令
python ngram_merge.py --kenlm_bin_path <path to the bin folder of KenLM library> \
--ngram_bin_path <path to the bin folder of OpenGrm Ngram library> \
--arpa_a <path to the ARPA N-gram model file A> \
--alpha <weight of N-gram model A> \
--arpa_b <path to the ARPA N-gram model file B> \
--beta <weight of N-gram model B> \
--out_path <path to folder to store the output files>
如果您提供 –test_file 和 –nemo_model_file,则此脚本支持字符级和 BPE 级编码和模型,这些编码和模型会根据模型类型自动检测。请注意,该过程中每个步骤的结果都缓存在 –out_path 中的临时文件中,以加快进一步的运行速度。您可以使用 –force 标志来丢弃缓存并从头开始重新计算所有内容。
python ngram_merge.py --kenlm_bin_path <path to the bin folder of KenLM library> \
--ngram_bin_path <path to the bin folder of OpenGrm Ngram library> \
--arpa_a <path to the ARPA N-gram model file A> \
--alpha <weight of N-gram model A> \
--arpa_b <path to the ARPA N-gram model file B> \
--beta <weight of N-gram model B> \
--out_path <path to folder to store the output files>
--nemo_model_file <path to the .nemo file of the model> \
--test_file <path to the test file> \
--symbols <path to symbols (.syms) file> \
--force <flag to recalculate and rewrite all cached files>
以下是 opengrm 脚本的参数列表
参数 |
类型 |
默认值 |
描述 |
kenlm_bin_path |
str |
必需 |
KenLM 库的 bin 文件夹的路径。它是 KenLM 安装位置下的名为 bin 的文件夹。 |
ngram_bin_path |
str |
必需 |
OpenGrm Ngram 的 bin 文件夹的路径。它是 OpenGrm Ngram 安装位置下的名为 bin 的文件夹。 |
arpa_a |
str |
必需 |
ARPA N-gram 模型文件 A 的路径。 |
alpha |
float |
必需 |
N-gram 模型 A 的权重。 |
arpa_b |
int |
必需 |
ARPA N-gram 模型文件 B 的路径。 |
beta |
float |
必需 |
N-gram 模型 B 的权重。 |
out_path |
str |
必需 |
用于写入临时文件和结果文件的路径。 |
test_file |
str |
None |
如果提供,则为用于计算困惑度的测试文件的路径。 |
symbols |
str |
None |
符号 (.syms) 文件的路径。如果未提供,则可以计算。 |
nemo_model_file |
str |
None |
ASR 模型的 ‘.nemo’ 文件路径,或预训练 NeMo 模型的名称。 |
force |
bool |
|
是否重新编译和重写所有文件。 |
WFST CTC 解码#
加权有限状态转换器 (WFST) 是有限状态机,每个转换都带有输入和输出符号以及半环的一些权重元素。WFST 可以充当 N-gram LM,用于特殊类型的 LM 强制波束搜索,称为 WFST 解码。
注意
更准确地说,WFST 解码更像是一种带有 LM 的贪婪 N 深度搜索。因此,它在渐近性上比传统的波束搜索解码算法差,但速度更快。
警告 目前,NeMo 仅支持用于 CTC 模型和基于单词的 LM 的 WFST 解码。
要在 NeMo 中运行 WFST 解码,需要提供 NeMo ASR 模型以及 ARPA LM 或 WFST LM(高级)。ARPA LM 可以使用 KenLM 从源文本构建,如下所示:<kenlm_bin_path>/lmplz -o <ngram_length> --arpa <out_arpa_path> --prune <ngram_prune>
。
使用 WFST 解码和 N-gram 模型评估 ASR 模型的脚本可以在 scripts/asr_language_modeling/ngram_lm/eval_wfst_decoding_ctc.py 中找到。
此脚本有大量可能的参数覆盖,因此建议使用 python eval_wfst_decoding_ctc.py --help
来查看完整的参数列表。
您可以按如下方式评估 ASR 模型
python eval_wfst_decoding_ctc.py nemo_model_file=<path to the .nemo file of the model> \
input_manifest=<path to the evaluation JSON manifest file> \
arpa_model_file=<path to the ARPA LM model> \
decoding_wfst_file=<path to the decoding WFST file> \
beam_width=[<list of the beam widths, separated with commas>] \
lm_weight=[<list of the LM weight multipliers, separated with commas>] \
open_vocabulary_decoding=<whether to use open vocabulary mode for WFST decoding> \
decoding_mode=<decoding mode, affects output. Usually "nbest"> \
decoding_search_type=<WFST decoding library. Usually "riva"> \
preds_output_folder=<optional folder to store the predictions> \
probs_cache_file=null
注意
由于 WFST 解码是 LM 强制的(搜索在最宽的图上进行),因此只有 WFST 接受的单词序列才会出现在解码结果中。为了规避此限制,可以传递 open_vocabulary_decoding=true
(实验性功能)。
快速入门示例#
wget -O - https://www.openslr.org/resources/11/3-gram.pruned.1e-7.arpa.gz | \
gunzip -c | tr '[:upper:]' '[:lower:]' > 3-gram.pruned.1e-7.arpa && \
python eval_wfst_decoding_ctc.py nemo_model_file="stt_en_conformer_ctc_small_ls" \
input_manifest="<data_dir>/Librispeech/test_other.json" \
arpa_model_file="3-gram.pruned.1e-7.arpa" \
decoding_wfst_file="3-gram.pruned.1e-7.fst" \
beam_width=[8] \
lm_weight=[0.5,0.6,0.7,0.8,0.9]
注意
构建解码 WFST 是一个漫长的过程,因此最好提供 decoding_wfst_file
路径,即使您没有它也是如此。这样,解码 WFST 将被缓冲到指定的文件路径,并且下次运行时无需重新构建它。
无外部 LM 的上下文偏置(单词提升)#
NeMo 工具包支持用于 CTC 和 Transducer (RNN-T) ASR 模型与基于 CTC 的单词识别器的快速上下文偏置方法。该方法涉及使用为上下文偏置列表中的单词和短语构建的上下文图解码 CTC 对数概率。将识别出的上下文偏置候选(及其分数和时间间隔)与来自贪婪 CTC 解码结果的单词按分数进行比较,以提高识别准确性并避免错误接受上下文偏置。
混合 Transducer-CTC 模型(与 CTC 和 Transducer 输出头一起训练的共享编码器)使 CTC-WS 方法能够用于 Transducer 模型。通过 CTC-WS 获得的上下文偏置候选也通过贪婪 CTC 预测的分数进行过滤,然后与贪婪 Transducer 结果合并。
CTC-WS 方法的方案

使用 CTC-WS 方法替换上下文偏置单词的高级概述

有关 CTC-WS 上下文偏置的更多详细信息,请参见 tutorial。
要使用 CTC-WS 上下文偏置,您需要创建一个上下文偏置文本文件,其中包含要提升的单词/短语,其转录(拼写)用下划线分隔。对于缩写词(“gpu” -> “g p u”)、复合词(“nvlink” -> “nv link”)或在我们的 ASR 模型中常见错误的单词(“nvidia” -> “n video”),多个转录可能很有用。
上下文偏置文件的示例
nvidia_nvidia
omniverse_omniverse
gpu_gpu_g p u
dgx_dgx_d g x_d gx
nvlink_nvlink_nv link
ray tracing_ray tracing
NeMo 中用于 CTC-WS 上下文偏置的主要脚本是
{NEMO_DIR_PATH}/scripts/asr_context_biasing/eval_greedy_decoding_with_context_biasing.py
上下文偏置由 apply_context_biasing
参数 [true 或 false] 管理。其他重要的上下文偏置参数包括
beam_threshold
- CTC-WS 波束剪枝的阈值。context_score
- 每个 token 的上下文偏置权重。ctc_ali_token_weight
- 每个 token 的 CTC 对齐权重(防止错误地接受上下文偏置词)。
所有上下文偏置参数都根据脚本中的默认值选择。您可以根据您的数据和 ASR 模型调整它们(在 [] 中列出所有值,以逗号分隔),例如:beam_threshold=[7.0,8.0,9.0]
, context_score=[3.0,4.0,5.0]
, ctc_ali_token_weight=[0.5,0.6,0.7]
。脚本将运行所有参数组合的识别,并将根据 WER 值选择最佳组合。
# Context-biasing with the CTC-WS method for CTC ASR model
python {NEMO_DIR_PATH}/scripts/asr_context_biasing/eval_greedy_decoding_with_context_biasing.py \
nemo_model_file={ctc_model_name} \
input_manifest={test_nemo_manifest} \
preds_output_folder={exp_dir} \
decoder_type="ctc" \
acoustic_batch_size=64 \
apply_context_biasing=true \
context_file={cb_list_file_modified} \
beam_threshold=[7.0] \
context_score=[3.0] \
ctc_ali_token_weight=[0.5]
要使用混合 Transducer-CTC 模型的 Transducer head,您需要设置 decoder_type=rnnt
。