音频课程文档

CTC 架构

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

CTC 架构

CTC(Connectionist Temporal Classification,连接时序分类)是一种与仅编码器 Transformer 模型一起用于自动语音识别的技术。此类模型的示例包括 Wav2Vec2HuBERTM-CTC-T

仅编码器 Transformer 是最简单的 Transformer 类型,因为它只使用模型的编码器部分。编码器读取输入序列(音频波形)并将其映射到隐藏状态序列,也称为输出嵌入。

对于 CTC 模型,我们在隐藏状态序列上应用额外的线性映射,以获得类别标签预测。类别标签是字母表中的字符(a、b、c 等)。这样,我们就可以使用小型分类头来预测目标语言中的任何单词,因为词汇表只需要包含 26 个字符加上一些特殊标记。

Transformer encoder with a CTC head on top

到目前为止,这与我们在 NLP 中使用 BERT 等模型所做的非常相似:仅编码器 Transformer 模型将我们的文本标记映射到编码器隐藏状态序列,然后我们应用线性映射,为每个隐藏状态获得一个类别标签预测。

关键在于:在语音中,我们不知道音频输入和文本输出的对齐方式。我们知道语音的语序与文本转录的语序相同(对齐是所谓的单调的),但我们不知道转录中的字符如何与音频对齐。这就是 CTC 算法的用武之地。

💡 在 NLP 模型中,词汇表通常由数千个标记组成,这些标记不仅描述单个字符,还描述单词的部分甚至完整的单词。但是,对于 CTC 来说,小型词汇表效果最佳,我们通常尝试将其保持在 50 个字符以下。我们不关心字母的大小写,因此仅使用大写(或仅使用小写)就足够了。数字会被拼写出来,例如 `"20"` 变为 `"twenty"`。除了字母之外,我们至少还需要一个单词分隔符标记(空格)和一个填充标记。与 NLP 模型一样,填充标记允许我们在批次中组合多个示例,但它也是模型将预测静音的标记。在英语中,保留 `'` 字符也很有用 — 毕竟,`"it's"` 和 `"its"` 具有非常不同的含义。

伙计,我的对齐在哪里?

自动语音识别或 ASR 涉及将音频作为输入并生成文本作为输出。关于如何预测文本,我们有几个选择

  • 作为单个字符
  • 作为音素
  • 作为单词标记

ASR 模型在由 (音频, 文本) 对组成的数据集上进行训练,其中文本是音频文件的人工转录。通常,数据集不包含任何时间信息,说明哪个单词或音节在音频文件中哪个位置出现。由于我们不能在训练期间依赖时间信息,因此我们不知道输入和输出序列应该如何对齐。

假设我们的输入是一个一秒的音频文件。在 Wav2Vec2 中,模型首先使用 CNN 特征编码器对音频输入进行下采样,得到较短的隐藏状态序列,其中每 20 毫秒音频有一个隐藏状态向量。对于一秒的音频,我们将 50 个隐藏状态的序列转发到 Transformer 编码器。(从输入序列中提取的音频段部分重叠,因此即使每 20 毫秒发射一个隐藏状态向量,每个隐藏状态实际上代表 25 毫秒的音频。)

Transformer 编码器为每个隐藏状态预测一个特征表示,这意味着我们从 Transformer 接收到 50 个输出的序列。这些输出中的每一个都具有 768 的维度。因此,在本示例中,Transformer 编码器的输出序列的形状为 (768, 50)。由于这些预测中的每一个都覆盖 25 毫秒的时间,这比音素的持续时间短,因此预测单个音素或字符而不是整个单词是有意义的。CTC 最适合小型词汇表,因此我们将预测字符。

The audio waveform gets mapped to a shorter sequence of hidden-states

为了进行文本预测,我们使用线性层(“CTC 头”)将 768 维编码器输出中的每一个映射到我们的字符标签。然后,该模型预测一个包含 logits 的 (50, 32) 张量,其中 32 是词汇表中的标记数。由于我们为序列中的每个特征进行一次预测,因此对于每秒音频,我们最终得到总共 50 个字符预测。

但是,如果我们只是每 20 毫秒预测一个字符,我们的输出序列可能如下所示

BRIIONSAWWSOMEETHINGCLOSETOPANICONHHISOPPONENT'SSFAACEWHENTHEMANNFINALLLYRREECOGGNNIIZEDHHISSERRRRORR ...

