基于声学token或语义token的TTS-VoiceCraft—VALL-E的后续改进

作为Zero shot-TTS VALL-E的后续改进,VoiceCraft不得不提。可以称之为“优雅的VALL-E”。它的优雅主要体现在两个方面:casual masking和delayed stacking。所谓的causal masking,是为了用自回归GPT架构来做语音编辑任务,就是把被mask的部分移动到序列末尾去预测,一套架构同时做合成和编辑任务;所谓的delay stacking,是为了适配自回归和RVQ,通过delay错位让当前码本的token预测正好可以利用前面那些token的预测结果,比起VALL-E那样自回归和非自回归缝合在一起的结构要优雅不少。

VoiceCraft的建模流程,标记重排过程和建模框架的示例。重排过程包括两个步骤:(1) 因果掩码,其中掩码的跨度被掩码标记替换并移动到末尾,以及 (2) 延迟堆叠,其中标记根据其码簿索引在时间维度上移动。

VoiceCraft 通过重新排列神经编解码器的输出标记,将序列填充(用于语音编辑)和延续(用于零样本 TTS)转换为简单的从左到右的语言建模。重排包括两个步骤:(1) 因果掩码以实现双向上下文的自回归延续/填充,以及 (2) 延迟堆叠以确保高效的多码簿建模。VoiceCraft 采用仅限解码器的 Transformer,并使用自回归序列预测 进行训练。

重排步骤 1:因果掩码:

给定一个连续的语音波形作为输入,我们首先使用 Encodec将其量化成一个 T by K codec 矩阵 X ,其中 T 是时间帧的数量,是 K RVQ 码本的数量。 X 可以写成 (X1,⋯,XT) ,其中 Xt 是一个长度 K 向量,表示在时间步 t 中来自不同码本的代码,我们假设 Codebook k 中的代码对 Codebook k−1 中的残差进行建模。在训练过程中,我们的目标是随机屏蔽一些 span 的标记 (Xt0,…,Xt1) ,然后以所有未屏蔽的标记为条件自动回归预测这些被屏蔽的标记。这在 时 t1<T 是个问题,因为在执行自回归生成时,我们无法以未来的输出为条件。我们需要修改掩码, X 使其具有因果关系,方法是将要掩码的跨度移动到序列的末尾,以便在填充这些标记时,模型可以针对过去和未来未掩码的标记。

只需将所有被屏蔽的 span 移动到序列的末尾,即可轻松地将上述过程扩展到多个被屏蔽的 span。要屏蔽 n 的 span 数从 Poison⁢(λ) 中采样,然后对于每个 span,我们采样一个 span length l∼Uniform⁢(1,L) 。最后,我们在约束 X 下随机选择 span 的位置,确保它们彼此不重叠。然后,选定的 n 范围将替换为掩码标记 ⟨M1⟩,⋯,⟨Mn⟩ 。这些掩码 span 中的原始标记将移动到 sequence X 的末尾,每个 span 前面都有其相应的掩码标记。

重排步骤 2:延迟堆叠

在因果掩码标记重新排列之后,重新排列矩阵 Y 的每个时间步都是标记向量 K 。Copet et al. ( 2023) 观察到,当对堆叠的 RVQ 令牌进行自回归生成时,应用延迟模式是有利的,这样时间对码簿 k 的预测 t 就可以以同一时间步长对码簿 k−1 的预测为条件。我们采用与本文类似的方法。假设 span Ys 的形状为 Ls×K .应用延迟模式会将其重新排列到 Zs=(Zs,0,Zs,1,⋯,Zs,Ls+K−1) 中,其中 Zs,t,t∈[Ls+K−1] 定义为

其中 Ys,t−k+1,k 表示位于 matrix Ys 中 coordinate (t−k+1,k) 处的标记,即 (t−k+1) 第 个时间步的 k 第 个 Codebook 条目。为了确保 ∀t∈[Ls+K−1] , Zs,t 包含 K 有效的标记,我们引入了一个特殊的可学习 [空] 标记并定义 Ys,t−k+1,k≜[empty],∀t∈{s:s⁢<k∪s−k+1>⁢Ls} 。请注意,掩码标记不是任何 span 的一部分,并且在延迟堆叠期间不会更改。我们定义延迟堆叠的结果矩阵 Z=(Z1,⟨M1⟩,Z2,⟨M1⟩,⋯,⟨MS−12⟩,ZS) 

推理:

语音编辑。语音编辑的设置如下:我们有语音记录 R 及其转录 W ,我们希望模型仅修改 的 R 相关跨度,以便它与目标转录 W′ 匹配。我们假设 是 W′ 的编辑版本 W ,其中插入、替换或删除了一些单词。这个任务和训练任务几乎一模一样,有两个区别: 1) 在训练过程中,输入的成绩单只是原始录音 W 的成绩单,而在推理过程中,它是一个修改后的成绩单 W′ 2) 在训练过程中,要屏蔽的跨度(即 编辑)是随机选择的。在推理过程中,我们通过比较原始转录本和目标转录本来识别应该屏蔽掉的单词来选择它们,然后使用原始转录本的单词级强制对齐来识别与这些要屏蔽的单词相对应的编解码器标记跨度。为了确保已编辑的语音和未编辑的语音之间的平滑过渡,还需要对要编辑的 span 周围的相邻单词进行轻微修改,以便对协同发音效果进行建模。因此,我们指定了一个小的 margin 超参数 ϵ ,并在左侧和右侧将掩码跨度长度 ϵ 延长.

在自回归生成过程中,我们将所有未屏蔽的跨度的目标转录本提供给模型,并在应进行编辑的位置插入掩码标记。然后,我们让模型自回归地继续这个序列,从而填充被掩盖的 span。然后,生成的编解码器令牌被拼接回它们在话语中的正确位置,我们使用 Encodec 解码器网络将完整的编解码器令牌序列映射回波形。

Zero-shot TTS。正如我们之前提到的,我们模型的零样本 TTS 很简单,因为它只对应于在原始话语的末尾执行插入编辑。在这种情况下,会为模型提供语音提示及其转录,以及要生成的语音的目标转录。这三个输入连接在一起并馈送到模型,然后它自动回归地生成目标转录本的编解码器序列。

Zero-shot TTS –微软研究院 VALL-E系列论文阅读

微软研究院发布了一系列的TTS相关的论文:

微软研究院;https://www.microsoft.com/en-us/research/project/vall-e-x/

VALL-E:https://arxiv.org/abs/2301.02111

VALL-E X https://github.com/Plachtaa/VALL-E-X https://arxiv.org/abs/2303.03926

VALL-E R https://arxiv.org/abs/2406.07855

VALL-E 2 https://arxiv.org/abs/2406.05370

MELLE https://arxiv.org/abs/2407.08551

RALL-E https://arxiv.org/abs/2404.03204

综述:

我们介绍了一种用于文本到语音合成(TTS)的语言建模方法。具体而言,我们使用从一个现成的神经音频编解码器模型中提取的离散编码训练了一个神经编解码器语言模型(称为 VALL-E),并将 TTS 视为一个条件语言建模任务,而不是像以往工作中那样的连续信号回归任务。VALL-E 展现了上下文学习的能力,只需一个未见过的说话者3秒钟的录音作为提示,就可以合成高质量的个性化语音。VALL-E 在语音自然度和说话者相似性方面显著优于现有的零样本 TTS 系统。此外,VALL-E 可以在合成时保留提示音频中的说话者情感和声学环境。为了扩展其能力,VALL-E X 能够适应多语言场景,促进跨语言零样本 TTS。而 VALL-E R 引入了音素单调对齐策略,增强了语音生成的稳健性。通过整合重复感知采样和分组编码建模技术,VALL-E 2 实现了一个突破性的里程碑:在 LibriSpeech 和 VCTK 数据集上达到了零样本 TTS 性能的“人类水平”。这是该领域首次取得如此成就,设立了新的标准。MELLE 是一种新颖的基于连续值标记的语言建模方法,用于文本到语音合成(TTS)。MELLE 直接从文本条件中自回归地生成连续的 mel 频谱图帧,绕过了矢量量化的需求,后者最初是为音频压缩设计的,与 mel 频谱图相比,会牺牲保真度。

尽管VALL-E系列在用GPT 【decoder only 模型】建模token的上下文关系的时候,基于token的层次化特性做了分治处理,可能是限于当前语音数据集的规模(几万小时可能不够),这种GPT自回归的难度还是相当大的,解码过程存在常见的错误传播现象,鲁棒性非常差,极其不稳定。根据Ilya Sutskever此前对于自回归的论述,GPT自回归相比于BERT这种双向结构是非常data-hungry的,几万小时的数据可能不够,至少需要十几万小时的数据。既然GPT自回归的难度这么大,就有不少人想方设法地来降低GPT学习的难度了。解决方案也非常类似:给GPT提供额外的条件信息不就行了比较典型的工作就是微软的RALL-E,RALL-E先生成了时长信息和音高信息,作为GPT【only decoder】自回归的先验,之所以会补充时长和音高,这大概是受到FastSpeech2这样的非自回归模型的启发,这两个指标的引入,有助于提升合成的鲁棒性

VALL-E

论文:https://arxiv.org/abs/2301.02111

VALL·E也和VQVAE类似,将音频量化成一系列离散tokens,其中第一个量化器负责捕捉音频内容和说话者身份特征,后几个量化器则负责细化信号,使之听起来更自然。随后以文本和3秒钟的声音提示作为条件,自回归地输出第一层离散音频编码,NAR根据上一层的输出,并行输出第二到第八层的离散编码。

条件编解码器语言建模

神经语音编码器模型使我们能够对离散音频表示进行操作。由于神经编码器模型中的残差量化,令牌具有层次结构:来自先前量化器的令牌恢复声学属性,如说话者身份,而连续量化器则学习细微的声学细节。每个量化器的训练旨在建模来自前一个量化器的残差。因此,我们设计了两个以层次方式进行的条件语言模型。

对于来自第一个量化器的离散令牌 C:,1​,我们训练一个自回归(AR)解码器语言模型。该模型以音素序列 x声学提示 C~:,1为条件,公式化为:

由于 VALL-E 是一个仅解码的语言模型,c~:,1​ 和 c:,1​ 的拼接形成一个完整的序列,在训练过程中我们并不区分它们或插入特定的标记。只有c:,1​ 在推理时被预测,而前缀 c~:,1​ 在推理中给出。

对于从第二个到最后一个量化器的离散令牌 c:,j​(其中 j∈[2,8]),我们训练一个非自回归(NAR)语言模型。由于在 NAR 方式中,令牌之间无法相互访问,因此使用声学提示矩阵 C~ 作为声学提示,从而约束说话者身份。因此,模型以音素序列 x、声学提示 C~属于前一个代码本的预测声学令牌 C:,<j​ 为条件进行训练

AR 模型和 NAR 模型的结合在语音质量和推理速度之间提供了良好的平衡。一方面,生成语音的速率应与已注册的录音一致,但由于不同说话者的语速可能差异很大,训练一个针对不同说话者的长度预测器是困难的。在这种情况下,AR 模型是更自然的选择,因为它在声学序列长度预测上具有灵活性。另一方面,对于后续阶段,由于输出槽的数量遵循第一阶段的序列长度,NAR 可以将时间复杂度从O(T) 降至 O(1)。总体而言,C 的预测可以建模为:

自回归编解码语言建模

自回归语言模型生成来自第一个量化器的标记。该模型包括音素嵌入 Wx​、声学嵌入 Wa​、一个变换器解码器和一个预测层。为了生成具有特定内容的语音,我们使用音素序列作为语言模型的音素提示。因此,模型输入是 x 和 c:,1​ 的连接,并在每个序列后附加两个特殊的 <EOS> 标记。我们为提示和输入标记分别计算波动的位置嵌入。对于因果变换器模型,每个标记 ct,1​ 可以关注到(x,c<t,1​)。该模型的优化目标是最大化第一个代码本中下一个标记的概率。我们共享输出投影层的参数与声学嵌入 Wa​ 的参数。

在自回归模型中,我们不在训练时显式提取音频片段作为提示。训练过程完全是因果语言模型训练。通过这种方式,任何前缀序列c<t,1​ 被视为后续序列 c≥t,1的提示。在推理过程中,给定已注册的录音,我们应将已注册录音的音素序列与合成的音素序列连接起来。同时,将已注册录音的声学标记序列用作自回归解码中的前缀。

在通过自回归模型获得第一个量化器的代码后,我们使用非自回归(NAR)模型生成其他七个量化器的代码。NAR 模型的架构与 AR 模型类似,只是包含八个独立的声学嵌入层。在每个训练步骤中,我们随机抽取一个训练阶段i∈[2,8]。该模型的训练目标是最大化来自第 i 个量化器代码本的声学标记。来自阶段 1 到阶段i−1 的声学标记被嵌入并求和作为模型输入:

其中 ⋅ 表示索引选择。音素序列同样被视为语言模型的提示。此外,为了克隆给定说话者的独特声音,我们还使用来自已注册语音的声学标记作为声学提示。具体来说,我们首先使用神经编解码模型对已注册语音进行标记,得到C~T×8​。来自八个代码本的嵌入表示被求和作为声学提示。为了预测来自第 i 个代码本的声学标记,变换器输入是音素嵌入ex​、声学提示 ec~​ 和 c:,<i​ 的连接。位置嵌入也分别为提示和声学序列计算。当前阶段 iii 通过自适应层归一化(AdaLN)操作注入到网络中,即 AdaLN(h,i)=aiLayerNorm(h)+bi,其中 h 是中间激活,ai​ 和 bi​ 是通过阶段嵌入的线性投影获得的。与 AR 不同,NAR 模型允许每个标记在自注意力层中关注所有输入标记。我们还共享声学嵌入层和输出预测层的参数,这意味着第 j 个预测层的权重与第 j+1 个声学嵌入层相同。

VALL-E X

论文:https://arxiv.org/abs/2303.03926

受VALL-E启发的跨语言编解码语言模型VALL-E X:受VALL-E的启发,跨语言编解码语言模型VALL-E X(记为φ)利用一个多语言自回归编解码语言模型和一个多语言非自回归编解码语言模型来生成不同粒度的声学标记,如图2左侧所示。我们还采用了神经编解码模型EnCodec [Défossez等人,2022] 作为声学量化器,这是一个具有L层量化层的编码器-解码器模型。在我们的实验中,我们选择L = 8,每一层以75Hz的频率生成1024个条目的量化码。

多语言自回归编解码语言模型:多语言自回归编解码LMφMAR是一个单向Transformer解码器,它基于语义标记(音素序列)自回归地生成声学标记。为了使句子级训练更高效并在推理过程中加速解码,类似于VALL-E,跨语言自回归编解码LMφMAR仅用于预测EnCodec模型第一层量化器的声学标记。

形式上,基于任何语言中的配对语音-转录数据,设S表示转录的音素序列,A:,1 = {ai,1 | i = 1, …, N} 表示从语音X中提取的第一层声学标记。解码器φMAR建模拼接序列〈S, A:,1〉,并被训练来自回归地预测A:,1。通过最大化对数似然来进行优化:

⟨⟩ 表示序列拼接操作。p(⋅) 是softmax函数。

多语言非自回归编解码语言模型:与自回归生成模式不同,多语言非自回归编解码语言模型φMNAR是一个非自回归Transformer语言模型,旨在迭代地从第一层生成其余层的声学标记。它由当前句子的音素序列 S 和具有相同说话人的另一句子的声学标记序列 A~ 提示。这里的 A~ 通常取自数据集中的前一句子,这些调整后的句子通常是从同一段落中分割出来的。预期 A~ 具有与当前句子相同的语音特征(如说话人、语速、背景等),并用作克隆目标语音的额外参考。

类似于VALL-E,对于生成每一层l∈[2,8] 的声学标记,前l−1层声学标记A:,1:l−1​的嵌入按层相加作为输入。第 l 层声学标记 A:,l 的学习目标可以计算为:

其中〈〉表示序列拼接。pNAR(.) 计算 A:,l 的逐点概率。

多语言训练:为了学习跨语言的声学转换信息,以支持跨语言TTS和语音到语音翻译任务,我们利用双语语音-转录(ASR)语料库,即 (Ss, As) (St, At) 的配对数据来训练我们的多语言编解码语言模型 φMAR 和 φMNAR,其中 s t 分别代表两种不同的语言(源语言和目标语言)。

语言ID模块:借鉴多语言TTS的方法,我们使用语言ID来指导VALL-E X中特定语言的语音生成。一方面,如果没有语言ID,VALL-E X可能会因为在多语言数据上进行训练而难以选择适合特定语言的声学标记。另一方面,某些语言具有非常不同的特征,例如,中文是一种声调语言,而英语是非声调语言,这增加了跨语言调整说话风格的难度。我们的实验发现,在多语言自回归编解码语言模型 φMAR 的输入中添加语言信息对于引导正确的说话风格和缓解L2口音问题非常有效,这一点将在第5.5节中详细介绍。具体来说,我们将语言ID嵌入到密集向量中,并将其添加到声学标记的嵌入中。

跨语言推理

训练完成后,VALL-E X 可以执行跨语言语音合成,如图 3 所示。具体来说,我们首先将源音素 Ss 和目标音素St 作为提示符进行拼接,并将第一层源声学标记A:,1s​ 作为解码前缀,基于此,多语言自回归编解码语言模型ϕMAR​ 生成第一层目标声学标记A:,1t​

其中 ∼ 表示基于概率的采样。采样过程会在{<end-of-sentence>} 标记被采样到时停止。如 3.3 节所述,语言 ID 用于控制生成语音的说话风格。在从ϕMAR​ 获得第一层目标声学标记 A:,1t​ 后,使用多语言非自回归编解码语言模型 ϕMNAR​ 来预测剩余的声学标记层 {A:,lt​∣l=2,…,8},通过贪心搜索,即选择最大概率的标记,

最后,我们使用 EnCodec 的解码器来综合完整的目标声学标记 A:,1:8t​ 生成目标语音。

VALL-E R

论文:https://arxiv.org/abs/2406.07855

图 1: VALL-E R 的概述。它同步预测声学符元(蓝色)及其对应的音素序列(绿色),这可以加强音素和音频之间的对齐,从而提高 VALL-E 模型的鲁棒性。 请注意,VALL-E R 通过在其自回归模型中采用提议的合并编解码器代码来实现更快的推理速度。

一种鲁棒且高效的零样本 TTS 系统,名为 VALL-E R。我们首先介绍了编解码器合并方法,该方法可在不重新训练编解码器的情况下提高推理速度,然后阐述了仅解码器神经编解码器 LM 中的单调对齐策略。

编解码器合并方法。

在借鉴 Encodec 基础工作的基础上,我们引入了合并编码器的概念。这一创新方法通过改变推理前向过程,实现了在各层离散码的下采样,显著地提高了对音频数据表示的高效操作。这一突破无需对模型进行重新训练或微调,标志着在音频数据表示操作上的重要进展。

如图 2 所示,所提出的编码器在视觉上进行了描述。整体架构与 Encodec 保持一致,包括以下三个组件:1)基于卷积的编码器,将波形数据x1×L​ 映射为潜在表示序列 zF×T​,其中 F 是通道数,T 是提取码的长度;2)解码器,从量化的潜在表示 z^F×T​ 中重建数据 x^1×L​ ;3)8 层残差向量量化器(RVQ)模块,可以将连续的潜在向量 zF×T​ 逐步转换为离散码表示 C8×T​。主要区别在于,我们的合并编码器在向量量化器模块之前插入了一个编码器合并模块,以对表示 zF×T​ 进行下采样。

假设第 d 层的合并率为 md​,rdF×T​ 代表第 d 层的残差输入。合并编码器模块包含两个步骤:第一步是通过平均池化将残差输入rdF×T 下采样为 rmd​​F×(T/md​),然后通过repeat操作将 rmd​​ 上采样回其原始长度。接着,经过合并模块处理的残差表示将被输入到后续的 VQ 层,通过对码本嵌入进行最近邻查找,量化为离散码Cd1×T​。通过合并模块,我们确保了连续 md​ 帧的码的一致性,从而降低了 Cd1×T 的分辨率。

具有单调对齐的神经编解码器 LM

以前,单调策略仅适用于编码器-解码器结构。 为了解决基于解码器-仅 Transformer 的 TTS 中的鲁棒性问题,我们将音素预测集成到神经编解码器 LM 的训练中,并在推理过程中设计了单调对齐策略。 概述如图 3 所示。

为了在语音质量和推理速度之间取得良好的平衡,我们的 VALL-E R 包含两个模型:自回归 (AR) 和非自回归 (NAR),这与 VALL-E (Wang et al., 2023a) 相一致。 具体来说,给定一个训练数据对 {𝐬,𝐩},其中 𝐬 是语音样本,𝐩={p1,p2,…,pL} 是其相应的音素转录。 然后,编解码器合并模型用于将语音波形 𝐬 压缩成具有 8 个量化器的离散声学符元 𝐀,公式为:MergeCodec⁢(𝐱)=𝐀8×T={𝐚1,…,𝐚8},其中 T 是离散码的长度,𝐚i={a1,…,aT} 表示第 i 层的符元。 由于 VALL-E R 的训练需要对齐的音素和声学符元,因此此处采用对齐工具将 𝐩 与声学符元 𝐀 对齐,表示为 𝐩^1:T={p1^,p2^,…,pL^},其中 p^i 包含 Ni 个重复的 pi 和 ∑i=1LNi=T。

对于 AR 阶段,为了增强音素和声学序列之间的联系,我们构建了一个神经编解码器 LM θA⁢R,以使用音素预测对来自编解码器合并模型的第一个量化器的离散声学符元 𝐚1:T1 进行建模。 如图 3 所示,它以音素序列 𝐩 为条件,同时生成声学符元 𝐚1:T1 和对齐的音素 p^1:T,公式为最大化以下概率:

在第二阶段,我们训练了一个 NAR LM θN⁢A⁢R,以从第 2n⁢d 到第 8-t⁢h 层量化器迭代地生成声学符元。 它以音素序列 𝐩、先前几层生成的声学符元 𝐚1:n 和音素对齐 l1:T 为条件,以预测下一层声学符元 𝐚n+1,公式为最大化:

