wikiAudio05|HiFi-GAN:并行波形生成与周期判别01|生成器:转置卷积、残差块与多感受野融合
7 分钟
1 次观看

01|生成器:转置卷积、残差块与多感受野融合

HiFi-GAN 的生成器不是把一个 mel 帧独立解码成一小段声音,再把小段拼起来。卷积核跨越相邻帧,逐级上采样后继续混合上下文,最后同时输出整段波形。理解这一点,才能解释长度错误、边界伪影和模型加速。

本篇以官方 V1 常见配置的倍率 8、8、2、2 为例,讲清张量沿途变化;不同版本可以更换通道数、残差块与倍率。论文 · 官方模型代码

时间分辨率逐级升高,通道逐级变少;MRF 在每个分辨率上融合不同跨度的上下文。

图 1|逐级上采样与并联残差分支的张量路径

图 1|逐级上采样与并联残差分支的张量路径

1. 从 10 帧 mel 到 2,560 点波形

节点示例形状该节点负责什么
输入 mel[1,80,10]80 个频带、10 帧条件
前置卷积[1,512,10]将频带映射到隐藏通道
上采样 1+MRF[1,256,80]时间扩大 8 倍,融合邻域
上采样 2+MRF[1,128,640]再扩大 8 倍
上采样 3+MRF[1,64,1280]扩大 2 倍
上采样 4+MRF[1,32,2560]扩大 2 倍
输出卷积+tanh[1,1,2560]压到单通道振幅

这些是指定配置下的形状,不是所有 HiFi-GAN 的固定规模。输出长度与帧移 256 一致时,频谱与波形才拥有相容的时间比例。采样率还需单独匹配。

2. 转置卷积的输出长度与边界配置

一维转置卷积的一般长度关系是:

Lout=(Lin−1)s−2p+d(k−1)+o+1.L_{\rm out}=(L_{\rm in}-1)s-2p+d(k-1)+o+1.
符号、形状与约定
符号解释与例值
Lin,LoutL_{\rm in},L_{\rm out}输入与输出时间长度,单位为该层位置数。
ssstride,教学值 8。
pppadding,教学值 4。
dddilation,本例 1。
kkkernel size,本例 16。
oooutput_padding,本例 0;用于长度歧义修正,不是额外可学习样本。

代入 L_in=10:(10−1)×8−2×4+1×15+0+1=80。若误把 padding 设为 3,会变成 82;连续四级后误差会被后续倍率放大。只在最后裁掉多出来的样本,可能隐藏中间的时间偏移。

转置卷积可理解为按 stride 展开位置,再让卷积核在新网格上叠加贡献。相邻输入位置的输出会重叠,因此它有上下文混合,而不是简单的 repeat_interleave。

图 2|步幅为 2 的核贡献重叠,示意值不代表训练结果

图 2|步幅为 2 的核贡献重叠,示意值不代表训练结果

3. MRF 的并联与残差的串联

MRF 的不同分支读取同一个上采样结果;分支内部有多个残差更新。官方代码对并联分支作平均,论文用融合求和概括该结构。分支之间不应误接成前后串联。

zj=Rj(u),v=1J∑j=1Jzj.z_j=R_j(u),\qquad v=\frac{1}{J}\sum_{j=1}^{J}z_j.
符号、形状与约定
符号解释与例值
uu当前上采样层输出,[B,C,L]。
Rj,zjR_j,z_j第 j 个残差分支及其输出;各分支形状相同。
J,jJ,j分支总数及索引,示例 3。
vv融合输出;分支平均保持通道和时间长度不变。

在一个单通道位置,三个分支给出 1、2、6,融合值为 3。平均可控制数值尺度;上下文范围的差异来自核与 dilation,而不是这个求平均动作。

残差分支内部,例如核宽 3、dilation 3、stride 1 的卷积读取间隔为 3;若后接普通核宽 3 的卷积,该两层串联的理论跨度为 1+(3−1)×3+(3−1)×1=9。这是当前分辨率的 9 个位置,不是最终波形必然只有 9 点感受野;前后层还会继续扩大范围。

4. 可运行的最小融合模块

下列教学模块对应图 1 的 MRF 子框,只保留三条单卷积残差分支,便于检查并联和形状。它省略官方多组 dilation、权重归一化和多层残差,不能载入官方权重。

class MiniMRF(nn.Module):
    """Teaching residual branches, not a HiFi-GAN checkpoint-compatible block."""
    def __init__(self, channels=4):
        super().__init__()
        self.branches=nn.ModuleList([
            nn.Conv1d(channels, channels, k, padding=(k-1)//2)
            for k in (3,5,7)])
    def forward(self, x):
        return torch.stack([x+layer(F.leaky_relu(x,0.1))
                            for layer in self.branches]).mean(0)

输入 [1,4,80] 分别进入三分支,stack 新增分支轴,再沿该轴求平均。CPU 检查已把 10 位置上采样为 80,再通过该模块并完成反向传播,输出仍为 [1,4,80]。

MRF 的三个分支都读取同一个张量;分支轴平均不能写成沿通道轴平均。

5. 从结构推断排错顺序

异常检查原因
输出长度错误每级 k、s、p、o长度误差会被后级扩大
周期性格纹/音调伪影上采样与核重叠、训练分布不均匀贡献可能留下规则模式
输出整体削顶tanh 前幅值、数据归一化大值进入饱和区
分段拼接有爆音边界上下文与裁切卷积依赖跨越分块边界

生成器能并行计算不代表它天然支持无状态逐块播放;分块要处理跨块感受野。

下一篇 MPD 与 MSD解释训练中谁来约束这些波形细节。

专题导航:TTS 总目录 · 上级章节 · 实验代码与实测记录

正在连接 GitHub 评论…