赞
踩
最近发现了一篇关于语音克隆的论文 Transfer Learning from Speaker Verification to Multispeaker Text-To-Speech Synthesis,但原论文是没有开源的。不过在 GitHub 上发现了别的大佬复现此论文的开源项目,特此来翻译一下复现论文。
原论文链接:https://arxiv.org/pdf/1806.04558.pdf
复现论文链接:https://matheo.uliege.be/handle/2268.2/6801
GitHub项目链接:https://github.com/CorentinJ/Real-Time-Voice-Cloning
由于前面是介绍一些相关的背景知识,我就不翻译了,直接从介绍原论文及复现过程开始。
我们的实时语音克隆方法主要基于 SV2TTS 。它描述了一个零样本语音克隆框架,只需要 5 秒的参考语音。这篇论文只是谷歌撰写的 Tacotron 系列的众多出版物之一。有趣的是,SV2TTS 论文本身并没有带来太多创新,而是基于谷歌的三个主要早期工作:GE2E loss、Tacotron 和 WaveNet 。完整的框架是一个三阶段的流水线,其中的步骤对应于之前按顺序列出的模型。 谷歌当前提供的许多 TTS 工具和功能,例如谷歌助手或谷歌云服务,都使用这些相同的模型。虽然网上有许多这些模型的开源重新实现,但据我们所知,没有一个 SV2TTS 框架(截至 2019 年 5 月)。
该框架的三个阶段如下:
• 说话人编码器(GE2E):在数千个带噪声的说话人数据集上训练,不需要文本数据,可从几秒的语音中生成一个 embedding 向量,embedding 是说话人声音的有意义的表示,使得相似的声音在潜在空间中很接近。
• 合成器(没有WaveNet的Tacotron):以speaker embedding为条件从文本生成频谱图。
• 基于WaveNet的自回归声码器:从合成器生成的频谱图中推断出音频波形。
在推理时,说话人编码器会收到要克隆说话人的简短参考话语。它生成用于调节合成器的 embedding,并将作为音素序列处理的文本作为输入提供给合成器。声码器采用合成器的输出来生成语音波形。如下图:
上图:推理期间的 SV2TTS 框架。蓝色块代表 Tacotron 架构的高级视图,经过修改以允许对语音进行调节。该图摘自(Jia et al., 2018)。
SV2TTS 框架的一个特殊性是所有模型都可以在不同的数据集上单独训练。对于编码器,人们试图拥有一种对噪声具有鲁棒性并能够捕获许多人类语音特征的模型。因此,最好使用由许多不同说话者组成的大型语料库来训练编码器,而对音频的噪声水平没有任何强烈要求。此外,编码器使用 GE2E 损失进行训练,除了说话者身份之外不需要任何标签。使用GE2E,模型要学习的任务是说话人验证任务,它本身与语音克隆几乎没有关系。 然而,该任务的规定是网络将输出一个 embedding,该 embedding 是说话人语音的有意义的表示。对于合成器和声码器的数据集,需要转录,生成的音频质量只能与数据一样好。因此需要更高质量和带注释的数据集,这通常意味着它们的大小更小。
在下面的小节中,我们正式定义了 SV2TTS 旨在解决的任务。在剩余的小节中,我们介绍了框架的三个部分,包括对每个部分的实现以及我们的实验结果。
考虑按说话人分组的话语数据集。我们将第 i 个说话人的第 j 个话语表示为
u
i
j
u_{ij}
uij。话语在波形域中。 我们用
x
i
j
x_{ij}
xij 表示话语
u
i
j
u_{ij}
uij 的对数梅尔谱图。对数梅尔谱图是一种确定性、不可逆(有损)函数,可从波形中提取语音特征,以便在机器学习中以更易于处理的方式处理语音。
编码器
ϵ
\epsilon
ϵ 计算的 embedding
e
i
j
=
ϵ
(
x
i
j
;
w
ϵ
)
e_{ij}=\epsilon(x_{ij};w_\epsilon)
eij=ϵ(xij;wϵ) 对应于话语
u
i
j
u_{ij}
uij ,其中
w
ϵ
w_\epsilon
wϵ 是编码器的参数。此外,作者将说话人 embedding 定义为说话人话语 embedding 的质心:
c
i
=
1
n
∑
j
=
1
n
e
i
j
(
1
)
c_i=\frac{1}{n} \sum_{j=1}^n{e_{ij}}\qquad(1)
ci=n1j=1∑neij(1)
合成器 S 由
w
s
w_s
ws 参数化,其任务是在给定
c
i
c_i
ci 和
t
i
j
t_{ij}
tij的情况下,去近似
x
i
j
x_{ij}
xij(即话语
u
i
j
u_{ij}
uij 的转录)。我们有
x
^
i
j
(
x
i
j
的
估
计
量
)
=
S
(
c
i
,
t
i
j
;
w
s
)
\hat{x}_{ij}(x_{ij}的估计量)=S(c_i,t_{ij};w_s)
x^ij(xij的估计量)=S(ci,tij;ws)。在我们的实现中,我们直接使用话语 embedding 而不是说话人 embedding,给出
x
^
i
j
=
S
(
u
i
j
,
t
i
j
;
w
s
)
\hat{x}_{ij}=S(u_{ij},t_{ij};w_s)
x^ij=S(uij,tij;ws)。
最后,声码器 V 由
w
v
w_v
wv 参数化,其任务是在给定
x
^
i
j
\hat{x}_{ij}
x^ij 的情况下,去近似
u
i
j
u_{ij}
uij。我们有
u
^
i
j
=
V
(
x
^
i
j
;
w
v
)
\hat{u}_{ij}=V(\hat{x}_{ij};w_v)
u^ij=V(x^ij;wv) 。
可以使用以下目标函数以端到端的方式训练这个框架:
m
i
n
w
ϵ
,
w
s
,
w
v
L
v
(
u
i
j
,
V
(
S
(
ϵ
(
x
i
j
;
w
ϵ
)
,
t
i
j
;
w
s
)
;
w
v
)
)
min_{w_\epsilon,w_s,w_v}L_v(u_{ij},V(S(\epsilon(x_{ij};w_\epsilon),t_{ij};w_s);w_v))
minwϵ,ws,wvLv(uij,V(S(ϵ(xij;wϵ),tij;ws);wv))
其中
L
v
L_v
Lv 是波形域中的损失函数。这种方法有以下缺点:
• 它需要在同一数据集上训练这三个模型,这意味着该数据集理想情况下需要满足所有模型的要求:编码器需要大量扬声器,但同时合成器需要大量转录。合成器的低电平噪声和编码器的平均噪声电平(以便能够处理嘈杂的输入语音)。这些冲突是有问题的,如果在不同的数据集上单独训练,会导致训练模型表现得更好。具体来说,小数据集可能会导致泛化不良,从而导致零样本性能不佳。
• 可能很难达到组合模型的收敛。特别是,Tacotron 合成器可能需要很长时间才能产生正确的对齐。
解决第二个问题的一个方法是将合成器和声码器的训练分开。假设有一个预训练编码器,可以训练合成器直接预测目标音频的梅尔谱图:
m
i
n
w
s
L
s
(
x
i
j
,
S
(
e
i
j
,
t
i
j
;
w
s
)
)
min_{w_s}L_s(x_{ij},S(e_{ij},t_{ij};w_s))
minwsLs(xij,S(eij,tij;ws))
其中
L
S
L_S
LS 是时频域中的损失函数。
然后直接在频谱图上训练声码器。注意,对真实频谱图或合成器生成的频谱图进行训练的方法都是有效的。 后者需要一个预训练的合成器。
m
i
n
w
v
L
v
(
u
i
j
,
V
(
x
i
j
;
w
v
)
)
o
r
m
i
n
w
v
L
v
(
u
i
j
,
V
(
x
^
i
j
;
w
v
)
)
min_{w_v}L_v(u_{ij},V(x_{ij};w_v))\quad or\quad min_{w_v}L_v(u_{ij},V(\hat{x}_{ij};w_v))
minwvLv(uij,V(xij;wv))orminwvLv(uij,V(x^ij;wv))
仍然是说话人编码器的优化。与合成器和声码器不同,编码器没有要训练的标签。该任务被糟糕地定义为产生 “ 有意义 ” 的 embedding,以表达话语中的声音。可以设想一种将说话人编码器训练为自动编码器的方法,但这需要相应的上采样模型了解要预测的文本。要么数据集被限制为同一个句子,要么需要转录本,而上采样模型就是合成器。在这两种情况下,训练质量都会受到数据集的影响,并且不太可能很好地推广。幸运的是,GE2E 损失为这个问题提供了解决方案,并允许独立于合成器训练说话人编码器。
上图:SV2TTS 连续的三个阶段训练。带有实线轮廓线的模型被冻结。 注意,进入说话人编码器的梅尔谱图和在合成器中用作目标的梅尔谱图是使用不同的参数创建的。
虽然框架的所有部分都是单独训练的,但合成器仍然需要来自训练过的编码器的 embedding,并且声码器需要来自合成器的梅尔谱图(如果不是在真实频谱图上进行训练)。上图说明了每个模型如何依赖前一个模型进行训练。说话人编码器需要足够好地泛化以在合成器的数据集上产生有意义的 embedding 。并且即使在通用数据集上训练,在推理时它必须能够在零样本设置中运行。
该模型是一个 3 层 LSTM,具有 768 个隐藏节点,后跟一个 256 个单元的投影层。虽然在任何论文中都没有提到什么是投影层,但我们的直觉是,它只是每个 LSTM 的 256 个输出的全连接层,重复应用于 LSTM 的每个输出。当我们第一次实现说话人编码器时,我们直接使用了 256 个单元的 LSTM 层,以实现快速原型设计、简单性和更轻的训练负载。最后一部分很重要,因为作者已经将他们自己的模型训练了 5000 万步(虽然是在更大的数据集上),这在技术上对我们来说很难重现。我们发现这个较小的模型表现得非常好,并且我们还没有找到时间来训练更大的版本。
该模型的输入是 40 通道的对数梅尔谱图,窗口宽度为 25 毫秒,步长为 10 毫秒。输出是最后一层的 L2 归一化隐藏状态,它是一个包含 256 个元素的向量。我们的实现在标准化之前还有一个 ReLU 层,目的是使 embedding 稀疏,从而更容易解释。
说话人编码器在说话人验证的任务上训练。说话人验证是生物识别技术的典型应用,通过语音验证一个人的身份。通过从一些话语中推导出他们的说话人 embedding(见公式 1),为一个人创建一个模板。这个过程称为注册。在运行时,用户用一个简短的话语来标识自己,系统将该话语的 embedding 与注册的说话人的 embedding 进行比较。在给定的相似度阈值之上,用户被识别。GE2E loss 就是模拟这个过程来优化模型。
在训练时,该模型计算来自 N 个说话人的 M 个固定时长的话语 embedding
e
i
j
e_{ij}
eij(1 ≤ i ≤ N,1 ≤ j ≤ M)。为每个说话人导出一个说话人embedding
c
i
:
c
i
=
1
M
∑
j
=
1
M
e
i
j
c_i:c_i=\frac{1}{M}\sum_{j=1}^Me_{ij}
ci:ci=M1∑j=1Meij 。相似度矩阵
S
i
j
,
k
S_{ij,k}
Sij,k 是将所有 embedding
e
i
e_i
ei 与批次中每个说话人 embedding
c
k
c_k
ck(1 ≤ k ≤ N)进行两两比较的结果。该度量是缩放余弦相似度:
S
i
j
,
k
=
w
⋅
c
o
s
(
e
i
j
,
c
k
)
+
b
=
w
⋅
e
i
j
⋅
∣
∣
c
k
∣
∣
2
+
b
(
2
)
S_{ij,k}=w·cos(e_{ij},c_k)+b=w·e_{ij}·\vert\vert c_k\vert\vert_2+b\qquad(2)
Sij,k=w⋅cos(eij,ck)+b=w⋅eij⋅∣∣ck∣∣2+b(2)
其中
w
w
w 和
b
b
b 是可学习的参数。整个过程如下图所示。从计算的角度来看,两个 L2 范数向量的余弦相似度只是它们的点积,因此是公式 2 的最右边。最优模型在一个话语和说话人匹配(
i
i
i =
k
k
k )时预计会输出高相似度值,而在其它地方(
i
i
i ≠
k
k
k )会输出低相似度值。为了在这个方向上进行优化,loss 是 row-softmax 损失的总合。
上图:训练时相似度矩阵的构建。该图摘自 (Wan et al., 2017)。
注意,在计算损失时,每个话语
e
i
j
e_{ij}
eij 都包含在同一说话人的质心
c
i
j
c_{ij}
cij 中。这会对正确的说话人产生偏差,而与模型的准确性无关。作者认为,这也为繁琐的解决方案留下了空间。为了防止这种情况,与说话人本身的 embedding 进行比较的话语将从说话人 embedding 中删除。然后相似度矩阵定义为:
f
(
x
)
=
{
w
⋅
c
o
s
(
e
i
j
,
c
i
(
−
j
)
+
b
)
i
f
i
=
k
w
⋅
c
o
s
(
e
i
j
,
c
k
)
+
b
o
t
h
e
r
w
i
s
e
(
3
)
f(x)=\left\{
其中互斥质心
c
i
(
−
j
)
c_i^{(-j)}
ci(−j) 定义为:
c
i
(
−
j
)
=
1
M
−
1
∑
m
=
1
,
m
≠
j
M
e
i
m
(
4
)
c_i^{(-j)}=\frac{1}{M-1}\sum_{m=1,m≠j}^Me_{im}\qquad(4)
ci(−j)=M−11m=1,m=j∑Meim(4)
训练批次中话语的固定持续时间为 1.6 秒。这些是从数据集中较长的完整话语中采样的部分话语。虽然模型架构能够处理可变长度的输入,但在训练中有理由期待它在使用所能看到持续时间相同的话语中表现最佳。因此,在推理时,一段话被分成 1.6 秒重叠 50% 的片段,并且编码器单独传递每个片段。输出的结果被平均然后归一化以产生话语 embedding 。这在下图中进行了说明。奇怪的是,SV2TTS 的作者主张在推理时使用 800 毫秒的窗口,但在训练期间仍然使用 1.6 秒的窗口。 我们更愿意在两种情况下都保持 1.6 秒,就像在 GE2E 中所做的那样。
上图:计算完整话语的 embedding 。d-vectors 只是模型的反归一化输出。该图摘自(Wan et al., 2017)。
作者使用 N = 64 和 M = 10 作为 batch size 的参数。 在实际应用中注册说话人时,应该期望每个用户有几个话语,但可能不会超过 10 个数量级,因此这种选择是合理的。至于说话人的数量,可以观察到计算相似度矩阵的时间复杂度为 O ( N 2 M ) O(N^2M) O(N2M)。因此,该参数不应选择太大,以免大大降低训练速度,而不是简单地选择适合 GPU 的最大 batch size 。当然,仍然可以在同一 GPU 上并行化多个批次,同时跨批次同步操作以提高效率。我们发现,在计算相似度矩阵时将所有操作向量化特别重要,以尽量减少 GPU 事务的数量
为了避免在从完整话语中采样部分话语时有大部分沉默的片段,我们使用 webrtcvad python 包来执行语音活动检测(VAD)。这会在音频上产生一个二进制标志,对应于该段是否是有声的。我们对这个二进制标志执行平均移动,以平滑检测中的短峰值,然后我们再次将其二进制化。最后,我们对标志进行扩张,内核大小为 s + 1,其中 s 是可允许的最大静音持续时间。然后对清音部分的音频进行修剪。我们发现值 s = 0.2s 是一个很好的选择,它保留了自然的语音韵律。这个过程如下图所示。应用于音频波形的最后一个预处理步骤是归一化,以弥补数据集中说话人音量的变化.。
上图:使用 VAD 进行静音移除的步骤,从上到下。橙色线是二进制语音标志,其中较高的值表示该段是有声的,较低的值表示该段是清音的。
作者结合了几个嘈杂的数据集,制作了一个质量类似于野外发现的大型语音语料库。这些数据集是 LibriSpeech、VoxCeleb1、VoxCeleb2 和我们无法访问的内部数据集。LibriSpeech 是一个有声读物语料库,由 2400 个说话人组成的 1000 小时的音频,分为 “ 干净 ” 和 “ 其他 ” 两组。据说干净集由比其他集更干净的语音组成,尽管干净集的某些部分仍然包含大量噪音。VoxCeleb1 和 VoxCeleb2 由从名人 YouTube 视频中提取的音频片段组成(通常在采访中)。VoxCeleb1 有 1.2k 个说话人,而 VoxCeleb2 有大约 6k。这两个数据集都有非英语使用者。我们使用基于说话人国籍的启发式方法从 VoxCeleb1 的训练集中过滤非英语的说话人,但无法将这些相同的启发式方法应用于 VoxCeleb2,因为该集合中没有引用国籍。注意,在没有实验的情况下,不清楚非英语人士是否会损害编码器的训练(作者也没有注意到)。 所有这些数据集都以 16kHz 采样。
作者测试了这些数据集的不同组合,并观察了对 embedding 质量的影响。他们根据说话人的数量将 LSTM 模型的输出大小(embedding 的大小)调整为 64 或 256。他们是这样评估主观自然度和相似度的,先是用每个模型产生的 embedding 去训练合成器,然后用合成器的生成语音的 ground truth 来评估。他们还报告了编码器在说话人验证中的等错误率,我们将在本节后面讨论。这些结果可以在下表中找到。
上表:在不同数据集上训练说话人编码器,该表来自(Jia et al., 2018)。LS 是 LibriSpeech,VC 是 VoxCeleb。合成器在 LS-Clean 上进行训练,并在测试集上进行评估。带有项目符号的行是我们旨在复制的实现。
这些结果表明,说话人的数量不仅与编码器在说话人验证任务上的良好性能密切相关,而且与整个框架的生成语音的质量及其克隆语音的能力方面的良好性能都有着密切的相关。在加入 VoxCeleb2 后获得的自然度、相似度和 EER 的小幅跳跃可能表明语言的变化正在损害训练。 作者的内部数据集是来自 18,000 名英语使用者的专有语音搜索语料库。在此数据集上训练的编码器性能明显更好,但我们只能访问公共数据集。因此,我们继续使用 LibriSpeech-Other、VoxCeleb1 和 VoxCeleb2。
我们的说话人编码器训练了一百万步。为了监控训练,我们报告 EER,并观察模型对说话人进行聚类的能力。我们定期对一批 10 个说话人进行采样,每个说话人有 10 个话语,计算话语 embedding 并使用 UMAP 将它们投影到二维空间中。由于预计不同说话人的 embedding 在潜在空间中比来自相同说话人的 embedding 更远,因此预计随着训练的进行,来自同一说话者的话语簇会形成。我们在下图中报告了我们的 UMAP 预测,其中可以观察到这种行为。
上图:在我们模型的不同迭代中,话语 embedding 的 UMAP 投影来自随机选择的训练集中的批次。 来自同一说话者的话语由相同颜色的点表示。 我们特别省略了将标签传递给 UMAP,因此聚类完全由模型完成。
如前所述,作者已经在他们的专有数据集上训练了 5000 万步的模型。然而我们的数据集和模型都较小,所以我们的模型在 100 万步仍然没有收敛。损失在几乎没有变化的情况下稳步下降,并且仍然可能减少更多,但我们受到时间的限制。
尽管如此,最终的模型还是产生了非常强的结果。事实上,我们计算出的测试集 EER 为 4.5%。相对于作者使用 50 倍多步数的 10.14%,这是一个惊人的低值。我们不知道我们的模型是否真的表现得那么好,或者作者的 EER 计算程序是否与我们的不同,导致产生相差如此大的值。
我们发现通过我们的模型产生的潜在空间中的聚类非常稳健并且可以很好地泛化。在我们所有的测试中,UMAP 投影完美地将话语与三个数据集的每一个的测试集分开,具有较大的簇间距离和较小的簇内方差。下图给出了一个示例。用于此评估的测试集是 LibriSpeech、VoxCeleb1 和 VoxCeleb2 测试集的组合。标有 F 的说话人为女性,带有 M 注释的说话人为男性。我们发现我们的投影在投影空间中线性地分离了说话者的性别。在作者的图中,话语仅来自 LibriSpeech。我们还包括 VoxCeleb1 和 VoxCeleb2,以及一些随机选择的不会说英语的说话人。注意,我们的集群比作者的集群更密集,但这只是使用不同的降维技术的结果。我们发现使用 T-SNE 时的结果与他们相似(van der Maaten 和 Hinton,2008 年)。
上图:120 个 embedding 的 UMAP 预测,12 个说话人中每人有 10 个 embedding 。从测试集中随机选择六名男性和六名女性说话人。
等错误率 (EER) 是生物识别系统中通常用于评估系统准确性的一种度量。它是 false positive 率等于 true negative 率时的值。通过改变生物识别系统识别用户的相似度阈值,可以将这些术语等同起来。SV2TTS 的作者没有提到他们评估 EER 的程序。这是有问题的,因为 EER 计算起来很棘手,并且高度依赖于选择的注册话语的数量。我们参考 GE2E 并使用 6 个话语进行注册,并将它们与 7 个话语进行比较。对于不同数量的话语,请参阅下图。他们的作者没有提到他们使用的话语(用于注册和测试)是完整的还是部分的话语。根据我们的结果,我们使用部分话语;但完整的话语会产生更低的 EER 。
上图:测试集上关于注册话语数量的说话人验证 EER 。每个说话人都会被用于注册的 n + 1 个话语进行测试。
由于缺乏 SV2TTS 作者提供的信息,并且由于我们没有找到可靠的来源表明如何为此类系统计算 EER ,因此无法保证将我们的结果与作者的结果进行比较的正确性和公平性。然而,独立于他们,我们的测试肯定表明我们的说话人编码器在说话人验证任务上表现非常好。考虑到这一点,我们相信说话人编码器正在生成有意义的 embedding 。
在推理速度方面,编码器是迄今为止三种模型中最快的,因为它在我们的 GTX 1080 GPU 上以大约 1000 倍的实时速度运行。事实上,对于我们数据集的所有话语,执行时间受 GPU I/O 的限制。
合成器是不带 Wavenet 的 Tacotron 2 。我们使用 Tacotron 2 的开源 Tensorflow 实现,我们将 Wavenet 去除并实现了 SV2TTS 添加的修改。
我们简要介绍了没有 Wavenet 的 Tacotron 2 架构(简称为 Tacotron)。Tacotron 是一种循环序列到序列模型,可从文本预测梅尔谱图。它具有编码器-解码器结构(不要与 SV2TTS 的说话人编码器混淆),该结构由位置敏感的注意力机制桥接。文本序列中的单个字符首先作为向量嵌入。卷积层紧随其后,以增加单个编码器帧的跨度。这些帧通过双向 LSTM 来生成编码器输出帧。这就是 SV2TTS 对架构进行修改的地方:一个说话人 embedding 连接到 Tacotron 编码器输出的每一帧。注意力机制关注编码器输出帧以生成解码器输入帧。每个解码器的输入帧与通过预网络传递的前一个解码器输出帧连接,使模型自回归。这个连接的向量在被投影到单个梅尔谱图帧之前经过两个单向 LSTM 层。相同向量到标量的另一个投影允许网络通过发出一个超过特定阈值的值来自己预测停止生成帧。整个帧序列在成为梅尔谱图之前通过一个残差后网络。该架构如下图所示。
上图:修改后的 Tacotron 架构。蓝色块对应编码器,橙色块对应解码器。这个图是从(Shen et al., 2017)中提取并修改的。
与说话人编码器相比,合成器的目标梅尔谱图呈现更多的特征。它们是从 50ms 窗口和 12.5ms 步长计算的,有 80 个通道。在我们的实现中,输入文本不进行发音处理,字符按原样输入。然而,有一些清理程序:用完整的文本形式替换缩写和数字,强制所有字符为 ASCII,规范化空格并使所有字符小写。可以使用标点符号,但在我们的数据集中不存在。
在 SV2TTS 中,作者考虑了用于训练合成器和声码器的两个数据集。这些是我们之前提到的 LibriSpeech-Clean 和 VCTK10,VCTK10 是一个只有 109 名以英语为母语的人用专业设备录制的语料库。VCTK 中的语音在他们的实验中以 48kHz 采样,下采样到 24kHz,仍然高于 LibriSpeech 的 16kHz 采样。他们发现在 LibriSpeech 上训练的合成器在相似度方面比在 VCTK 上的泛化效果更好,但代价是语音的自然度。他们通过在一组上训练合成器并在另一组上测试来评估这一点。 这些结果在下表中。我们决定使用在看不见的说话人上能够提供最佳语音克隆相似度的数据集,因此选择了 LibriSpeech。我们还尝试使用由 Tacotron 团队创建的较新的 LibriTTS(Zen 等人,2019 年)数据集。该数据集是整个 LibriSpeech 语料库的更清晰版本,其中去除了嘈杂的说话人、更高的 24kHz 采样率和 LibriSpeech 缺少的标点符号。不幸的是,由于我们忽略的原因,合成器无法在这个数据集上产生有意义的对齐。我们保留了原始的 LibriSpeech 数据集。
上表:对看不见的说话人的自然度和相似度的跨数据集评估。 该表摘自(Jia et al., 2018)。
根据作者的预处理建议,我们使用自动语音识别 (ASR) 模型将 LibriSpeech 转录本强制对齐到文本。我们发现Montreal Forced Aligner 在这项任务上表现良好。我们还为这些对齐方式制作了一个更清晰的版本 public12,以便为需要它们的其他用户节省一些时间。随着音频与文本对齐,我们在超过 0.4 秒的静音上分割话语。这有助于合成器收敛,这是因为既消除了目标频谱图中的静音,也减少了数据集中话语的中位持续时间,因为较短的序列为计时错误提供的空间较小。我们确保话语不短于 1.6 秒,即用于训练编码器的部分话语的持续时间,并且不超过 11.25 秒,以节省 GPU 内存用于训练。如果可能的话,我们不会因为静音而分割,这会导致话语过短或过长。数据集中话语长度的分布如下图所示。注意静音时间已经占了数据集的 64 小时 (13.7%)。
上图:(左)LibriSpeech-Clean 中话语持续时间的直方图,(中)在静音拆分后,(右)在限制长度并重新调整拆分后。
通过额外的将文本强制对齐到话语来隔离静音,这个过程可以为同一说话人的所有话语创建噪声的配置文件。我们使用 LogMMSE 算法的 Python 实现。 LogMMSE 通过在最早的几帧(通常不包含语音)中分析噪声并在整个话语中连续更新非语音帧上的噪声配置文件来清理音频语音段。我们调整此实现以在两个单独的步骤中分析噪声和清理语音。与作者一样,我们发现这个额外的预处理步骤可以极大地帮助减少合成频谱图的背景噪声。
在 SV2TTS 中,在训练时用于调节合成器的 embedding 是说话人 embedding 。我们认为,相同目标话语的话语 embedding 反而会带来更自然的选择。在推理时,还是使用话语 embedding 。虽然话语和说话人 embedding 的空间相同,但说话人 embedding 不是 L2 归一化的。正如在我们向作者询问时他们赞同的那样,这个领域的差异应该很小,并且对使用 embedding 的合成器几乎没有影响。然而,他们没有提到使用多少话语 embedding 来导出说话人 embedding 。人们会期望应该使用所有可用的话语;但是随着话语 embedding 数量的增加,平均向量(说话人 embedding )将进一步偏离其归一化版本。此外,作者还提到,由于他们模仿不同的字符,数据集中同一说话人的话语的音色和音调经常有大的变化。话语具有较低的内部变化,因为它们的范围最多仅限于一个句子。因此,与说话人的 embedding 相比,话语的 embedding 有望更准确地表示话语中所说的语音。如果话语的长度足以产生有意义的 embedding ,则这一点成立。虽然发现参考语音的 “ 最佳 ” 持续时间为 5 秒,但 embedding 表明仅使用 2 秒的参考语音就已经有意义(见下表)。我们相信话语不短于部分话语的持续时间(1.6s),话语 embedding 应该足以有意义地捕捉语音,因此我们使用话语 embedding 来训练合成器。
上表:参考语音持续时间的影响。在 VCTK 上评估。该表摘自(Jia et al., 2018)。
我们将合成器训练 150k 步,在 4 个 GPU 上 batch size 大小为 144。每一步解码器输出的数量设置为 2,就像在 Tacotron 1 中所做的那样。我们发现模型要么不收敛,要么在解码器每步输出一个时表现不佳。损失函数是预测值和真实梅尔谱图之间的 L2 损失。在训练期间,模型设置为 Ground Truth Aligned (GTA) 模式(也称为强制教师模式),其中预网络的输入是真实频谱图的前一帧而不是预测的帧。使用 GTA,生成的频谱图的音调和韵律与真实情况一致,从而允许预测值和真实值之间共享上下文以及更快的收敛。如果没有 GTA,合成器将在给定固定文本和 embedding 输入的情况下生成相同话语的不同变体(就像推理时的情况)。
正如之前讨论的那样,声码器也是如此,很难对模型的性能进行任何定量的评估。通过非正式的听力测试,我们可以观察到该模型产生了正确的输出,但正式评估需要我们设置主观评分调查以得出 MOS。虽然我们提到的一些作者可以这样做,但这超出了我们的能力范围。然而,在合成器的情况下,我们还可以验证注意力模块生成的对齐是否正确。我们在下图中绘制了一个示例。注意解码器步数 (223) 与通过解码器每步输出的数量 (2) 预测的帧数 (446) 相匹配。还要注意预测的频谱图如何比真实情况更平滑,这是模型在存在噪声时预测均值的典型行为。
上图:(左)编码器步数和解码器步数之间的对齐示例。(右)GTA 预测频谱图与真实频谱图的比较。
说话人的声音特征不好理解,但讲的话是可理解的。即使存在复杂或虚构的单词,合成器生成的语音也能与文本正确匹配。然而,韵律有时是不自然的,在句子中意外的位置停顿,或者在预期的地方没有停顿。这在 embedding 一些说话缓慢的说话人时尤其明显,表明说话人编码器确实捕获了某种形式的韵律。LibriSpeech 中缺少标点符号是造成这一点的部分原因,迫使模型仅从文本中推断标点符号。作者也强调了这个问题,并且可以在他们的一些 LibriSpeech 演讲者样本中听到。我们对数据集中话语的持续时间(1.6s - 11.25s)施加的限制也可能存在问题。太短的句子会因为长时间的停顿被拉长,太长的句子中声音会很急促。在推理时生成多个句子的时候,我们需要手动插入中断来划定输入文本的分割位置,以便将频谱图合成多个部分。这具有创建一批输入而不是长输入的优点,允许快速推理。
我们可以通过计算合成语音的 embedding 并使用 UMAP 将它们与真实的 embedding 一起投影来进一步观察 Griffin-Lim 是如何丢失一些语音特征的。下图给出了一个例子。我们观察到合成的 embedding 集群接近于它们各自的真实 embedding 集群。新兴特征的损失也是可见的,例如,对于粉红色、红色和两个蓝色说话人,合成的话语相比较真实话语有更低的簇间方差。灰色和紫色说话人也会出现这种现象。
上图:一个是真实的 embedding ,一个是由真实 embedding 生成的 Griffin-Lim 合成语音 embedding 的投影。真实 embedding 用圆圈绘制,合成 embedding 用十字绘制。
Tacotron 的运行通常比实时运行更快。通过比较生成时间和生成的频谱图的持续时间,我们测量了 5 到 10 倍的实时推理速度。
在 SV2TTS 和 Tacotron2 中,WaveNet 是声码器。自发布以来,WaveNet 一直是音频深度学习的核心,并且在 TTS 中的语音自然度方面仍然是最先进的。然而,它也是众所周知的推理时最慢的实用深度学习架构。后来的几篇论文在这方面进行了改进,使生成接近实时或比实时更快,例如 (van den Oord 等人,2017 年;Paine 等人,2016 年;Kalchbrenner 等人,2018 年),对生成的语音质量几乎没有影响。尽管如此,WaveNet 仍然是 SV2TTS 中的声码器,因为速度不是主要问题,并且因为谷歌自己的 WaveNet 实现和各种改进已经以每秒 8000 个样本的速度生成。这与 “ 普通 ” WaveNet 形成对比,后者最多以每秒 172 步的速度生成。在撰写本文时,WaveNet 的大多数开源实现仍然是普通实现。
(Kalchbrenner et al., 2018) 提出了一个简单的方案来描述自回归模型的推理速度。给定一个通过
∣
u
∣
|u|
∣u∣ 采样的目标向量
u
u
u 去预测,推理的总时间
T
(
u
)
T(u)
T(u) 可以分解为:
T
(
u
)
=
∣
u
∣
∑
i
=
1
N
(
c
(
o
p
i
)
+
d
(
o
p
i
)
)
T(u)=|u|\sum_{i=1}^N(c(op_i)+d(op_i))
T(u)=∣u∣i=1∑N(c(opi)+d(opi))
其中 N 是生成一个样本所需要的矩阵向量乘积的个数(∝层数),
c
(
o
p
i
)
c(op_i)
c(opi) 是第 i 层的计算时间,
d
(
o
p
i
)
d(op_i)
d(opi) 是第 i 层的计算的开销(通常是 I/O 操作)。注意,语音的标准采样率包括 16kHz、22.05kHz 和 24kHz(而音乐通常以 44.1kHz 采样),这意味着只有 5 秒的音频
∣
u
∣
|u|
∣u∣ 接近 100,000 个样本。标准 WaveNet 架构包含每两层 10 个残差块的三个堆栈,导致 N = 60。
WaveRNN 是 (Kalchbrenner et al., 2018) 中提出的模型,它改进了 WaveNet,不仅减少了 N 的贡献,还减少了
u
、
c
(
o
p
i
)
u、c(op_i)
u、c(opi) 和
d
(
o
p
i
)
d(op_i)
d(opi) 的贡献。我们使用的声码器模型是一个基于 WaveRNN 的开源 PyTorch 实现,但呈现了 github 用户 fatchord 做出的许多不同的设计选择。我们将这种架构称为 “ 替代 WaveRNN ” 。
在 WaveRNN 中,来自 WaveNet 的全部 60 个卷积被单个 GRU 层取代。作者认为 GRU 层本身的高度非线性就足以涵盖整个 WaveNet 模型的复杂性。事实上,他们报告的 Wavenet 的 MOS 为 4.51 ±0.08,他们最好的 WaveRNN 模型的 MOS 为 4.48 ±0.07。模型的输入是合成器生成的 GTA 梅尔谱图,以真实音频为目标。在训练时,模型预测固定尺寸的波形段。WaveRNN 的前向传递以一种仅使用 N = 5 的矩阵向量乘积的 “ 粗 - 精 ” 方案实现,这个方案首先预测目标 16 位样本中的低 8 位(粗),然后用于调节高 8 位样本的预测(精)。预测是基于对输出进行采样的分布参数上进行的。我们向读者推荐 (Kalchbrenner et al., 2018) 以获取更多详细信息。
作者通过将采样操作实现为自定义 GPU 操作来改进因子
c
(
o
p
i
)
c(op_i)
c(opi) 和
d
(
o
p
i
)
d(op_i)
d(opi)。我们不会复制这一点。他们还使用来自 (Narang et al., 2017; Zhu and Gupta, 2017) 的剪枝策略来稀疏网络。这种方法在训练期间逐渐修剪权重,而不是在多次训练之间运行的更经典的剪枝算法。该算法在权重上创建一个二进制掩码,指示权重是应该强制设置为 0 还是保持原样。网络中零权重与权重总数的比例称为稀疏度。(Narang et al., 2017; Zhu and Gupta, 2017) 的结果表明,稀疏度在 90% 到 95% 之间的大型网络明显优于其密集版本。WaveRNN 的作者还认为
c
(
o
p
i
)
c(op_i)
c(opi) 与非零权重的数量成正比。我们试验了这种剪枝形式,并在 5.2 节报告了我们的结果。
最后,他们通过分批采样改进了
∣
u
∣
|u|
∣u∣ 。在分批采样中,话语被分成固定长度的片段,并且在所有片段上并行生成。为了在段的结尾和后续段的开头之间保留一些上下文,在下一段的开头重复段结尾的一小部分,这个过程称为折叠。然后模型将折叠的段向前推进。为了检索展开的张量,连续段的重叠部分 cross-fade 合并。这在下图中进行了说明。我们将批量采样与替代 WaveRNN 一起使用,分段长度为 8000 个样本,重叠长度为 400 个样本。使用这些参数,大小为 2 的折叠批次将为 16kHz 的语音生成多于 1 秒的音频。
上图:张量的批量采样。注意重叠是如何在折叠张量中的每个下一段上重复的。
另一种 WaveRNN 是我们使用的架构。该模型没有文档或论文,因此我们依靠源代码和作者的图表(下图)来了解其内部工作原理。在每个训练步骤中,梅尔谱图及其对应的波形被切割成相同数量的片段。模型的输入是要预测的频谱图段 t 和波形段 t -1 。该模型希望输出相同长度的波形段 t 。梅尔谱图通过上采样网络以匹配目标波形的长度(梅尔通道数保持不变)。类似 Resnet 的模型还使用频谱图作为输入来生成特征,这些特征将在梅尔谱图转换为波形的整个过程中调节各层。生成的向量被重复以匹配波形段的长度。然后,该条件向量沿着通道维度被平均分为 4 个方向,第一部分与上采样频谱图和前一时间步的波形段连接。生成的向量通过跳跃连接经历了几次转换:前两个 GRU 层然后是一个密集层。在每一步之间,条件向量与中间波形连接。最后,两个密集层产生离散值的分布,对应于 mu-law 压缩音频的 9 位编码。
上图:替代WaveRNN 的架构。
在处理短话语时,声码器通常低于实时运行。推理速度高度依赖于分批采样的折叠次数。事实上,网络在折叠次数方面几乎以恒定的时间运行,随着折叠次数的增加,时间只有很小的增加。我们发现当讨论在模型上实时运行的语音的持续时间阈值更简单。在我们的设置中,这个阈值为 12.5 秒;这意味着对于短于此阈值的话语,模型的运行速度将比实时慢。在 PyTorch 上,性能似乎因某些环境因素(例如操作系统)而出乎意料地变化,因此我们针对单个相同的配置来表达我们的结果。
我们手上的实现没有 (Kalchbrenner et al., 2018) 的自定义 GPU 操作,并且实现它超出了我们的能力。相反,我们专注于作者提到的修剪方面。他们声称大型稀疏 WaveRNN 会比较小的密集 WaveRNN 表现得更好更快。我们已经对剪枝算法进行了实验,但由于时间限制没有完成剪枝模型的训练。这是我们希望在以后实现的里程碑。在撰写本文时,稀疏张量仍是 PyTorch 中的一项实验性功能。他们的实现可能不如作者使用的那样有效。通过实验,我们发现对于稀疏矩阵和稠密向量的矩阵乘法运算 addmm 仅在时间上与稀疏度高于 91% 的仅稠密 addmm 达到平衡。低于此值,使用稀疏张量实际上会减慢前向传递速度。作者报告了 96.4% 和 97.8% 的稀疏水平,同时保持了不错的性能。我们的测试表明,96.4% 的稀疏水平充其量会将实时阈值降低到 7.86 秒,将 97.8% 的水平降低到 4.44 秒。由于我们假设时间推理恒定,并且模型中的某些层无法稀疏,因此这些是实际阈值的乐观下限。该初步分析表明,修剪声码器将有利于提高推理速度。
不幸的是,在提交这篇论文之前,我们无法成功地训练最终版本的声码器。我们确实设法在 2 月份之前使原型工作,但此模型不再与我们对框架所做的更改兼容。我们决心在论文答辩之前提供一个有效的实现,但我们现在不能报告新的实验。我们对原型的印象是,我们的实现成功地创建了一个 TTS 模型,该模型可以克隆大多数声音,但不能克隆一些不常见的声音。由于我们的合成器质量不佳,因此存在一些伪影和背景噪音,这就是我们必须修改数据质量和预处理程序的原因。SV2TTS 框架的一个缺点是必须按顺序训练模型。一旦训练了新的编码器,合成器必须重新训练,声码器也必须重新训练。等待模型训练以了解下一步要关注什么是我们框架开发过程中经常出现的情况。尽管如此,我们相信我们很快就能在我们的存储库上发布样本,我们邀请读者关注未来的发展,即使它们现在已经超过了提交日期。
开发工作的一部分是使这个项目适合开源。您可以通过这个 url 访问存储库:
https://github.com/CorentinJ/Real-Time-Voice-Cloning
使项目开源意味着向每个模型公开一个干净的界面,用于训练和推理,以及记录代码和过程。我们相信努力是值得的。我们的动机是:
• 通过用户的贡献改进我们的实施
• 了解如何管理开源存储库
• 确保我们结果的可复制性
• 允许用户以很少的数据、时间和精力在消费硬件上执行语音克隆
对于最后一点,我们的目标是开发一个图形界面,让用户无需先学习即可快速掌握框架。 我们称之为 “ SV2TTS 工具箱 ” 。工具箱界面如下图所示。它是用 Python 编写的,带有 Qt4 图形界面,因此是跨平台的。
上图:SV2TTS 工具箱界面。最好在数字支持上查看此图像。
用户首先从存储在其磁盘上的任何数据集中选择话语音频文件。该工具箱处理几个流行的语音数据集,并且可以自定义添加新的数据集。此外,用户还可以记录话语以克隆自己的声音。
加载话语后,将计算其 embedding 并自动更新 UMAP 投影。绘制了话语的梅尔谱图(右侧中间行),但这仅用于参考,因为它不用于计算任何内容。我们还绘制了带有热图的 embedding 向量(在频谱图的左侧)。注意, embedding 是一维向量,因此方形对 embedding 值没有结构意义。绘制 embedding 提供了关于两个 embedding 是如何不同的视觉线索。
当一个嵌入被计算出来后,它可以被用来生成一个频谱图。用户可以编写任何要合成的任意文本(界面右上角)。提醒一下,我们的模型不支持标点符号,将被丢弃。为了调整生成话语的韵律,用户必须在应该单独合成的部分之间插入换行符。完整的频谱图就是这些部分的串联。合成的频谱图将显示在界面的右下角。多次合成相同的句子会产生不同的输出。
最后,用户可以使用声码器生成与合成频谱图对应的片段。加载条显示生成进度。完成后,将生成合成话语的 embedding(在合成频谱图的左侧),并且还将使用 UMAP 进行投影。用户可以自由地将该 embedding 作为进一步生成的参考。
我们开发了一个没有公开实施的实时语音克隆框架。尽管存在一些不自然的韵律,但我们发现结果令人满意,并且该框架的语音克隆能力相当不错,但与使用更多参考语音时间的方法不相符。我们希望在本文的范围之外改进我们的框架,并可能实现在撰写本文时在该领域取得的一些新进展。我们相信,在不久的将来,会出现更强大的语音克隆形式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。