我们还共享声学嵌入层和输出预测层的参数,这意味着第 j 个预测层的权重与第 (j+1) 个声学嵌入层相同。

在推理过程中,利用语言模型强大的上下文学习能力,我们提出的 VALL-E R 可以通过自回归预测声学和音素来自动克隆提示中说话人的音色和韵律。 由于 VALL-E R 明确地对音素进行建模,因此它对韵律具有很强的控制力:当我们在推理过程中使用预设的音素序列替换自预测的音素序列时,我们可以使用预设的韵律来生成语音,从而实现分别控制韵律和音色的效果。 它也可以被认为是一种语音转换任务,其目标是在不改变源语音的语言信息和韵律的情况下,使目标语音的音色听起来像提示语音。

VALL-E 2

论文: https://arxiv.org/abs/2406.05370

基于其前身 VALL-E,新迭代引入了两项重大增强功能:重复感知采样通过考虑解码历史中的词符重复来改进原始核心采样过程。 它不仅稳定了解码,还避免了无限循环问题。 分组代码建模将编解码器代码分组,有效缩短序列长度,不仅提高了推理速度,还解决了长序列建模的挑战。 

基于过往经验,研究员们发现 VALL-E 在推理中使用的随机采样可能会导致输出不稳定。尽管错误编码(图3中的红色方块)的概率很低,但由于采样步骤太多,它们仍然不可避免地会被采样到。为了稳定推理过程,通常会利用 Nucleus 采样来从累积概率低于预设阈值的最可能标记集合中进行采样。Nucleus 采样方法可以减少说错词的错误,但也可能导致模型为了减少错误而只生成静音。

因此,为了平衡随机采样和 Nucleus 采样,研究员们提出了重复感知采样的方法。在给定 AR 模型预测的概率分布基础上,研究员们首先使用预定义的 top-p 值通过 Nucleus 采样生成目标编码。然后使用固定的窗口大小来计算预测编码在前面的编码序列中的重复比例。如果重复比例超过预定义的重复阈值,研究员们就会使用随机采样从原始概率分布中获得新的预测结果来替换原来的目标编码。通过这种重复感知采样的方法,解码过程既可以受益于 Nucleus 采样的稳定性,还可以借助随机采样避免陷入静音的无限循环。

继VALL-E之后,我们使用现成的神经音频编解码器模型将语音信号表示为离散编解码器代码序列,并将TTS视为条件编解码器语言建模任务。 为了提高效率,VALL-E 2引入了分组编解码语言建模方法,将编解码代码序列划分为一定大小的组,并将每组编解码代码建模为一帧。 这样我们就可以摆脱现成的神经音频编解码模型的帧率约束,将帧率降低整数倍。 它不仅有利于推理效率,而且通过缓解长上下文建模问题也有利于整体语音质量。

VALL-E 2 的训练概述,由自回归和非自回归 Transformer 组成。 请注意,自回归 Transformer 旨在生成分组编解码器代码。

通过 TTS 训练目标,VALL-E 2 被优化以最大化给定文本条件的分组代码序列的可能性。 具体来说,给定一个音频样本 𝐲 及其相应的标记化文本转录 𝐱=[x0,x1,…,x(L−1)],其中 L 是文本序列长度,我们首先使用预训练的神经音频编解码器模型,用于将音频样本𝐲转换为编解码器代码序列𝐂T×J=[𝐜0,𝐜1,…,𝐜(T−1)],其中T是代码序列长度,J(这里J=8)是编解码器模型中量化器的数量,每个𝐜t代表每个时间步的8个代码。 然后我们将其划分为分组代码序列𝐂G=[𝐂0:G,𝐂G:2⁢G,…,𝐂(T−G):T],组大小为G,𝐂0:G代表组[𝐜0,𝐜1,…,𝐜(G−1)]。 由于话语开头通常有短暂的沉默,我们可以从代码序列的开头剪掉一些代码,让代码序列长度T为组大小的整数倍,而不需要删除任何代码。语音信息。 最后,我们训练 VALL-E 2 模型 θ 以最小化以文本序列 𝐱 为条件的分组代码序列 𝐂G 的负对数概率:

其中𝐂t⋅G:(t+1)⋅G是第t组编解码器代码[𝐜t⋅G,…,𝐜((t+1)⋅G−1)],𝐂<t⋅G是前面(t−1) 组。

推理过程中,VALL-E 2根据提示执行零样本TTS任务。 给定文本输入(包含语音提示的转录和要合成的文本)和来自看不见的说话者的分组编解码器代码,作为条件和提示,该模型可以生成具有相应内容和说话者语音的目标分组编解码器代码。 具体来说,给定文本序列𝐱和未见过的说话人的登记语音样本𝐲′,我们可以获得相应的分组代码序列𝐂P=𝐂<T′G=[𝐂0:G,𝐂G:2⁢G,…,𝐂(T′−G):T′]。 然后,我们以文本序列 𝐱 和代码提示 𝐂P 为条件生成目标分组代码序列 𝐂T=𝐂≥T′G=[𝐂T′:(T′+G),…,𝐂(T−G):T]:

最后,我们可以使用现成的神经编解码器将目标代码序列 𝐂T 转换为目标语音波形。

在 VALL-E 的基础上,VALL-E 2 还使用分层结构:自回归 (AR) 编解码器语言模型和非自回归 (NAR) 编解码器语言模型。 AR模型以自回归的方式生成每一帧的第一编解码器代码的序列,而NAR模型以非自回归的方式基于前面的代码序列生成每个剩余的代码序列。 两种模型都使用相同的 Transformer 架构,其中包含文本嵌入层、代码嵌入层和代码预测层。 我们对来自不同编解码器量化器的代码使用不同的嵌入,并与代码嵌入层的参数共享代码预测层的参数。 此外,AR模型还有一个组嵌入层,用于将代码嵌入投影到组嵌入,以及一个组预测层,用于预测一组中的代码。 NAR模型有一个代码ID嵌入层来指定要预测的代码序列的ID。 AR 模型和 NAR 模型具有不同的注意力掩码策略:AR 模型使用因果注意力策略,而 NAR 模型使用完全注意力策略,如图 2 的右侧所示。

为了加速推理过程,研究员们在 VALL-E 2 中采用了分组编码建模方法,将编码序列划分为一定大小的分组,并将每组编码建模为一步。在自回归模型中,研究员们利用分组嵌入层将编码嵌入结果映射到分组嵌入并作为网络的输入,并在输出层使用分组预测层对一组中的编码进行预测。通过这种方式,现有神经音频编码模型的帧率限制得以摆脱,帧率成倍数地降低得到实现。这不仅有利于推理效率的提高,还可以缓解长上下文建模的问题并提升整体语音质量。

图3 VALL-E 2 的推理概述,利用所提出的重复感知采样方法在自回归模型推理期间预测分组代码序列。

VALL-E 2的训练只需要简单的语音转录对数据,不需要任何复杂的数据,例如力对齐结果或同一说话者的额外音频片段以供参考。 这极大地简化了训练数据的收集和处理过程。

MELLE

论文:https://arxiv.org/abs/2407.08551

ELLE 是一种基于连续值令牌的新型语言建模方法,用于文本到语音合成 (TTS)。MELLE 直接从文本条件自回归生成连续的 mel 频谱图帧,绕过了向量量化的需求,与梅尔频谱图相比,矢量量化最初是为音频压缩和牺牲保真度而设计的。具体来说,(i) 我们应用回归损失和提出的频谱图通量损失函数,而不是交叉熵损失来模拟连续值标记的概率分布。(ii) 我们已将变分推理纳入 MELLE 以促进采样机制,从而提高输出多样性和模型稳健性。实验表明,与两阶段编解码器语言模型 VALL-E 及其变体相比,单阶段 MELLE 通过避免采样离散代码的固有缺陷来缓解健壮性问题,在多个指标上实现卓越的性能,最重要的是,它提供了一个更简化的范式。

MELLE包含以下主要组件:预网络,分别将文本转换为子词标记并在投影之前从语音中提取梅尔频谱图模型尺寸;充当语言模型的自回归 (AR) Transformer 解码器;潜在采样模块,从预测的高斯分布中采样潜在嵌入,然后将其投影回频谱图空间;确定语音结尾的停止预测层和用于声谱图细化的卷积后网络,类似于(Shen等人,2018;Li等人,2019)中描述的方法。 最后,使用声码器从生成的梅尔频谱图中恢复语音。

与迭代预测多层编解码器代码的神经编解码器语言模型不同,由于梅尔谱图的完整性,我们不需要额外的非自回归(NAR)模型。 这种简化显着提高了计算和存储效率。 此外,通过调整缩减因子,MELLE可以一步生成多个梅尔谱图帧,进一步提高效率,同时仍保持卓越的性能。

在每个自回归步骤中,MELLE 预计会根据文本提示 𝒙 和之前生成的 mel- 来预测下一个梅尔谱图帧 𝒚t。

在推理过程中,MELLE通过像VALL-E一样的提示来执行零样本TTS任务。 给定用于合成的文本内容𝒙、文本转录𝒙~和语音提示的梅尔频谱图𝒚~,该模型旨在生成目标梅尔频谱图𝒚对应的内容,同时保留提示中原说话人的特征,每一步的最大似然概率为arg⁢max𝒚⁡p⁢(𝒚t⋅r:(t+1)⋅r∣[𝒙~;𝒙;𝒚~;𝒚<t⋅r];θ),其中[;]表示串联操作,如果 r=1,则返回标准模式。

我们采用单向 Transformer 解码器作为语言模型(LM),根据文本输入和声学提示自回归生成声学连续特征。 具体而言,输入文本标记 x,在附加了 <EOS> 标记后,首先通过基于其索引的文本嵌入层转换为嵌入表示。同时,我们采用多层感知器(称为 pre-net)将梅尔谱图 𝒚 投影到语言模型维度。 LM 由多头注意力块和前馈层组成,将文本和声学嵌入的串联作为输入来对语义和声学信息之间的依赖关系进行建模。 LM 𝒆t 在时间步 t 的输出随后由 MELLE 的以下模块处理,以合成下一帧输出

我们在MELLE中集成了一种新颖的潜在采样模块,旨在增强表达多样性和鲁棒性,如图2(左)所示。 该模块根据 LM 的输出 𝒆t 预测分布,并从中采样潜在嵌入 𝒛t。

我们使用线性层作为二元分类器,用 𝒆t 来确定生成是否应该结束,如图 2(中)所示。 继之前的神经 TTS 模型(Wang 等人,2017;Shen 等人,2018)之后,我们采用多个卷积块作为后网络来产生残差并添加到 𝒚′={𝒚0′,𝒚1′,…,𝒚T−1′},得到精炼的梅尔谱图𝒚′′={𝒚0′′,𝒚1′′,…,𝒚T−1′′},如图2(右)所示。 在训练过程中,模型使用教师强制进行训练;而在推理过程中,后网络在 AR 生成结束后处理𝒚′。

RALL-E

论文:https://arxiv.org/abs/2404.03204

RALL-E背后的核心思想是思想链(CoT)提示,它将任务分解为更简单的步骤,以增强基于LLM的TTS的稳健性。 为了实现这个想法,RALL-E 首先预测输入文本的韵律特征(音调和持续时间),并将它们用作中间条件来预测 CoT 风格的语音标记。 其次,RALL-E利用预测的持续时间提示来指导Transformer中自注意力权重的计算,以强制模型在预测语音标记时关注相应的音素和韵律特征。

 RALL-E的核心思想是CoT提示,生成中间结果来辅助和稳定语音标记的生成,提高基于LLM的TTS的鲁棒性。 为了实现这个想法,我们首先建议在预测语音标记之前预测两种音素级韵律标记:音调和持续时间。 韵律标记的分布由单个 Transformer 与语音标记一起建模,以便它们可以影响预测的语音标记的持续时间和音调。 为了进一步利用预测的持续时间来指导生成并提高鲁棒性,我们提出了持续时间引导的掩蔽来增强语言模型学习的语音标记、音素和韵律标记之间的对齐。 在语音标记的每个解码步骤中,RALL-E 根据持续时间信息屏蔽与当前语音词符的合成无关的音素和韵律标记。

Prosody 标记作为思路提示。基于LLM的TTS的问题之一是它直接从音素生成语音,对韵律没有限制,例如:音高、时长等,通常会导致语音韵律不稳定。 CoT提示的思想是将一个复杂的任务分解为几个简单的任务,以便大语言模型利用中间结果得出最终答案。通过 CoT 提示,LLMs 在复杂任务上的正确率可以得到显著提高。 这促使我们通过在生成语音标记之前生成中间韵律标记来将 CoT 提示适应基于 LLM 的 TTS,以缓解基于 LLM 的 TTS 的鲁棒性问题。 为了将音高和持续时间合并到 VALL-E 的 AR Transformer 中,我们首先获得音素和语音标记之间的对齐,并提取每个语音词符的音高值。 然后,我们根据持续时间计算音素级音高值,并将其线性量化为 Mp 桶。 我们定义一个最大持续时间值Md,所有超过Md的持续时间值将被截断为最大值。 RALL-E 以 CoT 风格预测语音标记之前的两个韵律标记。 形式上,假设𝐩,𝐝是目标语音标记𝐂的离散音高和持续时间序列,𝐩~,𝐝~是提示𝐂~的离散音高和持续时间序列,我们对以下分布进行建模并最大化:

其中 L 是 𝐱 的长度。 在实践中,模型用两个独立的头来预测 pt 和 dt,它们的嵌入被总结并输入到模型中以进行下一步的预测。 然后,RALL-E 使用 𝐩 和 𝐝 作为新的条件预测语音符元,这使得等式 2 变成:

上述两个方程可以通过 AR Transformer 联合优化。 虽然所提出的方法增加了额外的L解码步骤,但由于L≪T,直观上对效率影响很小。

对于 NAR Transformer,我们只需将音素、音高和持续时间的嵌入求和作为输入。 这使得等式 3 变成:

如图 2 左侧所示,由于语音符元会关注 VALL-E 的 AR Transformer 中的所有音素,因此音素和语音符元之间的对齐由 VALL-E 的自注意力隐式建模。 这可能不精确并会导致诸如遗漏或幻觉之类的错误。 尽管RALL-E引入了韵律CoT提示来指导和稳定生成,但我们仍然发现模型在实验中可能无法对齐。 因此,我们提出持续时间引导掩蔽,以充分利用中间持续时间结果并提高鲁棒性。

如图 2 右侧所示,在提出的持续时间引导掩蔽中,语音符元被限制为仅关注以其对应音素(韵律符元)为中心的音素(韵律符元)窗口。 我们将窗口大小定义为k,因此每个语音词符可以参与2⁢k+1音素和2⁢k+1韵律标记。 其他位置的所有音素和韵律标记都将被屏蔽,因此它们的注意力权重始终为零。 当k=0时,语音词符严格关注其对应的音素。 如果对齐完美,这应该就足够了。 然而,在实验中,我们发现我们的对齐工具得到的对齐结果通常存在误差。 因此,我们通过允许语音词符出现在相应音素的附近音素处来放宽限制。 这种设计的另一个原因是音素的发音通常依赖于附近的音素。 正如将在第 4.3 节和附录 A 中看到的,实验结果验证了这种设计的有效性。 对于 NAR Transformer,我们在基础知识实验中应用所提出的掩蔽策略时几乎没有获得任何增益。 因此我们只在 AR Transformer 上应用屏蔽策略。

一般推理过程遵循 VALL-E [29],但有两个不同之处。 首先,在对语音词符 𝐜:,1 进行采样之前,先根据音素序列 𝐱 和声音提示 𝐩~,𝐝~ 对前音词符 𝐩 和 𝐝 进行采样。 其次,尽管普通语言模型依赖于一个特殊的词符 <eos> 作为停止条件,但由于我们知道总时长 D=∑t=1Ldt,因此我们提出了一种时长引导推理方法,强制推理在 D 步停止。 如果在 D 步之前预测到 <eos> 词符,该方法就会继续推理,并根据预测的持续时间在正确的步骤停止,从而确保不会遗漏或重复任何音素。

Seed-Music: 字节高质量音乐生成模型

字节音乐大模型Seed-Music发布,支持一键生成高质量歌曲、片段编辑等

关键内容

关键技术贡献如下:

  • 提出了一种基于新型 token 和语言模型(LM)的方法,并引入了一种能够根据不同类型用户输入生成专业生成内容(PGC)质量音乐的训练方法。
  • 提出了一种全新的基于扩散模型的方法,特别适合音乐编辑
  • 引入了一种在歌唱声音背景下的零样本声音转换的新颖方法。系统可以根据用户短至 10 秒的参考歌唱或甚至普通语音的音色生成完整的声乐混音。

据豆包大模型团队官网介绍,Seed-Music 是一个具有灵活控制能力的音乐生成系统,包含 Lyrics2Song(歌词转歌曲)、Lyrics2Leadsheet2Song(歌词转简谱再转歌曲)、Music Editing(音乐编辑)、Singing Voice Conversion (歌声转换)四大核心功能,具体涵盖十种创作任务。

目前,业界在 AI 音乐领域的研究主要集中在以下几个核心问题:

  • 音乐信号的复杂性:音乐信号包含多个重叠音轨、丰富的音调和音色以及广泛的频率带宽,不仅要保持短期旋律的连贯性,还要在长期结构上展现出一致性。
  • 评估标准的缺乏:音乐作为一种开放、主观的艺术形式,缺乏一套通用的问题表述和用于比较的黄金指标,评估局限性大。
  • 用户需求的多样性:不同的用户群体,如音乐小白、音乐初学者、资深音乐人等,对音乐创作的需求差异很大。

无论是传统的音乐辅助创作工具,还是当下热门的 AI 音乐生成的研究和产品,面向上述问题,均还处于摸索阶段。
比如针对音乐信号复杂性,Google、Meta、Stability AI 等各家在音频、演奏、曲谱层面上做了建模尝试,效果各有优缺,而且各家的评估方法均有局限,人工评测仍必不可少。
面对这些挑战,字节 Seed-Music 采用了创新的统一框架,将语言模型和扩散模型的优势相结合,并融入符号音乐的处理。

如上图所示,从高层次来看 Seed-Music 有着统一的音乐生成框架,主要包含以下三个核心组件:一个表征模型,用于将原始音频波形压缩成某种压缩表征形式;一个生成器,经过训练可以接受各种用户控制输入,并相应地生成中间表征;一个渲染器,能够从生成器输出的中间表征中,合成高质量的音频波形
基于统一框架,Seed-Music 建立了三种适用于不同场景的中间表征:音频 token、符号音乐 token 和声码器 latent。

  • 音频 token:通常以低于音频采样率的标记率学习,旨在有效编码语义和声学信息,能轻松桥接不同模态,但不同音乐信息高度纠缠,给生成器带来挑战。对应图二Audio Tokenizer的输出。
  • 符号音乐 token:如 MIDI、ABC 记号或钢琴卷帘记号等,本质上离散,可被大型语言模型操作,具有可解释性,便于用户在辅助音乐创作中交互,但缺乏声学信息,依赖渲染器生成声学细节。对应图二的MIDI编码器输出。
  • 声码器 latent在探索基于扩散模型的音乐音频生成中可作为中间表征,与量化音频标记相比,信息损失少、渲染器权重更轻,但生成器输出不可解释,且由于仅用波形重建目标训练,可能不够有效作为训练生成器的预测目标。对应图二扩散模型的输出部分。
模型架构跟Seed-TTS类似

满足多元需求专门提供高灵活编辑

Seed-Music 创新点之一,在于能通过 lead sheet(领谱)来编辑音乐,这增加了音乐创作可解释性。
在官方视频的 Lead2Song 部分,可以看到同一版歌词,通过领谱增减音轨、改变输入风格后,就能得到不同结果的歌曲,显著提高模型的实用性。
除领谱外,Seed-Music 也能直接调整歌词或旋律。比如,“情人节的玫瑰花,你送给了谁 / 你送给别人”,歌词修改前后,旋律保持不变,音乐的连贯性得以保持,过渡效果非常平滑。

输入内容除了文本,也可以是音频,它能基于原曲输出续作或仿作。下面这首英文歌曲“摇身一变”,仿写成了中文古风歌。

哪怕输入临时录制的 10 秒人声, Seed-Music 的零样本音频转换技术都能够将其转化为流畅的声乐。惊喜的是,Seed-Music 能将中文人声输入转换为英文声乐输出,实现了跨语种人声克隆,扩大了音乐小白们的创作空间。

Seed-Music pipeline:模型架构

如图所示,中间表征对整个系统来说很重要,每种表征都有其特点和适用场景,具体选择取决于用户的音乐创作任务。

  • 基于音频 token 的链路:包括 tokenizer、自回归语言模型、token 扩散模型和声码器,音频 token 有效地存储了原始信号的显著音乐信息,语言模型根据用户控制输入生成音频 token,token 扩散模型处理音频 token 以生成具有增强声学细节的音频波形
  • 基于符号音乐 token 的链路:采用符号音乐 token 作为中间表征,与音频 token 基于的管道类似,但有一些区别,如 lead sheet tokenizer 将信息编码为 token,语言模型学习预测 lead sheet token 序列,lead sheet token 是可解释的,并且允许在训练和推理中注入人类知识,但扩散模型从 lead sheet token 预测声码器 latent 更具挑战性,需要更大的模型规模。
  • 基于声码器 latent 的链路:遵循通过 latent 扩散建模从文本直接生成音乐到声学声码器 latent 表征的工作,通过变分自编码器和扩散模型将条件信号映射到归一化和连续的声码器 latent 空间。

在上述链路中,Seed-Music 经历三个训练阶段:预训练、微调和后训练。预训练旨在为音乐音频建模建立强大的基础模型;微调包括基于高质量音乐数据集的数据微调,以增强音乐性,或者针对特定创作任务提高可控性、可解释性和交互性的指令微调后训练是通过强化学习进行的,从整体上提高了模型的稳定性。
此外,在推理时,样本解码方案对于从训练模型中诱导出最佳结果至关重要。研究者们同时会应用模型蒸馏和流式解码方案来提高系统的延迟。

论文:《Seed-Music: Generating High-Quality Music in a Controlled Way》

摘要:

