17.2 使用编解码器学习离散音频词元
现代 TTS 系统的核心是把波形转换为离散音频词元序列。操纵离散音频词元的思想也适用于其他支持语音的系统,例如口语语言模型:它们接收文本或语音输入,并生成文本或语音输出,以解决语音到语音翻译、说话人分离或口语问答等任务。拥有离散词元意味着可以利用语言模型技术,因为语言模型专门处理离散词元序列。因此,音频分词器是现代语音工具箱的重要组件。
学习音频词元的标准方法是使用神经音频编解码器(codec 一词由 coder/decoder 形成)。历史上,编解码器是把模拟符号数字化的硬件设备。更一般地说,我们用这个词指一种机制:把模拟语音信号编码为数字化的压缩表示,以便高效存储和传输。编解码器仍用于压缩;但在 TTS 和口语语言模型中,我们还使用它们把语音转换为离散词元。
当然,第 15 章介绍的语音数字表示已经是离散的。例如,以 16 位格式存储的 16 kHz 语音,可以看作由 个符号组成,每秒语音有 16,000 个符号。但每秒生成 16,000 个符号,会使语音信号过长,难以由语言模型处理,尤其是使用低效二次注意力的 Transformer 模型。因此,我们希望符号表示更长的语音片段,例如每秒几百个词元。

图 17.2 执行推理的音频分词器标准架构(改编自 Mousavi et al., 2025)。输入波形 通常经过一系列下采样卷积网络编码为嵌入序列 。每个嵌入再经过量化器,生成量化词元序列 。为了重新生成语音信号,量化词元被重新映射为向量 ,然后通常经过一系列上采样卷积网络解码为波形。17.2.4 节将讨论该架构如何训练。
图 17.2(改编自 Mousavi et al., 2025)展示了音频分词器的标准架构。音频分词器接收音频波形作为输入,并通过由向量量化创建的离散词元中间表示,训练模型重建同一个音频波形。
音频分词器有三个阶段:
编码器把由 个值组成的声学波形 映射为 个嵌入组成的序列 。通常, 比 小 100–1000 倍。
向量量化器接收每个嵌入 (对应波形的一部分),并用一系列离散词元表示它;每个词元来自 个码本之一,即 。向量量化器还把各码本中的向量码字相加,得到量化器输出向量 。
解码器根据量化器输出向量 生成有损重建的波形片段 。
音频分词器通常以端到端方式学习,使用能够奖励“允许系统重建输入波形”的分词结果的损失函数。
下面几节将介绍一种特定分词器的组件,即 Defossez et al.(2023)的 ENCODEC 分词器。
17.2.1 ENCODEC 模型的编码器与解码器¶

