speechbrain.decoders.ctc 模块
CTC 的解码器和输出归一化。
- 作者
Mirco Ravanelli 2020
Aku Rouhe 2020
Sung-Lin Yeh 2020
Adel Moumen 2023, 2024
总结
类
CTCBaseSearcher 类,供其他 CTC 束搜索器继承。 |
|
此类在解码期间处理 CTC 束信息。 |
|
CTC Beam Search 是一种 CTC 的束搜索,它不跟踪空白和非空白概率。 |
|
此类是生成假设的数据处理程序。 |
|
CTC Prefix Beam Search 基于 Awni Y. 的论文 |
|
此类实现了参考文献 https://www.merl.com/publications/docs/TR2017-190.pdf 中算法 2 的 CTC 前缀分数。官方实现:https://github.com/espnet/espnet/blob/master/espnet/nets/ctc_prefix_score.py |
|
此类在解码期间处理 LM 分数。 |
|
TorchAudio CTC 前缀束搜索解码器。 |
函数
贪婪解码一批概率并应用 CTC 规则。 |
|
应用 CTC 输出合并和过滤规则。 |
参考
- class speechbrain.decoders.ctc.CTCPrefixScore(x, enc_lens, blank_index, eos_index, ctc_window_size=0)[source]
基类:
object
此类实现了参考文献 https://www.merl.com/publications/docs/TR2017-190.pdf 中算法 2 的 CTC 前缀分数。官方实现:https://github.com/espnet/espnet/blob/master/espnet/nets/ctc_prefix_score.py
- 参数:
- forward_step(inp_tokens, states, candidates=None, attn=None)[source]
此方法是前缀 ctc 评分器的一次前向操作步骤。
- 参数:
inp_tokens (torch.Tensor) – 前缀标签序列 g 的最后一个字符,其中 h = g + c。
states (tuple) – 先前的 ctc 状态。
candidates (torch.Tensor) – (batch_size * beam_size, ctc_beam_size),用于重新评分的 topk 候选。如果给定,则执行部分 ctc 评分。
attn (torch.Tensor) – (batch_size * beam_size, max_enc_len),注意力权重。
- 返回:
new_psi (torch.Tensor)
(r, psi, scoring_table) (tuple)
- speechbrain.decoders.ctc.filter_ctc_output(string_pred, blank_id=-1)[source]
应用 CTC 输出合并和过滤规则。
移除空白符号和输出重复。
- 参数:
- 返回:
CTC 预测的输出,不包含空白符号和重复项。
- 返回类型:
示例
>>> string_pred = ['a','a','blank','b','b','blank','c'] >>> string_out = filter_ctc_output(string_pred, blank_id='blank') >>> print(string_out) ['a', 'b', 'c']
- speechbrain.decoders.ctc.ctc_greedy_decode(probabilities, seq_lens, blank_id=-1)[source]
贪婪解码一批概率并应用 CTC 规则。
- 参数:
probabilities (torch.tensor) – 网络输出的概率(或对数概率),形状为 [batch, lengths, probabilities]
seq_lens (torch.tensor) – 相对真实序列长度(用于处理填充输入),最长序列长度为 1.0,其他序列长度在零和一之间,形状为 [batch, lengths]。
blank_id (int, string) – 空白符号/索引。默认值:-1。如果给定负数,则假定其表示从最大可能索引向下计数,因此 -1 指代最大可能索引。
- 返回:
输出为 Python 列表的列表,具有“不规则”维度;填充已被移除。
- 返回类型:
示例
>>> import torch >>> probs = torch.tensor([[[0.3, 0.7], [0.0, 0.0]], ... [[0.2, 0.8], [0.9, 0.1]]]) >>> lens = torch.tensor([0.51, 1.0]) >>> blank_id = 0 >>> ctc_greedy_decode(probs, lens, blank_id) [[1], [1]]
- class speechbrain.decoders.ctc.CTCBeam(text: str, full_text: str, next_word: str, partial_word: str, last_token: str | None, last_token_index: int | None, text_frames: List[Tuple[int, int]], partial_frames: Tuple[int, int], p: float = -inf, p_b: float = -inf, p_nb: float = -inf, n_p_b: float = -inf, n_p_nb: float = -inf, score: float = -inf, score_ctc: float = -inf)[source]
基类:
object
此类在解码期间处理 CTC 束信息。
- 参数:
text (str) – 当前 beam 的文本。
full_text (str) – 当前 beam 的完整文本。
next_word (str) – 将要添加到 beam 的下一个词。
partial_word (str) – 正在添加到 beam 的部分词。
last_token (str, optional) – 当前 beam 的最后一个 token。
last_token_index (int, optional) – 当前 beam 最后一个 token 的索引。
p (float) – 当前 beam 的概率。
p_b (float) – 当前 beam 以 blank 结尾的概率。
p_nb (float) – 当前 beam 不以 blank 结尾的概率。
n_p_b (float) – 当前 beam 之前以 blank 结尾的概率。
n_p_nb (float) – 当前 beam 之前不以 blank 结尾的概率。
score (float) – 当前 beam 的得分 (LM + CTC)
score_ctc (float) – 计算得到的 CTC 得分。
示例
>>> beam = CTCBeam( ... text="", ... full_text="", ... next_word="", ... partial_word="", ... last_token=None, ... last_token_index=None, ... text_frames=[(0, 0)], ... partial_frames=(0, 0), ... p=-math.inf, ... p_b=-math.inf, ... p_nb=-math.inf, ... n_p_b=-math.inf, ... n_p_nb=-math.inf, ... score=-math.inf, ... score_ctc=-math.inf, ... )
- class speechbrain.decoders.ctc.LMCTCBeam(text: str, full_text: str, next_word: str, partial_word: str, last_token: str | None, last_token_index: int | None, text_frames: List[Tuple[int, int]], partial_frames: Tuple[int, int], p: float = -inf, p_b: float = -inf, p_nb: float = -inf, n_p_b: float = -inf, n_p_nb: float = -inf, score: float = -inf, score_ctc: float = -inf, lm_score: float = -inf)[source]
继承自:
CTCBeam
此类在解码期间处理 LM 分数。
- 参数:
lm_score (float) – 当前 beam 的语言模型得分。
**kwargs – 其他参数参见 CTCBeam。
- class speechbrain.decoders.ctc.CTCHypothesis(text: str, last_lm_state: None, score: float, lm_score: float, text_frames: list | None = None)[source]
基类:
object
此类是生成假设的数据处理程序。
这个类是 CTC beam searcher 的默认输出。
如果以在线方式使用 beam searcher,可以复用于其他解码器。
- 参数:
- class speechbrain.decoders.ctc.CTCBaseSearcher(blank_index: int, vocab_list: List[str], space_token: str = ' ', kenlm_model_path: None | str = None, unigrams: None | list[str] | set[str] = None, alpha: float = 0.5, beta: float = 1.5, unk_score_offset: float = -10.0, score_boundary: bool = True, beam_size: int = 100, beam_prune_logp: float = -10.0, token_prune_min_logp: float = -5.0, prune_history: bool = True, blank_skip_threshold: float = 1.0, topk: int = 1, spm_token: str = ' ')[source]
继承自:
Module
CTCBaseSearcher 类,供其他 CTC 束搜索器继承。
该类提供了 CTC beam search 解码的基本功能。
如果你的转录文本预计包含空格,并且使用的词汇列表不是 SentencePiece 生成的,则需要 space_token。
- 参数:
blank_index (int) – 空白标记的索引。
vocab_list (list) – 词汇 token 的列表。
space_token (int, optional) – 空格 token 的索引。(默认值: -1)
kenlm_model_path (str, optional) – kenlm 模型的路径。使用 .bin 文件可以更快加载。如果为 None,则不会使用语言模型。(默认值: None)
unigrams (list, optional) – 已知的词 unigram 列表。(默认值: None)
alpha (float) – 浅层融合期间语言模型的权重。(默认值: 0.5)
beta (float) – 打分期间长度得分调整的权重。(默认值: 1.5)
unk_score_offset (float) – 未知 token 的对数得分偏移量。(默认值: -10.0)
score_boundary (bool) – 打分时 kenlm 是否遵循边界。(默认值: True)
beam_size (int, optional) – beam 的宽度。(默认值: 100)
beam_prune_logp (float, optional) – beam 的剪枝阈值。(默认值: -10.0)
token_prune_min_logp (float, optional) – token 的剪枝阈值。(默认值: -5.0)
prune_history (bool, optional) – 是否剪枝历史。(默认值: True)注意:当 topk > 1 时,应将其设置为 False,因为它会剪枝很多 beam。
blank_skip_threshold (float, optional) – 如果 log_prob(blank) > log(blank_skip_threshold),则跳过帧,以加速解码。注意:这仅在使用 CUDA 解码器时有效,并且可能会恶化 WER/CER 结果。请自行承担风险。(默认值: 1.0)
topk (int, optional) – 返回的 top k 假设数量。(默认值: 1)
spm_token (str, optional) – sentencepiece token。(默认值: " ")
示例
>>> blank_index = 0 >>> vocab_list = ['blank', 'a', 'b', 'c', ' '] >>> space_token = ' ' >>> kenlm_model_path = None >>> unigrams = None >>> beam_size = 100 >>> beam_prune_logp = -10.0 >>> token_prune_min_logp = -5.0 >>> prune_history = True >>> blank_skip_threshold = 1.0 >>> topk = 1 >>> searcher = CTCBaseSearcher( ... blank_index=blank_index, ... vocab_list=vocab_list, ... space_token=space_token, ... kenlm_model_path=kenlm_model_path, ... unigrams=unigrams, ... beam_size=beam_size, ... beam_prune_logp=beam_prune_logp, ... token_prune_min_logp=token_prune_min_logp, ... prune_history=prune_history, ... blank_skip_threshold=blank_skip_threshold, ... topk=topk, ... )
- partial_decoding(log_probs: Tensor, beams: List[CTCBeam], cached_lm_scores: dict, cached_p_lm_scores: dict, processed_frames: int = 0)[source]
执行解码的单个步骤。
- finalize_decoding(beams: List[CTCBeam], cached_lm_scores: dict, cached_p_lm_scores: dict, force_next_word=False, is_end=False) List[CTCBeam] [source]
通过添加并对最后一个部分词进行打分来完成解码过程。
- decode_beams(log_probs: Tensor, wav_lens: Tensor | None = None, lm_start_state: Any = None) List[List[CTCHypothesis]] [source]
解码 CTC 输出的输入对数概率。
它会自动将 SpeechBrain 的 wav 输入相对长度转换为绝对长度。
请确保输入处于对数域。解码器无法解码 logits 或概率。输入应为 CTC 输出的对数概率。
- __call__(log_probs: Tensor, wav_lens: Tensor | None = None, lm_start_state: Any = None) List[List[CTCHypothesis]] [source]
解码 CTC 输出的对数概率。
它会自动将 SpeechBrain 的 wav 输入相对长度转换为绝对长度。
每个张量都被转换为 numpy 和 CPU,因为它更快且占用内存更少。
- partial_decode_beams(log_probs: Tensor, cached_lm_scores: dict, cached_p_lm_scores: dict, beams: List[CTCBeam], processed_frames: int, force_next_word=False, is_end=False) List[CTCBeam] [source]
执行解码的单个步骤。
- 参数:
- 返回:
CTCBeam 列表。
- 返回类型:
- class speechbrain.decoders.ctc.CTCBeamSearcher(blank_index: int, vocab_list: List[str], space_token: str = ' ', kenlm_model_path: None | str = None, unigrams: None | list[str] | set[str] = None, alpha: float = 0.5, beta: float = 1.5, unk_score_offset: float = -10.0, score_boundary: bool = True, beam_size: int = 100, beam_prune_logp: float = -10.0, token_prune_min_logp: float = -5.0, prune_history: bool = True, blank_skip_threshold: float = 1.0, topk: int = 1, spm_token: str = ' ')[source]
继承自:
CTCBaseSearcher
CTC Beam Search 是一种 CTC 的 Beam Search 方法,它不跟踪 blank 和 non-blank 概率。每个新 token 的概率都被添加到总得分中,并且共享相同文本的 beam 会合并在一起。
该实现支持对单词和 SentencePiece token 进行 n-gram 打分。输入应为形状为 [batch, time, vocab_size] 的对数概率张量。
CTCBeamSearcher 相较于 CTCPrefixBeamSearcher 的主要优势在于它相对更快,并且可以获得稍好的结果。然而,该实现基于 PyCTCDecode 工具包中的实现,并针对 SpeechBrain 的需求进行了调整,并未遵循特定的论文。如果你想引用与解码方法相关的适当论文,我们确实推荐使用 CTCPrefixBeamSearcher。
实现了一些启发式方法来加速解码过程: - beam 剪枝:如果 beam 的得分低于
最佳 beam 得分减去 beam_prune_logp,则进行剪枝
- token 剪枝如果 token 的得分低于
token_prune_min_logp,则进行剪枝
- 历史剪枝如果 beam 在
max_ngram 历史中是相同的,则进行剪枝
- blank 跳过如果 blank 概率
高于 blank_skip_threshold,则跳过帧
注意:如果声学模型未训练,Beam Search 将花费大量时间。我们确实建议在验证期间使用 Greedy Search,直到模型完全训练好并准备好在测试集上进行评估。
- 参数:
CTCBaseSearcher (参见)
passed. (参数直接)
示例
>>> import torch >>> from speechbrain.decoders import CTCBeamSearcher >>> probs = torch.tensor([[[0.2, 0.0, 0.8], ... [0.4, 0.0, 0.6]]]) >>> log_probs = torch.log(probs) >>> lens = torch.tensor([1.0]) >>> blank_index = 2 >>> vocab_list = ['a', 'b', '-'] >>> searcher = CTCBeamSearcher(blank_index=blank_index, vocab_list=vocab_list) >>> hyps = searcher(probs, lens)
- get_lm_beams(beams: List[CTCBeam], cached_lm_scores: dict, cached_partial_token_scores: dict, is_eos=False) List[LMCTCBeam] [source]
如果语言模型不为 None,则使用语言模型对 beam 进行打分,并返回新的 beam。
此函数修改并改编自 https://github.com/kensho-technologies/pyctcdecode
- class speechbrain.decoders.ctc.CTCPrefixBeamSearcher(blank_index: int, vocab_list: List[str], space_token: str = ' ', kenlm_model_path: None | str = None, unigrams: None | list[str] | set[str] = None, alpha: float = 0.5, beta: float = 1.5, unk_score_offset: float = -10.0, score_boundary: bool = True, beam_size: int = 100, beam_prune_logp: float = -10.0, token_prune_min_logp: float = -5.0, prune_history: bool = True, blank_skip_threshold: float = 1.0, topk: int = 1, spm_token: str = ' ')[source]
继承自:
CTCBaseSearcher
CTC 前缀波束搜索基于 Awni Y. Hannun 等人的论文《First-Pass Large Vocabulary Continuous Speech Recognition using Bi-Directional Recurrent DNNs》(https://arxiv.org/abs/1408.2873)。
此实现会跟踪空白和非空白概率。它还支持对单词和 SentencePiece tokens 进行 n-gram 评分。输入应为形状为 [batch, time, vocab_size] 的对数概率张量。
实现了一些启发式方法来加速解码过程: - beam 剪枝:如果 beam 的得分低于
最佳 beam 得分减去 beam_prune_logp,则进行剪枝
- token 剪枝如果 token 的得分低于
token_prune_min_logp,则进行剪枝
- 历史剪枝如果 beam 在
max_ngram 历史中是相同的,则进行剪枝
- blank 跳过如果 blank 概率
高于 blank_skip_threshold,则跳过帧
注意:CTCPrefixBeamSearcher 可能比 CTCBeamSearcher 或 TorchAudioCTCPrefixBeamSearcher 搜索器更不稳定。请谨慎使用并仔细检查结果。
注意:如果声学模型未训练,Beam Search 将花费大量时间。我们确实建议在验证期间使用 Greedy Search,直到模型完全训练好并准备好在测试集上进行评估。
注意:此实现不提供假设的时间对齐。如果需要,请使用 CTCBeamSearcher。
- 参数:
CTCBaseSearcher (参见)
passed. (参数直接)
示例
>>> import torch >>> from speechbrain.decoders import CTCPrefixBeamSearcher >>> probs = torch.tensor([[[0.2, 0.0, 0.8], ... [0.4, 0.0, 0.6]]]) >>> log_probs = torch.log(probs) >>> lens = torch.tensor([1.0]) >>> blank_index = 2 >>> vocab_list = ['a', 'b', '-'] >>> searcher = CTCPrefixBeamSearcher(blank_index=blank_index, vocab_list=vocab_list) >>> hyps = searcher(probs, lens)
- get_lm_beams(beams: List[CTCBeam], cached_lm_scores: dict, cached_partial_token_scores: dict, is_eos=False) List[LMCTCBeam] [source]
如果语言模型不为 None,则使用语言模型对 beam 进行打分,并返回新的 beam。
此函数修改并改编自 https://github.com/kensho-technologies/pyctcdecode
- class speechbrain.decoders.ctc.TorchAudioCTCPrefixBeamSearcher(tokens: list | str, lexicon: str | None = None, lm: str | None = None, lm_dict: str | None = None, topk: int = 1, beam_size: int = 50, beam_size_token: int | None = None, beam_threshold: float = 50, lm_weight: float = 2, word_score: float = 0, unk_score: float =-inf, sil_score: float =0, log_add: bool =False, blank_index: str | int =0, sil_index: str | int =0, unk_word: str ='<unk>', using_cpu_decoder: bool =True, blank_skip_threshold: float =1.0)[source]
基类:
object
TorchAudio CTC 前缀束搜索解码器。
此类是 TorchAudio 中 CTC 解码器的封装。它提供了一个简单的接口,可以使用 CPU 或 CUDA CTC 解码器。
CPU 解码器较慢但使用的内存较少。CUDA 解码器较快但使用的内存较多。CUDA 解码器也仅在 torchaudio 的 nightly 版本中可用。
CUDA 解码器缺少许多功能,例如使用语言模型、约束搜索等。如果想使用这些功能,必须使用 CPU 解码器。
有关 CPU 解码器的更多信息,请参阅 TorchAudio 文档:https://pytorch.ac.cn/audio/main/generated/torchaudio.models.decoder.ctc_decoder.html
有关 CUDA 解码器的更多信息,请参阅 TorchAudio 文档:https://pytorch.ac.cn/audio/main/generated/torchaudio.models.decoder.cuda_ctc_decoder.html#torchaudio.models.decoder.cuda_ctc_decoder
如果想使用语言模型或词汇表搜索,请确保你的分词器/声学模型使用与语言模型/词汇表相同的 tokens。否则,解码将失败。
此实现与 SentencePiece Tokens 兼容。
注意:使用 CUDA CTC 解码器时,blank_index 必须为 0。此外,使用 CUDA CTC 解码器需要 torchaudio 的 nightly 版本以及大量的 VRAM 内存(如果想使用很多波束)。总的来说,如果想使用 n-gram + 波束搜索解码,我们建议使用 SpeechBrain 中的 CTCBeamSearcher 或 CTCPrefixBeamSearcher。如果想进行约束搜索,请使用 torchaudio 的 CPU 版本;如果想尽可能加快解码速度,请使用 CUDA 版本。
- 参数:
tokens (list 或 str) – tokens 列表或 tokens 文件的路径。如果这是一个路径,则文件应包含每行一个 token。
lexicon (str, 默认值: None) – 包含可能单词及其对应拼写的词汇表文件。每行包含一个单词及其用空格分隔的拼写。如果为 None,则使用无词汇表解码。(默认值:None)
lm (str, 可选) – 包含 KenLM 语言模型的路径;如果未使用语言模型,则为 None。(默认值:None)
lm_dict (str, 可选) – 包含用于 LM 的字典的文件,每行一个单词,按 LM 索引排序。如果使用词汇表进行解码,lm_dict 中的条目也必须出现在词汇表文件中。如果为 None,则使用词汇表文件构建 LM 的字典。(默认值:None)
topk (int, 可选) – 返回的顶级 CTCHypothesis 数量。(默认值:1)
beam_size (int, 可选) – 每个解码步骤后保留的假设数量。(默认值:50)
beam_size_token (int | None, 可选) – 在每个解码步骤中考虑的最大 tokens 数量。如果为 None,则设置为 tokens 总数。(默认值:None)
beam_threshold (float, 可选) – 用于剪枝假设的阈值。(默认值:50)
lm_weight (float, 可选) – 语言模型的权重。(默认值:2)
word_score (float, 可选) – 单词插入分数。(默认值:0)
unk_score (float, 可选) – 未知词插入分数。(默认值:float("-inf"))
sil_score (float, 可选) – 静音插入分数。(默认值:0)
log_add (bool, 可选) – 合并假设时是否使用 logadd。(默认值:False)
blank_index (int 或 str, 可选) – 空格 token 的索引。如果 tokens 是文件路径,则应为 str。否则,应为 int。(默认值:0)
sil_index (int 或 str, 可选) – 静音 token 的索引。如果 tokens 是文件路径,则应为 str。否则,应为 int。(默认值:0)
unk_word (str, 可选) – 未知词 token。(默认值:“<unk>”)
using_cpu_decoder (bool, 可选) – 是否使用 CPU 搜索器。如果为 False,则使用 CUDA 解码器。(默认值:True)
blank_skip_threshold (float, 可选) – 如果 log_prob(blank) > log(blank_skip_threshold) 则跳过帧,以加快解码速度(默认值:1.0)。注意:这仅在使用 CUDA 解码器时使用,并且可能会恶化 WER/CER 结果。请自行承担风险。
示例
>>> import torch >>> from speechbrain.decoders import TorchAudioCTCPrefixBeamSearcher >>> probs = torch.tensor([[[0.2, 0.0, 0.8], ... [0.4, 0.0, 0.6]]]) >>> log_probs = torch.log(probs) >>> lens = torch.tensor([1.0]) >>> blank_index = 2 >>> vocab_list = ['a', 'b', '-'] >>> searcher = TorchAudioCTCPrefixBeamSearcher(tokens=vocab_list, blank_index=blank_index, sil_index=blank_index) >>> hyps = searcher(probs, lens)
- decode_beams(log_probs: Tensor, wav_len: Tensor | None = None) List[List[CTCHypothesis]] [source]
使用 TorchAudio CTC 解码器解码 log_probs。
如果
using_cpu_decoder=True
,则在解码前将 log_probs 和 wav_len 移至 CPU。使用 CUDA CTC 解码器时,时间步长信息不可用。因此,返回的假设中的时间步长被设置为 None。请确保输入处于对数域。解码器无法解码 logits 或概率。输入应为 CTC 输出的对数概率。
- 参数:
log_probs (torch.Tensor) – 输入音频的对数概率。形状:(batch_size, seq_length, vocab_size)
wav_len (torch.Tensor, 默认值: None) – SpeechBrain 风格的相对长度。形状:(batch_size,) 如果为 None,则假定每个音频的长度为 seq_length。
- 返回:
解码后的假设。外部列表表示 batch 维度,内部列表表示 topk 维度。
- 返回类型:
list of list of CTCHypothesis
- __call__(log_probs: Tensor, wav_len: Tensor | None = None) List[List[CTCHypothesis]] [source]
使用 TorchAudio CTC 解码器解码 log_probs。
如果
using_cpu_decoder=True
,则在解码前将 log_probs 和 wav_len 移至 CPU。使用 CUDA CTC 解码器时,时间步长信息不可用。因此,返回的假设中的时间步长被设置为 None。- 参数:
log_probs (torch.Tensor) – 输入音频的对数概率。形状:(batch_size, seq_length, vocab_size)
wav_len (torch.Tensor, 默认值: None) – SpeechBrain 风格的相对长度。形状:(batch_size,) 如果为 None,则假定每个音频的长度为 seq_length。
- 返回:
解码后的假设。外部列表表示 batch 维度,内部列表表示 topk 维度。
- 返回类型:
list of list of CTCHypothesis