我们推出 Seed-Music,这是一套音乐生成和编辑系统,旨在通过细粒度的风格控制来制作高质量的音乐。我们的统一框架利用自回归语言建模和扩散方法来支持两个关键的音乐创作工作流程:受控音乐生成和后期制作编辑。为了控制音乐生成,我们的系统可以通过多模式输入的性能控制来生成声乐,包括歌词、风格描述、音频参考、乐谱和语音提示。对于后期制作编辑,它提供了交互式工具,可直接在现有音乐音轨中编辑歌词、旋律和音色。我们鼓励读者探索 https://team.doubao.com/seed-music 上的演示音频示例。

贡献。鉴于这些挑战,我们强调Seed-Music的多功能性。它支持声乐和器乐音乐生成、歌唱声合成、歌唱声转换、音乐编辑等。我们的方法、实验和解决方案旨在满足多样化的使用案例。我们提出一个统一框架,适应音乐家的不断发展工作流程,而不是依赖于单一的建模方法,如自回归(AR)或扩散。我们的关键贡献包括:

  • 我们介绍了一个统一框架,该框架结合了自回归语言建模和扩散方法,以实现基于多种多模态输入的高质量声乐生成
  • 我们提出了一种基于扩散的方法,能够对音乐音频进行细粒度编辑。
  • 我们提出了一种新颖的零样本歌唱声转换方法,仅需用户提供10秒的歌唱或语音录音。

第三部分介绍框架,该框架建立在三种基本表示上:音频标记、符号标记和声码器潜变量。将详细说明相应的流程和设计选择。在第四部分,我们深入探讨了我们的统一框架如何配置和训练以支持各种音乐生成和编辑任务。在第五部分和第六部分,我们讨论了Seed-Music的潜在应用和局限性,包括构建安全和道德生成AI系统的相关问题。

Method

我们的音乐生成系统由三个核心组件组成,如 Figure 1 所示:一个 表示学习模块,它将原始音频波形压缩为中间表示,作为训练后续组件的基础;一个 生成器,它处理各种用户控制输入并生成相应的中间表示;以及一个 渲染器,它根据生成器中的中间表示合成高质量的音频波形。

主要设计选择是中间表示。如第2节所述,我们确定了三种实用的选项:音频标记、符号音乐标记和声码器潜变量。每种选项的优缺点总结在表1中。

音频token旨在以远低于音频采样率的速率高效编码语义和声学信息。当与基于自回归语言模型的生成器一起使用时,音频标记可以有效连接不同的模态。然而,它们的主要限制在于缺乏可解释性,诸如声乐发音、音色和音高等音乐属性以高度纠缠的格式嵌入。先前的研究探讨了某些音频标记与语义特征的对应关系,而其他标记则捕捉声学方面。这种纠缠使生成器在生成音频标记时难以控制音乐的特定元素,如旋律和音色

符号token(如MIDI、ABC符号和MusicXML)是离散的,可以轻松地被标记化为与语言模型兼容的格式。与音频标记不同,符号表示是可解释的,允许创作者直接读取和修改。然而,它们缺乏声学细节,这意味着系统必须高度依赖渲染器生成音乐表演的细腻声学特征。训练这样的渲染器需要大量的配对音频和符号转录数据集,而这种数据集在声乐音乐中尤其稀缺。

来自变分自编码器的声码器潜变量作为连续的中间表示,尤其是在与扩散模型结合使用时。这些潜变量捕获比量化音频标记更细致的信息,使得在此流程中渲染器可以更轻量化。然而,与音频标记类似,声码器潜变量也是不可解释的。此外,由于声码器潜变量是为了音频重构而优化的,它们可能编码过多的声学细节,这对生成器的预测任务帮助不大。

选择中间表示取决于具体的下游音乐生成和编辑任务。在本节的其余部分,我们将介绍系统设计的技术细节,以及这三种中间表示的应用案例,详见第4节。

Audio Token-based Pipeline

基于音频令牌的管道,如图2所示,包含四个构建块:(1) 音频令牌化器,将原始音乐波形转换为低速率离散令牌;(2) 自回归语言模型(即生成器),接收用户控制输入,将其转换为前缀令牌,并预测目标音频令牌序列;(3) 令牌扩散模型根据音频令牌预测声码器潜变量;(4) 声学声码器,渲染最终的44.1kHz立体声音频波形。目标音频令牌到潜变量扩散模块和潜变量到波形声码器模块共同形成令牌到波形的过程,称为渲染器。

图2. Seed-Music管道概述,使用音频令牌作为中间表示。(1) 输入嵌入器将多模态控制输入(如音乐风格描述、歌词、参考音频或乐谱)转换为前缀嵌入序列。(2) 自回归语言模型生成一系列音频令牌。(3) 扩散变换模型生成连续声码器潜变量。(4) 声学声码器生成高质量的44.1kHz立体声音频。

音频tokenizer。音频tokenizer的有效性对该管道的成功至关重要。音频令牌嵌入了原始信号中的关键信息,如旋律、节奏、和声、音素和乐器音色。我们的实现受到Betker [2023]、Wang等 [2023b] 和Łajszczak等 [2024]的启发,并在架构和训练上进行了进一步优化,以实现以下目标:
在低压缩率下高保留关键信息,提高自回归语言模型的训练效率。
在语义和声学特征之间保持平衡,确保有足够的语义细节来优化生成器的训练,同时保持足够的声学细节以便渲染器准确重建波形。这个令牌生成与信号重建之间的权衡 [Blau和Michaeli,2019] 被仔细管理。

生成器。自回归语言模型通过对控制信号进行条件处理生成音频令牌,这些控制信号引导生成期望的音频输出。每个训练示例由配对的注释和音频组成,注释被转换为一系列嵌入,作为语言模型的前缀。不同控制信号模态的处理总结如下:

分类信号:闭合词汇标签(如音乐风格)通过查找表转换为分类嵌入,而自由形式的文本描述则使用MuLan [Huang et al., 2022]的通用文本编码器进行处理
浮点信号:旋律音符持续时间或歌曲长度等变量使用xVal编码 [Golkar et al., 2023] 嵌入,以表示连续数值输入。
歌词信号:歌词被转换为音素序列,以捕捉发音,改善模型对未见单词的泛化能力。
参考音频信号:tokenizer从参考音频中提取离散令牌序列,然后将其映射到与tokenizer的码本大小相同的连续嵌入查找表中,或者进一步聚合为轨道级嵌入。
在训练过程中,模型通过使用教师强制在下一个令牌预测任务上最小化交叉熵损失。在推理阶段,用户输入根据指定模态转换为前缀嵌入,然后自回归地生成音频令牌。

渲染器。一旦自回归语言模型生成音频令牌,这些令牌就由渲染器处理,以生成丰富的高质量音频波形。渲染器是一个级联系统,由两个组件组成:扩散变换器(DiT)和声学声码器,两者均独立训练。DiT采用标准架构,具有堆叠的注意力层和多层感知机(MLP)。其目标是逆转扩散过程,从噪声中预测干净的声码器潜变量,通过在每一步估计噪声水平。声学声码器是低帧速率变分自编码器声码器的解码器,设计类似于[Kumar et al., 2024, Lee et al., 2022, Cong et al., 2021, Liu and Qian, 2021]。我们发现,将声码器潜变量结构化为级联系统中的信息瓶颈,并结合可控的模型大小和训练时间进行优化,能够产生优于直接将音频令牌转换为波形的单一模型的音频质量和更丰富的声学细节

Symbolic Token-based Pipeline

与音频令牌基础管道不同,符号令牌生成器(如图3所示)旨在预测符号令牌,以提高可解释性,这对解决Seed-Music中音乐家的工作流程至关重要。

图3. 使用符号令牌作为中间表示的管道概述。(1) 自回归语言模型根据用户提示生成对应于乐谱的符号令牌。(2) 扩散变换模型根据符号令牌生成连续声码器潜变量。(3) 然后,声码器生成高质量的44.1kHz立体声音频波形。

先前的研究提出了旋律生成算法 [Ju et al., 2021; Zhang et al., 2022]。然而,它们缺乏对声乐音乐生成至关重要的明确音素和音符对齐信息。此外,它们仍然仅限于符号音乐生成,无法进行音频渲染。在另一条研究线上,有一些特定任务的先前工作研究了通过和声 [Copet et al., 2024]、力度和节奏 [Wu et al., 2023] 等音乐可解释条件来引导音乐音频生成的方法。受到爵士音乐家如何使用乐谱来勾勒作品旋律、和声和结构的启发,我们引入了“乐谱令牌”作为符号音乐表示。我们强调乐谱令牌与音频令牌相比的关键组成部分、优点和局限性如下。

• 为了从音频中提取符号特征以训练上述系统,我们利用内部开发的音乐信息检索(MIR)模型,包括节拍跟踪 [Hung et al., 2022]、调性和和弦检测 [Lu et al., 2021]、结构部分分段 [Wang et al., 2022]、五种乐器的MIDI转录(即人声、钢琴、吉他、贝斯和鼓) [Lu et al., 2023; Wang et al., 2024a],以及歌词转录。乐谱令牌表示音符级细节,如音高、持续时间、在小节中的位置、与音符对齐的声乐音素,以及轨道级属性,如段落、乐器和节奏。

• 乐谱令牌与可读乐谱之间的一对一映射使创作者能够直接理解、编辑和与乐谱互动。我们尝试了不同的方法来生成乐谱令牌序列:REMI风格 [Huang和Yang, 2020] 和 xVal [Golkar et al., 2023]。REMI风格的方法将乐器轨道交错到量化的基于节拍的格式中,而xVal将起始和持续时间编码为连续值。虽然xVal风格编码在更贴合我们生成模型的最终产品——音乐表现,但我们发现REMI风格更适合与音乐家的用户互动。

• 乐谱令牌允许在训练和推理过程中融入人类知识。例如,可以在预测序列中下一个令牌时应用音乐理论规则作为约束,以提高预测准确性。

• 由于乐谱令牌缺乏声学特征表征,我们需要在级联渲染器中扩大令牌到潜变量的扩散模型,以实现与音频令牌基础系统相同的端到端性能。

Vocoder Latent-based Pipeline

先前的研究 [Evans et al., 2024c,d; Levy et al., 2023; Rombach et al., 2022] 表明,“文本到音乐”的任务可以通过直接预测声码器潜变量来实现高效的方法。类似地,我们训练了一个在低潜变量帧率下运行的变分自编码器(VAE),并配合一个扩散变换器(DiT),将条件输入映射到标准化的连续声码器潜变量,如图4所示。

图4. Seed-Music管道,使用声码器潜变量作为中间表示。(1) 通过交叉注意、前缀或时间条件将各种输入类型输入到扩散变换器(DiT)。(2) 扩散变换模型预测连续声码器潜变量。(3) 然后,声学声码器生成高质量的44.1kHz立体声音频

基于音频令牌的管道相比(见第3.1节),自回归变换器模块被省略,尽管DiT和声码器的架构仍然大体相似。为了实现可比的性能,其他剩余模块的模型大小被扩大。在自回归方法中,所有条件输入被编码为前缀序列中的令牌,这可能导致过长的前缀,从而在处理更大和更复杂的输入时性能下降。相反,基于声码器潜在设计提供了更大的灵活性,能够更好地融入更广泛的条件信号,并支持多通道输入和输出。我们总结了不同类型提示的使用方式如下:

  • 声码器潜在空间中的上下文条件:这使得音频修补场景成为可能,例如音频延续和编辑。
  • 输入噪声空间中的上下文条件:对于歌词和风格描述等可变长度输入,交叉注意层在每个变换器块中应用,以融入这些输入。
  • 跨多个轨道的时间输入:时间变化信号(如旋律轮廓、强度曲线和时间对齐的乐器音轨)可以在去噪过程中每一步添加作为条件输入。
  • 多通道输出:在训练期间提供多通道输出示例时得到支持。例如,模型可以生成多个音乐上不同的音轨(如人声、贝斯、鼓和吉他),从而实现混音和重混等下游制作场景。这些音轨级别的训练示例可以通过音乐源分离(MSS)获得。

Model Training and Inference

对于上述所有管道,Seed-Music经历三个训练阶段:预训练、微调和后训练,类似于Seed-TTS和其他基于文本的语言模型。预训练阶段旨在为通用音乐音频建模奠定更好的基础。微调阶段包括数据微调以增强音乐性,或指令微调以提高特定创作工作流程的可控性、可解释性和互动性。

Seed-Music的后训练通过强化学习(RL)进行,这已被证明在文本和图像处理方面是一种有效的学习范式。近期研究表明,近端偏好优化(PPO)可以扩展到音乐和语音生成。受这些发现的启发,我们探索了RL方法,以改善生成输出与各种输入控制信号的对齐,并增强音乐性。我们考虑的奖励模型包括:原歌词提示与从生成音频提取的歌词转录之间的编辑距离,输入流派与音频输出检测流派的比较精度,以及歌曲结构提示与生成音频检测结构之间的匹配。此外,基于节奏、乐器、音频参考和用户语音提示的额外奖励模型可以用于指示生成输出中强调哪些音乐属性。此外,结合人类反馈可以产生捕捉用户细微偏好的奖励模型。我们将对RL的深入研究留待未来工作。

在推理过程中,样本解码方案的选择对自回归和扩散模型的输出质量和稳定性至关重要。我们观察到,仔细调整无分类器引导至关重要,以确保音乐性和对提示的遵循。为了减少延迟,我们应用模型蒸馏以最小化DiT模型所需的迭代步骤。此外,我们开发了一种流式解码方案,允许在自回归模型继续生成令牌序列的同时进行音频流生成。

Experiments

在本节中,我们展示了四个基于模型能力的应用:Lyrics2Song(第4.1节)、Lyrics2Leadsheet2Song(第4.2节)、MusicEDiT(第4.3节)和zero-shot唱歌声音转换(第4.4节)。

Lyrics2Song中,我们介绍了一个基于用户提供的歌词和音乐风格输入生成高质量人声音乐的系统。Lyrics2Leadsheet2Song在Lyrics2Song的基础上,结合了符号音乐表示,以增强可解释性,并生成乐谱,用户可以访问并调整旋律和节奏,从而更精细地控制最终音频输出。MusicEDiT探索了一种基于扩散的修补系统,使用户能够编辑现有音乐音频的歌词和旋律,作为后期制作工具来修改歌曲的人声。在zero-shot唱歌声音转换中,我们提供了一种解决方案,允许用户基于自己的声音在现有音频中修改人声音色,且仅需最少的参考数据。这一应用以低准备成本促进了人声个性化。对于上述每个应用,我们讨论了与中间表示、模型架构和其他配置相关的设计选择,以优化系统以适应各自的用例。

Lyrics2Song

Lyrics2Song生成基于用户提供的音乐风格描述和带有章节标签(如“段落”、“副歌”和“桥段”)的歌词的声乐音乐表演。这项任务利用音频基于令牌的管道,借助令牌化和自回归技术对多模态数据(即歌词、风格、标签和音频)进行对齐,并支持流式解码以实现快速、响应式的交互。

该系统支持短音频片段的生成和完整曲目的制作。生成的音频展示了富有表现力和动态的人声表演,旋律动人,并且乐器种类繁多,涵盖多种风格,展现出成熟的音乐性。

带音频参考的人声音乐生成

除了风格描述外,我们的系统还支持音频输入作为提示来指导音乐生成。通过收听示例,可以看到输出是如何参考音频提示的音乐风格生成的。由于用文本或标签描述所需音乐对新手用户来说可能不够直观,因此音频提示提供了一种更有效的交流音乐意图的方式。

我们的系统支持两种音频提示模式:继续模式和混音模式。在继续模式中,从音频参考提取的音频令牌被连接到前缀中,以继续自回归生成,从而确保与参考音频在结构、旋律和声响上的高度相似。在混音模式中,音频参考被转换为预训练的联合文本-音频嵌入空间中的嵌入向量。这一嵌入总结了音频参考的全局特征,然后被纳入前缀中以指导生成,使生成的音频能够采纳不同的风格。

在这两种模式下,我们的模型展示了强大的能力,能够保持输入歌词与音频参考中固有歌词之间的连贯性,即使在没有自动歌词转录的帮助下。当输入歌词在结构和语义上与音频参考中的歌词相似时,模型倾向于模仿参考的旋律和结构。然而,当输入歌词在风格上显著不同(例如语言、结构、押韵)时,连贯性会减弱。尽管如此,模型仍能有效保持自然的节奏模式、乐器、声乐质量和整体音乐主题。

器乐音乐生成

虽然音频基于令牌的管道主要设计用于声乐音乐生成,但如果歌词输入仅包含章节标签而没有文本,它也支持器乐音乐生成。我们提供了多种风格的器乐生成示例,每个部分按指定时间展开,并展示了部分之间清晰的结构转换(例如,从段落到副歌)。

评估指标

我们使用以下定量指标在开发过程中评估生成质量。这些指标也被重新用于自回归语言模型的强化学习过程中的奖励模型。

  • 词错误率(WER):我们使用内部开发的唱歌歌词转录模型,该模型支持英语和中文,以转录生成的音频并计算与歌词提示的词(或拼音)错误率。虽然有用,但由于延长元音、辅音、音高变化和类似非语言节奏等因素,WER并不是评估音乐声乐质量的完美指标。这些特征可能会引入噪声。
  • 音乐标签性能:为了评估生成音频与输入风格描述之间的对齐,我们使用内部开发的音乐标签和结构分段模型,从生成的音频中预测高层次的音乐属性,包括流派、情绪、声乐音色、声乐性别和结构部分。这些预测属性与输入的风格描述和章节标签进行比较,以平均精确度分数作为相关性的定量指标。

对于定性评估,我们使用比较平均意见得分(CMOS),基于一组音乐训练评审员的反馈。我们定义了以下三个评估维度:

  • 音乐性:评估音乐属性,包括声乐旋律的新颖性、和声的适当使用、惯用音乐形式(例如主题、变奏)、连贯结构、合适的和弦进行、特征节奏模式和完善的乐器配器。
  • 音频质量:评估声学特性,如声乐清晰度、乐器真实感、频谱细节以及鼓的瞬态和起音的清晰度。评审员还考虑任何不希望的音频伪影,如失真、闷音或某些频段能量缺失。
  • 提示遵循:衡量生成音频与输入歌词和风格提示的吻合程度。

在语音领域,基准数据集已建立用于评估TTS系统,采用WER和自动说话人验证(ASV)等指标。然而,目前没有相应的音乐生成基准提供定量评分。此外,音乐性—评估音乐生成质量的关键因素—具有高度的主观性,并且难以用客观指标量化。我们鼓励读者收听提供的音频示例,以更好地评估我们系统的质量。

音频令牌与声码器潜在

我们还使用声码器潜在基础管道进行Lyrics2Song实验,取得了与音频令牌基础管道相当的性能。然而,我们发现自回归语言模型在交互应用中固有地更适合于扩散模型。其因果架构使流式解决方案能够提供近乎实时的体验,同时还允许与多模态模型的未来集成。

Lyrics2Leadsheet2Song

Lyrics2Leadsheet2Song管道是一个两步过程,用于实现Lyrics2Song任务:Lyrics2Leadsheet和Leadsheet2Song。在第一步中,从输入的歌词和风格描述生成乐谱令牌。在第二步中,从乐谱令牌生成音乐音频。整体管道如第3.2节所示。乐谱令牌使用户能够参与生成过程,在最终渲染之前编辑旋律、和弦、乐器和节奏。

Lyrics2Leadsheet

我们基于[Chen et al., 2024c]开发了一种基于规则的符号音乐编码方案,以将音乐音频片段的符号特征编码为乐谱令牌序列。如图5所示,该方案编码了歌词和各种音乐事件。它识别八种事件类型:歌词音素、小节、和弦、声乐音符、低音音符、钢琴音符、吉他音符和鼓音符。除“小节”外,每种事件类型在乐谱令牌中都表示为一个独特的“轨道”。小节事件定义了基本的时间结构,各轨道按小节交错排列。

对于轨道内的每个事件(例如,音素、音符、和弦),我们在适用时编码开始时间、持续时间和音高值。

如第3.2节所述,生成器使用我们内部的MIR模型提取的乐谱令牌进行训练。以下是一些示例,展示了自回归语言模型如何根据输入的歌词和风格提示预测与音素对齐的音符,以及适合流派的旋律和节奏。

Leadsheet2Song

Leadsheet2Song管道涉及从一系列乐谱令牌渲染完整的音频混音。在演示示例中,我们展示了生成的声乐音乐如何遵循给定乐谱令牌中的声乐旋律、音素、节奏、和弦进行和乐器音符。渲染器有效地生成自然且富有表现力的多乐器音乐表演的细微差别,为专业人士提供了一种强大的工具,以快速回顾音频结果,而无需在合成器中进行细致的参数调整。

Leadsheet2Vocals

除了生成完整的音频混音外,Lyrics2Leadsheet2Song系统可以配置为生成单独的音轨,包括人声、鼓、低音、钢琴和吉他,既可以使用符号表示也可以生成音频。唱歌声音合成(SVS)是该系统的一个应用,其中模型设置为仅输出人声音轨,如这些示例所示。

Music Editing

在本节中,我们探讨音乐音频编辑作为后期制作过程。第3.3节中描述的基于扩散的方法的非因果特性使其特别适合此类任务。例如,在文本条件下的修补中,扩散模型能够在遮蔽音频段前后访问上下文,从而确保更平滑的过渡[Wang et al., 2023c]。我们将此框架视为乐谱条件下的修补任务,以训练DiT模型。在推理过程中,修改后的乐谱作为条件输入,遮蔽与乐谱中修改部分对应的音频段并重新生成。

在这些听力示例中,我们展示了系统在保持旋律和伴奏的同时,精确修改演唱歌词的能力,支持英语和普通话的演唱。在某些情况下,歌词在同一语言内进行修改,而在其他情况下,系统允许在语言之间交替。此外,在这些示例中,我们展示了用户如何在指定的时间段内精确调整旋律,同时保持歌词、其余旋律和伴奏轨道不变。这种新的“生成音频编辑”范式让我们感到兴奋,因为它保留了原始曲目的音乐表现和基本特质,而这一点在没有重新录制人声及原始乐器音轨的情况下以往是复杂或几乎不可能实现的。

Zero-shot Singing Voice Conversion