图 17.3 ENCODEC 模型的编码器和解码器阶段。编码器的目标是把输入波形下采样,编码为 75 Hz 的嵌入序列,即每秒 75 个嵌入。由于原始信号以 24 kHz 表示,这相当于下采样 倍。编码器和解码器之间是量化步骤,产生有损嵌入 。解码器的目标是接收这一有损嵌入并对其上采样,将其转换回波形。
ENCODEC 模型(Defossez et al., 2023)的编码器和解码器如图 17.3 所示。编码器的目标是把时间 的一段波形(采样率 24 kHz,即一秒语音包含 24,000 个实数)下采样为 75 Hz 的嵌入表示 ;一秒音频由 75 个向量表示,每个向量维度为 。为便于说明,取 。
这一过程通过一系列编码器块实现。编码器块由步长大于 1 的卷积层组成,按照 16.2 节末尾讨论的方法,逐步对音频进行下采样。图 17.3 概略展示了卷积块,其中包含很长的卷积序列,以及把卷积加入前一输入的残差单元。
编码器输出时间 的嵌入 ,每秒产生 75 个这样的嵌入。随后对嵌入进行量化(下一节讨论),把每个 转换为 个离散符号组成的序列 ,同时把这些符号转换为新的量化器输出向量 。最后,解码器接收量化器输出嵌入 ,通过一组对称的卷积网络对音频进行上采样,生成波形。
总之,输入一个 24 kHz 波形,把它编码/下采样为维度 的向量 ,将其量化为离散符号 ,再把符号转换回维度 的向量 ,最后将该向量解码/上采样为 24 kHz 波形。
17.2.2 向量量化¶
向量量化(vector quantization,VQ)步骤的目标,是把向量序列转换为离散符号序列。
历史上,向量量化(Gray, 1984)用于压缩语音信号,以降低传输或存储所需的比特率。压缩语音的向量表示序列时,把每个向量转换为一个整数,即表示某个类别或簇的索引。这样,与其传输一个很大的浮点数向量,不如传输这个整数索引;在传输的另一端,再根据索引重建向量。
对 TTS 和其他现代语音应用而言,使用向量量化的原因不同:VQ 可以方便地创建离散词元,而离散词元非常适合语言建模范式,因为语言模型擅长预测离散词元序列。
在实践中,ENCODEC 模型和其他音频分词器使用一种强大的向量量化形式,即残差向量量化;下一节将定义它。不过,先了解基本 VQ 算法,再进行扩展会很有帮助。
向量量化有训练阶段和推理阶段。16.4.3 节介绍向量 k-means 聚类时,已经介绍了基本 VQ 训练算法的核心,因为 k-means 聚类是实现 VQ 最常用的算法。回顾一下,VQ 训练时,把大量语音波形文件输入编码器,生成 个向量,每个向量对应一帧语音。然后把这 个向量聚类为 个簇; 由算法设计者作为离散符号数量这一参数设定,通常 。在最简单的 VQ 算法中,使用迭代 k-means 算法学习这些簇。回忆 16.4.3 节,k-means 是一种通过迭代更新 个质心向量来工作的两步算法;质心是 维空间中一组点的几何中心。
用于聚类的 k-means 算法先为每个簇 分配一个随机向量,然后反复执行两个步骤。在分配步骤中,给定当前 个质心和完整向量数据集,将每个向量分配给码字最近的簇(按平方欧氏距离计算)。在重新估计步骤中,重新计算一个新的均值向量,以得到每个簇的码字。这样,簇及其质心会逐渐适应训练空间;两个步骤交替执行,直到算法收敛。

图 17.4 已学习码本后,推理阶段的基本 VQ 算法。输入是一段语音,编码器把它编码为维度 的向量。将该向量与码本中的每个码字(簇质心)比较。第 3 簇的码字最相似,因此 VQ 输出 3,作为该向量的离散表示。
VQ 也可以作为端到端训练的一部分,下面将讨论这种情况。这时不使用迭代 k-means,而是在小批量训练中通过指数移动平均等在线算法重新计算均值。
聚类结束后,簇索引可以作为离散符号。每个簇还关联一个码字,即该簇所有向量的质心向量。我们把簇 ID(词元)及其码字组成的列表称为码本,通常把簇 ID 称为编码。
推理时,新向量到来后,将其与码本中的每个向量比较;哪个码字最近,就把它分配给该码字关联的簇。图 17.4 在语音编码场景下展示了这一推理步骤:
把输入语音波形编码为向量 ;
将输入向量 与码本中的 1,024 个可能码字逐一比较;
发现 与码字 3 最相似;
因此,VQ 的输出是离散符号 3,作为 的表示。
如下面将看到的,要端到端训练 ENCODEC 模型,需要把这个离散符号转换回波形。对简单 VQ,可以直接使用该簇的码字,把码字传给解码器,由解码器重建波形。当然,码字向量不会与输入语音片段的原始向量编码完全匹配,尤其是在只有 1,024 个可能码字时;但如果码本良好,希望它至少足够接近,解码器仍能生成合理语音。不过,实践中通常使用更强大的方法,如下一节所述。
17.2.3 残差向量量化¶
在实践中,简单 VQ 不能产生足够好的重建结果,至少当码本大小为 1,024 时是如此。1,024 个码字向量不足以表示编码所有可能语音波形所得嵌入的丰富多样性。因此,ENCODEC 模型以及许多其他音频分词方法使用一种更复杂的变体,称为残差向量量化(residual vector quantization,RVQ)。在残差向量量化中,使用以某种层次结构排列的多个码本。

