wikiAudio04|FastSpeech:时长监督与并行声学生成02|长度调节器实现:形状、梯度与边界检查
5 分钟
0 次观看

02|长度调节器实现:形状、梯度与边界检查

本实验只实现音素向量展开,目标是弄清最容易出错的时间轴与梯度累积。FFT、音高预测和声码器仍需由完整模型提供;函数输出的是隐藏矩阵,没有声音意义。

repeat_interleave 复制条件行,反向传播把重复行的梯度加回原位置。 图 1|length_regulate 的输入、重复次数与输出行

图 1|length_regulate 的输入、重复次数与输出行

1. 接口与调用关系

对象输入输出 / 状态
length_regulatehidden[N,H] float;durations[N] int64[sum(d),H];无跨调用缓存
调用方去除 padding 后的单条样本负责 batch 逐条展开并重新 padding
时长预测器文本隐藏状态连续预测需先转换成非负整数
def length_regulate(hidden, durations):
    """One unpadded item: [N,H], integer [N] -> [sum(d),H]."""
    if durations.dtype != torch.long or (durations < 0).any():
        raise ValueError('durations must be non-negative int64')
    if len(hidden) != len(durations): raise ValueError('length mismatch')
    return torch.repeat_interleave(hidden, durations, dim=0)

代码先拒绝负值与错误 dtype,再沿第 0 轴重复。把 dim=0 错写成 dim=1 会扩大通道数,不能通过随后 reshape 修复语义。代码允许零时长,以适应某些特殊符号约定;普通发音音素是否必须至少一帧,应由前端与训练标签共同规定。

2. 梯度为何等于重复次数

用输出元素之和作教学损失,每个被复制元素对损失的导数都是 1,因此原行接收所有副本的和。

∂L∂hi,j=di.\frac{\partial L}{\partial h_{i,j}}=d_i.
公式符号与约定
符号含义、单位与约定
LL本实验展开矩阵所有元素之和;不是 FastSpeech 实际训练损失。
hi,jh_{i,j}第 i 个音素、第 j 个隐藏通道的值。
i,ji,j分别为音素索引、隐藏通道索引。
did_i该行重复次数,教学例为 2、1、3。
∂\partial偏导数,固定其他变量时的局部变化率。
实测检查(CPU)结果说明
输入 [3,2],时长 [2,1,3]输出 [6,2]时间轴展开正确
输出求和后反向传播每通道梯度 [2,1,3]重复行的梯度正确累积
时长变为负数抛出 ValueError防止静默产生非法长度

这些检查验证张量机制,可在 CPU 上快速重复。

整数取整和重复次数没有普通的连续梯度;时长预测器需要自己的监督目标。

3. 运行入口与完整实现

完整实验在 机制实验源码,复制为 mechanism_lab.py 后运行 python mechanism_lab.py。结果写入同目录的 results/mechanism-checks.json。本文记录来自 PyTorch 2.14.0+cpu;没有使用预训练模型,也没有测量 MOS 或合成速度。

把输出交给 mel 解码器前,还应检查帧 mask。两条句子分别展开成 6、9 帧时,batch 的 [2,9,H] 中,第一条最后 3 行不能参与声学损失。返回 FastSpeech 2。

专题导航:TTS 总目录 · 上级章节

正在连接 GitHub 评论…