如果仔细观察,它有点像英语,但很多字符都被重复了。这是因为模型需要为输入序列中每 20 毫秒的音频输出某些内容,如果一个字符的跨度超过 20 毫秒,那么它将在输出中多次出现。这是无法避免的,特别是由于我们不知道转录的时间安排。CTC 是一种过滤掉这些重复项的方法。

(实际上,预测序列还包含许多填充标记,用于模型不太确定声音代表什么,或者用于字符之间的空白。为了清晰起见,我们从示例中删除了这些填充标记。音频段之间的部分重叠是字符在输出中重复出现的另一个原因。)

CTC 算法

CTC 算法的关键是使用一个特殊标记,通常称为空白标记。这只是模型将预测的另一个标记,它是词汇表的一部分。在本例中,空白标记显示为 _。此特殊标记充当字符组之间的硬边界。

来自 CTC 模型的完整输出可能如下所示

B_R_II_O_N_||_S_AWW_|||||_S_OMEE_TH_ING_||_C_L_O_S_E||TO|_P_A_N_I_C_||_ON||HHI_S||_OP_P_O_N_EN_T_'SS||_F_AA_C_E||_W_H_EN||THE||M_A_NN_||||_F_I_N_AL_LL_Y||||_RREE_C_O_GG_NN_II_Z_ED|||HHISS|||_ER_RRR_ORR||||

| 标记是单词分隔符字符。在示例中,我们使用 | 而不是空格,这样更容易发现单词分隔符在哪里,但它的用途相同。

CTC 空白字符使得过滤掉重复字符成为可能。例如,让我们看一下预测序列中的最后一个单词 _ER_RRR_ORR。如果没有 CTC 空白标记,这个词看起来像这样

ERRRRORR

如果我们只是简单地删除重复字符,这将变成 EROR。这显然不是正确的拼写。但是有了 CTC 空白标记,我们可以删除每个组中的重复项,以便

_ER_RRR_ORR

变成

_ER_R_OR

现在我们删除 _ 空白标记以获得最终单词

ERROR

如果我们将此逻辑应用于整个文本,包括 |,并将幸存的 | 字符替换为空格,则最终的 CTC 解码输出为

BRION SAW SOMETHING CLOSE TO PANIC ON HIS OPPONENT'S FACE WHEN THE MAN FINALLY RECOGNIZED HIS ERROR

总而言之,模型为来自输入波形的每 20 毫秒(部分重叠)音频预测一个标记(字符)。这会产生大量重复项。感谢 CTC 空白标记,我们可以轻松删除这些重复项,而不会破坏单词的正确拼写。这是一种非常简单方便的方法来解决将输出文本与输入音频对齐的问题。

💡 在实际的 Wav2Vec2 模型中,CTC 空白标记与填充标记 相同。模型将预测许多这些 标记,例如,当当前 20 毫秒的音频没有明确的字符可以预测时。使用与 CTC 空白相同的标记进行填充简化了解码算法,并有助于保持词汇表较小。

将 CTC 添加到 Transformer 编码器模型很容易:来自编码器的输出序列进入一个线性层,该线性层将声学特征投影到词汇表。该模型使用特殊的 CTC 损失进行训练。

CTC 的一个缺点是它可能会输出听起来正确的单词,但拼写不正确。毕竟,CTC 头只考虑单个字符,而不是完整的单词。提高音频转录质量的一种方法是使用外部语言模型。此语言模型本质上充当 CTC 输出之上的拼写检查器。

Wav2Vec2、HuBERT、M-CTC-T 等之间有什么区别?

所有基于 Transformer 的 CTC 模型都具有非常相似的架构:它们使用 Transformer 编码器(但不使用解码器),顶部带有 CTC 头。从架构上看,它们的相似之处多于不同之处。

Wav2Vec2 和 M-CTC-T 之间的一个区别是,前者处理原始音频波形,而后者使用梅尔频谱图作为输入。这些模型也针对不同的目的进行了训练。例如,M-CTC-T 经过多语言语音识别训练,因此具有相对较大的 CTC 头,其中除了其他字母表外,还包括汉字。

Wav2Vec2 和 HuBERT 使用完全相同的架构,但以截然不同的方式进行训练。Wav2Vec2 的预训练方式类似于 BERT 的掩码语言建模,通过预测音频掩码部分的语音单元。HuBERT 更进一步地借鉴了 BERT 的灵感,并学习预测“离散语音单元”,这类似于文本句子中的标记,以便可以使用已建立的 NLP 技术来处理语音。

为了澄清,这里强调的模型并不是唯一的基于 Transformer 的 CTC 模型。还有许多其他模型,但现在您知道它们都以类似的方式工作。

< > 在 GitHub 上更新