【VALL-E-02】核心原理

2024-03-25 21:44
文章标签 02 原理 核心 vall

本文主要是介绍【VALL-E-02】核心原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文系个人知乎专栏文章迁移
VALL-E 网络是GPT-SOVITS很重要的参考

知乎专栏地址:
语音生成专栏

相关文章链接:
【VALL-E-01】环境搭建
【VALL-E-02】核心原理

【参考】

【1】Neural Codec Language Models are Zero-Shot Text to Speech Synthesizers
【2】https://www.shili8.cn/article/detail_20001089545.html
【3】https://zhuanlan.zhihu.com/p/647390304?utm_id=0
【4】https://github.com/facebookresearch/encodec
【5】https://www.bilibili.com/video/BV1zo4y1K7oK/?spm_id_from=333.337.search-card.all.click&vd_source=030dfdbeaef00211755804fc3102911e
【6】https://www.doc88.com/p-78547750936802.html

1、前置知识点:Encodec

Vall-E 是基于 Encodec 来完成语音编码的生成。

1.1、向量量化编码

在这里插入图片描述

  1. 向量量化压缩把原始信息以字典表的形式做进一步压缩
  2. 在 vall-e 的源码中采用 EuclideanCodebook,每个EuclideanCodebook 默认大小是 1024*128
  3. 每次输入待编码的帧也是128,通过计算欧式距离的最大值,并返回最大值的索引(0~1024之间)

在这里插入图片描述

1.2、总体结构

在这里插入图片描述

  • encodec 是一个encoder 和 decoder 结构,分别利用卷积和反卷积进行压缩和解压缩
  • 中间的残差量化层 Quantier 是对 encoder 压缩完的结构进行进一步压缩
  • 所谓的残差量化,是在每一层的量化后,所形成与输入的差会进行再一次量化,形成一个量化的结果组
  • 由于是残差的,也可知其第一个量化结果能表征最粗粒度的信息,因此在VALL-E中被特殊处理
  • 源码如下图所示,有 nq 的量化器,每次返回其字典中欧式距离最大的索引,最终形成一个 8 维度的向量
    在这里插入图片描述

1.3、代码举例

from encodec import EncodecModel
from encodec.utils import convert_audioimport torchaudio
import torchmodel = EncodecModel.encodec_model_24khz()# 当设置带宽为 6.0 时,采用 nq=8 的编码字典
model.set_target_bandwidth(6.0)wav, sr = torchaudio.load("shantianfang.wav")
wav = convert_audio(wav, sr, model.sample_rate, model.channels)
wav = wav.unsqueeze(0)with torch.no_grad():encoded_frames = model.encode(wav)
codes = torch.cat([encoded[0] for encoded in encoded_frames], dim=-1)
print(codes)
print(codes.shape) # ([1, 8, 725]) 1 段音频,总共 725 帧,每帧的字典索引大小为 8(对应编码字典的 nq)

在 VALL-E 的源码中其设置的带宽也是 6.0,因此与论文中 C 的维度是 8 一致,如下

class AudioTokenizer:"""EnCodec audio."""def __init__(self,device: Any = None,) -> None:# Instantiate a pretrained EnCodec modelmodel = EncodecModel.encodec_model_24khz()model.set_target_bandwidth(6.0)remove_encodec_weight_norm(model)

2、VALL-E 总体结构

Vall-E 论文中将 TTS 问题定义为一个条件编解语言模型,具体如下:

2.1、数据集

考虑一个数据集 D = { x i , y i } D= \{x_i, y_i\} D={xi,yi} ,其中 y 是音频样本 x = { x 0 , x 1 , . . . . , x L } x = \{x_0, x_1, ...., x_L\} x={x0,x1,....,xL} 是 音频 y 对应的【文本音素】序列

2.2、Encodec编解码器

利用一个预训练模型将原始音频数据进行处理,用Encodec的【编码器】:
E n c o d e c ( y ) = C T × 8 Encodec(y) = C^{T \times 8} Encodec(y)=CT×8 编解码后的结果如上式可知是一个二维矩阵,其中长度 T 是原始音频的降采样后的长度(如分为30帧),8 是每一帧的特征长度。
同样用Encodec【解码器】具备相反的能力,定义如下: D e c o d e c ( C ) ≈ y ^ Decodec(C) \approx \hat{y} Decodec(C)y^
在这里插入图片描述

2.3、零样本训练

这里训练的目的最大化 p ( C ∣ x , C ^ ) p(C|x,\hat{C}) p(Cx,C^),定义如下:
C ^ = C ^ T ‘ × 8 \hat{C} = \hat{C}^{T‘ \times 8} C^=C^T×8 是一段语音提示(prompt)对应的编码结果,如上文 b 所示。— 提示语音特征
x 是某个音频数据 y 的【文本因素】的序列,如上文 a 所示 – 目标文本特征

C 是某个音频数据 y 的编码结果,如 上文 b 所示 – 目标语音特征
于是,在训练时,我们的目标是训练一个模型,可以通过一个 【提示语音编码】+【目标文本特征】转换为【目标语音编码】。这个目标语音特征是可以利用 Decodec 转换为最终音频文件。

训练时,【提示语音编码】和【目标语音编码】应该为同一个人,而推理时,将目标说话人一个较短的音频文件生成【提示语音特征】,最终即可构建符合目标人语音效果的【新的目标语音编码】

在这里插入图片描述
理解:
1、在 encodec 的编码量化结果中本质上包含了文本要素(说什么),以及语音要素(如音色等)
2、在 vall-e 的模型中量化结果不需要完整的音频信息,而是从 prompt 的量化结果中提取语音要素 加上 文本要素 后生成一个完整的语音编码量化结果,这个结果被用来生成最终语音

3、VALL-E 核心设计

3.1、自回归模型AR

在这里插入图片描述
自回归模型使用特征中的第一个维度,即 prompt 的 C ^ : 1 \hat{C}_{:1} C^:1 和原始音频对应编码的 C : 1 C_{:1} C:1
该模型是自回归,同时给出 prompt 的全部对应编码特征,然后依次推到知道终结符EOS(类似经典transformer的解码器)

3.2、非自回归模型NAR

在这里插入图片描述
自回归模型使用特征中除第一个之外的维度

模型是非自回归的,对于整个编码序列,用之前的全部特征维度 C , 1 : j − 1 C_{,1:j-1} C,1:j1 推导 C : j C_{:j} C:j

这篇关于【VALL-E-02】核心原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/846329

相关文章

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

SpringQuartz定时任务核心组件JobDetail与Trigger配置

《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

Linux find 命令完全指南及核心用法

《Linuxfind命令完全指南及核心用法》find是Linux系统最强大的文件搜索工具,支持嵌套遍历、条件筛选、执行动作,下面给大家介绍Linuxfind命令完全指南,感兴趣的朋友一起看看吧... 目录一、基础搜索模式1. 按文件名搜索(精确/模糊匹配)2. 排除指定目录/文件二、根据文件类型筛选三、时间

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操