大模型之三十-语音合成TTS(coqui)

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:

  1. 验证集Loss:关注验证集上的loss是判断过拟合和模型普适性的关键。理想情况下,验证集的loss应当与训练集的loss相似或略高。如果验证集的loss开始增加,而训练集的loss继续下降,这可能是过拟合的标志。
  2. 听觉评估:最终,由于TTS系统的目标是产生高质量、自然的语音,因此主观听觉测试也非常重要。即使loss值看起来合理,最终的语音质量和自然度才是评估模型性能的关键。

模型结构

xtts 基于Tortoise模型,做了几个改动以实现multilingual e ZS-TTS,其模型结构主要包括VQ-VAE、Encoder(GPT2 blocks)以及Decoder(HiFi-GAN vocoder)。

在这里插入图片描述
升级的xTTSv2大致结构上和v1版本一直,主要是多了一个用于说话人编码的Perceiver模块。

  • xTTSv2 支持18种语言
  • 流式生成时间小于200ms
  • 支持跨语言音色克隆,开源了模型,支持fine-tune
    这个以两阶段的TTS系统(区别于VITS一阶段),其首先将文本转成梅尔谱,然后从梅尔谱生成时域波形。这个两阶段的实现过程主要包括对梅尔谱编码的VQ-VAE模块、GPT-2 Encoder模块、HIFI-GAN声码器模块以及一个用于说话人编码的Perceiver模块。

VQ-VAE

VAE(变分自编码)在《大模型之二十六- 图像生成Diffusion model实例浅析》汽车生成的Diffusion模型中有涉及,其预测高斯分布的均值和方差,这样好处是可以不依赖于编码器,通过采样一个高斯分布送入解码器,解码后直接得到图片,这个是矢量量化的变分自编码,尽管学术界从模型层面进行了解释,比如可以避免VAE的后验坍塌问题、更严格的latent space约束(矢量量化)是的生成质量更高。

个人更觉得VQ的思想起源于音视频编码中的码本概念而来的,比如Opus音频编码的时候会提取(SILK部分)LPC系数,然后通过矢量量化的方式对编码的语言特征参数进行压缩,压缩成码本的索引,这样可以极大提升压缩效率,比如实时音频编解码之十九 基于AI的语音编码(LPCNet)。对于图像也是一样,图像上通过将数据空间划分为有限数量的区域(每个区域由码本中的一个“码字”代表)来工作。

VQ-VAE(Vector Quantised-Variational AutoEncoder)是一种使用向量量化的变分自编码器。该技术结合了自编码器的强大数据压缩能力和向量量化的高效编码方法,在保留重要信息的同时,实现了数据的有效压缩。

xTTSv2使用的VQ-VAE的输入是梅尔谱,帧率是21.53Hz,每帧1个对应一个码字,总共8192个码字,VQ-VAE模型从参数量是13M。XTTSv2在训练VQ-VAE之后只保留了1024个码字。

基本概念

  • 自编码器(AutoEncoder):是一种无监督学习的神经网络,用于学习一个数据的有效表示(即编码),通常用于降维或特征学习。在自编码器中,数据通过一个编码器被压缩成一个低维空间(潜在空间),然后通过一个解码器重新构建。这种自编码的Encoder之后的特征分布是未知的。
  • 变分自编码器(Variational AutoEncoder, VAE):是自编码器的一种变体,它不仅学习数据编码,还学习编码的分布,使模型能生成新的数据点,这种分布一般使用的是高斯类的分布,这就使得在训练完成之后,可以人为构建类高斯的分布数据,这样可以直接输入到Decoder而生成新的数据(图像、音频)而不需要Encoder了。
  • 向量量化(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分词器,这种分词方法通过合并常见的字节对来有效减少词汇表的大小,从而提升处理效率。但是中文的分词效率太低,比如还出现了,“shu3xia4de5yi2ge4”: 4739,此外对符号的处理也不够详细,对笑声、叹息声等也没有支持。这些是可以改进的点。
  • 输出:编码器的输出是对VQ-VAE音频编码的码字,这些码字用于后续的音频生成或处理。
  • 这个GPT-2是一个条件解码,其也接受梅尔谱输入,这是通过后面的Perceiver采样模块将说话人音频转成固定长度的Embedding输入GPT-2模块。

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的码字。

我觉得之所以存在这一问题,是因为不同于图片类生成任务,图片生成一次可以看到整张图所有信息,音频是一个强时域信号,帧间的甚至是长上下文信息对生成的质量至关重要,而GPT-2的Transformer正好可以很好的处理上下文长时信息。所有可以看到VITS模型衍生出的GPT-VITS类模型效果也是比较好的。

在解码过程中说话人的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 中,网络会整合来自不同尺寸感受野的信息,这些感受野可能由不同大小的卷积核或不同数量的卷积层堆叠形成。通过这种方式,网络能同时捕捉细节(小感受野)和更广泛的上下文信息(大感受野)。

Perceiver

输入是约3~6秒的说话人音频,输入是该音频的梅尔谱,输出是32 latent vectors,表示说话人信息,论文说这比Encoder的Embedding来编码说话人信息更好。

fine-tune

Tortoise 49k英文
Mega-TTS 2 38k 中英文
Xtts的模型使用了1.4万小时的英文数据,233小时的中文数据。相比而言,几乎相同结构的chattts开源的小版本使用了4万小时,闭源的使用了10万小时音频数据。

在训练的时候,需要32GB内存的GPU卡,免费GPU应该是蹭不到了。欢迎关注、收藏、点赞,以便及时收到下一篇 fine-tune博客推送

下一篇公布fine-tune细节,这里剧透一个Training loss截图。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shichaog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值