为创作者编辑声乐音乐的最直观方式之一是将声乐音色转换为与其自身声音相匹配的音色。本节探讨了作为Seed-Music套件最终组成部分的唱歌声音转换(VC)系统。尽管我们的唱歌VC方法与Seed-TTS中介绍的语音VC有相似之处,但在声乐生成背景下的声音克隆和转换面临更大的挑战[Arik et al., 2018]:

  • 声乐混合:声乐音乐通常由声乐和背景乐器伴奏组成,两者在和声和节奏方面具有强一致性。相比之下,语音信号往往包含与语音内容无关的背景环境声音。尽管现代MSS模型可以隔离声乐,但通常会引入降低质量的伪影。我们的目标是开发一个可扩展的系统,能够直接处理声乐与背景轨道的混合,而不依赖MSS,从而避免这些伪影。
  • 声乐范围:唱歌声音的音高范围远大于语音。在零-shot唱歌VC中,系统必须将参考声音的音高范围推广到合成的唱歌声音,这对模型的鲁棒性提出了很高要求。
  • 声乐技巧:唱歌声音具有高度表现力,并涉及比语音更多的技巧。同一位歌手在歌剧中、音乐剧或爵士即兴中演唱时,听起来可能截然不同。唱歌VC系统必须准确捕捉和重现这些表现性技巧,同时处理清晰发音和韵律等常规语音特征。
  • 唱歌与语音参考:在VC应用中,用户通常提供语音作为参考声音,无论是用于语音还是唱歌合成。我们的系统专门设计为能够接受无论是语音还是唱歌的参考声音,并能够有效地使用短语音片段作为参考进行唱歌VC。
  • 业余与专业唱歌:与语音VC数据相比,业余唱歌与专业唱歌的配对数据显著较少。这使得唱歌VC特别具有挑战性,因为模型必须适应非专业唱歌输入,并将其转换为专业质量的表现。例如,如果用户提供的唱歌参考音调不准,唱歌VC系统不仅要捕捉其声音的音色,还必须纠正音高。

听力示例展示了我们的唱歌VC系统在不同场景下的表现。结果的质量在很大程度上取决于参考声音与目标唱歌信号之间的相似性。例如,当两者都是用英语演唱的男性声音时,效果最佳。然而,处理跨性别和跨语言的情况更具挑战性,往往会导致伪影、失真和发音不一致等问题。

结论

在本报告中,我们介绍了Seed-Music,这是一个全面的音乐生成和编辑系统套件,旨在支持多样化的音乐创作工作流程。我们展示了该系统如何基于多模态输入(包括歌词、风格描述、音频参考、乐谱和声音提示)生成高质量的声乐音乐。我们的统一框架通过三种中间表示(即音频标记、乐谱标记和声码器潜在表示)及其相关管道,满足各种用例,为用户提供灵活的工具,从创意到生成和编辑。

从应用的角度来看,Seed-Music 降低了艺术创作和音乐表达的门槛。我们相信本报告中的演示可以赋能从初学者到专业人士的广泛创作者。例如,文本到音乐系统与零-shot唱歌声音转换的结合,使初学者能够更深入地参与创作过程。初学者不仅是从远处与音乐互动,而是能将自己独特的声音和身份融入到过程中,增强创意的构思。

音乐也是短视频、电影、游戏和增强现实/虚拟现实体验等补充媒体的重要组成部分。实时条件控制和生成音乐的渲染引入了全新的互动形式,超越了传统的音频播放。我们展望新的艺术媒介,在这些媒介中,生成音乐能够响应来自文本、游戏叙事和视觉艺术风格的条件信号。

对于专业人士而言,提议的乐谱标记旨在无缝集成到音乐家、作曲家、歌手和艺术家的工作流程中。我们相信,这些标记有潜力发展成为音乐语言模型的符号标准,类似于传统音乐制作中的MIDI。音乐家和制作人可以在保持对旋律、和声和节奏元素的熟悉控制的同时,利用生成模型的强大功能。此外,能够编辑和操控录制的音乐,同时保持其音乐语义,将为行业节省大量时间和成本。我们对未来在音轨生成和编辑方面的发展特别感兴趣,这将超越声乐轨道。这些能力将使专业人士能够更高效地探索音乐创意,从而增加发现“意外惊喜”的可能性,这通常对创作过程至关重要。

讨论:如何用1024张显卡训练一个模型?

文章来源于一个知乎问题:如何判断候选人有没有千卡GPU集群的训练经验?确实对于普通开发者来说,大概率从未尝试过使用数千张GPU训练一个模型,这方面确实是一个很好的研究方向,也是成为顶尖算法工程师所必需的必经之路,因此记录下知乎的一些回答,用于学习和记录。虽然目前还没有机会能够调用数千张GPU用于模型训练,但对于目前几十张GPU进行并行训练也有帮助。

高赞回答1:如何用千卡进行训练

最近看到知乎一个回答,把千卡训练的难度吹上天了。但其实真正用过千卡就会发现也就那么几个点。于是想写一篇文章简单讲讲。

本文将包括三个部分:

  • 首先我们将讨论千卡训练的难题,以及应该在什么时候使用千卡训练;
  • 接着,我们将讨论如何在一千张卡上开始训练,如何让他达到近乎线性的性能提升;
  • 最后我们将展开讨论一些千卡训练当中仍然悬而未决(至少对于开源社区来说)的问题。

为什么千卡训练是困难的?

其实那篇回答在这部分说的没错。千卡训练和八卡训练的区别是—显卡多了一百多倍。

这意味着什么呢?

  1. 通信时间增加
  2. 故障概率增加

这俩问题都很好理解。

时间上,PyTorch 内部支持 NCCL / Gloo / MPI 三个通信后端(请务必使用 NCCL。)其中训网络最常用的 AllReduce 操作【从多个sender那里接收数据,最终combine到一个节点上】会根据具体硬件配置走 Ring AllReduce 和 Tree AllReducering allreduce和tree allreduce的具体区别是什么?。Ring 的时间复杂度是 O(pn),Tree 的时间复杂度是 O(log⁡pn)。就算是理论上 128 节点也比单节点慢至少七倍,实践当中跨节点通信要远比单节点慢得多。

故障上,一个节点出问题的概率是 p,128 个节点就是 1−(1−p128)。也就是说如果一个操作在一个训练当中的出错概率是 1%,那么在 128 节点当中的出错概率就是 72.37%。

