以下例子来自真实联动视频。正如我们将要看到的,模型成功的分离了两个vtuber的声音。
<script src="sounds.js" type="text/javascript"></script> <style> table, th, td { border: 2px solid black; border-collapse: collapse; } th, td { padding: 5px; text-align: center; } th { text-align: center; } </style>Mixed voice | 白上フブキ | 夏色まつり |
---|---|---|
Example_1 | Fbk_1 | Matsuri_1 |
Example_2 | Fbk_2 | Matsuri_2 |
Example_3 | Fbk_3 | Matsuri_3 |
Example_4 | Fbk_4 | Matsuri_4 |
Example_5 | Fbk_5 | Matsuri_5 |
Example_6 | Fbk_6 | Matsuri_6 |
Vtuber 联动时声音会混在一起,而这会对字幕组的工作造成困难。为了解决这个问题,我们提出了一个可以分离不同vtuber声音的模型。目前模型可以分离白上吹雪和夏色祭混合起来的声音,多个Vtuber的声音混合问题将会在下一步解决。顺便,诚招愿意在本项目上浪费时间的人。
本模型来源于谷歌的这篇论文。该论文提供了相关的Pytorch代码。然而,因为数据库等等原因,我们发现该模型并不能直接用于Vtuber语音分离。因此,本项目从头对数据库进行了建立,并且对模型进行了优化更改。
-
可以在这里找到相关代码.
-
假设说话人A和B的声音混了起来,而我们要对他们的声音进行分离。首先,我们要获取只包含说话人A或说话人B的音轨。然后,如同谷歌的论文所指导,两种音轨将会被混合以用于训练。因此,我们需要首先人工选取音轨。在本项目中,音轨选自Vtuber的youtube相关频道。
-
本项目应用youtube-dl进行下载。利用 --extract-audio 选项,我们可以直接从视频中提取opus格式的音频。
-
因为音频可能会包含背景音乐,本项目使用现成的Spleeter模型进行背景音乐分离。之后,48000Hz的音频被降采样到8000Hz。
-
-
可以在这里找到相关代码.
-
数据被切成三秒长的小段。
-
如果一小段语音中有一半时间没人说话,则舍弃之。从结果而言,这部分对模型表现非常重要。
-
首先,来自两个人的数据信号被归一化:
s1_target /= np.max(np.abs(s1_target)) s2 /= np.max(np.abs(s2))
然后,每条数据信号都按比例缩放。缩放比例来自一个连续型均匀分布。
w1_ratio = np.random.uniform(low=0.05, high=1.2) w2_ratio = np.random.uniform(low=0.05, high=1.2) w1 = s1_target * w1_ratio w2 = s2 * w2_ratio
之后,来自不同vtuber的数据信号被相加,并且进一步归一化:
mixed = w1 + w2 norm = np.max(np.abs(mixed)) * 1.1 w1, w2, mixed = w1/norm, w2/norm, mixed/norm
再然后,运用短时傅里叶变换将音频信号转入频域。
-
-
这部分的相关代码可以在这里找到。需要注意的是,模型的输入中包含了一个代表说话人的映射向量。输入的说话人映射向量不同,模型分离出的说话人也将不同。如果想要得知更多的细节,请参照原论文以及我们修改过的模型代码。这是模型结构图:
我们主要对原始模型做了以下更改:- 增加了一个双向长短期记忆层。
- 应用了注意力机制。当模型产生遮罩时,它可以对卷积神经网络的输出分配不同的权重。(如果你看不懂这里的遮罩是什么,那证明你需要先去阅读谷歌的论文)