WeNet 之前实现的热词方案为基于规则的热词增强,即在解码过程中匹配到热词列表中的词时,给予该解码路径一定的奖励,这样含热词的搜索路径概率更大,更容易被识别出来。详见:
虽然该方案在一般情况下也能有不错的处理能力,但对于训练中少见或没有见过的词即 rare word 的识别效果却非常很差。本质上因为该方法为浅融合(shadow fusion,或者后融合)的热词方案,在训练中没有见过,很难预测出来,在解码候选路径中根本没有出现,所以再怎么奖励也无济于事。而下文介绍的神经网络的热词则为深融合(deep fusion,或者前融合)则可以非常有效的解决 rare word 的问题,同时在常见热词识别也有更好的效果。
热词编码器(Bias Encoder):通过 RNN 对热词信息进行编码,将不等长的热词编码为相同维度的热词嵌入。 热词偏置层(Attention):包含一个多头注意力层,使用音频编码作为 Query,热词编码作为 Key 和 Value,查询与当前音频相关的热词,提取热词感知编码。


热词编码器(Context Encoder):我们使用 BLSTM 作为热词编码器对热词短语进行编码。 热词偏置层(Biasing Layer):如图(b)所示,查询与当前音频相关的热词,提取热词感知编码。 组合器(Combiner):拼接音频编码与热词感知编码,并通过一个线性层集成信息。 热词短语预测网络(CPP Network):如图(a)所示,包含两个线性层,其中第二个线性层与 Encoder 的 CTC 线性层共享参数。热词短语预测网络使用热词感知编码作为输入,对语句中包含的热词短语进行预测,并使用 CTC 损失监督训练。例如对于语句标签为“我想去西工大学习语音识别”,如果“西工大”和“语音识别”是热词,则热词短语预测网络的标签为“西工大语音识别”。
1、大部分热词增强模块的实现都位于 transformer/context_module.py 中,我们在 ContextModule 类中分别声明了热词编码器、热词偏置层、组合器、热词短语预测网络,以及增强任务的 CTC 损失。相比于论文中的实现,在此处我们将组合器替换为了更加简单的通过一个线性层后直接与音频编码相加的形式,这样能使 ASR 模型与热词模块更加解耦,并且经测试效果基本没有区别。并且我们还额外设置了一个热词增强权重用于控制热词增强的程度,热词感知编码先会与该权重相乘后再与音频编码相加。
class ContextModule(torch.nn.Module):
"""Context module, Using context information for deep contextual bias
During the training process, the original parameters of the ASR model
are frozen, and only the parameters of context module are trained.
Args:
vocab_size (int): vocabulary size
embedding_size (int): number of ASR encoder projection units
encoder_layers (int): number of context encoder layers
attention_heads (int): number of heads in the biasing layer
"""
def __init__(
self,
vocab_size: int,
embedding_size: int,
encoder_layers: int = 2,
attention_heads: int = 4,
dropout_rate: float = 0.0,
):
super().__init__()
self.embedding_size = embedding_size
self.encoder_layers = encoder_layers
self.vocab_size = vocab_size
self.attention_heads = attention_heads
self.dropout_rate = dropout_rate
# 热词编码器
self.context_extractor = BLSTM(self.vocab_size, self.embedding_size,
self.encoder_layers)
self.context_encoder = nn.Sequential(
nn.Linear(self.embedding_size * 4, self.embedding_size),
nn.LayerNorm(self.embedding_size)
)
# 热词偏置层
self.biasing_layer = MultiHeadedAttention(
n_head=self.attention_heads,
n_feat=self.embedding_size,s
dropout_rate=self.dropout_rate
)
# 组合器
self.combiner = nn.Linear(self.embedding_size, self.embedding_size)
self.norm_aft_combiner = nn.LayerNorm(self.embedding_size)
# 热词短语预测网络
self.context_decoder = nn.Sequential(
nn.Linear(self.embedding_size, self.embedding_size),
nn.LayerNorm(self.embedding_size),
nn.ReLU(inplace=True),
)
self.context_decoder_ctc_linear = nn.Linear(self.embedding_size,
self.vocab_size)
# 热词 CTC 损失
self.bias_loss = torch.nn.CTCLoss(reduction="sum", zero_infinity=True) 2、我们将热词短语筛选部分的代码放到了 /utils/context_graph.py 中实现,该文件原本负责实现基于解码图的热词增强,包含有解码时所用的热词列表的信息,因此适合在此处进行热词短语筛选并将 tensor 形式的热词列表传递给热词增强模块。
class ContextGraph:
def get_context_list_tensor(self, context_list: List[List[int]]):
"""Add 0 as no-bias in the context list and obtain the tensor
form of the context list
"""
def two_stage_filtering(self,
context_list: List[List[int]],
ctc_posterior: torch.Tensor,
filter_window_size: int = 64):
"""Calculate PSC and SOC for context phrase filtering,
refer to: https://arxiv.org/abs/2301.06735
"""
def context_sampling(data,
symbol_table,
len_min,
len_max,
utt_num_context,
batch_num_context,
):
"""Perform context sampling by randomly selecting context phrases from the
utterance to obtain a context list for the entire batch
Args:
data: Iterable[List[{key, feat, label}]]
Returns:
Iterable[List[{key, feat, label, context_list}]]
"""
def context_label_generate(label, context_list):
""" Generate context labels corresponding to the utterances based on
the context list
""" 实验结果
我们在 Librispeech test other 测试集上进行测试,使用 [9] 中给出的热词列表,热词列表可以从该链接获取:
https://github.com/facebookresearch/fbai-speech/tree/main/is21_deep_bias
我们使用 WeNet 开源的 Librispeech 预训练 AED 模型进行实验,冻结原本 ASR 模型的参数,仅对热词增强模块训练 30 epoch 后取 3 个 epoch 平均得到的模型作为结果。在训练时,需要关闭 use_dynamic_chunk 流式训练选项,开启该选项会使得热词增强效果变差。经过测试非流式训练得到的模型对非流式和流式解码具有基本一致的热词增强性能。
训练好的热词增强模型可以从该链接下载:
https://huggingface.co/kxhuang/Wenet_Librispeech_deep_biasing/tree/main
除了词错误率 (WER) 之外,我们分别使用 U-WER 和 B-WER 来评估非热词部分与热词部分的字错误率,实验的结果如下。
| Method | List size | Graph score | Biasing score | WER | U-WER | B-WER |
|---|---|---|---|---|---|---|
| baseline | / | / | / | 8.77 | 5.58 | 36.84 |
| context graph | 3838 | 3.0 | / | 7.75 | 5.83 | 24.62 |
| CPPN | 3838 | / | 1.5 | 7.93 | 5.92 | 25.64 |
| context graph + CPPN | 3838 | 2.0 | 1.0 | 7.66 | 6.08 | 21.48 |
| context graph | 100 | 3.0 | / | 7.32 | 5.45 | 23.70 |
| CPPN | 100 | / | 2.0 | 7.08 | 5.33 | 22.41 |
| context graph + CPPN | 100 | 2.5 | 1.5 | 6.55 | 5.33 | 17.27 |
表中 context graph 表示 WeNet 中基于解码图的热词增强方法。在使用较大热词列表(3838)的情况下,基于解码图的方法效果较好,而使用较小热词列表(100)的情况下,CPPN 的增强效果则更好。而无论热词列表大小,以合理的增强权重和分数同时使用两种方法时都能够取得比单一方法更好的效果。
热词列表(3838)的情况下,基于解码图的方法效果较好,而使用较小热词列表(100)的情况下,CPPN 的增强效果则更好。而无论热词列表大小,以合理的增强权重和分数同时使用两种方法时都能够取得比单一方法更好的效果。
小热词列表实验同时还表现出了非热词部分 WER 下降的情况,这是由于经过热词增强,模型在波束搜索时能够选择到包含正确热词并且非热词部分更加准确的路径。
流式推理 (chunk 16):
| Method | List size | Graph score | Biasing score | WER | U-WER | B-WER |
|---|---|---|---|---|---|---|
| baseline | / | / | / | 10.47 | 7.07 | 40.30 |
| context graph | 100 | 3.0 | / | 9.06 | 6.99 | 27.21 |
| CPPN | 100 | / | 2.0 | 8.86 | 6.87 | 26.28 |
| context graph + CPPN | 100 | 2.5 | 1.5 | 8.17 | 6.85 | 19.72 |
在流式推理的结果中,使用CPPN也有显著的 B-WER 改进,与非流式推理热词增强效果基本一致。
[1] Kaixun Huang, Ao Zhang, Zhanheng Yang, Pengcheng Guo, Bingshen Mu, Tianyi Xu, Lei Xie: Contextualized End-to-End Speech Recognition with Contextual Phrase Prediction Network. INTERSPEECH 2023
[2] Golan Pundak, Tara N. Sainath, Rohit Prabhavalkar, Anjuli Kannan, Ding Zhao: Deep Context: End-to-end Contextual Speech Recognition. SLT 2018
[3] Mahaveer Jain, Gil Keren, Jay Mahadeokar, Geoffrey Zweig, Florian Metze, Yatharth Saraf: Contextual RNN-T for Open Domain ASR. INTERSPEECH 2020
[4] Minglun Han, Linhao Dong, Shiyu Zhou, Bo Xu: Cif-Based Collaborative Decoding for End-to-End Contextual Speech Recognition. ICASSP 2021
[5] Guangzhi Sun, Chao Zhang, Philip C. Woodland: Tree-Constrained Pointer Generator for End-to-End Contextual Speech Recognition. ASRU 2021
[6] Tsendsuren Munkhdalai, Khe Chai Sim, Angad Chandorkar, Fan Gao, Mason Chua, Trevor Strohman, Françoise Beaufays: Fast Contextual Adaptation with Neural Associative Memory for On-Device Personalized Speech Recognition. ICASSP 2022
[7] Feng-Ju Chang, Jing Liu, Martin Radfar, Athanasios Mouchtaris, Maurizio Omologo, Ariya Rastrow, Siegfried Kunzmann:
Context-Aware Transformer Transducer for Speech Recognition. ASRU 2021 [8] Zhanheng Yang, Sining Sun, Xiong Wang, Yike Zhang, Long Ma, Lei Xie: Two Stage Contextual Word Filtering for Context bias in Unified Streaming and Non-streaming Transducer. INTERSPEECH 2023
[9] Duc Le, Mahaveer Jain, Gil Keren, Suyoun Kim, Yangyang Shi, Jay Mahadeokar, Julian Chan, Yuan Shangguan, Christian Fuegen, Ozlem Kalinli, Yatharth Saraf, Michael L. Seltzer: Contextualized Streaming End-to-End Speech Recognition with Trie-Based Deep Biasing and Shallow Fusion. INTERSPEECH 2021