此外,随着规模的增大,许多问题都会变得难以忍受。比如数据增强要花 0.1s,一亿条数据就是 278 个小时(当然这只是胡拆的一个数字,实际有各种机制所以不会有这么大影响。

因此,钱多烧手并不是使用千卡训练的理由。闲得蛋疼可能是,但你得多蛋疼才能想出这么折磨自己的 idea?

因此,千卡训练解决的问题是大模型&大数据问题如果你的训练时间没有超过 8192 GPU 日,那么你绝对不需要一千张显卡。

看到这里,绝大多数人已经可以关掉这篇文章了。除非你的模型和数据都以 B(十亿)来作为计量单位。当然如果你正在厕所里手机没电想看点儿东西解闷儿的话(虽然我很怀疑是否会有人把他打出来……那么可以继续往下看

如何使用一千张卡训练?

如何提高计算效率?

这件事情其实是一个 case by case 的事情。因为通信、计算速度啥的受硬件影响更多。同样是 A100 集群,我全 DGX 节点,每一张 A100 都是 SXM 接口并配一块儿专属的 IB 网卡。你一个小破普惠服务器插 8 张 PCI-E A100,IB 卡一个节点只给一张。那咱俩遇到的问题就完全不是一个问题。

因此,要讨论如何提高训练效率、减少训练耗时,我们首先要了解训练耗时在哪里。那么,一个训练步的耗时在哪里呢?需要谨记,没有 profile 的优化是没有意义的。

你可能会说,forward backward sync。很好,这说明你了解 PyTorch 的基本流程。不过现实当中要复杂得多。

  1. dataset 读取数据,构建输出
  2. dataloader collate 数据,进行数据预处理
  3. 模型 forward 计算输出
  4. loss compute
  5. 模型 backward 计算梯度
  6. 模型 sync 梯度
  7. 优化器 step 更新权重
  8. 打印 log

当然这是可以无限细分下去的,但一般这些就够了。需要注意的是,除了 4-7 的耗时是真耗时,其他都需要通过异步操作来盖掉。这也是我们的优化目标。

异步执行在 PyTorch 的 dataloader、CUDA 和分布式当中都存在。前者可以通过设置 num_workers 和 prefetch_count 为 0 来关闭,后两者可以通过 cuda.synchornize 和 dist.barrier 来执行手动同步。在 profile 时,我们需要首先需要测整个 step 的时长。然后再在每次测量前执行手动同步来计算每个部分的时长。如果前者的总耗时等于后者 4-7 的耗时之和,那么通常不需要执行任何操作。但这种情况在千卡操作中几乎不可能发生。

第 6 步通信往往需要耗费大量时间。因此,我们还需要进一步优化通信。

以下内容是对PyTorch Distributed的概括,有感兴趣的同学建议通读并背诵全文。

计算-通信重叠

在 PyTorch 当中,梯度的通信和反向传播是交叠进行的。也就是说,每完成一层的梯度计算,都会立即触发当前层的同步。实现起来也很简单,每个进程在完成自己第 k 层的梯度计算后都会触发一个钩子来给计数器+1s。当计数器达到进程数时开火进行梯度通信。有很多同学在计算梯度过程中遇到过 RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. 错误,这就是因为有的模块没有参与计算 loss,导致梯度同步卡住了。需要注意,当 find_unused_parameters=True 时,PyTorch 分布式使用 nn.Module.__init__ 当中定义子模块的反向顺序来作为梯度桶的构建顺序。因此,确保模块定义和调用的顺序一致是一个良好的实践。

梯度合桶

尽管理论上来说,同步发生的越及时,重合度越高,性能越好。但实际上每次发起通信都是有上头的。因此,现实当中梯度同步并不是越多越好越快越好。为此,PyTorch 引入了梯度合桶机制,通过把多个 Tensor 装在一个桶里再通信桶来减少通信次数从而减少总耗时。合桶的 bucket_cap_mb 默认是 25MiB,这对于绝大多数模型来说都是太小的。目前已经有提升这个默认值的特性需求,但是这个还是调一下更好。

梯度累加

当你做完所有操作之后,惊喜的发现 TMD 怎么同步时间还是单节点的好几倍。这其实是正常情况……实际上超过 256 卡的训练想要把通信盖掉就是一件不可能的事情。你说老师我看 FB 论文说他们 256 卡就是线性提升啊…那这里不得不提的一个策略就是梯度累加了。梯度累加会执行 k 次 forward+backward 之后再执行优化器步进。这有很多好处,首先对于大模型 batch size 通常不能开多大,梯度累加可以提升等效 batch size。其次累加期间的 backward 不需要通信梯度,加快了训练速度。

少即是快

Python 是一种很慢的语言。当然你说 JIT trace+torch.compile 有提升我也不反对,但对于最高效率来说,只有必须要存在的代码和不存在的代码两种。

抱抱脸的 Transformers 就是一个反例。两个子模块就能写完的 TransformerLayer 他们硬是能写出来一堆…偏偏他们还信奉 Single Model File Policy……我寻思你这完全不考虑继承的封这么多层是要搞鸡毛啊?正例反而是 PyTorch……(笑死,我竟然会夸脸书代码写得好。具体来说就是 nn.functional 当中的各种实现。你会发现他们第一行往往是 handle_torch_func。熟悉 Python 装饰器的小伙汁通常要问了,为啥这里不用个装饰器统一一下?因为装饰器会引入额外的函数调用,额外的函数调用就是额外的上头。

因此,如果你想确保最高的效率,写一个简单的训练代码和模型代码非常重要。毕竟,1%的效率提升,节省的可能是数百个 GPU 日。

如何平稳训练

这一段当中中咱们只讨论你能控制的问题。

捕捉不致命的异常

故障率高的问题其实很好解决。在训练当中,大部分异常都是非致命异常,接住他们就好了。我之前写过一个装饰器,catch,它的作用就是接住异常,然后调回调函数(默认当然就是把错误打印到 log 里)。所有你需要做的只是使用它来装饰所有非 fatal 的操作。

在实际应用当中,我们遇到的最常见的问题是存 ckpt 写满了磁盘(不准笑,从商汤到上海 AI Lab,这个问题在哪儿都日常出现。咱也不知道为啥肯买那么多显卡但不肯多插点儿硬盘,咱也不敢问)。接住所有保存操作,如果你有闲心可以在回调里删一下之前的 ckpt。没闲心的话…大不了重训一次嘛(逃。)第二常见的问题,你猜对了……存 log 写满了硬盘……所以所有 logging 操作也都是要 catch 的。这就是为啥我都用 tmux 然后开很长的缓存窗口,总是能抢救一些 log 出来的。

咳咳,说点儿正经的。任何联网操作都是需要 catch 的,常见的联网操作主要包括从 ceph 读取数据和…写 log 到远程(逃。其他就没啥了吧,我见过有大哥尝试恢复 OOM 的,但效果似乎不是很好,至少我自己没用过。简单来说,唯一不应捕捉的错误是集群炸了。

那有的大兄弟就说了,集群没爆炸,但是有两张卡突然掉了咋办。这个咱第三部分再讨论。

管好模型的输出

模型训着训着发散了几乎是每个训大模型的人都会遇到的问题。输出和 loss 只要有 nan 果断丢掉。梯度先 clip by value 再 clip by norm 都是常规操作。哦对了,还有初始化……关于大模型收敛性的论文有一堆,此处不再赘述。

比更大,还更大,再更大

弹性训练

实际上当你的训练超过 2048 个 GPU 日时,在整个训练过程当中发生单个 GPU 甚至单个节点下线是再正常不过的事情了。

PyTorch 在 1.10 就引入了 torchelastic 弹性训练机制。这个东西,用过的都骂娘。等下,让我先骂一遍。呸。ok 咱们继续吧。

我印象当中在微软的最后一轮面试当中被问到了这个问题:如何设计一个弹性分布式系统。

我的回答很教科书。每 k 分钟,系统会做一次 AllGather 来统计存活进程数,然后选举出一个主进程。主进程会计算好每个进程的 rank 和 local rank 然后广播给各个进程。所有进程每次前向传播开始时向主进程发送一个心跳包来汇报状态。主进程会根据心跳包来确定这一个 step 参与同步的机器有多少。

但很可惜,2024 年了。还是没人去写。他妈的。

层次化梯度同步

我一直认为梯度同步不应该以 GPU/进程为单位。而应该分为大同步(节点间同步)和小同步(节点内同步)。小同步可以更高频的进行,大同步则可以更慢的执行。这样不仅能提高实际的梯度同步频率,降低同步总耗时,并且还能天然的去结合小 batch 和大 batch 训练的优点—节点内小 batch 关注个体,节点间大 batch 关注整体。

有没有发现所有东西都很简单?
是这样的,千卡训练是任何一个普通CS本科生花三个月就能学会的东西。没有任何复杂的地方。

延伸阅读

PyTorch DDP 设计笔记

PyTorch 微调菜谱

分析与优化使用 PyTorch 训练机器学习模型

使用 Nsight Systems 来分析 GPU 负载

DLProf

NVProf

NCCL AllReduce 设计

Spike No More

Understanding the difficulty of training deep feedforward neural networks

高赞回答2:关于千卡训练的难度分析

千卡,其实是个相对模糊的概念,对于多数人而言,这就跟你告诉你,我有1兆资产和10兆资产一样,你只知道很多很多,但是完全傻傻分不清楚,这到底是多少,能买多少东西。千卡,也是一样。按照常见的一机8卡GPU的类型来看,用过125台机器训练的,就算得上是千卡了。从这个角度上说,其实门槛也没有那么那么的高。可事实呢?真正的大模型要用多少机器训练?答案是远超千卡 —— 看看下面的GPT-4信息,这是千卡吗?比万卡还要多!!!

How much compute was used to train GPT-4?
2.15e25 floating

Some key facts about how this enormous model was trained: Used 25,000 Nvidia A100 GPUs simultaneously. Trained continuously for 90–100 days. Total compute required was 2.15e25 floating point operations.Sep 27, 2023

另外,从根本上说,千卡训练是一个复合体。很多时候,大家就知道一件事,“牛逼”,除了知道喊666之外,就少有了解到底牛逼在哪里。以至于说,觉得非常的高大上。我可以这么说一句,千卡及其以上的训练对于绝大多数人和企业而言,这就是个屠龙术 —— 除了某些个,用手指头数的出来的地方,别的地方完全没有这样的需求,也没有这样的资源来进行千卡训练。这是什么意思?意思就是。如果真有这样经验的人,流了出来,大概率很难对口的找工作,因为他在千卡集训中的训练经验和工程实践,大概率根本别的地方用不上。另一层意思是,如果你只是个一般人,那你想想就得了,就跟你可以意淫下某个自己喜欢的明星,但别真去追求,真要去了,你大概是连榜一大哥的待遇都不会有,注定了人财两空。我当然知道有人会说,那难道流出来的人,不能去那几个指头数的出来的地方吗?可以的,但是别着急,你们往后面看就知道了 —— 去还是能去的,但是如果他不是跟着大佬一起跑,到了新地方他们真不见的能继续干。

再来说说,千卡训练是个什么复合体 —— 至少是,科学,工程和人情世故。先看大模型训练中的任务怎么从“量变到质变”的 —— 任何一个小规模训练上的问题,放大几百几千倍之后,都有可能成为不可忽视的问题。比如,数据预处理,小的时候,你也许完全不在意,这到底是多少个毫秒搞定的。但是,如果你现在有上百T的数据要处理,手一抖,写个不那么高效的算法,多处理个几天,甚至几周都有可能。当然,更可怕的就不是慢,而是坏了 —— 一个小bug可以坏了整条pipeline。有的时候,你甚至都不能说是bug,但是反正不爽就是了。比如,两个人写预处理,一个人把图片弄成了BGR,一个弄成了RGB —— 又不是不能用,但是就是膈应人;又比如,数据原图太大了,要统一缩放,然后有人做的时候直接就缩成了方形,然后呢?我们之后需要的模型要正常长宽比的数据又该怎么办呢?再来一次嘛?再搞两个礼拜?你说这是个什么问题?可以看成是科学,当然也可以看成是工程的一部分,这两个就是紧密结合在一起的,单单你会调模型,在这个千卡训练的事情上,你是玩不转的。因为很多问题卡脖子的问题,根本就是,或者大概率是工程问题 —— 什么网络通信,什么磁盘空间,什么读取速度,什么数值稳定,小规模的时候,你都可以不用管,想怎么搞怎么搞,怎么搞可以怎么有。可是上了规模之后,很多东西都被限定死了,根本不是你想怎么干就能怎么干的。我说的这个话,大概很多用pytorch+cuda的朋友也不见的认同,毕竟这套组合下,没有太多技术支持的团队也干成了这样的事情。但是,这背后是因为,使用能支持这样训练的云服务本身就意味着,付了更多的钱,在已经白嫖了nvidia一波的前提下,外加meta(pytorch),外加微软(deepspeed),外加……,又变相雇佣了一个专门的支持团队。但是,这些都不改变一个事实 —— 那就是,这都是你跟着前人的脚步前进,有人替你已经把这条路上的坑,踩的差不多了。可是,如果你要做些原创性的工作呢?必然是会遇到很多前人都不会有的问题。

多说一句,也许有人会说,“我不关心别的,我就只关心pytorch+cuda下,做训练的经验”。那我告诉你,这本质上这跟你单机单卡训练就不应该有什么不一样,跟是不是pytorch,用不用cuda都没什么大关系 —— 你想想最理想情况下,这是不是就应该跟单机单卡训练一样么,无非就是现在的这个“单机”的GPU内存是所有的机器GPU内存的总和,能让你用一个更大的batch size和学习率。至于,GPU内部怎么通信,数据怎么通信,各个机器怎么通信,gradient传播怎么实现,需要你这个训模师知道吗?你在单机单卡的时候都不用知道,在单机多卡的时候不用知道,在小规模分布式训练的时候不用知道,那为什么到了千卡的时候,你就应该知道了?理想情况下,就算到了百万卡,也不用做建模的你去知道这里的各种工程实践。

那千卡训练到底难在哪里了?首先,就是难在之前提及的工程上面了 —— 简单假设一个卡在一天内不挂掉的概率是p,那么现在现在千卡同时一天内不挂掉的概率是多少?算算你就知道,对于p^1000,其实有机器挂掉才是正常的。如果是万卡呢?你可见的是,机器N越多,p^N就越小,这个事情就是越难。有人要说“我单机训练的时候,几年都遇不到问题,老黄的GPU稳定的一塌糊涂。”对此,我也只有呵呵,没人告诉你训练不下去都是GPU的问题。你大概是选择性忘记了各种自己训练中遇到的事情 —— 比如,上次实验中断,GPU进程没杀干净,还占着内存;和人共享的服务器上,有个卧龙觉得你训练的时候CPU占用率低了点,给你加了点任务;好巧不巧,默认的缓存地址没地方了,包装不上了,预训练模型下不来了…… 说这么多看似和训练无关的事情是因为,所有这些都要能自动化,因为里面有一个地方翻车了,你训练就进行不下去了。通信连不上,磁盘满了,遇上了奇葩的GPU,IO巨慢 …… 不管什么原因挂掉了,关键的是之后应该怎么办?有没有可能对这个出问题的机器进行热替换?怎么办才能最大程度不影响训练进程?怎么样才能在下次避免同样的问题。当然,实际情况可以更加复杂,GPU不见的是同批次的,模型也可以大到,哪怕在A100上也只能这个机器放一部分,那个机器放一部分……

但是也别误解,以为千卡训练,就对训模师而言,其实没什么挑战。这样的理解显然是错的。这对训模师的实操来说,肯定是一个巨大的挑战。完全是拿着卖白菜钱(想想你年薪才多少,算你年薪百万好了),操着卖白粉的心(这千卡训练要花多少钱?你年薪都不够它的一个零头)。因为这机器一开,实在是太烧金了。而且可见的是,你必然是要去debug的 —— 为什么小模型的时候,训练的挺好的,一变大就翻车了?或者说,虽然没翻车,但是为什么性能就涨了一丢丢?或者为什么前面训练挺稳定的,到了后面的loss curve就会有很大的spike?有经验的训模师能更早,更快的发现问题。也能更快和更好的解决问题。很多时候,也真不见的看log就能看出来点啥的,看数据,看gradient的大小分布,和其他模型的训练进行记录做比对,甚至做可视化,都是很有必要的。而这所有的一切,都需要你很有经验 —— 同样的log,有人就能一眼看出来问题在哪里,有人就只能对着发呆,或者机械性的说“换一组参数再试一下”。同样觉得可能哪里有问题,有人就能知道应该来验证这个猜想是对是错,有人就只能天马行空的给出一堆,谁也不知道对不对的原因。所以,一旦这条路线被摸索出来之后,其实也就没什么难度了 —— 数据,脚本,机器都在那里了,我就问你,我在服务器上run那条千卡训练命令,跟你run的能有什么不同?所以,真正的关键不是在于有没有用过千卡GPU训练过模型,而是有没有从头至尾,一路披荆斩棘的自己淌出来一条可重复的模型技术路线!!

当然,如果你要以为,这事情就只是技术,那也是太年轻了点。机器一开,要多少钱,这账真要算准从训模师的角度说是很难的,毕竟具体价格都是大公司之间协议的,属于商业机密,但是估算个大概的数目不难。按照aws的p4d算(8卡A100,见下图),便宜的算法,千卡训练一个月,需要花费 $11.57/每台小时*24小时/天*125台*30天 = $1,041,340;按照阿里云的算法,单卡年费¥170533.8,也就是¥19.47每小时,但是算上多卡的费用,这实际上比上面aws的价格更贵。当然,你也许能用更便宜的价格拿到机器,比如别找这么大的云服务平台,找个小的,但是再少还能少多少,算打5折,这都是50多万美刀,350多万人民币一个月。要知道,这可是训练一次的价格哦。一个能用的模型背后,可是5x,甚至10x更多的不能用模型哦,所以烧个几千万,真跟玩一样。

正是因为这么贵,所以也同样表明了,为什么一定要找有经验的训模师 —— 你要知道,你自己的每个实验决定,都是变相的花出去十几,几十甚至上百万的美金。早发现问题,早停下来;早解决问题,早开始;知道怎么偷懒,什么样的ablation study可以跳什么必须做,什么时候可以用小模型替代,什么时候可以用一个老的checkpoint来个jump start,什么时候直接白嫖论文上的结论就行……,所有这些都和花多少钱才能把这个事情办了,输出一个达标的模型,直接相关 。相反的,万一你要找个拉垮的训模师,前面不知道怎么计划,代码不知道怎么验证,训练起来了不懂怎么有效监控,有了异常不知道如何排除,……,最后都要靠着模型训练全完了之后做evaluation才知道行不行的那种。那么就算预算全花完了,什么都没有训练出来,我也没有什么好奇怪的。

铺垫这么多,终于可以来谈谈最后一个层面 —— 人情世故了。你看,千卡训练这个事情,有这么大的风险翻车,要花这么多的预算,那么现在问题来了,你要是部门领导,你让谁来干这个事情?哦,你想放权给下面的经理,让他来找人?又或者找个刚来的博士?找个顶校+顶会的博士?不管你怎么找,可问题是,你就这么信得过他吗?你怎么保证他,能干这个,能干好这个,不会中途跑路,不会磨洋工…… 要知道,这样大的项目和预算,如果要真干塌了,不说整个部门要一起完蛋,至少这一条线的人员必然是要担责的,哪怕是主要领导也跑不掉。所以喽,关键的关键是,你必须找自己信的过的人,还要找确实有能力可以担当重任的人 —— 真正最后来干这个千卡训练的人,不但自己技术要过硬,更是团队的中坚力量,至少也要得到一两个大头目的支持,而且还要得到小头目支持。你再牛逼,没信任没大佬支持,这事情不说完全不可能,也是基本没可能。你再牛逼,要是真的小头目给你上眼药,比如,跟上面吹风,“好像看见你在看招聘网站”,你想大头目心里会不会有阴影?所以,别给我扯什么,老子有多少顶会顶刊,老子导师是谁谁谁,这在绝大多数情况,都不好使。所以,刚毕业的,或者做实习的,或者刚工作的,如果宣称自己有这个经验,就是一眼丁真。因为上面是绝对不会找不信任的人来这样重要的工作,这跟你有没有相关的工作经验无关。这同样意味着,真正干这些事情的人也很难流出来 —— 因为对于嫡系来说,加薪升职,在干好了的前提下,那还不都是so easy吗?所以,是你,你愿意出来吗?出来了,就算你牛逼,但是获取信任,成为嫡系也要一个时间,不是吗?

Qwen2-Audio:让LLM 拥有“耳朵”

Qwen2-Audio-7B 🤖 🤗  | Qwen-Audio-7B-Instruct 🤖 🤗  | Demo 🤖 | 🤗 

论文链接https://arxiv.org/abs/2407.10759

代码链接github.com/QwenLM/Qwen2-Audio

Qwen2-Audio作为一个大规模音频语言模型,Qwen2-Audio能够接受各种音频信号输入,并根据语音指令执行音频分析或直接响应文本。我们引入两种不同的音频交互模式:

  • 语音聊天:用户可以自由地与Qwen 2-Audio进行语音交互,无需文字输入;
  • 音频分析:用户可以在交互过程中提供音频和文本指令进行分析;
  • 多语言支持:该模型支持超过8种语言和方言,例如:中文、英语、粤语、法语、意大利语、西班牙语、德语和日语。

Qwen 2-Audio是一个大规模的音频语言模型,它能够接受各种音频信号输入,并对语音指令进行音频分析或直接的文本响应。与复杂的分层标签相比,我们通过利用不同数据和任务的自然语言提示简化了预训练过程,并进一步扩大了数据量。我们提升了Qwen 2-Audio的语音追踪能力,并实现了语音聊天和音频分析两种不同的音频交互模式。在语音聊天模式下,用户可以自由地与Qwen 2-Audio进行语音交互,无需文字输入。在音频分析模式下,用户可以在交互过程中提供音频和文本指令进行分析。请注意,我们不使用任何系统提示来在语音聊天和音频分析模式之间切换。 Qwen 2-Audio能够智能地理解音频中的内容,并按照语音命令做出适当的响应。例如,在同时包含声音、多说话者对话和语音命令的音频片段中,Qwen 2-Audio可以直接理解命令并提供对音频的解释和响应。

Qwen2-Audio、Qwen-Audio 以及之前 LALM 顶级产品的性能,例如 SpeechT5 、SpeechNet、 SpeechLLaMA、SALMONN、Whisper、Pengi,和 SpeechVerse。 我们展示了 10 个数据集的测试集结果,涵盖自动语音识别 (ASR)、语音到文本翻译 (S2TT)、语音情绪识别 (SER)、声音分类 (VSC) 和指令跟踪基准。 ASR 数据集(例如 Librispeech 和 Aishell2)的结果参考 1 – WER%。 CoVoST2的结果是七个翻译方向(en-de、de-en、en-zh、zh-en、es-en、fr-en和it-en)的平均BLEU得分。 AIR-Bench 聊天基准测试的结果包含四个维度:语音、声音、音乐和混合。 每个维度的分数由 GPT-4 自动评估,值范围为 0 到 10。 Qwen2-Audio 无需任何针对特定任务的微调即可实现卓越的性能,超越了同类产品。
图2:Qwen2-Audio的三阶段训练过程概述。

介绍

音频是人类和其他生物之间互动和交流的重要媒介,承载着丰富的信息内容。 全面理解各种形式的音频信号对于实现通用人工智能 (AGI) 至关重要。Qwen2-Audio主要重点是增强其指令跟踪能力。 Qwen2-Audio 是一种大型音频语言模型 (LALM),旨在处理音频和文本输入以生成文本输出。 与之前的模型相比,Qwen2-Audio 显着扩展了训练数据集。 为了减少训练前和训练后阶段之间的差距,我们通过直接使用自然语言提示各种数据和任务来简化预训练过程,如下图所示。 遵循大语言模型(OpenAI,2023;Qwen,2023)的实践,我们进一步进行指令调优和直接偏好优化,使模型的输出与人类偏好保持一致。

Qwen2-Audio 以两种不同的模式运行:音频分析语音聊天。 这两种模式从功能上有所区别,但用户在使用过程中无需区分。 在音频分析模式下,用户可以利用Qwen2-Audio来分析多种音频类型,包括语音、声音、音乐或各种混合音频形式。 命令可以通过音频或文本发出,Qwen2-Audio 将自动识别音频中的命令片段。 相反,在语音聊天模式下,用户可以与 Qwen2-Audio 进行交互,就好像它是一个会话代理一样,进行不受限制的对话。 提供音频交互,用户可以随时切换到文本交互。 例如,如果用户输入一个音频剪辑,其中初始部分是键盘打字的声音,然后用户询问“这是什么声音?”在口语中,Qwen2-Audio 预计会直接回复“这是键盘的声音”。

方法

模型架构

Qwen2-Audio的训练过程如图2所示,其中包含音频编码器和大语言模型。 给定配对数据(𝒂,𝒙),其中𝒂和𝒙表示音频序列和文本序列,训练目标是最大化下一个文本词符的概率为:

以音频表示和先前文本序列 𝒙<t 为条件,其中 θ 和 ϕ 分别表示大语言模型和音频编码器的可训练参数。

与Qwen-Audio不同的是,Qwen2-Audio的音频编码器的初始化是基于Whisper-large-v3模型。 为了预处理音频数据,我们将其重新采样到 16kHz 的频率,并使用 25ms 的窗口大小和 10ms 的跳跃大小将原始波形转换为 128 通道梅尔频谱图。 此外,还合并了步长为 2 的池化层,以减少音频表示的长度。 因此,编码器输出的每一帧大约对应于原始音频信号的 40ms 片段。 Qwen2-Audio 仍然采用大型语言模型 Qwen-7B 作为其基础组件。 Qwen2-Audio的总参数为8.2B参数。

预训练数据集的统计(小时)。

预训练

在预训练阶段,我们用自然语言提示替换分层标签。 如图2所示。 我们发现使用语言提示可以提高更好的泛化能力和更好的指令跟随能力。

有监督微调

Qwen2-Audio的彻底预训练使模型对音频内容有了全面的理解。 在此基础上,我们采用基于指令的微调技术来提高模型与人类意图保持一致的能力,从而形成交互式聊天模型。 我们的初步研究强调了 SFT 数据的质量和复杂性对模型性能的关键影响。 因此,收集了一组精心策划的高质量 SFT 数据,并实施了严格的质量控制程序。

我们考虑两种不同的人类互动模式:

  • 音频分析:在音频分析模式下,用户可以灵活地让 Qwen2-Audio 分析各种音频。 用户指令可以通过音频或文本给出。该模式常用于音频文件的离线分析。
  • 语音聊天:在语音聊天模式下,鼓励用户与Qwen2-Audio进行语音对话,提出各种问题。 请随意将其视为您的语音聊天助手。该模式常用于与 LALM 的在线交互。

为了一致性和模型统一性,两种交互模式都经过联合训练,用户在使用过程中不会出现模式差异化,也无需使用单独的系统提示在不同模式之间切换。 两种模式在实际使用中是无缝结合的。

直接偏好优化(DPO)

我们采用 DPO (Rafailov 等人, 2024) 来进一步优化模型以遵循人类偏好。 通过获取带有三元组数据(𝒙,𝒚𝒘,𝒚𝒍)的数据集𝒟,其中𝒙是带有输入音频的输入序列,𝒚𝒘和𝒚𝒍 分别是人工注释的好响应和坏响应,我们对模型 𝒫θ 进行如下优化:

其中𝒫ref表示用𝒫θ初始化的参考模型,σ表示sigmoid函数,β是超参数。 图2说明了Qwen2-Audio的三阶段训练过程。

实验

在实践中,我们发现之前的许多测试数据集都非常有限,无法充分反映现实场景中的性能,例如一些SLU(口语理解)和SER(语音情感识别)数据集。 因此,我们主要直接在AIR-Bench上评估性能。 我们发现 AIR-Bench 的分数更符合实际的用户交互体验。 同时,为了评估Qwen2-Audio的通用理解能力,如表1所示,我们仍然进行了涵盖各种任务的综合评估,即自动语音识别(ASR)、语音识别-文本翻译(S2TT)、语音情感识别(SER)、语音分类(VSC)。 评估是在 13 个数据集上进行的。 评估数据集被严格排除在训练数据之外,以避免数据泄露。 我们比较的模型包括开源模型和可调用的 API,例如 Gemini。

表2:自动语音识别 (ASR)、语音到文本翻译 (S2TT)、语音情绪识别 (SER)、声音分类 (VSC) 和 AIR-Bench 聊天基准测试的结果。 请注意,对于 Qwen2-Audio,Fleurs 的结果是零样本,而 Common Voice 的结果不是零样本。

案例:

结论:

在本文中,我们提出了 Qwen2-Audio,它建立在 Qwen-Audio 分析各种类型音频的能力之上,同时还被赋予了语音交互能力。 在预训练阶段,我们针对不同的数据和任务利用自然语言提示,进一步扩大了数据量。 在SFT阶段,我们通过提高SFT数据的数量、质量和复杂性来增强Qwen2-Audio与人类交互的一致性,从而实现无缝的语音和文本交互。 此外,我们还通过 DPO 阶段提高了 Qwen2-Audio 的响应质量。 在不同基准上测试的客观指标证明了 Qwen2-Audio 在音频理解和对话能力方面的熟练程度。 论文中的案例也说明了Qwen2-Audio流畅灵活的语音交互能力。

补充:语音/文本嵌入融合

Qwen-audio-chat模型如何将音频特征与文本提示无缝融合,通过特征编码、位置标记和信息整合,提升模型的跨模态理解能力。

系统会提取音频的特征,然后对文本提示进行嵌入(Embedding)处理。具体来说,它通过将音频特征转换成一个三维向量(如[1,56,4096]),并将这个向量嵌入到文本提示中。例如,考虑到一个文本提示信息,其中包括标记转换为ID的过程,随后是与音频特征的结合,即在文本中通过和标签指明音频的开始与结束位置。

在融合过程中,系统通过ID定位到这些标签所代表的位置,并用音频特征向量A替换掉文本提示中的“Audio_path/audio_name.flac”相对应的向量表示。这样,音频特征就被有效地融合到文本提示中,形成了一个语言模型能够理解的向量表示。

 // A code block
     <|im_start|>system
    You are a helpful assistant.<|im_end|>
    <|im_start|>user
    Audio 1:<audio>Audio_path/audio_name.flac</audio>
    what does the person say?<|im_end|>
    <|im_start|>assistant

代码实现:

// An highlighted block
bos_pos = torch.where(input_ids == self.config.audio['audio_start_id'])
eos_pos = torch.where(input_ids == self.config.audio['audio_start_id'] + 1)
audio_pos = torch.stack((bos_pos[0], bos_pos[1], eos_pos[1]), dim=1)
if audios is not None:
	for idx, (i, a, b) in enumerate(audio_pos):
	     hidden_states[i][a : b+1] = audios[idx]
	output_shape = input_shape + (hidden_states.size(-1),)

LLaMA-Omni 开源语音交互大模型

LLaMA-Omni是基于Llama-3.1-8B-Instruct构建的低延迟、高质量的端到端语音交互模型,旨在实现GPT-4o级别的语音功能。

HF链接https://huggingface.co/ICTNLP/Llama-3.1-8B-Omni

论文链接https://arxiv.org/pdf/2409.06666

代码链接https://github.com/ictnlp/LLaMA-Omni

总的来说,LLaMa-Omni的训练方法第一阶段类似Qwen2Audio模型,都是用whisper large作为音频编码器,“输入文本-语音特征-文本”的输入,输出文本,用于训练LLM和 Speech Adaptor 。第二阶段,为了将文本输出转成语音输出,固定LLM和 Speech Adaptor, 用 LLM输出的隐藏状态作为输入,生成与语音响应对应的HUBERT离散单元序列,然后使用该序列合成语音。缺点:hubert token合成的语音生硬、缺乏声学信息,后续可以替换为WavTokenizer 或者 RVQ【encodec、soundsream】的方法合成带声学特征的语音。因为输出的是离散的hubert token,可以一边输出,一边流式合成语音。第一阶段本质上是让LLM拥有“耳朵”,第二阶段是让LLM能够”说话“。但一二阶段分离训练会不会导致第一阶段LLM学习到的都是一些语义知识,声学信息都损失掉了,这样的话即使在第二阶段替换不同的token方法也很难从LLM的输出中学习到声学信息。另外,在数据集的制作上,使用LJSpeech数据集训练了一个TTS,缺乏丰富的情感控制,后续可以考虑使用Seed-TTS /cosyvoice/SeedTTS 等情感可控的等语音合成方法来合成响应的音频。 对于LLM主干网络的选择,可以考虑使用Qwen2Qudio这样的经过音频预训练过的LLM模型和语音编码器作为主干,只需要对音频解码器进行第二步的解码器微调训练。

自从OpenAI推出了GPT-4o之后,它开启了语音交互大模型的大门。国内相继也有很多大公司和创业公司开始模仿它,计划推出自己的语音交互大模型。ChatGPT等大语言模型通常只支持基于文本的交互,而GPT4o的出现使得通过语音与LLM交互成为可能,按照极低的延迟响应用户的指令,并显著提升了用户体验。然而,开源社区在构建基于LLM的语音交互模型方面仍然缺乏探索。当前,实现与LLM的语音交互的最简单方法是通过基于自动语音识别(ASR)和文本到语音(TTS)模型的三段式级联系统,其中ASR模型将用户的语音指令转录为文本,TTS模型将LLM的响应合成为语音。然而,由于级联系统顺序输出转录文本、文本响应和语音响应,因此整个系统往往具有更高的延迟。   

为了解决这个问题,作者提出了LLaMA-Omni,这是一种新的模型架构,旨在与LLM进行低延迟和高质量的语音交互。LLaMA-Omni集成了预训练语音编码器、语音适配器、LLM和流式语音解码器。它消除了对语音转录的需要,并且可以直接从语音指令中以极低的延迟同时生成文本和语音响应。LLaMA-Omni在内容和风格上都能提供更好的响应,响应延迟低至226ms。此外,整个LLaMA-Omni模型仅需要在4个GPU上训练3天左右。

💪 基于Llama-3.1-8B-Instruct构建,确保高质量的响应。

🚀 低延迟语音交互,延迟低至226 ms。

🎧 同时生成文本和语音响应。

♻️ 仅️使用4个GPU,在不到3天的时间内完成训练。

语音交互大语言模型发展历程

SpeechGPT算法简介

  2023年,Dong Zhang, Shimin Li等人提出“SpeechGPT: Empowering large language models with intrinsic cross-modal conversational abilities”算法。本文提出了SpeechGPT,这是一种具有内在跨模态会话能力的大型语言模型,能够感知和生成多模型内容。通过离散语音表示,作者首先构建了SpeechInstruct,这是一个大规模的跨模态语音指令数据集。此外,作者采用了一种三阶段训练策略,包括模态适应预训练、跨模态教学微调和模态教学链微调。大量的实验结果表明:SpeechGPT具有令人印象深刻的能力,可以遵循多模态人类指令,并突出了用一个模型处理多种模态的潜力。

SALMONN算法简介

   2024年,Changli Tang, Wenyi Yu等人提出“SALMONN: Towards generic hearing abilities for large language models”算法。SALMONN是一个支持语音、音频事件和音乐输入的大型语言模型(LLM),由清华大学电子工程系和字节跳动共同开发。SALMONN可以感知和理解各种音频输入,从而获得多语言语音识别和翻译以及音频语音协同推理等新兴功能,而不是仅语音输入或仅音频事件输入。这可以被视为赋予了LLM“耳朵”和认知听觉能力,这使SALMONN朝着有听觉功能的通用人工智能迈出了一步。

Qwen2-audio算法简介

2024年7月,Yunfei Chu, Jin Xu等人提出“Qwen2-audio technical report”算法。作为一个大规模音频语言模型,Qwen2-Audio能够接受各种音频信号输入,并根据语音指令执行音频分析或直接响应文本。作者介绍了两种不同的音频交互模式:语音聊天 voice chat 和音频分析 audio analysis。语音聊天:用户可以自由地与 Qwen2-Audio 进行语音互动,而无需文本输入;音频分析:用户可以在互动过程中提供音频和文本指令对音频进行分析;作者已经开源了 Qwen2-Audio 系列的两个模型:Qwen2-Audio-7B和Qwen2-Audio-7B-Instruct。

LLaMA-Omni背景简介

 以ChatGPT为代表的大型语言模型(LLM)已经成为强大的通用任务求解器,它们能够通过对话交互帮助人们解决日常生活中的问题。然而,大多数LLM目前只支持基于文本的交互,这限制了它们在文本输入和输出不理想的情况下的应用场景。最近,GPT4o的出现使得通过语音与LLM交互成为可能,按照极低的延迟响应用户的指令,并显著提升了用户体验。然而,开源社区在构建基于LLM的语音交互模型方面仍然缺乏探索。因此,如何利用LLM实现低延迟和高质量的语音交互模型是一个亟待解决的重大挑战。    当前,实现与LLM的语音交互的最简单方法是通过基于自动语音识别(ASR)和文本到语音(TTS)模型的三段式级联系统,其中ASR模型将用户的语音指令转录为文本,TTS模型将LLM的响应合成为语音。然而,由于级联系统顺序输出转录文本、文本响应和语音响应,因此整个系统往往具有更高的延迟。

    相比之下,学者们相继已经提出了一些多模态语音语言模型,这些模型将语音离散化为标记,并扩展LLM的词汇表从而支持语音输入和输出。这种语音语言模型理论上可以直接从语音指令生成语音响应,而无需产生中间文本,从而实现极低的响应延迟。然而,在实践中,由于涉及复杂的映射,直接根据语音生成语音可能具有挑战性,因此通常会生成中间文本来实现更高的生成质量,然而这会牺牲一些响应延迟。

LLaMA-Omni算法简介

LLaMA-Omni由语音编码器、语音适配器、LLM和流式语音解码器组成。LLM用户的语音指令由语音编码器编码,然后由语音适配器编码,然后输入到LLM中。LLM直接从语音指令解码文本响应,而不首先将语音转录成文本。语音解码器是非自回归(NAR)流式传输Transformer,其将LLM的输出隐藏状态LLM作为输入并使用连接主义时间分类(CTC)来预测对应于语音响应的离散单元的序列。 在推理过程中,当LLM自回归生成文本响应时,语音解码器同时生成相应的离散单元。为了更好地适应语音交互场景的特点,我们通过重写现有的文本指令数据并进行语音合成来构建一个名为InstructS 2S-200 K的数据集。

 大量的实验结果表明,与之前的语音语言模型相比,LLaMA-Omni在内容和风格上都能提供更好的响应,响应延迟低至226ms。此外,整个LLaMA-Omni模型仅需要在4个GPU上训练3天左右,为未来高效开发语音语言模型铺平了道路。

图1:LLaMA-Omni可以根据语音指令同时生成文本和语音响应,响应延迟极低。

LLaMA-Omni组成和算法流程

图2:左:LLaMA-Omni的模型架构。右图:LLaMA-Omni的两阶段培训策略示意图。

如上图所示,左图展示了LLaMA-Omni的模型的整体架构。它由一个语音编码器、语音适配器、LLM和语音解码器组成。详细的步骤如下所述:

  • 首先,将用户的提问语音输入到一个Speech Encoder模块中执行语音编码操作,作者使用Whisper-large-v3的编码器作为语音编码器E;
  • 然后,将其结果送入一个Speech Adaptor模块中。为了使LLM能够理解输入语音,作者引入了一个可训练的语音适配器,它能够将语音连续特征表示映射到LLM的嵌入空间中;
  • 接着,将语言适配器的结果送入一个大语言模型中。作者使用Llama-3.1-8B-Instruct3,这是目前最先进的开源LLM。它具有很强的推理能力,与人类的偏好非常一致。
  • 最后,将大语言模型的结果经过上采样之后送入一个Speech Decoder模块中。为了在生成文本响应的同时生成语音响应,作者在LLM之后添加了一个流式语音解码器D。它由几个与LLaMA具有相同架构的标准Transformer层组成,每个层都包含一个因果自我注意模块和一个前馈网络。

右图展示了LLaMA- Omni的两阶段训练策略示意图。在第一阶段中,作者训练模型直接从语音指令中生成文本响应。具体而言,语音编码器被冻结,语音适配器和LLM使用方程中的目标Lllm进行训练。在此阶段,语音解码器不参与训练。在第二阶段,训练模型从而生成语音响应。在此阶段,语音编码器、语音适配器和LLM都被冻结,只有语音解码器使用目标Lctc进行训练。

Speech Encoder

使用Whisper-large-v3的编码器作为语音编码器 ℰ 。Whisper是一种基于大量音频数据训练的通用语音识别模型,其编码器能够从语音中提取有意义的表示。具体地,对于用户的语音指令 XS ,编码语音表示由 𝐇=ℰ⁢(XS) 给出,其中 𝐇=[𝐡1,…,𝐡N] 是长度为 N 的语音表示序列。我们在整个训练过程中保持语音编码器的参数冻结。

Speech Adaptor

为了使LLM能够理解输入语音,我们结合了一个可训练的语音适配器 𝒜 ,它将语音表示映射到LLM的嵌入空间中。我们的语音适配器首先对语音表示 𝐇 进行下采样以减小序列长度。具体地,每 k 个连续帧沿特征维度被沿着连接:

接下来, 𝐇′ 通过线性层之间具有ReLU激活的2层感知器,产生最终的语音表示 𝐒,非离散的特征 。上述过程可以形式化如下:

Large Language Model

我们使用Llama-3.1-8B-Instruct 作为LLM ℳ ,这是目前最先进的开源LLM。它具有强大的推理能力,并且与人类的偏好保持一致。提示模板 𝒫⁢(⋅) 如图3所示。将语音表示序列 𝐒 填充到对应于<speech>的位置,然后将整个序列 𝒫⁢(𝐒) 输入到LLM中。LLM最后,LLM自回归直接基于语音指令生成文本响应 YT=[y1T,…,yMT] ,并使用交叉熵损失进行训练:

Speech Decoder

对于语音响应 YS ,我们首先遵循Zhang等人将语音离散化为离散单元。具体来说,我们使用预训练的HuBERT模型来提取语音的连续表示,然后使用K均值模型将这些表示转换为离散聚类索引。随后,将连续的相同索引合并成单个单元,从而产生最终的离散单元序列 YU=[y1U,…,yLU],yiU∈{0,1,…,K−1},∀1≤i≤L ,其中 K 是簇的数目,并且 L 是离散单元序列的长度。离散单元可以用附加的基于单元的声码器 𝒱 转换成波形

为了与文本响应同时生成语音响应,我们在LLM之后添加了流式语音解码器 𝒟 。LLM它由几个标准的Transformer组成具有与LLaMA相同架构的层,每个包含因果自我注意模块和前馈网络。与Ma等人(2024 a); Zhang等人(2024 b)2024 a)类似,语音解码器以非自回归方式运行,将LLM输出的隐藏状态作为输入,生成与语音响应对应的离散单元序列LLM具体地,对应于文本响应的输出隐藏状态被表示为 𝐂=[𝐜1,…,𝐜M] ,其中

LLaMA-Omni算法实现细节

提示词模版

 上图展示了提示模板P。语音表示序列S被填充到与<speech>对应的位置,然后整个序列P(S)被输入到LLM中。最后,LLM直接基于语音指令自回归生成文本响应结果,整个过程使用交叉熵损失进行训练。

Training

如图2所示,作者采用两阶段训练策略为LLaMA-Omni。在第一阶段,作者训练模型直接从语音指令生成文本响应。具体而言,语音编码器被冻结,而语音 Adapter 和LLM使用公式(3)中的目标进行训练。在这一阶段,语音解码器不参与训练。在第二阶段,作者训练模型生成语音响应。在此阶段,语音编码器、语音 Adapter 和LLM都被冻结,只有语音解码器使用公式(5)中的目标进行训练。

Inference

在推理过程中,LLM 自动回归地生成文本响应。同时,由于作者的语音解码器使用因果注意力,一旦 LLM 生成一个文本响应前缀 ,对应的 upsampled 隐藏状态  可以被输入到语音解码器中,生成一个部分对齐 ,从而得到与生成的文本前缀对应的离散单元。

为了进一步实现语音波形的 Stream 合成,当生成的单元数量达到预定义的块大小  时,作者将这个单元段输入到 vocoder 中,合成一个语音段,然后立即播放给用户。因此,用户可以在等待完整文本响应生成完成之前开始听语音响应,确保低响应延迟,该延迟不受文本响应长度的影响。

此外,由于语音解码器使用非自回归建模,每个文本令元  对应的对齐  都在块内并行生成。因此,同时生成文本和语音的解码速度与仅生成文本的速度之间没有显著差异。

在推理过程中,LLM根据语音指令自回归生成文本响应。同时,由于其语音解码器使用因果注意力机制,一旦LLM生成文本响应前缀,相应的上采样隐藏状态就可以被馈送到语音解码器中生成部分对齐结果,这反过来又产生了与生成的文本前缀对应的离散单元。

    为了进一步实现语音波形的流式合成,当生成的单元数量达到预定义的块大小时,作者将该单元段输入到声码器中以合成语音段,然后立即向用户播放。因此,用户可以开始收听语音响应,而无需等待生成完整的文本响应,从而确保不受文本响应长度影响的低响应延迟。

INSTRUCTS2S-200K数据集构建细节

 为了训练LLaMA-Omni,作者需要利用由<语音指令、文本响应、语音响应>组成的三元组数据。然而,大多数公开的指令数据都是文本形式的。因此,作者通过以下步骤来基于现有的文本指令数据构建语音指令数据集。

步骤1–指令重写。由于语音输入与文本输入具有不同的特征,作者根据以下规则重写文本指令:1)在指令中添加适当的填充词(如“hey”、“so”、“uh”、 “um”等),来模拟自然语音模式。2) 将指令中的非文本符号(如数字)转换为相应的口语形式,从而确保TTS的正确合成。3) 修改说明,使其相对简短,不要过于冗长。作者利用Llama-3-70BInstruct4模型根据这些规则重写指令。

步骤2–响应生成。在语音交互中,来自文本指令的现有响应不适合直接用作语音指令响应。这是因为,在基于文本的交互中,模型倾向于使用复杂的句子生成冗长的响应,并可能包含有序列表或括号等非语言元素。然而,在语音交互中,简洁而信息丰富的回答通常是首选。因此,作者使用Llama-3-70B-Instruct模型根据以下规则生成语音指令的响应:1)响应不应包含TTS模型无法合成的内容,如括号、有序列表等。2)响应应非常简洁明了,避免冗长的解释。

步骤3–语音合成。在获得适合语音交互的指令和响应后,作者需要使用TTS模型将其进一步转换为语音。对于指令,为了使合成的语音听起来更自然,作者利用CosyVoice-300M-SFT模型为每条指令随机选择男声或女声。对于响应,作者使用在LJSpeech数据集上训练的VITS模型将响应合成为标准语音。

LLaMA-Omni算法性能评估

实验配置

训练数据集:

作者使用第3节中提到的InstructS2S-200K数据集(包含20万条语音指令数据)。为了提取对应目标语音的离散单元,作者使用了一个预训练的K-means分箱器9,它从HuBERT特征中学习了1000个簇。预训练的高保真GAN解码器用于将离散单元合成为波形。

对于评估数据,作者从Alpaca-Eval10中选择了两个子集:_helpful_base_和_vicuna_,因为它们的问题更适合语音交互场景。作者删除了与数学和代码相关的问题,总共得到199条指令。为了获得语音版本,作者使用CosyVoice-300M-SFT模型将指令合成为语音。作者将在以下章节中将其称为InstructS2S-Eval测试集。

模型配置:

作者使用Whisper-large-v3的编码器作为语音编码器,使用LLama-3.1-8B-Instruct作为LLM。语音 Adapter 对语音表示进行5倍下采样。语音解码器由2个与LLaMA相同的Transformer层组成,具有4096个隐藏维度、32个注意力头和11008个 FFN 维度,其中包含425M参数。上采样因子λ设置为25。对于输入语音编码器的最小单位块大小Ω,作者在主要实验中设置Ω=+∞,这意味着作者等待整个单位序列生成后再将其输入到语音合成器进行语音合成。在后续实验中,作者将分析如何调整Ω的值来控制响应延迟,以及延迟和语音质量之间的权衡。

训练全功能的LLaMA-Omni遵循两阶段的训练过程。在第一阶段,作者使用32个批量的语音 Adapter (speech adapter)和语言模型(LLM),训练3个周期,每次迭代32步。作者使用余弦学习率调度器,前3%的步骤用于 Warm up ,峰值学习率设置为2e-5。在第二阶段,作者使用相同的批量大小、步骤数和调度器训练语音解码器,但峰值学习率设置为2e-4。整个训练过程大约需要65小时,在4个NVIDIA L40 GPU上运行。

Evaluation

由于LLaMA-Omni可以根据语音指令同时生成文本和语音响应,作者评估模型在两个任务上的性能:语音到文本指令遵循(S2TIF)和语音到语音指令遵循(S2SIF)。作者使用贪心搜索以确保可重复的实验结果。从以下方面对模型进行评估:

为了评估模型遵循语音指令的能力,作者使用 GPT-4o对模型的响应进行评分。对于S2TIF任务,评分基于语音指令的转录文本和模型的文本回复。对于S2SIF任务,作者首先使用 Whisper-large-v3 模型将模型的语音回复转录为文本,然后像S2TIF任务一样以相同的方式进行评分。 GPT-4o 在两个方面给出评分:内容风格。 内容评分评估模型回复是否充分解决了用户指令,而风格评分评估模型回复的风格是否适合语音交互场景。详细说明可以在附录A中找到。

语音文本对齐为了评估文本响应和语音响应之间的对齐情况,作者使用Whisper-large-v3模型将语音响应转录为文本,然后计算转录文本和文本响应之间的Word Error Rate(WER)和Character Error Rate(CER)。作者将这些指标分别称为ASR-WERASR-CER

为了评估生成的语音的质量,作者使用了名为UTMOS11的Mean Opinion Score(MOS)预测模型,该模型能够预测语音的MOS分数以评估其自然度。作者将这个指标称为UTMOS分数。

响应延迟latency是语音交互模型的一个关键指标,它指的是从输入语音指令到语音响应开始之间的时间间隔,这对用户体验有显著影响。此外,当语音响应开始时,作者还计算出已经生成的文字数量,称为**#滞后词**。

Baseline Systems

作者将以下语音语言模型作为基准系统:

SpeechGPT 是一种支持语音输入和输出的语言模型。作者使用原论文中采用的连续模态 Prompt 进行解码,根据语音指令依次输出文本指令、文本响应和语音响应。

SALMONN (+TTS) 是一种能够接受语音和音频输入并作出文本响应的LLM,使其能够执行S2TIF任务。对于S2SIF任务,作者在SALMONN之后添加了一个VITS TTS模型,以分阶段方式生成语音响应。

Qwen2-Audio (+TTS) 是一种强大的通用音频理解模型,能够执行各种与音频相关的任务,包括S2TIF任务。作者还构建了一个Qwen2-Audio和VITS ConCat 的系统,以完成S2SIF任务。

主要结果

表1展示了在InstructS2S-Eval基准测试上的主要结果。首先,对于S2TIF任务,从内容角度来看,LLaMA-Omni相较于之前的模型有显著提高。这主要是由于LLaMA-Omni是基于最新的LLaMA-3.1-8B-Instruct模型开发的,利用其强大的文本指令遵循能力。从风格角度来看,SALMONN和Qwen2-Audio的得分较低,因为他们是语音转文本模型。他们的输出风格与语音交互场景不匹配,经常产生格式化内容并包含大量冗余解释。

相比之下,SpeechGPT作为语音转语音模型,实现了更高的风格分数。同样,作者的LLaMA-Omni也获得了最高的风格分数,表明在经过作者InstructS2S-200K数据集的训练后,输出风格已经与语音交互场景很好地对齐。对于S2SIF任务,LLaMA-Omni在内容和风格得分上都优于之前的模型。这进一步证实了LLaMA-Omni能够在简洁高效的方式下,有效地处理用户的指令。

此外,在语音与文本响应的对齐方面,LLaMA-Omni实现了最低的ASR-WER和ASR-CER分数。相比之下,SpeechGPT在将语音与文本响应对齐方面表现不佳,这可能是由于其顺序生成文本和语音的缘故。

级联系统的语音-文本对齐,如SALMONN+TTS和Qwen2-Audio+TTS,也是次优的,主要原因是生成的文本响应可能包含无法合成为语音的字符。这个问题在Qwen2-Audio中尤为明显,它偶尔会输出中文字符,导致语音响应中出现错误。相比之下,LLaMA-Omni实现了最低的ASR-WER和ASR-CER分数,表明生成的语音与文本响应之间的对齐程度更高,进一步验证了同时生成文本和语音响应的优势。

Case Study

    上图展示了该模型与多个不同模型(Qwen2-Audio、SALMOON、Speech GPT)针对输入指令(“我该如何把礼物包装整齐?”)的输出结果。通过观察与分析,我们可以发现:Qwen2 Audio的响应相当长,包括换行符和括号等无法合成语音的元素。SALMONN的回应也有点长。SpeechGPT的响应风格更适合语音交互场景,但其响应中包含的信息量较少。相比之下,LLaMA Omni给出的响应更详细、更有用,同时保持了简洁的风格,在语音交互场景中优于之前的模型。

语音质量和响应延迟之间的权衡

LLaMA-Omni 可以同时生成文本响应和与语音响应对应的离散单元。如第2.6节所述,为了进一步实现流形波生成,当生成的离散单元数量达到一定块大小Ω时,该块单元被输入到语音合成器中进行合成和播放。通过调整Ω的值,作者可以控制系统的延迟,其中较小的Ω对应较低的系统延迟。当Ω=+∞时,意味着在合成语音之前等待所有单元生成。同时,Ω的值也影响生成的语音质量。较小的Ω意味着将语音分割成更多段进行合成,这可能导致段与段之间的断续,可能降低语音的整体连贯性。

为了更好地理解Ω的影响,作者研究了系统的延迟、语音与文本响应的对齐以及不同Ω设置下生成的语音质量。如表2所示,当Ω设置为10时,系统的响应延迟低至226毫秒,甚至低于GPT-4o的平均音频延迟320毫秒。此时,语音响应在开始时平均滞后1.82个词。当Ω设置为无穷大时,延迟增加到约2秒。对于ASR-WER和ASR-CER指标,作者惊讶地发现,随着块大小的增加,错误率也增加。作者认为可能有两个原因。

  • 一方面, vocoder可能比长序列更可靠地处理短单元序列,因为它通常训练在较短序列上。
  • 另一方面,作者使用的ASR模型Whisper-large-v3具有很强的鲁棒性。即使语音与较小Ω的较小连续性,对ASR识别精度影响很小。

因此,作者进一步使用UTMOS指标评估生成的语音自然度。它显示,随着Ω的增加,语音的自然度提高,因为语音的不连续性减少。总之,作者可以根据不同的场景调整Ω的值,以实现响应延迟和语音质量之间的权衡。

Decoding Time

表3列出了不同模型在S2TIF和S2SIF任务上的平均解码时间。对于S2TIF任务,SpeechGPT需要先输出文本指令,然后输出文本回复,而SALMONN和Qwen2-Audio倾向于产生冗长的回复。

相比之下,LLaMA-Omni能直接提供简洁的答案,导致解码时间显著降低,每条指令的平均解码时间仅为1.49秒。对于S2SIF任务,SpeechGPT逐条输出文本和语音回复,导致解码时间比仅生成文本回复时大约延长6倍。相比之下,LLaMA-Omni同时输出文本和语音回复,并采用非自动回归架构生成离散单元。因此,总生成时间仅增加1.28倍,证明了LLaMA-Omni在解码速度上的优势。

客观指标性能评估

上表展示了该算法与多个SOTA算法在InstructS2S评估基准上的评估结果。首先,对于S2TIF任务,从内容的角度来看,LLaMA Omni与之前的模型相比有了显著改进。这主要是因为LLaMA Omni是基于最新的LLaMA-3.1-8BInstruct模型开发的,利用了其强大的文本指令跟踪功能。

从风格角度来看,SALMONN和Qwen2 Audio的得分较低,因为它们是语音转文本模型。它们的输出风格与语音交互场景不一致,通常会产生格式化的内容,并包含大量冗余的解释。相比之下,SpeechGPT作为一种语音对语音模型,其风格得分更高。同样,LLaMA Omni获得了最高的风格得分,这表明在该算法InstructS2S-200K数据集上训练后,输出风格与语音交互场景非常一致。    对于S2SIF任务,LLaMA Omni在内容和风格得分方面也优于之前的模型。这进一步证实了LLaMA Omni能够以简洁高效的方式通过语音有效地处理用户的指令。

摘自:https://mp.weixin.qq.com/s/pjCIJaGNyfWiwGwP03zMNg

WavTokenizer-突破语音表征瓶颈

突破音频语言表征的瓶颈! 1s音频仅需40个Token,就能够高质量重建音频

  论文:Wavtokenizer: An Efficient Acoustic Discrete Codec Tokenizer For Audio Language Modeling

  论文地址:https://arxiv.org/pdf/2408.16532

  Github地址:https://github.com/jishengpeng/WavTokenizer

  HuggingFace地址:https://huggingface.co/novateur/WavTokenizer

浙江大学,联合阿里通义语音实验室和Meta研究员发表了一篇题为“Wavtokenizer: An Efficient Acoustic Discrete Codec Tokenizer For Audio Language Modeling”的论文。该论文研究了如何将多码本(RVQ)语音声学编解码器模型简化为单码本(VQ)结构,它不仅在压缩率和重构质量上超越了现有的最先进Codec模型,在UTMOS主观感知质量等指标上实现了SOTA的性能,还在语义信息建模上取得了重要进展,极致的序列压缩将有效提升下游语音大语言模型/多模态大语言模型的建模能力。

背景动机:解决音频语言建模的瓶颈,迈向更高效的音频处理

在大规模语言模型快速发展的背景下,音频处理领域依赖于离散化声学编解码器模型将音频信号转换为离散token,使其能被语言模型处理。然而,当前的技术在以下几个方面存在显著的局限性:

  1. 压缩与重构质量的权衡:大多数现有模型(如DAC、Encodec)通过多量化器层的设计来提升音频重构质量,但这也增加了计算复杂性和资源消耗。例如,DAC模型在9个量化器层的条件下,每秒需要900个token来重构一秒音频。如此高的压缩比率和计算成本,使得下游应用和模型部署变得复杂且代价高昂。
  2. 缺乏语义信息的丰富表达:当前的声学编码模型大多专注于音频的重构,而未能有效捕捉和保留语音和音频中的语义信息这是重建任务和下游生成任务本身的训练gap。一些研究通过添加独立的语义模块来增强语义内容,但这通常需要多阶段的模型架构,增加了训练复杂度,并导致难以统一建模语音、音乐和其他音频数据。
  3. 单量化器模型的探索潜力:多量化器模型的复杂性推动了研究者对单量化器模型的探索,但在极端压缩条件下保持高质量重构仍是一个挑战。单量化器模型的优势在于更简单的架构和更低的计算成本,但如何优化矢量量化(VQ)空间以增强表示能力,并设计出避免重构伪影的解码器结构,依然是未解决的问题。

基于这些挑战,我们提出了 WavTokenizer。通过创新设计扩展VQ空间、优化解码器架构、扩展上下文建模窗口和引入多尺度判别器,我们的模型实现了极致的压缩效果,同时显著提升了音频重构质量和语义信息表达能力。这一工作不仅为音频语言建模提供了新方向,也在音频生成和理解的未来应用中展现出巨大潜力。

它与SOTA声学编解码器相比,在音频领域具有以下几个优点:

1)极限压缩。通过压缩量化器的层次和离散编解码器的时间维度,24kHz采样率的一秒音频仅需要具有40或75个令牌的单个量化器。

2)提高主观质量。尽管减少了令牌的数量,但WavTokenizer仍能以出色的UTMOS得分实现最先进的重建质量,并固有地包含更丰富的语义信息。 

实现细节:WavTokenizer的核心技术设计

图1:WavTokenizer和最先进的声学编解码器模型之间的比较。纵轴UTMOS表示更接近人类听觉感知的重构质量,横轴kbps表示音频压缩水平。圆圈的大小表示每秒离散令牌的数量。

为了突破当前音频语言建模中存在的压缩和重构质量瓶颈,我们设计了一个新的离散声学编解码器模型——WavTokenizer。它在音频压缩、重构质量和语义信息表达能力上实现了前所未有的平衡。

我们的模型建立在VQ-GANs框架上,遵循与SoundStream和EnCodec相同的模式。具体来说,WavTokenizer通过三个模块传递原始音频 X ,编码器模块、量化模块、解码器模块

1) 采用音频输入并生成潜在特征表示 Z 的全卷积编码器网络;

2) 用于生成离散表示 Z的单个量化器来离散化特征Z。

3) 一种改进的解码器,用于从压缩的潜在表示 Zq 中重构音频信号 X~ 。

该模型是端到端训练的,优化了在时间和频率域上应用的重建损失,以及在不同分辨率下操作的鉴别器形式的感知损失。

考虑到WavTokenizer被设计为大型音频语言模型的离散令牌表示,重点应该放在编解码器的主观重建质量(音频保真度)和语义内容信息上。在图1中,我们可视化了比特率和UTMOS度量之间的关系。我们可以观察到WavTokenizer仅用75个令牌就实现了最先进的重建质量。此外,它还探索了极端的压缩比特率,在0.48 kbps时达到了3.6的UTMOS分数。

编码器设计

跟Encodec设计类似,编码器模型由具有C个通道的1D卷积组成,并且核大小为7,随后是B个卷积块。每个卷积块由单个残差单元组成,该残差单元之后是由步长S的两倍的核大小的步长卷积组成的下采样层。残差单元包含两个核大小为3的卷积和一个跳跃连接.每当发生下采样时,通道数量加倍。卷积块之后是用于序列建模的两层LSTM和具有7个核大小和D个输出通道的最终1D卷积层。

扩展矢量量化(VQ)空间,提高码本利用率

在传统的声学编解码器模型中,矢量量化(VQ)空间的大小通常是固定的,这限制了模型对音频信号的表达能力。我们通过将VQ空间从 1024 扩展到4096,显著提升了模型对高维音频数据的压缩和表达能力。为了确保扩展后的VQ空间得到充分利用,WavTokenizer 采用了基于K-means聚类初始化和随机唤醒策略的优化方法。这种设计能够在保证较低码率的同时,维持高质量的音频重构效果,并且能够有效减少信息损失。

图2:WavTokenizer量化码本空间的可视化分析,图(a)说明了LibriTTS测试干净集上每个码本索引(1-16384)的概率分布。图(B)检查了不同码本空间上的重构质量和码本利用率之间的关系。

最初,在不改变任何结构的情况下,我们试图在训练期间仅依赖于单个量化器来进行重构,但发现结果不是最佳的。考虑到自然语言中巨大的词汇空间,我们假设将语音作为一种独特的语言来处理可能会产生更好的结果。因此,我们首先将码本空间从 210 扩展到 214 。我们对LibriTTS进行了585小时的训练,并在LibriTTS测试-清理数据集上可视化了码本的概率分布,如图2(a)所示。 我们观察到语音词汇空间集中在 212 的左侧,表明利用更大的 212 语音词汇空间的潜力。当前的编解码器码本 210 可能没有充分利用语音空间的潜力。

此外,扩展量化码本空间可能导致较低的利用率,

我们使用K均值聚类来初始化码本向量。我们将聚类中心的数量调整为200,以与较大的码本空间对齐。在训练期间,使用衰减为0.99的指数移动平均值来更新每个输入的所选代码,并且用从当前批次中随机采样的输入向量来替换对于若干批次未分配的代码。这种强制激活策略有助于确保大码本空间的有效利用。 如图2(B)所示,我们分析了码本利用率与重构结果的关系,确认了 212 是合适的,与图2(a)的结论一致,适当扩展相应的码本空间可以减少将分层RVQ结构压缩到单个量化器所带来的信息损失。语音可以在串行化量化器结构下有效地重构,其中 212 的码本空间实现利用率和重构质量之间的有利平衡。这表明了将语音与广泛的自然语言词汇对齐的潜力,通过标记器将其作为一种独特的语言进行强有力的映射。

改进的解码器架构:逆傅里叶变换、注意力机制与扩展的上下文窗口结合

传统的编解码器模型通常使用镜像卷积上采样的方法,但这容易产生混叠伪影,影响音频重构质量。为了解决这一问题,WavTokenizer 在解码器设计中基于Vocos模型,采用了基于逆傅里叶变换(iFFT)的方法。iFFT 能在所有深度上保持一致的特征分辨率,有效减少重构伪影,同时更精确地恢复音频信号。在解码器部分中,使用短时傅立叶变换(STFT)来表示目标音频信号 X~ 

此外,WavTokenizer 在解码器中引入了注意力模块,并设计了扩展的上下文窗口来增强语义信息的建模能力。研究表明,使用更大的上下文窗口(例如 3 秒)有助于捕捉更多的语义信息,提升模型对长音频序列的重构质量。这种方法能够更好地处理音频中的静音段,提高了重构结果的连贯性和自然度。通过将注意力网络与逆傅里叶变换结合,WavTokenizer 在极低码率下实现了高质量的音频重构。

将WavTokenizer的上下文建模窗口扩展到3秒,注意力模块将进一步改善训练过程中的编解码器重建。这可能是因为一秒钟的剪辑,包括沉默,可能包含不足的语义信息。增加上下文建模窗口大小有助于编解码器模型更好地捕获上下文。我们通过详细的消融研究验证了这些发现。在我们的实验中,我们还发现在WavTokenizer中引入注意力模块只对解码器有益。

多尺度判别器与复数STFT判别器的设计

为了进一步优化生成音频的质量,WavTokenizer 引入了多尺度判别器(MSD)和复数短时傅里叶变换(STFT)判别器。这些判别器能够在不同时间尺度和频谱范围内对生成的音频进行评估。模型使用了对抗性损失(adversarial loss)和特征匹配损失(feature matching loss)进行联合优化。与现有模型相比,这种创新设计能够更好地保留音频的细节信息和语义内容,提高了音频重构的主观质量。

端到端优化策略,实现高效压缩

WavTokenizer 采用了端到端的优化策略,同时考虑时间域和频率域的重构损失。与现有的多量化器层模型相比,WavTokenizer能够在单量化器条件下实现更高效的音频压缩。在 24kHz 采样率下,每秒音频仅需 40 或 75 个离散token,这大大减少了模型的带宽需求,同时保持了高水平的音频重构质量。

这些技术创新使得WavTokenizer能够在单量化器结构下实现音频的极致压缩和高质量重构,同时提供丰富的语义信息表达能力。我们相信,这一模型将为音频语言建模的未来应用提供新的可能性。

实验验证:WavTokenizer的卓越性能

为了验证 WavTokenizer 在音频语言建模中的实际效果,我们在多个数据集上进行了广泛的实验,涵盖了语音重构、语义信息评估和消融研究。结果显示,WavTokenizer 在多个指标上均优于现有的最先进模型,展现了其卓越的压缩效率、重构质量和语义表达能力。在LibriTTS测试集上的语音重构实验中,WavTokenizer-small在0.9 kbps的压缩率下,仅使用一个量化器和75个token,就实现了4.05的UTMOS得分,显著超越了使用9个量化器和900个token的DAC模型的3.91分。这一结果表明,WavTokenizer在极低码率下依然能够保持卓越的音频重构质量,接近人类听觉感知水平。相比于需要多个量化器的复杂模型,WavTokenizer在使用单一量化器、40个token的条件下,也展现出高效的压缩率和优异的重构效果,大大降低了计算成本。同时,在PESQ等感知语音质量指标上,WavTokenizer表现与多量化器模型相当甚至更优,进一步验证了其在单量化器设置下对音频质量的强大保持能力。

在语义信息评估方面,我们使用ARCH基准评估了WavTokenizer在不同音频任务中的表现。结果显示,WavTokenizer在情感语音、歌曲(RAVDESS)和口语理解(SLURP)等多领域任务中,表现优于使用更多量化器的Encodec和DAC,展现出卓越的语义捕捉能力。这一结果说明,WavTokenizer不仅能够在极限压缩条件下保持高质量的重构,还能在语义信息表达方面提供强大支持,为下游任务带来更高的应用价值。

为了深入研究WavTokenizer中各个模块的贡献,我们还进行了消融实验,验证了VQ空间扩展、上下文窗口长度的作用。实验结果表明,扩展VQ空间能够显著提高音频重构质量,从而验证了VQ空间优化对模型性能的关键作用;增加上下文窗口长度也有助于更好地捕捉语义信息,尤其是在处理长音频序列时表现突出。

通过这些实验,WavTokenizer 展现出在极限压缩率和长序列生成任务中的强大适应性和稳定性,证明了其在音频压缩、重构质量和语义表达能力方面的全面优势。这些结果不仅为音频语言建模提供了新的可能性,也为未来多模态大模型的音频处理与生成提供了一个更高效、更有潜力的解决方案。

进一步探索

由于训练成本较大,我们将在十月之前补充WavTokenizer-medium,WavTokenizer-large版本的实验结果,以及在audio和music领域codec重建性和语义丰富性的实验。同时将进一步探索WavTokenizer模型在下游生成任务例如text-to-speech和GPT-4o范式任务上的性能,并且补充更多的消融实验结果。

总 结

在本文中,我们提出了一个新的离散声学编解码器模型——WavTokenizer,旨在解决音频语言建模中压缩效率和重构质量之间的权衡问题。与现有的多量化器模型相比,WavTokenizer通过一系列技术创新,包括扩展矢量量化(VQ)空间、改进的解码器架构(结合逆傅里叶变换和注意力机制)、扩展的上下文建模窗口、多尺度判别器和复数STFT判别器的设计,实现了在单量化器架构下的高效音频压缩和高质量音频重构。实验结果表明,WavTokenizer在LibriTTS、RAVDESS、SLURP等多个数据集上的重构质量和语义信息表达方面,均优于当前最先进的模型。

通过对模型架构的改进和优化,WavTokenizer在保持高效压缩的同时,成功减少了模型的计算复杂性和带宽需求,在24kHz采样率下每秒音频仅需40或75个离散token。这一工作不仅验证了单量化器模型的可行性,还为音频生成和语义建模的未来发展提供了新的视角和方向。未来,我们计划进一步扩展模型的应用场景,探索WavTokenizer在更多下游任务和多模态数据处理中的潜力。

Soul语音大模型重磅升级:实时端到端语音通话 AI虚拟人堪比真人!

https://www.soulapp.cn/media/news/article-2

在国内“AI+社交”这条赛道上,Soul App即将利用AI注入了新的活力!

最近,Soul官方宣布其语音大模型再次升级,上线自研端到端全双工语音通话大模型

这次升级带来最惊艳的效果是,可以让用户和虚拟人之间的语音通话就像和真人聊天一样自然流畅!

那么,Soul自研端到端语音通话大模型到底有什么特别之处呢?

根据官方描述,其最大的亮点包括:

  • 具备超低交互延迟
  • 快速自动打断
  • 超真实声音表达
  • 情绪感知理解能力等

超低交互延迟能力意味着,你说话的那一瞬间,AI 就能立刻做出反应,没有任何的延迟,瞬间就能拉近你和 AI 之间的距离。想要和它进行真实的交流,根本不需要等待,简直就像在跟真人对话一样。

Soul 的语音大模型支持快速自动打断功能。也就是说,当你和 AI 交流的时候,如果你想插话,它完全能理解你的意思,轻松打断对方,这样的互动真是太有趣了!

再加上超真实的声音表达和情绪感知理解能力,AI 不仅能听懂你的话,还能感知你的情绪,根据情绪给予适当的的回应。

结合官方展示的视频示例,如果这个功能之后全量上线,估计有一大波用户在Soul上体验的时候,可能会连真人和AI虚拟人都傻傻分不清楚。

Soul方面表示,目前其端到端语音通话大模型已应用于“异世界回响”实时通话场景(内测中),并将在后续拓展至AI苟蛋等多个AI陪伴、AI互动场景

据了解,早在2020年,Soul已经启动了AIGC技术研发,专注于智能对话、语音技术、虚拟人等关键技术的研发,并把这些AI能力深度融入到社交场景中。

在用AI升级社交的过程中,Soul特别注重实现拟人化、自然化的情感陪伴体验。

为了给用户带来更好的情绪反馈和陪伴感,Soul技术团队一直在关注情绪理解和延迟问题。

社交平台Soul App(以下简称“Soul”)语音生成大模型上线,同时自研语音大模型“伶伦”正式升级,现阶段,Soul语音大模型“伶伦”包括了语音生成大模型、语音识别大模型、语音对话大模型、音乐生成大模型等,可支持真实音色生成、语音DIY、多语言切换、多情感拟真人实时对话等能力。目前,“伶伦”已应用于Soul “AI苟蛋”、站内狼人游戏“狼人魅影”AI语音实时互动、独立新产品“异世界回响”等场景。

Soul自研的端到端语音通话大模型上线了,意味着用户可以享受到更自然的人机交互体验。

在语音探索方面,Soul基于平台沉淀丰富且多风格的高质量公域语音数据,推出自研语音大模型“伶伦”,在深度融入站内“AI苟蛋”等场景提供多模态互动体验外,还推出了系列趣味社交玩法和活动。

如Soul于2023年上线了“Soul次元歌手”活动,帮助每个人打造自己的AI歌手分身,让很多热爱音乐但不一定会唱歌的人,也能实现“唱歌自由”;“懒人KTV”活动则在音色克隆的基础上,创新性实现多人UGC“AI合唱”。基于音乐模型个性化的创作能力,平台的“AI帮你出灵魂专辑“活动,使用户自由输入任意作曲的主题关键词,即可一键完成词曲创作。

此次,新升级的“伶伦”在训练数据规模和模型架构上均实现了拓展和创新,实现了更真实自然、更多样性和更细颗粒度的控制效果以及流式超低延迟的生成。特别是上线的语音生成大模型在多风格多情感可控、超自然人声生成、多语言切换等方面表现出色。

具体来说,在多情感可控上,“伶伦”能够实现对情绪的深度理解和模拟,在语音生成和对话中表现出不同情感;在声音颗粒度上,支持包括吸气、喘气、笑声、结巴/重复、咳嗽 、叹气、哭声等一系列副语言语音合成,声音效果更真实生动。

未来,Soul 还计划进一步推动多模态端到端大模型能力的建设,让人与 AI 的互动更加有趣、沉浸感更强。

ASR语音识别—N-gram 语言模型

最近在做ASR语音识别任务,基于阿里FunASR框架,特此记录下跟语言模型(LM)相关知识。

语言模型解码

传统基于CD-phone声学建模ASR系统解码器普遍采用HCLG构建解码网络,当前方案中paraformer声学模型直接对音素或字符建模,为此我们采用TLG(Token、Lexicon、Grammar)结构构建统一解码网络,直接将音素/字符序列[ paraformer声学模型 ]、发音词典、语言模型编译形成T、L、G三个wfst子网络,再通过composition、determinization、minimization等一系列操作生成统一解码网络。

我们借鉴EESEN方案,基于openfst/kaldi构建TLG解码网络编译pipeline,支持从原始语料和发音词典到最终解码资源的全流程编译,便于用户自行定制适合自身的解码资源。如下是TLG网络编译流程图。

为什么需要语言模型?

为什么有些句子比其他句子更 流畅(fluent),或者说 更自然(natural)
我们为什么关心这个问题呢?
因为在很多应用中,我们很关心语言的流畅性与自然性。
例如,在语音识别中,你听到一句话,并且想将它转换成文本,所以你需要区分这段语音可能对应的不同文本,并从中选择更加流畅和自然的版本。比如下面两个句子的发音很接近:recognise speech > wreck a nice beach,从流畅和自然的角度考虑,显然,左边的句子更有可能代表了讲话者的本意。而语言模型可以帮你做到这一点,它会告诉你 “recognise speech” 是人们更倾向表达的意思。

  • 那么,我们如何衡量这种 “优度(goodness)”(或者说流畅度、自然度)呢?
    我们用 概率 来衡量它,而语言模型提供了一种很自然的方式来估计句子的概率。
  • 在此基础上,一旦你构建了一个语言模型,你还可以用它来 生成(generation) 语言。

语言模型可以用于哪些任务呢?

  • 主要用于:
    • 语音识别(Speech recognition)
    • 拼写纠错(Spelling correction)
    • 查询补全(Query completion)
    • 光学字符识别(Optical character recognition)
  • 其他生成任务:
    • 机器翻译(Machine translation)
    • 概括(Summarisation)
    • 对话系统(Dialogue systems)

N-gram 语言模型

N-Gram是基于一个假设:第n个词出现与前n-1个词相关,而与其他任何词不相关(这也是隐马尔可夫当中的假设)。整个句子出现的概率就等于各个词出现的概率乘积。各个词的概率可以通过语料中统计计算得到。通常N-Gram取自文本或语料库。

概率:从联合概率到条件概率

我们的目标是得到一个由 m 个单词组成的任意序列(即一个包含 m 个单词的句子)的概率:

P(w1,w2,…,wm)

第一步是利用链式法则(chain rule)将联合概率转换成条件概率的连乘形式:

P(w1,w2,…,wm)=P(w1)P(w2∣w1)P(w3∣w1,w2)⋯P(wm∣w1,…,wm−1)

马尔可夫假设(The Markov Assumption)

目前,这仍然是一个比较棘手的问题,因为随着上下文的不断增加,我们构建的模型中将包含越来越多的参数。所以这里,我们采用一种称为 “马尔可夫假设” 的简化假设:某个单词出现的概率不再依赖于全部上下文,而是取决于离它最近的 n 个单词。因此,我们得到: P(wi∣w1,…,wi−1)≈P(wi∣wi−n+1,…,wi−1)

对于某个很小的 n:

  • 当 n=1 时,一个 unigram 模型:P(w1,w2,…,wm)=∏i=1mP(wi)在 unigram 模型中,我们假设一个句子出现的概率等于其中每个单词单独出现的概率的乘积,这意味着每个单词出现的概率之间相互独立,即我们并不关心每个单词的上下文。
  • 当 n=2 时,一个 bigram 模型:P(w1,w2,…,wm)=∏i=1mP(wi∣wi−1)在 bigram 模型中,我们假设句子中每个单词出现的概率都和它前一个单词出现的概率有关。
  • 当 n=3 时,一个 trigram 模型:P(w1,w2,…,wm)=∏i=1mP(wi∣wi−2,wi−1)在 trigram 模型中,我们假设句子中每个单词出现的概率都和它前两个单词出现的概率有关。

最大似然估计

我们如何计算这些概率?

非常简单,我们只需要一个大的用于训练的语料库(corpus),然后我们就可以根据语料库中各个单词的计数(counts),利用最大似然估计来估计该单词出现的概率:

  • 对于 unigram 模型:

其中,C 是一个计数函数,C(wi) 表示单词 wi 在语料库中出现的次数,M 表示语料库中所有单词 tokens 的数量。

  • 对于 bigram 模型:

其中,C(wi−1,wi) 表示单词 wi−1 和单词 wi 前后相邻一起出现的次数。

  • 对于 n-gram 模型:

同理,我们计算 n-gram 出现的次数,除以 (n-1)-gram(即上下文)出现的次数。

序列的开头和结尾表示

在我们进入例子之前,我们需要用一些特殊的记号表示一个序列的开始和结束:

  • <s> 表示句子的开始
  • </s> 表示句子的结束

Trigram 例子

现在,让我们来看一个玩具例子,假设我们有一个只包含两个句子的语料库。

语料库

可以看到,每个句子开头有两个起始标记,因为我们采用的是 trigram 模型。

我们希望知道下面的句子在一个 trigram 模型下的概率是多少?

说明

  • 首先,我们对要计算的句子的概率按照 trigram 模型拆分成条件概率的连乘形式。
  • 然后,对于等式右边的每一个条件概率项,按照 trigram 模型中的条件概率计算公式,分别统计 “当前单词连同它的上下文” 以及 “单独的上下文部分” 在语料库中出现的次数,并将两者相除,得到该项的计算结果。
    例如,对于上面等式右边第一个条件概率项,我们考虑句子中第一个单词 “yes” 及其相邻的 bigram 上下文 “<s><s>”:

可以看到,子序列 “<s><s>yes” 在语料库中只出现过 1 次;而子序列 “<s><s>” 在语料库中一共出现了 2 次,所以第一个条件概率项的结果为 12。其余各条件概率项的计算方式同理,另外请注意,在计算第四个条件概率项时,bigram 上下文 “nono” 在语料库中一共出现了 5 次。

