Kahsolt / soft-vc-acoustic-models

Provides scripts for conveniently training your own acoustic model for Soft-VC, also providing a list of experimentally pretrained acoustic models.
MIT License
1 stars 0 forks source link

关于hubert使用的几个疑问 #2

Open joan126 opened 1 year ago

joan126 commented 1 year ago

如果我想得到一个中文的hubert_soft, 没那么多数据,无法从头训hubert_soft;那我该如何做呢?

拿英文预训练好的hubert_discrete来encode我的中文数据,然后再基于这个hubert_discrete warm_up来finetune吗?

还有一个疑问, 声学模型使用的是hubert_soft,那么针对目标说话人数据集,encode的时候只能指定hubert_soft吧?

Kahsolt commented 1 year ago

泥嚎~ 感谢关注相关研究~

  1. 关于这个做法 “拿英文预训练好的hubert_discrete来encode我的中文数据,然后再基于这个hubert_discrete warm_up来finetune” 我个人感觉从某种信息论意义上似乎不是很有道理 (🤔?) ,在代码实现上可能也不太行。 我们知道,hubert_discrete的encode过程,将任意给定的一个mel帧分解为已知嵌入表词典所有伪mel帧的线性加权(e.g: 当权值足够的onehot时,就意味着这个给出的mel帧几乎恰好就是词典里某个已知词)。现在,观察Hubert的forward函数:
class Hubert(nn.Module):
    def forward(self, x: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
        # CNN+Transformer,将wav转为enc
        x, mask = self.encode(x)
        # 调整维度到与Embed一致
        x = self.proj(x)
        # 对照Embed向量、计算相似度
        logits = self.logits(x)
        return logits, mask

可以发现对于 embedding table 的优化位于 self.logits(x) 中,而滞后于 encode 的结果,如果我们只能拿到 inference 阶段的 encode 数据,那么我们只能训练 CNN+Transformer 部分而没办法优化后续的 Linear 和 Embed 层。如果单单训练 CNN+Transformer 部分,又该用什么ground truth和损失函数呢?🤔 说到底 hubert 训练时的 ground truth 并不是某种 encode,无论 soft 还是 discrete 版本,它们的 ground truth 来自于 kmeans 聚类结果id号,这是个hard onehot label而不是某种soft label;btw, 为了达到好语音帧分类效果效果,这一步其实应当选用一个多语种多说话人的大型语料库。(但我们可能毕竟没钱……)

  1. (已修正)是的,看模型输入输出结构就会发现不匹配, hubert_soft/hubert_discrete 和 acoust 两个模型的输入输出pipeline:
真实mel帧 -> [hubert_soft] -> 丢失原音色的伪mel帧/向量编码 -> [acoustic_soft] -> 含有目标的真实mel帧
真实mel帧 -> [hubert_discrete] -> 丢失原音色的伪mel帧的字典编号 -> [acoustic_discrete] -> 含有目标的真实mel帧
joan126 commented 1 year ago

这里提供了一个基于中文1W小时数据训练的hubert模型,https://github.com/TencentGameMate/chinese_speech_pretrain 这个模型是hubert_discrete的,也提供了 kmeans模型文件,可以看一下,是不是可用这个encode custom的中文数据集,然后,再去训练hubert soft @Kahsolt

Kahsolt commented 1 year ago

看了一下,应该是可以的~ 它的 hubert_kmeans/hubert_base_iter1_32gpu_l6/model.mdl 提供了一个 sklearn.MiniBatchKMeans 模型,这是在 ~9933h 的数据上聚类的 500 个簇。先预处理custom的中文数据集得到ground truth,然后拿去按transformers框架的文档微调。

谢谢发现新大陆,俺也去玩玩这个repo(

Kahsolt commented 1 year ago

等等,不过,“再去训练hubert soft” 是说,用这个 chinese_speech_pretrain 这个repo 的 kmeans 结果去训练 softvc 的 hubert_soft 吗?🤔 那可能又不太行,因为首先这个Kmean聚类是500类,softvc/hubert_soft 是100 类,维数对不上。 即使你说没关系,我把最后一层Linear换掉,但是由于目标数据集的分布高度不一致,这对于 hubert_soft 的训练而言不是微调,而是重新映射,因此训练用数据集大小还是暗示了最后的效果。

joan126 commented 1 year ago

等等,不过,“再去训练hubert soft” 是说,用这个 chinese_speech_pretrain 这个repo 的 kmeans 结果去训练 softvc 的 hubert_soft 吗?🤔 那可能又不太行,因为首先这个Kmean聚类是500类,softvc/hubert_soft 是100 类,维数对不上。 即使你说没关系,我把最后一层Linear换掉,但是由于目标数据集的分布高度不一致,这对于 hubert_soft 的训练而言不是微调,而是重新映射,因此训练用数据集大小还是暗示了最后的效果。

嗯,直接用好像不行了,再想想办法吧