Few-shot TTS 解决方案
== 目前的解决方案
目前自研的解决方案是:
- 需要30条target speaker的语音(3分钟)
- 训练10分钟
- MOS: 4.5, 下限根据数据来看
- 鲁棒性99%, 下限根据数据来看
- Similarity: 4.5, 下限根据数据来看
- RTF:200ms/10s = 0,02,甚至可以再做压缩。
痛点:
- 把10分钟训练时间砍掉,尽量做到实时的
- 30条语音数据需要的质量较高,采集有难度:方向1)降低数据所需质量,2)降低数据所需数量
With open-source code
Quick Overview
Code # | Model | Date | Institution | Author | Architecture | # of tgt audios | MOS | Similarity | RTF | memo |
---|---|---|---|---|---|---|---|---|---|---|
4 | YourTTS | Feb 2022 | Brazil | Edresson Casanova | VITS+spk emb+language emb+SCL | 1 | 3.97 | 3.07 | 2 | 🌟🌟🌟英文 |
5 | Meta-StyleSpeech | Jun 2021(ICML) | KAIST | Dongchan Min | FastSpeech+GST+episodic meta learning | 1 | 3.82 | 2.6 | NA | 🌟🌟英文 |
10 | Tortoise | Apr 2022 | Jbetker | autoregressive decoder+clvp+cvvp+diffusion decoder+vocoder+... | 1~5 | 3.5 | 2.3 | 12 | 🌟英文 | |
2 | Unet-TTS | ICASSP 2022 | CloudMinds | Rui Li | Unet | 1 | 3.3 | 2.5 | NA | 🌟中文 |
3 | BaiduVC | Oct 2018 | Baidu | Sercan Ö. Arık | Spk adaption | 10 | 3.16 | 3.16 | NA | |
8 | OneModel | Jul 2021 | HKUST | Mutian He | byte | 10 | 3.7 | NA | NA | |
1 | SV2TTS-CN | NA | Mocking Bird | NA | Tacotron2/Transformer+spk emb | 1 | 2.9 | 2.5 | NA | |
6 | Zero-shot VITS | Jan 2019 | Seoul National University | Minchan Kim | VITS+wav2vec | 10min | 4.42 | NA | NA | |
7 | AdaSpeech 1&2 | March&Apr 2021 | Microsoft | Xu Tan | Fastspeech+ConLayerNorm | 10-20 | 3.45 | 3.59 | NA | |
9 | SV2TTS | Jan 2019 | Ye Jia | Tacotron2+spk emb | 1 | 4.2 | 3.28 | NA |
== [✅] Code 1: Realtime Voice Clone for Chinese (Mocking Bird)
改自 仅支持英语的Real-Time-Voice-Cloning 分叉出来的支持中文的Repo
支持的功能点有:
- Voice cloning 语音克隆
- 语音转换 (PPG-based)
- 支持中文、英文
Conclusion 听demo效果有点差,电音很严重,mos估计3.0左右
== [✅] Code 2: Unet-TTS: Improving Unseen Speaker and Style Transfer in One-shot Voice Cloning
支持的功能点有:
- 一句参考语音可进行克隆TTS; 一句话语音风格迁移系统,给定reference audio,能够克隆目标说话人的语音和韵律,可实现多情感合成,但是MOS较低
- 支持中文
Conclusion 复现mos3.0左右,但可实现多情感;也有预训练好的中文模型,不需要从0训练
== [❌] Code 3: Neural Voice Cloning with a Few Samples (Sercan Ö. Arık, Baidu, 2018 Dec.)
支持的功能点有:
- 一句参考语音可进行克隆TTS
== [✅] Code 4: YourTTS: Towards Zero-Shot Multi-Speaker TTS and Zero-Shot Voice Conversion for everyone (Edresson Casanova, Universidade de Sa ̃o Paulo, 2022 Feb)
支持的功能点有:
- 单语种多说话人数据训练模型,实现单语种的zero-shot tts
- bi/tri-lingual
- tri-lingual for single language plus
- Zero-shot cross-lingual VC
- Speaker Adaption
Conclusion: - MOS: 3.8 连贯性还ok,问题1: 噪声, 问题2: 韵律 ||| 论文里的MOS 3.97左右 - Similarity: 3.0 比较难以听出是target speaker的声音,如果两个对比的话可以区分出来一点点区别 ||| 论文里的 Similarity 3.07 - RTF: 2 - coquiTTS的 tts_models--multilingual--multi-dataset--your_tts.zip 测试了之后,可以实现one-shot TTS。 - 没有提供训练的方案,难以在其他语言中复现。
论文里的speaker adaption MOS提升了0.07左右,Similarity持平,并且听Demo也比较差,相似度低,仍存在zero-shot 的噪声和韵律问题,所以不准备再尝试了。
== [✅] Code 5: Meta-StyleSpeech: Multi-Style Adaptive Text to Speech Generation
支持的功能点有:
- 单语种zero-shot tts 且包含口音
Conclusion: MOS: 3.5, Similarity: 2.5。英文效果来说不及YourTTS
== [❌] Code 6: Transfer Learning Framework for Low-Resource Text-to-Speech using a Large-Scale Unlabeled Speech Corpus
支持的功能点有:
- 只需要最少10min的labeled数据集,利用了大量的unlabed的数据集
Conclusion: 10min数据太长了,目前只需要3min
== [❌] Code 7: AdaSpeech
AdaSpeech
- voice cloning given (10~20)+ sentences of any speaker, adaptively training 2k steps
- 需要:1) LibriTTS (2456 speakers, 586 hours)
AdaSpeech 2
- voice cloning given 50 unlabeled sentences of any speaker, adaptively training1w+2k steps
- 需要:1) LibriTTS (2456 speakers, 586 hours)
Conclusion: 不及现有算法。samples和training time都达不到目前的算法预期。
== [Waiting] Code 8: One model to speak them all
- Byte2Speech, 40s 语音 实现voice cloning 和 low-resources languages tts。
- 可以使biaobei说英文,ljspeech说中文。
- 可以尝试小数据量下的粤语模型实现(按照github的recipe,30-100条【文本,音频】可以得到有效的粤语模型)
== [❌] Code 9: Transfer Learning from Speaker Verification to Multispeaker Text-To-Speech Synthesis
Conclusion: 复现过,效果差。以前复现过中文,效果一般,可以参照Mocking Bird的B站demo,mos估计3.0左右
== [✅] Code 10: TorToiSe
Conclusion: 1. 英文复现在部分说话人上还可以(比如ljspeech),2-5条可以得到不错的效果,但在任意给定的自然人上效果一般。 2. 生成速度略慢,按照原文是2分钟生成10s左右的语音。rtf:12。 3. 没有提供训练的方案,难以在其他语言中复现。
模型细节: 1. 由5个独立训练的模型组成: autoregressive decoder
-- reference clips
被ViT(一组reducing convolutions + 一组全注意力的transformers)的模块所读取,在head处,我们取序列中所有元素的mean。然后,我们取所有reference clip的latent的mean来生成一个single reference latent,在代码里被称作conditioning latent。
-- 语音和文本输入
自回归解码器主要负责从文本到语音的转换。首先,语音被采样到22kHz,再将其降采样 1024x,即将其编码为Mel频谱(一个256x的压缩),然后再通过一个在mel频谱上训练的VQVAE将其降低4x。
当压缩了1024x后,生成的语音有相较于对应文本2x的空间维度。这样,这个问题将变成一个容易处理的问题,即通过一个nlp中使用的flat transformer即可处理。
文本首先通过一个经典的256-token的BPE词典来转化为tokens,这个词典是在所使用的语音数据库的文本侧来训练的。语音通过上述提到的VQVAE方法,被转换为8192tokens。
-- 模型
对于实际模型来说,我采用了多层transformer结构来实验。最吸引人的选项是标准的encoder-decoder结构。然而,当我伸缩decoder的深度或者隐藏层的大小时,我遇到了收敛问题。由于这个原因,我选择建立一个只有decoder的结构,就像DALLE中所完成的那样。类似于DALLE,我使用了一个从Huggingface Transformer library中的 GPT-2模型 ,且做了一点小的改进以支持多种模态。
通过使用GPT-2, 我能够在一组transformer layers中执行所有的计算。就像通过OpenAI研究所展示的那样,这样模型的类型很难变换且在多模态情况下完成的更好。最终的GPT结构由30层组成,每一层有16个attention heads和一个1024维的隐藏层。这个总体上有420M参数。作为对比,GPT-2有1.5B参数,DALLE是12B,GPT-3是175B。
与DALLE不同的是,我在所有层上选择了全联接。
我在提交到全尺寸版本的时候训练了一系列的玩具模型,并且发布到了Tortoise。 更小的模型是成功的,但是他们的多说话人的能力比较差。我强烈相信,这个模型是一个用于伸缩变换的杰出的候选人。它欠拟合于数据,在3个epoch内收敛,且在训练和验证集之间没有显著差异。
-- 组成输入
一旦文本和语音都被tokenized,并且条件隐状态被计算了,每个文本和语音序列都被他们自己的START和STOP tokens来padded,然后通过分别的embeddings来输入。然后我们建立了GPT-2 transformer 的inputs通过拼接3个inputs如下:【conditioning_point_latent, text_embeddings, voice_embeddings】
输出的模型是一个 next-token-prediction模型配套了一个转换:它能够预测文本和语音tokens,后者通过首先给模型一些text tokens和一个START voice token。
-- 问题
这个模型包含了一个概率性的理解,文本和语音如何关系到彼此通过给定上下文的声音。然而,如果你简单的常识解码高度压缩的语音表示,它将近乎不智能。这是因为这样巨大的压缩比例使得大部分的音频信息丢失。
这个模型的另一个问题是,解码本身是“有挑战性的”。执行束搜索和贪婪解码会使得,语音像一个长的“uhhhhhhhhhh”或者仅仅简单的静音。这个是自回归解码众所周知的问题。
以上问题的解决方案通过如下来解决。
-- CLVP
Contrastive Language-voice pretraining (CLVP)模型被构建来解决上述提到的解码器的问题。为了解决这个问题,我用了类似于DALLE的解决方案。nucleus sampling被使用来从自回归解码器生成大量的候选者,然后CLVP模型被用来从这些候选者之中选择最可能的text和voice对。
在实际操作中,这个步骤进展的很顺利,除了一个缺点,即你必须首先从自回归模型中计算出许多candidates。
-- The model
CLVP与CLIP的结构很相似,除了图像作为第二模态,CLVP吸收了自回归解码器生成的tokenized outputs (其实是高度压缩的语音片段)。tokenized inputs被使用而不是原始语音或者频谱,因为,解码这些tokens来省城语音采样点是非常计算昂贵的。CLVP倾向于在token-space运转的非常好。
CLVP的文本和语音编码器由一组12层全注意力的transformer层来组成。隐藏层维度是512维且包含8个注意力头。模型总共是67M参数
-- CVVP
Contrastive voice-voice pretraining (CVVP)是一个对比模型学习pair一个clip of 某人说某事通过自回归解码器的tokenized outputs 当输入某个人说某件事。它的目的是steer自回归解码器以相似于reference clip的vocal质量。
CVVP与CLVP几乎是完全相似的,除了它输入文本而不是音频。
CVVP对Tortoise的贡献很小。它能够被完全忽略,并且你用剩下的部分仍旧能够获得一个很好的TTS程序。我没有一种方式来量化它对Tortoise的贡献,但我能主观上分辨出CVVP生成的输出与那些没有CVVP的输出
-- Diffusion decoder
剩下我们需要解决的问题就是解码高度压缩的语音表示回能够用计算机播放的真实语音。即,一个super-resolution的问题。Diffusion models 是super-resolution问题的king(实际上Diffusion models是所有生成模型的king)。所以我自然的选择了这个模型。
Diffusion decoder采取自回归transformer的输出和reference clips并且用这两个输入来构建真实的mel频谱
-- Model
自回归输出首先被一组4x全注意力模块来预处理,并且一个额外的3组全注意力/resnet模块。
The reference clips被一个ViT风格的transformer栈来预处理为point-latent,相似于reference clips被自回归解码器预处理的方式。这个模块的输出称为"conditioning latent".
The conditioning latent 被用来scale和shift mean和variance of the codes latents。这些突变的codes然后被拼接回diffusion decoder的输入在输入到主要的transformer stack之前。
大多数文献中的diffusion models 是Unets和full attention在底层。因为diffusion decoder 仅仅在mel频谱数据上操作,也是深度压缩的,我能够采用一个简单的结构。The diffusion decoder 由一组 10个可替换的full-attention层和残差卷积模块。隐藏维度是1024和16个attention heads。这个模块最终是292M 参数。
就像在文献中提到的,diffusion timestep 信号被输入到网络结构,且被用于计算残差模块输出的mean和variance。
-- The vocoder
以上述描述的结构,我们有一个能生成mel频谱的模型当给定文本和一些reference语音数据。最后一步是将mel频谱转换为语音。
幸运的是,这种框架在TTS领域是很常见的,所以过去一些年,大部分研究被投入其中,开源的声码器如WaveGlow和Univnet提供了显著的效果来将mel频谱转化为语音,甚至能够对集外的声音进行转换。
由于这个原因,我选择使用off-the-shelf vocoder:univnet。这个vocoder与waveglow对比有显著的优势,但是推理更快,模型更小。
这个结论的一个结果是,我被迫在univnet期待的采样率输出语音:24KHz。这与Tortoise模型的其他部分不同,是在22kHz上运作的。相似的,我被迫使用从Tacotron中生成的Mel频谱来与univnet交互,而不是Pytorch libraries(这两种生成略微有点区别的频谱)。
-- Why vocoder
其实Diffusion models已经能够输出原始语音了,那为何我还要采用一个vocoder?实际上我花费了大量的时间来用diffusion models直接输出语音。发现如下: 1. 在高维数据上进行操作意味着我不需要使用U-net结构,这个相对我使用的flat结构效果差些; 2. 在高维数据上运作意味着diffusion U-net不得不有一个非常小的channel 在顶层,这导致了严重的性能损失 3. 重复性的在高维空间操作convolutions在计算上是低效的(因为diffusion models在推理阶段是必须的) 4. Vocoders开源好用
-- System Level Description
最后我们整体上描述Tortoise的结构,来理解他们如何生成语音: 1. 自回归解码器输入文本和reference clips。输出latents和对应的token codes来代表高度压缩的语音数据 1) Nucleus sampling被用作decoding strategy 2) 这个步骤被执行了多次来生成许多“candidate” latents 2. CLVP和CVVP模型选择最好的candidate: 1) CLVP模型在输入文本和每个candidate code sequence之间生成来一个相似分数 2) CVVP模型啦在reference clips和每个candidate之间生成一个相似分数 3) 两个相似度分数被结合到一起。 4) candidate和最高的整体相似度被选择进行下一步骤 3. Diffusion decoder输入自回归latents和reference clips来生成mel频谱代表某些语音输出 4. Univnet声码器被用来将Mel频谱转换为实际的语音数据。