# Seq2Seq结构

上一小节中介绍的CTC结构仅适用于Tranformer结构的编码器（encoder）部分。如果我们给模型添加一个解码器（decoder）构建一个自编码模型（autoencoder，也称编码-解码模型，encoder-decoder），这个模型也可以被称为**序列到序列**模型（sequence-to-sequence，简称seq2seq）。Seq2Seq模型将一种数据序列映射到另一种数据序列。

在仅使用编码器的Transformer模型中，编码器为输入序列中的每个元素进行预测。因此，输入和输出序列的长度总是相同的。在CTC模型（如Wav2Vec2）的情况下，输入波形会被下采样，但我们仍然对下采样后的每个元素（对应20毫秒的音频）输出一个对应的预测标记，因此输入标记和输出的预测标记仍然是等长的。

而在seq2seq模型中，输入和输出序列的长度可以不同。这使得seq2seq模型更适合文本摘要或翻译等的NLP任务，也同时适用于语音识别等音频任务。

Seq2Seq结构中的解码器（decoder）和编码器（encoder）非常类似，两者都使用自注意力（self-attention）作为主要的运算单元。但是解码器的任务与编码器不同。为了理解这一点，让我们看看seq2seq模型如何进行自动语音识别。

## 自动语音识别

下图展示了**Whisper**模型的结构（图片来自[OpenAI Whisper博客](https://openai.com/blog/whisper/)）：

    

看起来十分熟悉。左边是**Transformer编码器**。它以对数梅尔时频谱（log-mel spectrogram）作为输入，并对其进行编码，输出一个编码器隐藏状态序列（sequence of encoder hidden states），从中提取出输入语音的重要特征。这个隐藏状态张量代表了整个输入序列，并高效地编码了输入语音的“含义”。

💡 这些seq2seq模型通常使用时频谱作为输入。不过，seq2seq模型也可以直接使用音频波形作为输入。

编码器的输出被传递到右边的**Transformer解码器**，使用一种称为**交叉注意力**（cross-attention）的机制。交叉注意力与自注意力类似，不过此处注意力的对象是编码器的输出。在这之后，我们就不再需要编码器了。

解码器会使用**自回归**（autoregressive）的方式来预测一个文本标记序列，每次只预测一个标记，从一个仅含有“起始”标记（Whisper使用`SOT`作为起始标记）的序列开始。在每个时间步，前一个时间步的输出序列会作为新的输入序列被传递给解码器。这样，解码器每次只会输出一个新的标记，逐步增长输出序列，直到预测出“结束”标记，或者达到最大时间步数。

虽然解码器的结构与编码器类似，但是解码器和编码器有两个主要的区别：

1. 解码器会使用交叉注意力机制，允许它查看编码器生成的对于输入序列的隐藏状态向量。
2. 解码器的注意力是**因果**（causal）的——解码器不允许查看未来的信息。

在这个架构中，解码器的功能类似于**语言模型**（language model），它处理编码器的隐藏状态表示，并生成相应的文本转录。这种方法比CTC更强大，甚至CTC结合外部语言模型也无法相比。Seq2Seq结构可以使用相同的训练数据和损失函数进行端到端（end-to-end）训练，从而提供更好的灵活性和更好的性能。

💡 与CTC模型输出单个字母的序列不同，Whisper模型的输出是完整的单词或词素。它使用GPT-2的分词器，有50k+个不同的标记。因此，seq2seq模型可以输出比CTC模型更短的序列。

Seq2Seq语音识别模型最常使用的损失函数为交叉熵损失（cross-entropy loss），因为我们通常把模型最终层的输出视为一个标记的概率分布。交叉熵损失通常与[束搜索（beam search）](https://huggingface.co/blog/how-to-generate)等技术结合使用，生成最终的序列。语音识别的度量标准是WER（word error rate），它衡量将预测文本转换为目标文本所需的替换、插入和删除的数量。所需的操作越少说明预测结果越好。

## 文本到语音（Text-to-speech，TTS）

可能不会让你感到惊讶的是， Seq2Seq的TTS模型基本上和ASR模型相同，仅仅是将输入和输出的数据种类互换！Transformer编码器接收文本标记序列，并提取表示输入文本的隐藏状态序列。Transformer解码器使用交叉注意力机制，预测输出的时频谱序列。

💡 时频谱图是通过对音频波形的连续时间切片进行频谱分析得到的。换句话说，时频谱图是一个序列，其中的元素是（对数梅尔）频谱，每个时间步一个。

在ASR模型里，解码器的初始输出序列是一个仅包含“起始”标记的序列。而在TTS模型里，我们可以使用一个长度为1，值全为0的时频谱序列来代替“起始”标记。有了这个初始时频谱序列和编码器隐藏状态的交叉注意力，解码器就可以预测下一个时间步的时频谱，逐步增长时频谱序列。

    

但我们的解码器怎样知道需要在什么时候停止呢？在**SpeechT5**模型中，解码器会预测第二个序列。这个序列包含当前时间步是否是最后一个时间步的概率。在推理时，如果这个概率超过某个阈值（比如0.5），我们就认为解码器在指示时频谱序列已经生成完毕，应该结束生成循环。

在解码器生成完整的时频谱序列后，SpeechT5会使用一个称为**后处理网络**（post-net）的模型对时频谱序列进行微调。后处理网络由几个卷积层组成，用于微调时频谱序列。

在训练TTS模型时，我们的生成目标是训练数据的时频谱图，损失函数为L1损失或最小二乘损失（mean square error，MSE）。在推理时，我们希望将输出的时频谱图转换为音频波形，这样我们就可以听到它。为此，我们需要使用一个外部模型，称为**声码器**（vocoder）。这个声码器不是seq2seq架构的一部分，而是单独训练的。

TTS任务的难点在于其一对多的映射。对于语音到文本的任务，每个输入语音只对应一个正确的输出文本，但是对于文本到语音的任务，输入文本可以映射到多个可能的语音。例如，不同的说话人可能会强调同一个句子中的不同部分。这使得TTS模型很难评估。因为这个原因，L1或MSE损失实际上并不是理想的损失函数，因为同一个文本可以映射到多种不同的时频谱序列。这就是为什么TTS模型通常会由人类听众进行评估的原因，使用的指标称为MOS（mean opinion score，平均意见分数）。

## 总结

Seq2Seq结构是一种强大的模型，其能力往往优于仅含编码器的模型。通过将输入序列的编码与输出序列的解码分离，我们可以很好地处理音频和文本的对齐问题。

然而，编码器-解码器模型也存在一些缺点，比较重要的一点是其推理速度较慢。这是由于其解码过程在每一步仅生成一个输出元素，因此完整的预测需要进行数次推理。输出序列越长，推理的速度也就越慢。自回归模型也可能会陷入循环或者跳过一些元素。束搜索（beam search）等技术可以提高预测结果的质量，但也会进一步降低推理速度。

