最近在做和 TTS/SVC 相关的内容,在 Svc 经典项目 https://github.com/svc-develop-team/so-vits-svc 里面, 发现他用的声码器 NSF-HifiGan 而非之前常用的 Hifi-GAN/MelGAN。 在跑过他的 demo 后效果果然很好,特别是在音质方面。 在想是不是这个声码器的缘故,所以就回来重新读了一下对应论文,还是感觉很有收获。
NSF 论文: Neural source-filter waveform models for statistical parametric speech synthesis , 同时,作者在维护一个 NSF 模型家族的官网,可以更详细得介绍 NSF 的方方面面。https://nii-yamagishilab.github.io/samples-nsf/
HifiGan 声码器出来到现在这段不短的时间内,很多人都提到了使用 f0/lf0 可以提升声码器的质量。 但我一直被两个问题困扰,1)显示指定f0,那如果 f0 和 mel 中包含的 f0 发生冲突,是否会造成合成效果的下降? 之前我们认为 mel 包括了音频中几乎所有的信息,同一份信息在两个地方出现,会不会有问题? 2)f0 是一个一维向量,和 mel 怎么很好的结合。为什么要单独把 f0 拿出来进行讨论? 这两个问题使得我认为使用 f0 作为声码器的输入总不是很 “美观”,所以一直也不太看好这种方法。 但后来事实证实 其实是我没仔细思考,其实 NSF 就很好但解决了这两个问题。
回到 NSF 方法本身,NSF 的核心在于 SF,source/filter 模型其实是信号,特别是语音信号中一个很常见的概念了。 简单来说就是每一个信号都是由主干部分+小量部分组成的,主干部分刻画信号的基本走势,小量部分刻画具体细节。
声码器的输入是f0/声学特征,这里声学特征可以是线性谱或 mel 谱。首先,对于 f0,我们认为f0 是时间的一维函数,且 f0 我们认为并不会剧烈变化。 为了满足 f0 平稳的假设,我们把音频段分成语音段/非语音段,非语音段可能是静音或者噪声,一般 f0 为 0/-1。对于非语音帧,我们用两侧语音帧的f0 进行差值,这样可以得到之前说的相对平滑的 f0 曲线。同时,用另一组向量(uv)来刻画当前帧是否为语音帧。 拿到 f0 以后,我们产生一个正弦激励函数,使得其在每个时间小窗内的频率由 f0 决定。同时,对于非语音帧的部分,用随机高斯噪声代替。 这样就拿到了正弦激励函数,我们认为这个正弦激励函数就是声码器合成音频的其实状态。
在该激励函数的基础上,我们经过多个 Neural-filter-module 模块,不断向内添加细节。 每个 module 包括一个上采样函数,把帧级别的特征在时间纬度上扩展,直到和采样点数目相同。 同时,将声学特征(mel)作为 condition,来生成更多的信息。整个过程是音频细节逐渐丰富的过程(感觉这个过程和 diffusion 模型非常像)。 这里并不涉及 module 的具体结构,因此论文里也比较了几种常用的声码器模型。事实上,waveNet/waveRNN/WaveGlow/XXXGan 都可以衍生出对应的 NSF 版本。 但是因为 hifigan 的全卷积结构,天然轻计算量以及适合并行的特点,最终衍变成了 NSF-Hifigan。
大体思路就是这样,然后论文里讲了几个比较有意思的点:
- 一些对比实验,一个显著的提升是在计算生成音频和源音频直接距离的时候,大家一般都会使用 stft 之后的频谱 loss,论文里说采用多个不同长度的窗分别计算 loss,会比单个窗显著提升。之前看代码好像大多数实现都是单一长度,可以重点尝试一下看看。 另外一些 haramonic 相关探索,使用正弦激励vs纯噪声激励(类似diffusion-model中的常用做法)前者还是会更好一些。
- 探索我之前提到的第一个问题,如果f0/mel不匹配会怎样?结果会发现 NSF 具有很好的性质,生成音频的 f0 总是和显示指定的 f0 更接近(论文使用相关系数进行刻画)。这样的话,在生成音频的时候,就可以直接调 f0。 但我自己实际测试的时候,如果严重 mismatch 的时候,可能效果还是会有损失。
- 中间层的结果展示。每个 filter 之后的信号量画出来看,会看到之前说的信号的包络不变但细节逐渐丰富的过程。
论文大概就这么多,回到代码本身,可能大部分实现上和 Hifigan 几乎一致。 判别器完全相同,生成器有一点点区别,但会发现和论文里有一点不一样是只使用了正弦/噪声激励信号作为起始信号,并没有像 diffusion 那样对每个过程模块加噪声以获得更好的鲁棒性。 这里可能还不太一样,可能需要实际再改改代码看看是否会有提升。 总之论文+对应代码+实际训练了几个case,大体摸了个七七八八。特此记录,也算对之前的一些困惑的解决吧。
如果再有和音乐生成相关的任务,NSF-hifigan 感觉应该是首选项。
真的体会到了读论文醍醐灌顶的那种感觉。