TTS是text2speech的简称,TTS主要的一些常见包括小说、对话、视频配音、chatbot、虚拟人等场景,因coqui/XTTS-v2
生成质量高、完全开源、多语言支持等特点,所以本篇基于coqui/XTTS-v2
工具包浅出TTS。官方文档见[link]。
介绍
Coqui TTS 是一个开源的文字到语音(Text-to-Speech, TTS)系统,旨在使语音合成技术对研究人员、开发者和创造者更加可接近。它基于先前的 Mozilla TTS 项目。
这个TTS端到端模型提供的特征如下:
- 音色克隆,可以提供仅仅3 秒的音频就实现声音克隆;
- 跨语言克隆,比如英文到中文,中文到英文等,共计16中语言
- 24kHz采样率,对于speech够了,但是对于Music一般要支持立体声、44.1kHz
- 流式推理延迟小于200ms
- 支持模型fine-tune
因其完全开源的特性,所以很多后继的TTS都是基于此的,比如中英的chatTTS的架构和XTTS-v2
非常类似,使用的也是DVAE和GPT架构,包括采样率也都是24kHz,chatTTS开源了4万小时训练的小模型,但是没有开源fine-tune的代码,而诸如Stability AI公司在开源小模型的时候,也会附上完整的fine-tune代码,这极有可能是因为chatTTS堆数据出来的结果,训练并没有多少trick,所以我的建议是,直接看coqui/XTTS-v2
。
语音识别是从波形到频谱,频谱输入模型,模型输出文字的token,语音合成是其逆过程,首先是将文字token化,然后输入模型得到频谱,再从频谱恢复到波形。
coqui/XTTS-v2
是从文本到语音频谱,然后再用声码器(如WaveNet神经网络)将频谱编码成音频,TTS 还包含了许多其他组件,如说话人编码器、语种、音色转换模型等。这些组件共同协作,确保 TTS 能够生成高质量的语音。这里我们只关注和中文有关系的模型,对于其他支持诸如法语、葡萄牙语、丹麦语等模型就不再一一列出了。
(venv) ➜ TTS git:(dev) ✗ pip install tts
(venv) ➜ TTS git:(dev) ✗ tts --list_models
Name format: type/language/dataset/model
## 多语言,多数据集
1: tts_models/multilingual/multi-dataset/xtts_v2
4: tts_models/multilingual/multi-dataset/bark
34: tts_models/zh-CN/baker/tacotron2-DDC-GST
## 声码器模型
Name format: type/language/dataset/model
1: vocoder_models/universal/libri-tts/wavegrad
2: vocoder_models/universal/libri-tts/fullband-melgan
## 音色转换模型
Name format: type/language/dataset/model
1: voice_conversion_models/multilingual/vctk/freevc24
对bark和tacotron2-DDC-GST感兴趣的,可以自行研究。
对于语种支持和内置多说话人的情况,可以参考:
tts --model_name tts_models/multilingual/multi-dataset/xtts_v2 \
--list_language_idx
tts --model_name tts_models/multilingual/multi-dataset/xtts_v2 \
--list_speaker_idx
生成语音和音色克隆也很方便
#内置说话人生成 英语
tts --model_name tts_models/multilingual/multi-dataset/xtts_v2 \
--text "It took me quite a long time to develop a voice, and now that I have it I'm not going to be silent." \
--speaker_idx "Ana Florence" \
--language_idx en \
--use_cuda true
#音色克隆
tts --model_name tts_models/multilingual/multi-dataset/xtts_v2 \
--text "Bugün okula gitmek istemiyorum." \
--speaker_wav /path/to/target/speaker.wav \
--language_idx tr \
--use_cuda true
当然也提供了API的调用方式,下面是流式生成的例子。
import os
import time
import torch
import torchaudio
from TTS.tts.configs.xtts_config import XttsConfig
from TTS.tts.models.xtts import Xtts
print("Loading model...")
config = XttsConfig()
config.load_json("/path/to/xtts/config.json")
model = Xtts.init_from_config(config)
model.load_checkpoint(config, checkpoint_dir="/path/to/xtts/", use_deepspeed=True)
model.cuda()
print("Computing speaker latents...")
gpt_cond_latent, speaker_embedding = model.get_conditioning_latents(audio_path=["reference.wav"])
print("Inference...")
t0 = time.time()
chunks = model.inference_stream(
"It took me quite a long time to develop a voice and now that I have it I am not going to be silent.",
"en",
gpt_cond_latent,
speaker_embedding
)
wav_chuncks = []
for i, chunk in enumerate(chunks):
if i == 0:
print(f"Time to first chunck: {time.time() - t0}")
print(f"Received chunk {i} of audio length {chunk.shape[-1]}")
wav_chuncks.append(chunk)
wav = torch.cat(wav_chuncks, dim=0)
torchaudio.save("xtts_streaming.wav", wav.squeeze().unsqueeze(0).cpu(), 24000)
模型结构
XTTS是建立在自回归模型的最新进展基础上的,比如Tortoise、Vall-E和Soundstorm,这些模型基于训练有离散音频表示的语言模型。XTTS利用VQ-VAE模型将音频离散成音频标记。随后,它使用GPT模型来根据输入文本和说话者的潜变量来预测这些音频标记。说话者的潜变量是通过一组自注意力层计算的。GPT模型的输出传递给一个解码器模型,该模型输出音频信号。对于XTTS-v1,我们采用Tortoise方法,它结合了扩散模型和UnivNet声码器。这种方法涉及使用扩散模型将GPT输出转换为谱图帧,然后利用UnivNet生成最终的音频信号。
关于loss:
- 验证集Loss:关注验证集上的loss是判断过拟合和模型普适性的关键。理想情况下,验证集的loss应当与训练集的loss相似或略高。如果验证集的loss开始增加,而训练集的loss继续下降,这可能是过拟合的标志。
- 听觉评估:最终,由于TTS系统的目标是产生高质量、自然的语音,因此主观听觉测试也非常重要。即使loss值看起来合理,最终的语音质量和自然度才是评估模型性能的关键。
模型结构
xtts 基于Tortoise模型,做了几个改动以实现multilingual e ZS-TTS,其模型结构主要包括VQ-VAE、Encoder(GPT2 blocks)以及Decoder(HiFi-GAN vocoder)。
VQ-VAE
VQ-VAE(Vector Quantised-Variational AutoEncoder)是一种使用向量量化的变分自编码器。该技术结合了自编码器的强大数据压缩能力和向量量化的高效编码方法,在保留重要信息的同时,实现了数据的有效压缩。
VQ的思想其实早在传统的语音编码器中就使用到了,比如实时音频编解码之十九 基于AI的语音编码(LPCNet)。
基本概念
- 自编码器(AutoEncoder):是一种无监督学习的神经网络,用于学习一个数据的有效表示(即编码),通常用于降维或特征学习。在自编码器中,数据通过一个编码器被压缩成一个低维空间(潜在空间),然后通过一个解码器重新构建。
- 变分自编码器(Variational AutoEncoder, VAE):是自编码器的一种变体,它不仅学习数据编码,还学习编码的分布,使模型能生成新的数据点。
- 向量量化(Vector Quantisation, VQ):是一种将大量的向量简化为较少量的代码的技术,常用于数据压缩。在VQ-VAE中,编码的潜在表示被量化为离散的向量,这些向量来自预定义的码本(codebook)。
模型描述 - 参数数量:VQ-VAE模型有13M(1300万)个参数。
- 输入:输入数据是梅尔频谱图,这是一种常用于语音处理的频率特征表示方法。
- 编码:模型使用一个包含8192个码字的码本对每一帧的梅尔频谱进行编码。
- 帧率:编码的帧率为21.53 Hz,意味着每秒产生21.53个编码帧。
码本过滤
过滤过程:在VQ-VAE训练完成后,为了提高模型的表达能力,对码本进行了过滤,只保留了最常用的前1024个码字。这可以看作是一种优化过程,通过减少不常用的代码来提高模型整体的效率和输出质量。
实验验证:初步实验表明,过滤掉较少频繁的代码后,模型的表达能力有所提高。
GPT模型
采用的就是GPT-2的结构,这是Transformer结构中的Decoder部分,共计443M个参数,关于Transformer可以参考《大语言模型之一 Attention is all you need —Transformer》
- 输入:编码器接受通过特定的Byte-Pair Encoding(BPE)分词器得到的文本token作为输入。这里使用的是6681个token的自定义BPE分词器,这种分词方法通过合并常见的字节对来有效减少词汇表的大小,从而提升处理效率。
- 输出:编码器的输出是对VQ-VAE音频编码的码字预测,这些码字用于后续的音频生成或处理。
Conditioning Encoder(条件编码器)
- 功能:Conditioning Encoder 接收梅尔频谱图(mel-spectrograms)作为输入,为不同长度的每个音频样本产生32个1024维的嵌入向量。
- 结构:该编码器由六层16头的缩放点积注意力(Scaled Dot-Product Attention)层组成,这是一种常见的注意力机制,用于模型中不同部分的交互和信息整合。
Perceiver Resampler:接着使用Perceiver Resampler对注意力层的输出进行重采样,以产生固定数量的嵌入,使输出的尺寸独立于输入音频的长度。
Decoder
Decoder是基于26M参数量的 HiFi-GAN vocoder,其输入是GPT-2 Encoder的潜空间(latent vectors)向量,由于VQ-VAE的高压缩率,直接从VQ-VAE的码字重构音频会导致很多发音问题和机械音。所以直接使用了GPT-2的latent vectors作为Decoder的输入而非VQ-VAE的码字。
在解码过程中说话人的Embedding通过Linear projection的方式增加到每一个upsampling层。所以在loss的设计的时候,也增加了speaker Consistency Loss(SCL)。
HiFi-GAN网络结构的简化图,用以说明主要的数据流和网络结构,
输入 x
|
v
Leaky ReLU (lrelu)
|
v
Upsampling Layer
|
v
Residual Block 1 (resblock1_k1x1) ---> z1
| |
v |
Residual Block 2 (resblock2_k2x1) ---> z2
| |
v |
. .
. .
. .
v |
Residual Block N (resblockN_kNx1) ---> zN
| |
v v
------------------------------------> +
| |
v |
Divide by Number of Residual Blocks (#resblocks)
|
v
Leaky ReLU (lrelu)
|
v
Convolutional Layer (conv_post_7x1)
|
v
Tanh Activation (tanh)
|
v
输出 o
在这张图中:
- 数据流 从上到下流动。
- 每个 “zN” 表示从对应的残差块输出的特征,这些特征在流程的末端被累加。
- “+” 表示将所有残差块的输出累加在一起。
- “/ #resblocks” 表示将累加的结果除以残差块的数量,进行平均化处理。
- 最后,通过一系列的激活和卷积层,将处理过的信号输出。
其Residual Block中采用了MRF技术,Multi-Receptive Field Fusion (MRF) 是 HiFi-GAN 中用于提高生成音质的一种技术。MRF 的目的是在生成网络中利用不同大小的感受野,从而更好地捕捉和再现音频信号中的各种时间尺度的特征。感受野是指神经网络中一个节点能“看到”的输入数据的区域大小。
在普通的卷积神经网络中,每个卷积层的感受野是固定的。而在使用 MRF 的 HiFi-GAN 中,网络会整合来自不同尺寸感受野的信息,这些感受野可能由不同大小的卷积核或不同数量的卷积层堆叠形成。通过这种方式,网络能同时捕捉细节(小感受野)和更广泛的上下文信息(大感受野)。
fine-tune
Tortoise 49k英文
Mega-TTS 2 38k 中英文
Xtts的模型使用了1.4万小时的英文数据,233小时的中文数据。相比而言,几乎相同结构的chattts开源的小版本使用了4万小时,闭源的使用了10万小时音频数据。
在训练的时候,需要32GB内存的GPU卡,免费GPU应该是蹭不到了。欢迎关注、收藏、点赞,以便及时收到下一篇 fine-tune博客推送。
下一篇公布fine-tune细节,这里剧透一个Training loss截图。