图 17.5 残差 VQ(图源:Chen et al., 2025)。对编码器输出嵌入执行 VQ,产生一个离散符号及对应码字。然后查看残差,即编码器输出嵌入 与 VQ 选定码字之间的差异。接着取第二个码本,对这个残差执行 VQ。重复这一过程,直到得到 8 个词元。
思想非常简单。像图 17.4 一样,使用一个码本执行标准 VQ。对于输入嵌入 ,取输出的码字向量,记作由第一个码本量化得到的 ,并计算二者之差:
这个残差是 VQ 的误差,即原始向量中 VQ 尚未捕捉的部分。残差有点像舍入误差:仿佛在 VQ 中把向量“舍入”到最近的码字,从而产生了一些误差。于是,再把这个残差向量送入另一个向量量化器!这会得到表示向量残差部分的第二个音频词元。然后从第二个码字得到新的残差,再次执行相同过程。最终结果是 8 个码字(原始码字加上 7 个残差码字)。
这意味着在 RVQ 中,原始语音片段由 8 个离散符号序列表示,而基本 VQ 只用 1 个离散符号。图 17.5 展示了这一思想。
如何重建语音?ENCODEC RVQ 使用的方法同样简单:把 8 个码字相加!所得向量 再传给解码器,生成波形。
17.2.4 ENCODEC 模型的训练¶
ENCODEC 模型(与类似的音频分词器模型一样)以端到端方式训练。输入是一段波形,即从音频中截取的可能为 1 秒或 10 秒的语音片段;期望输出是相同的波形片段,因为该模型是一种学习将输入映射回自身的自编码器。模型在 Common Voice(Ardila et al., 2020,包含 133 种语言、超过 30,000 小时语音)等大型语音数据集,以及 Audio Set(Gemmeke et al., 2017,来自 YouTube 的 170 万段 10 秒音频片段,按照包含自然、动物、机器声音、音乐等的大型本体进行标注)等其他音频数据上训练重建任务。

图 17.6 音频分词器训练架构(改编自 Mousavi et al., 2025)。音频分词器使用多种损失函数的加权组合进行训练,图中总结了这些损失,下面将分别描述。
ENCODEC 模型和大多数音频分词器一样,使用多个损失函数进行训练,如图 17.6 所示。重建损失 衡量输出波形与输入波形的相似程度,例如计算原始音频与重建音频之间的平方差之和:
还可以在频域中衡量相似度:比较原始与重建的 Mel 声谱图,同样使用平方(L2)距离、L1 距离,或二者的某种组合。
另一种损失是对抗损失 。对于这一损失,训练一个生成对抗网络,其中包括生成器和二元判别器 ;判别器是一个区分真实波形文件 与生成波形的分类器。我们希望训练模型欺骗判别器,因此判别器越强,重建就越差;可以使用判别器的成功程度作为损失函数。还可以加入生成器的各种特征。
最后,还需要量化器损失。这是因为在端到端训练中间加入量化器,会给训练反向传播的梯度传播造成问题:量化步骤不可微。我们通过两种方式处理这一问题。第一,在反向传播时忽略量化步骤;把量化器输出 的梯度复制回量化器输入 ,这种方法称为直通估计器(straight-through estimator)(Van Den Oord et al., 2017)。
但还需要一种方法,确保向量量化步骤中的码字在训练中更新。一种方法是先对向量 使用 k-means 聚类,得到初始簇。随后加入损失项 ,它表示编码器输出向量 与量化后重建向量 (即码字)之间的差异,并对全部 个码本和残差求和:
总损失函数可以是这些损失的加权和: