随着大型语言模型(Large Language Models,LLMs)在生成式人工智能领域的快速发展,基于语音的应用如文本到语音合成(TTS)、自动语音识别(ASR)以及语音对话系统等日益受到关注。语音编解码器作为连接原始语音信号与语言模型的重要桥梁,其作用类似于自然语言处理中的文本分词器,能够将连续的语音波形转化为离散的编码 token,便于与LLM等模型进行有效融合和交互。
这三个表示之间的关系可以用公式S + G ≈ A 来描述,其中 S 是离散语义编码,G 是全局级副语言编码,A 是连续声学表示。通过这种方式,SecoustiCodec能够在单码本空间中实现语义和副语言信息的分离。
1.声学建模
声学建模部分包括语音编码器、声学投影和语音解码器。语音编码器将输入的语音信号Sin编码为连续的声学表示 A,然后通过声学投影模块进一步处理。语音解码器则负责将声学表示 A 重建为语音信号。
2. 语义建模
语义建模部分包括语义投影、变分自编码器(VAE)、有限标量量化(FSQ)和对比学习模块。其目标是从语音信号中提取纯净的语义信息,并将其编码为离散的语义表示 S。首先通过语义投影,将语音编码器的输出进一步映射到一个低维的语义空间。随后采用VAE + FSQ,通过VAE生成语义表示的均值 μ 和方差 σ,然后通过FSQ将这些连续的语义表示量化为离散的语义编码 S。这种方法不仅保留了语义信息,还进一步去除了副语言信息,同时提高了码本利用率。最后通过对比学习模块,将语音编码器生成的语义表示 S 和文本编码器生成的音素表示 P 对齐到一个联合帧级对齐的多模态空间中。通过最大化正样本对(S和对应的P)之间的相似度,同时最小化负样本对(S和不对应的P)之间的相似度,模型能够学习到纯净的语义表示。
其中 P 是音频表征,S 是语义表征,A是声学表征。
3. 副语言建模
副语言建模部分包括副语言编码器和语义连接器。其目标是从语音信号中提取副语言信息,并将其编码为全局级的副语言表示G。首先通过副语言编码器才从语音信号中提取副语言信息,如音色、情感等。随后经过语义连接器,将语义表示 S 和副语言表示 G 结合起来,预测声学表示 A^。通过这种方式,模型能够在解码阶段利用副语言信息来重建语音信号。
### Support loss weighting for packing ###
loss = None
if labels is not None:
lm_logits = lm_logits.to(torch.float32)
# Shift so that tokens < n predict n
shift_logits = lm_logits[..., :-1, :].contiguous()
if isinstance(labels, tuple) or isinstance(labels, list):
labels, weights = labels
shift_labels = labels[..., 1:].contiguous()
if self.pack_loss:
shift_weights = weights[..., 1:].contiguous()
loss_fct = CrossEntropyLoss(ignore_index=-100, reduction='none')
loss = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1))
loss = (loss * shift_weights).sum()
else:
loss_fct = CrossEntropyLoss(ignore_index=-100)
loss = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1))
lm_logits = lm_logits.to(hidden_states.dtype)
loss = loss.to(hidden_states.dtype)
### -------------------------------------- ###
我们考虑一个源语言的语音话语,将其表示为单声道波形X∈Rfs⋅d,采样率为 fs=24kHz,时长为 d。类似地,其目标语言的翻译表示为 Y∈Rfs⋅d。我们假设对 X 进行了填充,以确保 X 和 Y 拥有相同的时长。我们的目标是建模条件概率 P[Y∣X]。此外,我们增加了一个约束:在已知 X 的情况下对 Y 的建模应具有因果性,并且相对于源语音具有最小延迟,例如与人工同声传译员在实时翻译场景中所面临的约束相同。
为了通过监督学习学习这一约束,目标语音 Y 本身必须构建为满足因果性约束。我们首先假设 Y 满足这一约束,并介绍如何对其分布进行建模。随后,我们引入一个信息论准则,用以验证 Y 相对于 X 是否具有因果性,并进一步将一个非因果的翻译转换为一个因果的翻译。
模型
以 Moshi框架为基础,对从神经音频编解码器中获得的多个离散标记序列进行联合建模。
Neural audio codec
我们使用预先训练的因果和流式 Mimi 编解码器将 X 和 Y 编码为低帧率的离散标记序列。
编码器将持续时间为 d 的输入波形转换为一个潜在向量 U∈RC×fr⋅d,其中 C是潜在空间的维度,帧率 fr=12.5 Hz。随后,U被投影到其在一个包含NA 个条目的码本中的最近邻。该投影的残差接着被投影到另一个具有相同大小的码本中,如此重复,直到完成 Q 次投影。最后一次的残差被舍弃,解码器则被训练为从这些投影张量的总和中重构原始输入波形。
Kyutai STT 是一个流式模型,这意味着它在接收音频的同时实时转录,而不是假设音频在开始处理前已全部可用。这使其非常适合诸如 Unmute [Make any LLM listen and speak using Kyutai’s speech-to-text and text-to-speech.] 之类的实时应用。
它输出格式良好的转录文本,包含标点符号,同时还提供词级时间戳。
在准确性方面,它的表现仍可与那些能够一次性访问完整音频的最先进非流式模型相媲美。
语义语音活动检测器
对于像 Unmute [Make any LLM listen and speak using Kyutai’s speech-to-text and text-to-speech.] 这样基于串联式语音对话的应用程序,需要一种方式来判断用户是否已经说完,以便生成回应。最常见的方法是使用一个独立的语音活动检测(VAD)模型,判断用户是否在说话,并在用户说完之后等待一个固定的时间。但在实际应用中,不可能找到一个适用于所有情况的等待时间。人们在说话时经常会出现长时间停顿,这会导致这种朴素方法出现误判。
在 Unmute [Make any LLM listen and speak using Kyutai’s speech-to-text and text-to-speech.]中,我们使用一种称为 “flush trick”(刷新技巧)的方法来进一步降低响应延迟。当语音活动检测器预测用户已经说完时,我们还需再等 500 毫秒(即 STT 模型的延迟),以确保不会截断转录的结尾部分。