N-gram 语言模型的一些问题

  • 语言通常具有长距离效应 —— 需要设置较大的 n 值
    有些词对应的上下文可能出现在句子中距离该词很远的地方,这意味着如果我们采用固定长度的上下文(例如:trigram 模型) ,我们可能无法捕捉到足够的上下文相关信息。例如:The lecture/s that took place last week was/were on processing.在上面的句子中,假如我们要决定系动词 be 是应该用第三人称单数形式 was 还是复数形式 were,我们需要回头看句子开头的主语是 lecture 还是 lectures。可以看到,它们之间的距离比较远,如果我们采用 bigram 或者 trigram 模型,我们无法得到相关的上下文信息来告诉我们当前位置应该用 was 还是 were。这是所有有限上下文语言模型(finite context language models)的一个通病。
  • 计算出的结果的概率通常会非常小
    你会发现,一连串条件概率项连乘得到的结果往往会非常小,对于这个问题,我们可以采用取对数计算 log 概率来避免数值下溢(numerical underflow)。
  • 对于不存在于语料库中的词,无法计算其出现概率
    如果我们要计算概率的句子中包含了一些没有在语料库中出现过的单词(例如:人名),我们应该怎么办?
    一种比较简单的技巧是,我们可以用某种特殊符号(例如:<UNK>)来表示这些所谓的 OOV 单词(out-of-vocabulary,即不在词汇表中的单词),并且将语料库中一些非常低频的单词都替换为这种表示未知单词的特殊 token。
  • 出现在新的上下文(context)中的单词
    默认情况下,任何我们之前没有在语料库中见过的 n-gram 的计数都为 0,这将导致计算出的 整个句子的概率为 0。这个问题和前面的 OOV 单词的问题类似,我们的语料库中可能已经包含了这些单词,但是并没有包含该单词在新句子中对应的特定的 n-gram(即上下文信息)。这意味着该单词在新的句子中对应 n-gram 对于语言模型来说是全新的,而且因为 n-gram 的组合存在如此多的可能性,以至于语料库很难将所有的可能性都覆盖到。例如:假设我们构建了一个 five-gram 语言模型,我们的语料库中一共有 20000 个词汇,那么一共存在多少种可能的 five -gram 组合?答案是:200005。这是一个非常非常大的数字,以至于无论我们的训练语料库有多大,都不可能捕捉到所有的可能性组合。这是一个相当常见的问题,并且很重要。如果我们回顾一下链式法则,可以看到所有的条件概率都连乘在一起,所以只要其中某一项在计算子序列时 n-gram 的计数为 0,那么最终 计算出的整个句子的概率就会为 0。为此,我们需要对语言模型进行 平滑处理(smoothing)

平滑处理

  • 基本思想:给之前没有见过的事件赋予概率。
  • 必须附加一个约束条件:P(everything)=1
  • 有很多不同种类的平滑处理方法:
    • 拉普拉斯平滑(Laplacian smoothing,又称 Add-one smoothing,即 “加一” 平滑)
    • “加 k” 平滑(Add-k smoothing)
    • Jelinek-Mercer 插值(又称 线性插值平滑)
    • 卡茨回退法(Katz backoff)
    • 绝对折扣(Absolute discounting)
    • Kneser-Ney
    • ……

拉普拉斯平滑(“加一” 平滑)

简单思想:假装我们看到的每一个 n-gram 都比它们实际出现的次数多 1 次。

  • 这意味着即使是那些我们在语料库中没有见过的 n-gram,我们也将它们出现的次数记为 1 次。所以对于一个新句子中的任何东西都至少有 1 次计数。
  • 对于 unigram 模型(V= 词汇表):

在之前的模型中,我们只是简单的计算单词 wi 在语料库中出现的次数 C(wi) ,然后除以语料库中所有单词 tokens 的数量 M。

现在,对于分子而言,我们总是在它此前的基础上加上 1。然后,为了保证它仍然是一个合法的概率分布,即单词 wi 遍历词汇表中所有可能情况的的概率之和 ∑i=1|V|P(wi)=1,我们需要在此前分母 M 的基础上加上词汇表的长度 |V|(即语料库中所有单词 types 的总数)。

  • 对于 bigram 模型:

同样地,我们在之前分子的基础上加 1,在分母的基础上加 |V|。

所以现在,我们解决了之前新句子中的未知单词或者 n-gram 的计数为 0 从而导致最终计算出的概率为 0 的问题。

“加 k” 平滑

  • “加一” 往往太多了
    但是很多时候,加 1 会显得太多了,我们并不想每次都加 1,因为这会导致原本的罕见事件可能变得有点过于频繁了。并且我们丢弃了所观测的 n-gram 的太多有效计数。
  • 用 “加 k” 来代替 “加一”
    这种方式也被称为 Lidstone 平滑(Lidstone Smoothing)
  • 对于 trigram 模型,公式如下

可以看到,和 “加一” 平滑类似,只是我们将分子中的加 1 变成了加 k,并且为了满足单词 wi 遍历词汇表中所有可能情况的概率之和为 1,我们在分母中的 |V| 前面乘了一个系数 k。

  • 必须选择一个 k
    事实上,如何选择一个合适的 k 值对于模型影响非常大。k 在这里实际上是一个超参数,我们需要尝试对其进行调整以便找到一个使模型表现比较好的 k 值。

 Absolute Discounting 平滑

另外一种更好的方法是采用 绝对折扣平滑(Absolute Discounting)

  • 从每个 观测到的 n-gram 计数中 “借” 一个 固定的概率质量(a fixed probability mass) d。
  • 然后将其 重新分配(redistributes) 到 未知的 n-grams 上。

Backoff 平滑

基本上,我们会按照不断改进的顺序来介绍各种平滑处理方式的变体,由此,我们可以看到对于这些平滑方式的评估。现在,我们继续介绍另一种更好的平滑方式:Backoff 平滑

  • 在之前的 Absolute Discounting 平滑中,我们从观测到的每个 n-gram 计数中 “借来” 一个固定的概率质量,并将它们重新 平均 分配给所有的未知 n-grams。
  • Katz Backoff:概率质量的重新分配是基于一个 低阶(lower order) 模型(例如:unigram 模型)

例如,假设我们现在有一个 bigram 模型,当我们将概率质量重新分配到未知的 bi-grams 时,我们将基于上下文单词的 unigram 概率进行重新分配。因为比例很简单,如果我们看到上下文出现次数越多,我们就给它更高的权重。

对于一个 bigram 模型,它的 Katz Backoff 平滑的概率公式 如下:

我们为什么将这种方式称为 Backoff(回退) 呢?

因为我们在碰到未知的 n-grams 的时候会将原来的模型回退到一个更低阶的 (n-1)-gram 模型:对于一个 bigram 模型,我们在计算未知 bi-grams 的概率时将回退到 unigram 模型;而对于一个 trigram 模型,我们在计算未知 tri-grams 的时候将回退到 bigram 模型。所以,我们总是只回退一步。

 Kneser-Ney 平滑

现在,我们将介绍一种比 Katz Backoff 更好的平滑处理方式:Kneser-Ney 平滑

  • 概率质量分配基于当前单词 w 出现在 不同上下文 中的次数。
    对于概率质量重新分配的问题,相比 Katz Backoff 中只是简单地基于低阶模型,Kneser-Ney 平滑采用的方法是基于当前单词 w 在多少个 不同的上下文 中出现过,或者说是基于该单词的 多功能性(versatility)
    回忆前面 “glasses” 和 “Francisco” 的例子,其中 ,“Francisco” 是一个非常特殊的词,它的 versatility 非常低,因为它很可能只在上下文单词 “San” 后面出现过。因此,对于其他绝大多数的上下文单词,它们后面都不太可能出现 “Francisco” 这个词。而相比之下,“glasses” 这个词具有较高的 versatility,它可能在很多不同的上下文单词之后都出现过。
  • 这种度量被称为 多功能性(versatility) 或者 延续概率(continuation probability)

可以看到,对于观测到的 n-grams,Kneser-Ney 概率和 Katz Backoff 概率两者是相同的。而对于那些未知的 n-grams,Kneser-Ney 概率中从观测 n-grams 中 “借来” 的概率质量 α(wi−1) 与之前一样保持不变,而之前关于低阶模型 P(wi) 的部分则由我们所说的延续概率 Pcont(wi) 来替代。

在延续概率 Pcont(wi) 的计算公式中:分子部分计算的是一共有多少个 唯一 的上下文单词 wi−1 和当前单词 wi 共同出现过(co-occurrence);而分母部分就是将所有可能的单词 wi 对应的不同共现上下文单词数量(即分子部分)进行一个累加。

Interpolation

我们将介绍最后一种也是最好的一种平滑处理方式:插值(Interpolation)

  • 将不同阶数的 n-gram 模型结合起来 的更好的平滑方式。
    我们在前面提到过的 Katz Backoff 平滑:对于一个 trigram 模型,如果我们遇到了一些未知的 tri-grams,我们将回退到一个低阶模型。
    但是一种更好的做法是:将不同阶数的 n-gram 模型结合起来。
  • 逐步缩短的上下文的概率加权求和
    例如,对于一个 trigram 模型,我们计算未知 tri-grams 的平滑概率时会贯穿 trigram、bigram 和 unigram 三种阶数的模型。
  • 一个 trigram 模型下的 Interpolation 平滑概率


我们可以按照下面的步骤计算单词 wm 在上下文单词 “wm−2” 和 “wm−1” 之后出现的 Interpolation 平滑概率:

  • 首先计算 trigram 概率 P3∗,并将其乘以一个系数 λ3;
  • 然后计算 bigram 概率 P2∗,并将其乘以一个系数 λ2;
  • 然后计算 unigram 概率 P1∗,并将其乘以一个系数 λ1;
  • 最后,将三者相加得到最终结果。

并且,为了保证所得到的仍然是一个合法的概率分布,我们需要满足所有 λ 之和为 1。此外,这些 λ 的值甚至并不需要我们手动设置,而是由模型通过一些留存数据学习到的,因为我们想知道对于这些不同阶数的模型,什么样的 Interpolation 方式是最高效的。

 Interpolated Kneser-Ney 平滑

基于 Interpolation,我们得到了 Kneser-Ney 的最后一种版本:Interpolated Kneser-Ney 平滑

Interpolation 替代 back-off

这里,我们所做的唯一改变就是:将之前观测 n-grams 和未知 n-grams 两种情况加在一起,取代了之前的 back-off 操作。所以,相比之前二选一的情况,现在我们都合并在一个公式里。

另外,相比之前的固定概率质量 α(wi−1),这里我们替换为归一化常数 β(wi−1),以确保上下文 wi−1 对应的所有可能的 wi 的概率 PIKN(wi∣wi−1) 之和为 1。

这就是我们到目前为止介绍过的最有效的平滑方式,在实际应用中有很多 n-gram 语言模型都是基于 Interpolated Kneser-Ney 平滑实现的。

实践应用

  • 在实践中,我们通常采用 Kneser-Ney 语言模型并将 5-grams 作为最高阶数。
  • 对于每个 n-gram 阶数都有不同的 discount 值。
  • 当我们试图学习如何在它们之间进行 Interpolation 时,我们将从数据中学习。

生成语言

在最后一部分中,我们将介绍如何利用语言模型来 生成语言(Generating Language)

我们这里讨论的是利用语言模型生成语言的一种通用的方法,并不仅仅局限于 n-gram 语言模型。

但是我们还是会以 n-gram 语言模型作为例子:

  • 给定一个初始单词,从语言模型定义的概率分布中抽取一个词作为下一个出现的单词。
  • 在我们的 n-gram 语言模型中包含 (n−1) 个起始 tokens,用于提供生成第一个单词所需的上下文。
    • 永远不会生成起始标记 <s>,它只作为初始单词的生成条件
    • 生成 </s> 来结束一个序列

例子:Bigram 语言模型

  •  Sentence =<s>
  •  P(?∣<s>)=“a”

这里是一个很简单的例子,我们有一个 bigram 语言模型。现在有一个空句子,即只包含一个起始标记 <s>。我们试图预测在给定一个起始标记 <s> 的条件下,下一个最有可能出现的单词是什么。所以,我们会利用 bigram 语言模型来逐个检查词汇表中每个单词 w 的条件概率 P(w∣<s>),并选择其中概率最大的那个单词作为我们的预测结果。这里,我们可以看到单词 “a” 出现在一个句子开头的概率最大,我们将它添加到句子中。

  •  Sentence =<s> a
  •  P(?∣a)=“cow”

现在我们的句子有了第一个单词 “a”,我们想知道下一个最有可能出现的单词是什么。还是和之前一样,我们逐一检查词汇表中各个词在给定上下文单词 “a” 的情况下,哪个词对应的条件概率最大。可以看到,这里单词 “cow” 出现在单词 “a” 之后的概率最大,所以我们将它添加到句子中。

  •  Sentence =<s> a cow
  •  P(?∣cow)=“eats”

重复上面的步骤,我们得到了下一个最有可能的单词 “eats” 并将它添加到句子中。

  •  Sentence =<s> a cow eats
  •  P(?∣eats)=“grass”

继续,我们得到单词 “grass” 并将它添加到句子中。

  •  Sentence =<s> a cow eats grass
  •  P(?∣grass)=“</s>”

最终,我们预测单词 “grass” 后面最有可能出现的是结束标记 “</s>”,我们将它添加到句子中。

  •  Sentence =<s> a cow eats grass </s>
  • 完成

现在我们得到了一个由这个 bigram 语言模型生成的句子:a cow eats grass

如何选择下一个单词

  • Argmax:在每一轮中选择与上下文共现概率最高的那个单词。
    • 贪婪搜索(Greedy search )
      这其实是一种贪婪搜索策略,因为即使在每一步中我们都选择概率最高的那个单词,也无法保证最终生成的句子具有最优的概率。
  • Beam search decoding
    一种更好的方法是 Beam search decoding,它在机器翻译中应用非常广泛。
    • 在每轮中,我们跟踪概率最高的前 N 个单词
    • 我们总是检查这几个候选单词给出的完整句子的概率
    • 这种方法可以生成具有 近似最优(near-optimal) 概率的句子
  • 从分布中随机抽样
    另一种方法是从语言模型给出的概率分布中随机抽样,例如:temperature sampling

评估语言模型

如何评估一个语言模型的质量?

评估

语言模型的评估通常有两种范式:

  • 外部的(Extrinsic)
    这种评估范式常见于下游应用中,我们根据其反馈来评估语言模型的表现。比如对于机器翻译中的某些任务,我们可以比较不同语言模型在完成该任务上的表现。
    • 例如:拼写纠错、机器翻译
  • 内部的(Intrinsic)
    在这种评估范式下,我们不依赖任何下游应用,而是观察我们的语言模型在保留测试集上的 Perplexity
    • 在保留测试集(held-out test set)上的 Perplexity
    • Perplexity(困惑) 衡量的是我们对于模型在测试数据上给出的预测的置信度。置信度越高,对应的 Perplexity 就越低,代表我们的模型越好。

 Perplexity

  • 整个测试集的逆概率(Inverse probability)
    • 通过单词 tokens(包括结束标记 </s>)的数量实现归一化(Normalization)
  • 假设我们保留的测试集语料库是一个由 m 个单词 w1,w2,…,wm 组成的序列,我们用 PP 表示 Perplexity。从下面的公式可以看到,它是通过对整个测试集的概率 P(w1,w2,…,wm) 取倒数,然后再开 m 次方得到的:
  • 如果我们遇到未知单词(OOV),我们通常是直接忽略掉,因为我们没有办法表示它们。
  • Perplexity 越低,模型表现越好。
    假如我们模型的 Perplexity 只有 1,那么这是最好的情况。因为当我们的测试集语料库上的概率 P(w1,w2,…,wm)=1 时,PP(w1,w2,…,wm)=1。而对于一个非常差的语言模型,可能在测试集上的概率 P(w1,w2,…,wm)=0,此时模型的 Perplexity 将趋近 ∞。所以,最理想的情况是 Perplexity 等于 1,当然,我们永远不可能达到这个值。

总结

  • N-gram 模型在捕捉语言的可预测性方面是一种简单且高效的方法。
    模型的构建很容易:我们只需要一个大的语料库,并且对单词和上下文进行计数即可。
  • 信息可以通过无监督的方式推导得出,可以扩展到大型语料库。
  • 由于稀疏性的存在,需要进行平滑处理才能保证有效性。
    我们需要一些工程上的技巧处理稀疏性问题,例如:smoothing、back-off、interpolation 等。

虽然 n-gram 模型非常简单,但是它在实践中的效果非常好。所以,在构建语言模型时,我们通常会选择将 n-gram 模型作为 baseline,尽管目前有很多模型都采用了深度学习。

思考

思考: Interpolation、Interpolated Kneser-Ney 和 Kneser-Ney 之间有什么区别?我们应当如何判断应该采用哪种方法?

首先,我们应该明确一点:Interpolated(插值)、Smoothing(平滑)和 Backoff(回退)都是用来解决数据稀疏问题(sparsity)的方法。我们在这节课中讨论的前 3 种平滑方法(拉普拉斯、“加 k” 和 Lidstone)都是在 和原先的 N-gram 模型相同的阶数 内重新分配概率,将概率质量从常见情况向罕见情况进行偏移。

Interpolation 和 Backoff 都是通过 结合不同阶数的 N-gram 模型 来解决这个问题。对于 Backoff 而言,如果高阶 higher-gram 的计数为 0,那么它将完全落回低阶 lower-gram;而 Interpolation 则是通过将我们所有的 N-gram 模型加权求和来将它们结合起来。

现在,当我们采用低阶模型时又会带来一个新的问题。例如,对于单词 “Old” 和 “Zealand”,很可能它们的 bi-gram “Old Zealand” 计数为 0,所以我们需要依赖 unigram 模型提供的概率。想象一下,如果单词 “Zealand” 具有一个非常高的 unigram 概率,那么对于这两个词的 bi-gram,我们还是可以得到一个相对较高的共现概率,而这不是我们希望看到的。

Kneser-Ney Smoothing 中引入了所谓 延续计数(continuation count) 的概念。因为在大多数情况下,单词 “Zealand” 只出现在上下文单词 “New” 的后面,所以对于单词 “Zealand” 出现在上下文单词 “Old” 后面这种情况(即 bi-gram “Old Zealand”)的延续计数会非常低。到这里,我们通过 在不同上下文中的频率计数 解决了上述例子中的问题。

回到原问题中提到的哪种方法更好,我们可以在 Backoff 或者 Interpolation 二者中选择一种来使用 Kneser-Ney Smoothing。通常来说,Interpolation 可能更合适,因为这种方式更灵活(因为我们考虑了所有阶数的 N-gram 模型)。

ASR语音识别—Fst热词模型

有限加权【热词】状态转换机(Weighted Finite State Transducers, WFST)

最近在做ASR语音识别任务,基于阿里FunASR框架,特此记录下跟热词模型相关知识。

wfst热词增强

热词构图,我们采用AC自动机结构进行热词网络构图,解决热词前缀重叠场景下难以有效激励的问题。例如热词列表包含“阳光保险”与“保定”两个热词,实际语音内容为“阳光保定”,在匹配到“定”时匹配失败则会根据AC自动机回退机制回退至“保定”热词路径,确保仍可继续匹配的最大子串路径可正常激励。

如下是热词网络实例图。

热词发现与匹配我们采用对主解码网络弧上ilabel音素/字符序列信息进行热词发现及匹配,而非在网络搜索出词时再对整词匹配,该方式优势是能够更早实现对尚未出词热词路径激励,避免热词路径被过早误裁减,其次也可避免由于热词分词结构不一致而导致匹配失败。

热词激励方式,我们采用过程渐进激励和整词激励相结合的方式,而非热词首字或尾字激励。采用仅首字激励方式可能存在部分case在热词后续字的解码过程中路径仍被裁剪掉的情况,而仅在尾字出词时施加激励则可能激励过晚。

过程渐进激励(incremental bias)对过程中每匹配成功一步即进行等量激励,如在后续扩展过程匹配失败则通过回退弧跳转进行激励减除。

整词激励(word bias)支持用户针对不同的热词做差异化的激励分配置,在热词整词出词时进一步施加对应的补偿或惩罚,进而提高热词综合效果。

FST热词是一种基于 有限状态转换器(Finite State Transducer)的关键词识别技术,它具有较高的准确率和实时性,适用于对大量文本进行快速匹配的场景。 但是,FST热词需要提前构建好词典和规则库,且不支持多语种和变体。

FST目前在语音识别和自然语言搜索、处理等方向被广泛应用。例如,在自然语言处理中,经常会遇到一些针对某些内容法则做出修改的操作,比如:如果c的后面紧接x的话,则把c变为b,FST则是基于这些规则上的数学操作,来把若干个规则整合成一个单程的大型规则,以有效提高基于规则的系统(rule-based system)的效率。其功能类似于字典的功能,但其查找是O(1)的,仅仅等于所查找的key长度。目前Lucene4.0在查找Term时就用到了该算法来确定此Term在字典中的位置。FST 可以表示成FST<Key, Value>的形式,我们可以用O(length(key))的复杂度,找到key所对应的值。除此之外,FST 还支持用Value来查找key以及查找Value最优的key等功能。在查找最优的Value时,会用到求最短路径的Dijikstra算法,但建图过程与此无关。

FST是一种用于映射输入符号序列到输出符号序列的有向图结构。它由一组状态组成,状态之间通过带有权重的转换(transitions)相连。每个转换关联输入符号、输出符号和权重(或代价),用于表示从一个状态转移到另一个状态时的条件。

FST与热词的结合

  • 提高权重或优先级FST可以通过增加热词的优先级或降低其识别权重,使得在解码过程中,热词的路径更容易被选择。
  • 热词优先通路:可以通过引入热词的专有路径(transition paths),使得这些词比其他普通词汇更容易通过FST的状态转换。
  • 增强精度通过调整FST中热词的权重或映射路径,系统在遇到热词时会优先选择包含热词的路径,从而提高识别或转换的准确率。

实现方法

  • 构建基础FST: 首先,需要基于词典或语言模型构建一个基础FST。这个FST将输入符号(如字母、音素或单词)映射到输出符号。在语音识别中,FST通常将输入的音素序列映射为单词。
  • 加入热词权重
    • 修改权重对热词的转换路径赋予更低的权重,降低其状态转换代价,使得解码器(decoder)在搜索时更倾向于选择这些路径。例如,使用一个加权的FST,可以将普通词的转换权重设为较大值,而将热词的权重设为较小值。
    • 插入额外路径将热词的路径单独插入到FST中,创建直接通路,以便系统在解码过程中直接选择这些热词而不需要复杂的转移。
  • 组合语言模型和热词FST在实际应用中,通常会将热词FST与其他语言模型(如N-gram或神经网络语言模型)结合起来。例如:
    • 使用热词FST作为一个小型的子图插入到更大规模的语言模型FST中。
    • 热词FST可以作为一个前端过滤器,预处理输入序列以优先选择热词的路径。
  • 动态插入热词: 热词列表可能会根据应用场景动态变化。例如,在语音助手中,用户可能会要求系统识别特定的品牌名称。在这种情况下,FST需要支持动态更新,即在运行时动态插入或删除热词路径。这可以通过以下几种方式实现:
    • On-the-fly 插入:根据实时需求,将新的热词添加到现有FST结构中,可能使用备用状态机或其他支持增量更新的FST实现。
    • 重构FST:当热词发生较大变化时,重新构建FST,以反映新的热词权重。