upload files
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import os
|
||||
import json
|
||||
import math
|
||||
import numpy as np
|
||||
import torch
|
||||
from torch import no_grad, LongTensor
|
||||
import librosa
|
||||
from torch.nn import functional as F
|
||||
import argparse
|
||||
from mel_processing import spectrogram_torch
|
||||
import commons
|
||||
import utils
|
||||
from models_infer import SynthesizerTrn
|
||||
from text import text_to_sequence
|
||||
import gradio as gr
|
||||
import torchaudio
|
||||
|
||||
def get_text(text, hps):
|
||||
text_norm = text_to_sequence(text, hps.symbols, hps.data.text_cleaners)
|
||||
if hps.data.add_blank:
|
||||
text_norm = commons.intersperse(text_norm, 0)
|
||||
text_norm = torch.LongTensor(text_norm)
|
||||
return text_norm
|
||||
|
||||
def create_vc_fn(model, hps, speaker_ids):
|
||||
def vc_fn(original_speaker, target_speaker, record_audio, upload_audio):
|
||||
input_audio = record_audio if record_audio is not None else upload_audio
|
||||
if input_audio is None:
|
||||
return "You need to record or upload an audio", None
|
||||
sampling_rate, audio = input_audio
|
||||
original_speaker_id = speaker_ids[original_speaker]
|
||||
target_speaker_id = speaker_ids[target_speaker]
|
||||
|
||||
audio = (audio / np.iinfo(audio.dtype).max).astype(np.float32)
|
||||
if len(audio.shape) > 1:
|
||||
audio = librosa.to_mono(audio.transpose(1, 0))
|
||||
if sampling_rate != hps.data.sampling_rate:
|
||||
audio = librosa.resample(audio, orig_sr=sampling_rate, target_sr=hps.data.sampling_rate)
|
||||
with no_grad():
|
||||
y = torch.FloatTensor(audio)
|
||||
y = y.unsqueeze(0)
|
||||
spec = spectrogram_torch(y, hps.data.filter_length,
|
||||
hps.data.sampling_rate, hps.data.hop_length, hps.data.win_length,
|
||||
center=False)
|
||||
spec_lengths = LongTensor([spec.size(-1)])
|
||||
sid_src = LongTensor([original_speaker_id])
|
||||
sid_tgt = LongTensor([target_speaker_id])
|
||||
audio = model.voice_conversion(spec, spec_lengths, sid_src=sid_src, sid_tgt=sid_tgt)[0][
|
||||
0, 0].data.cpu().float().numpy()
|
||||
del y, spec, spec_lengths, sid_src, sid_tgt
|
||||
return "Success", (hps.data.sampling_rate, audio)
|
||||
|
||||
return vc_fn
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--model_dir", default="./G_latest.pth", help="directory to your fine-tuned model")
|
||||
|
||||
args = parser.parse_args()
|
||||
hps = utils.get_hparams_from_file("./configs/finetune_speaker.json")
|
||||
device = "cpu"
|
||||
|
||||
net_g = SynthesizerTrn(
|
||||
len(hps.symbols),
|
||||
hps.data.filter_length // 2 + 1,
|
||||
hps.train.segment_size // hps.data.hop_length,
|
||||
n_speakers=hps.data.n_speakers,
|
||||
**hps.model).to(device)
|
||||
_ = net_g.eval()
|
||||
|
||||
_ = utils.load_checkpoint(args.model_dir, net_g, None)
|
||||
speaker_ids = hps.speakers
|
||||
speakers = list(hps.speakers.keys())
|
||||
vc_fn = create_vc_fn(net_g, hps, speaker_ids)
|
||||
app = gr.Blocks()
|
||||
with app:
|
||||
gr.Markdown("""
|
||||
录制或上传声音,并选择要转换的音色。User代表的音色是你自己。
|
||||
""")
|
||||
with gr.Column():
|
||||
record_audio = gr.Audio(label="record your voice", source="microphone")
|
||||
upload_audio = gr.Audio(label="or upload audio here", source="upload")
|
||||
source_speaker = gr.Dropdown(choices=speakers, value="User", label="source speaker")
|
||||
target_speaker = gr.Dropdown(choices=speakers, value=speakers[0], label="target speaker")
|
||||
with gr.Column():
|
||||
message_box = gr.Textbox(label="Message")
|
||||
converted_audio = gr.Audio(label='converted audio')
|
||||
btn = gr.Button("Convert!")
|
||||
btn.click(vc_fn, inputs=[source_speaker, target_speaker, record_audio, upload_audio],
|
||||
outputs=[message_box, converted_audio])
|
||||
app.launch()
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"train": {
|
||||
"log_interval": 100,
|
||||
"eval_interval": 1000,
|
||||
"eval_interval": 200,
|
||||
"seed": 1234,
|
||||
"epochs": 10000,
|
||||
"learning_rate": 2e-4,
|
||||
"betas": [0.8, 0.99],
|
||||
"eps": 1e-9,
|
||||
"batch_size": 1,
|
||||
"batch_size": 16,
|
||||
"fp16_run": true,
|
||||
"lr_decay": 0.999875,
|
||||
"segment_size": 8192,
|
||||
@@ -50,5 +50,155 @@
|
||||
"use_spectral_norm": false,
|
||||
"gin_channels": 256
|
||||
},
|
||||
"symbols": ["_", ",", ".", "!", "?", "-", "~", "\u2026", "N", "Q", "a", "b", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "s", "t", "u", "v", "w", "x", "y", "z", "\u0251", "\u00e6", "\u0283", "\u0291", "\u00e7", "\u026f", "\u026a", "\u0254", "\u025b", "\u0279", "\u00f0", "\u0259", "\u026b", "\u0265", "\u0278", "\u028a", "\u027e", "\u0292", "\u03b8", "\u03b2", "\u014b", "\u0266", "\u207c", "\u02b0", "`", "^", "#", "*", "=", "\u02c8", "\u02cc", "\u2192", "\u2193", "\u2191", " "]
|
||||
"symbols": ["_", ",", ".", "!", "?", "-", "~", "\u2026", "N", "Q", "a", "b", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "s", "t", "u", "v", "w", "x", "y", "z", "\u0251", "\u00e6", "\u0283", "\u0291", "\u00e7", "\u026f", "\u026a", "\u0254", "\u025b", "\u0279", "\u00f0", "\u0259", "\u026b", "\u0265", "\u0278", "\u028a", "\u027e", "\u0292", "\u03b8", "\u03b2", "\u014b", "\u0266", "\u207c", "\u02b0", "`", "^", "#", "*", "=", "\u02c8", "\u02cc", "\u2192", "\u2193", "\u2191", " "],
|
||||
"speakers": {"特别周 Special Week (Umamusume Pretty Derby)": 0,
|
||||
"无声铃鹿 Silence Suzuka (Umamusume Pretty Derby)": 1,
|
||||
"东海帝王 Tokai Teio (Umamusume Pretty Derby)": 2,
|
||||
"丸善斯基 Maruzensky (Umamusume Pretty Derby)": 3,
|
||||
"富士奇迹 Fuji Kiseki (Umamusume Pretty Derby)": 4,
|
||||
"小栗帽 Oguri Cap (Umamusume Pretty Derby)": 5,
|
||||
"黄金船 Gold Ship (Umamusume Pretty Derby)": 6,
|
||||
"伏特加 Vodka (Umamusume Pretty Derby)": 7,
|
||||
"大和赤骥 Daiwa Scarlet (Umamusume Pretty Derby)": 8,
|
||||
"大树快车 Taiki Shuttle (Umamusume Pretty Derby)": 9,
|
||||
"草上飞 Grass Wonder (Umamusume Pretty Derby)": 10,
|
||||
"菱亚马逊 Hishi Amazon (Umamusume Pretty Derby)": 11,
|
||||
"目白麦昆 Mejiro Mcqueen (Umamusume Pretty Derby)": 12,
|
||||
"神鹰 El Condor Pasa (Umamusume Pretty Derby)": 13,
|
||||
"好歌剧 T.M. Opera O (Umamusume Pretty Derby)": 14,
|
||||
"成田白仁 Narita Brian (Umamusume Pretty Derby)": 15,
|
||||
"鲁道夫象征 Symboli Rudolf (Umamusume Pretty Derby)": 16,
|
||||
"气槽 Air Groove (Umamusume Pretty Derby)": 17,
|
||||
"爱丽数码 Agnes Digital (Umamusume Pretty Derby)": 18,
|
||||
"青云天空 Seiun Sky (Umamusume Pretty Derby)": 19,
|
||||
"玉藻十字 Tamamo Cross (Umamusume Pretty Derby)": 20,
|
||||
"美妙姿势 Fine Motion (Umamusume Pretty Derby)": 21,
|
||||
"琵琶晨光 Biwa Hayahide (Umamusume Pretty Derby)": 22,
|
||||
"重炮 Mayano Topgun (Umamusume Pretty Derby)": 23,
|
||||
"曼城茶座 Manhattan Cafe (Umamusume Pretty Derby)": 24,
|
||||
"美普波旁 Mihono Bourbon (Umamusume Pretty Derby)": 25,
|
||||
"目白雷恩 Mejiro Ryan (Umamusume Pretty Derby)": 26,
|
||||
"雪之美人 Yukino Bijin (Umamusume Pretty Derby)": 28,
|
||||
"米浴 Rice Shower (Umamusume Pretty Derby)": 29,
|
||||
"艾尼斯风神 Ines Fujin (Umamusume Pretty Derby)": 30,
|
||||
"爱丽速子 Agnes Tachyon (Umamusume Pretty Derby)": 31,
|
||||
"爱慕织姬 Admire Vega (Umamusume Pretty Derby)": 32,
|
||||
"稻荷一 Inari One (Umamusume Pretty Derby)": 33,
|
||||
"胜利奖券 Winning Ticket (Umamusume Pretty Derby)": 34,
|
||||
"空中神宫 Air Shakur (Umamusume Pretty Derby)": 35,
|
||||
"荣进闪耀 Eishin Flash (Umamusume Pretty Derby)": 36,
|
||||
"真机伶 Curren Chan (Umamusume Pretty Derby)": 37,
|
||||
"川上公主 Kawakami Princess (Umamusume Pretty Derby)": 38,
|
||||
"黄金城市 Gold City (Umamusume Pretty Derby)": 39,
|
||||
"樱花进王 Sakura Bakushin O (Umamusume Pretty Derby)": 40,
|
||||
"采珠 Seeking the Pearl (Umamusume Pretty Derby)": 41,
|
||||
"新光风 Shinko Windy (Umamusume Pretty Derby)": 42,
|
||||
"东商变革 Sweep Tosho (Umamusume Pretty Derby)": 43,
|
||||
"超级小溪 Super Creek (Umamusume Pretty Derby)": 44,
|
||||
"醒目飞鹰 Smart Falcon (Umamusume Pretty Derby)": 45,
|
||||
"荒漠英雄 Zenno Rob Roy (Umamusume Pretty Derby)": 46,
|
||||
"东瀛佐敦 Tosen Jordan (Umamusume Pretty Derby)": 47,
|
||||
"中山庆典 Nakayama Festa (Umamusume Pretty Derby)": 48,
|
||||
"成田大进 Narita Taishin (Umamusume Pretty Derby)": 49,
|
||||
"西野花 Nishino Flower (Umamusume Pretty Derby)": 50,
|
||||
"春乌拉拉 Haru Urara (Umamusume Pretty Derby)": 51,
|
||||
"青竹回忆 Bamboo Memory (Umamusume Pretty Derby)": 52,
|
||||
"待兼福来 Matikane Fukukitaru (Umamusume Pretty Derby)": 55,
|
||||
"名将怒涛 Meisho Doto (Umamusume Pretty Derby)": 57,
|
||||
"目白多伯 Mejiro Dober (Umamusume Pretty Derby)": 58,
|
||||
"优秀素质 Nice Nature (Umamusume Pretty Derby)": 59,
|
||||
"帝王光环 King Halo (Umamusume Pretty Derby)": 60,
|
||||
"待兼诗歌剧 Matikane Tannhauser (Umamusume Pretty Derby)": 61,
|
||||
"生野狄杜斯 Ikuno Dictus (Umamusume Pretty Derby)": 62,
|
||||
"目白善信 Mejiro Palmer (Umamusume Pretty Derby)": 63,
|
||||
"大拓太阳神 Daitaku Helios (Umamusume Pretty Derby)": 64,
|
||||
"双涡轮 Twin Turbo (Umamusume Pretty Derby)": 65,
|
||||
"里见光钻 Satono Diamond (Umamusume Pretty Derby)": 66,
|
||||
"北部玄驹 Kitasan Black (Umamusume Pretty Derby)": 67,
|
||||
"樱花千代王 Sakura Chiyono O (Umamusume Pretty Derby)": 68,
|
||||
"天狼星象征 Sirius Symboli (Umamusume Pretty Derby)": 69,
|
||||
"目白阿尔丹 Mejiro Ardan (Umamusume Pretty Derby)": 70,
|
||||
"八重无敌 Yaeno Muteki (Umamusume Pretty Derby)": 71,
|
||||
"鹤丸刚志 Tsurumaru Tsuyoshi (Umamusume Pretty Derby)": 72,
|
||||
"目白光明 Mejiro Bright (Umamusume Pretty Derby)": 73,
|
||||
"樱花桂冠 Sakura Laurel (Umamusume Pretty Derby)": 74,
|
||||
"成田路 Narita Top Road (Umamusume Pretty Derby)": 75,
|
||||
"也文摄辉 Yamanin Zephyr (Umamusume Pretty Derby)": 76,
|
||||
"真弓快车 Aston Machan (Umamusume Pretty Derby)": 80,
|
||||
"骏川手纲 Hayakawa Tazuna (Umamusume Pretty Derby)": 81,
|
||||
"小林历奇 Kopano Rickey (Umamusume Pretty Derby)": 83,
|
||||
"奇锐骏 Wonder Acute (Umamusume Pretty Derby)": 85,
|
||||
"秋川理事长 President Akikawa (Umamusume Pretty Derby)": 86,
|
||||
"綾地 寧々 Ayachi Nene (Sanoba Witch)": 87,
|
||||
"因幡 めぐる Inaba Meguru (Sanoba Witch)": 88,
|
||||
"椎葉 紬 Shiiba Tsumugi (Sanoba Witch)": 89,
|
||||
"仮屋 和奏 Kariya Wakama (Sanoba Witch)": 90,
|
||||
"戸隠 憧子 Togakushi Touko (Sanoba Witch)": 91,
|
||||
"九条裟罗 Kujou Sara (Genshin Impact)": 92,
|
||||
"芭芭拉 Barbara (Genshin Impact)": 93,
|
||||
"派蒙 Paimon (Genshin Impact)": 94,
|
||||
"荒泷一斗 Arataki Itto (Genshin Impact)": 96,
|
||||
"早柚 Sayu (Genshin Impact)": 97,
|
||||
"香菱 Xiangling (Genshin Impact)": 98,
|
||||
"神里绫华 Kamisato Ayaka (Genshin Impact)": 99,
|
||||
"重云 Chongyun (Genshin Impact)": 100,
|
||||
"流浪者 Wanderer (Genshin Impact)": 102,
|
||||
"优菈 Eula (Genshin Impact)": 103,
|
||||
"凝光 Ningguang (Genshin Impact)": 105,
|
||||
"钟离 Zhongli (Genshin Impact)": 106,
|
||||
"雷电将军 Raiden Shogun (Genshin Impact)": 107,
|
||||
"枫原万叶 Kaedehara Kazuha (Genshin Impact)": 108,
|
||||
"赛诺 Cyno (Genshin Impact)": 109,
|
||||
"诺艾尔 Noelle (Genshin Impact)": 112,
|
||||
"八重神子 Yae Miko (Genshin Impact)": 113,
|
||||
"凯亚 Kaeya (Genshin Impact)": 114,
|
||||
"魈 Xiao (Genshin Impact)": 115,
|
||||
"托马 Thoma (Genshin Impact)": 116,
|
||||
"可莉 Klee (Genshin Impact)": 117,
|
||||
"迪卢克 Diluc (Genshin Impact)": 120,
|
||||
"夜兰 Yelan (Genshin Impact)": 121,
|
||||
"鹿野院平藏 Shikanoin Heizou (Genshin Impact)": 123,
|
||||
"辛焱 Xinyan (Genshin Impact)": 124,
|
||||
"丽莎 Lisa (Genshin Impact)": 125,
|
||||
"云堇 Yun Jin (Genshin Impact)": 126,
|
||||
"坎蒂丝 Candace (Genshin Impact)": 127,
|
||||
"罗莎莉亚 Rosaria (Genshin Impact)": 128,
|
||||
"北斗 Beidou (Genshin Impact)": 129,
|
||||
"珊瑚宫心海 Sangonomiya Kokomi (Genshin Impact)": 132,
|
||||
"烟绯 Yanfei (Genshin Impact)": 133,
|
||||
"久岐忍 Kuki Shinobu (Genshin Impact)": 136,
|
||||
"宵宫 Yoimiya (Genshin Impact)": 139,
|
||||
"安柏 Amber (Genshin Impact)": 143,
|
||||
"迪奥娜 Diona (Genshin Impact)": 144,
|
||||
"班尼特 Bennett (Genshin Impact)": 146,
|
||||
"雷泽 Razor (Genshin Impact)": 147,
|
||||
"阿贝多 Albedo (Genshin Impact)": 151,
|
||||
"温迪 Venti (Genshin Impact)": 152,
|
||||
"空 Player Male (Genshin Impact)": 153,
|
||||
"神里绫人 Kamisato Ayato (Genshin Impact)": 154,
|
||||
"琴 Jean (Genshin Impact)": 155,
|
||||
"艾尔海森 Alhaitham (Genshin Impact)": 156,
|
||||
"莫娜 Mona (Genshin Impact)": 157,
|
||||
"妮露 Nilou (Genshin Impact)": 159,
|
||||
"胡桃 Hu Tao (Genshin Impact)": 160,
|
||||
"甘雨 Ganyu (Genshin Impact)": 161,
|
||||
"纳西妲 Nahida (Genshin Impact)": 162,
|
||||
"刻晴 Keqing (Genshin Impact)": 165,
|
||||
"荧 Player Female (Genshin Impact)": 169,
|
||||
"埃洛伊 Aloy (Genshin Impact)": 179,
|
||||
"柯莱 Collei (Genshin Impact)": 182,
|
||||
"多莉 Dori (Genshin Impact)": 184,
|
||||
"提纳里 Tighnari (Genshin Impact)": 186,
|
||||
"砂糖 Sucrose (Genshin Impact)": 188,
|
||||
"行秋 Xingqiu (Genshin Impact)": 190,
|
||||
"奥兹 Oz (Genshin Impact)": 193,
|
||||
"五郎 Gorou (Genshin Impact)": 198,
|
||||
"达达利亚 Tartalia (Genshin Impact)": 202,
|
||||
"七七 Qiqi (Genshin Impact)": 207,
|
||||
"申鹤 Shenhe (Genshin Impact)": 217,
|
||||
"莱依拉 Layla (Genshin Impact)": 228,
|
||||
"菲谢尔 Fishl (Genshin Impact)": 230,
|
||||
"User": 999
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -240,8 +240,10 @@ def train_and_evaluate(rank, epoch, hps, nets, optims, schedulers, scaler, loade
|
||||
if global_step % hps.train.eval_interval == 0:
|
||||
evaluate(hps, net_g, eval_loader, writer_eval)
|
||||
utils.save_checkpoint(net_g, None, hps.train.learning_rate, epoch, os.path.join(hps.model_dir, "G_{}.pth".format(global_step)))
|
||||
utils.save_checkpoint(net_g, None, hps.train.learning_rate, epoch,
|
||||
os.path.join(hps.model_dir, "G_latest.pth".format(global_step)))
|
||||
# utils.save_checkpoint(net_d, optim_d, hps.train.learning_rate, epoch, os.path.join(hps.model_dir, "D_{}.pth".format(global_step)))
|
||||
old_g=os.path.join(hps.model_dir, "G_{}.pth".format(global_step-4000))
|
||||
old_g=os.path.join(hps.model_dir, "G_{}.pth".format(global_step-400))
|
||||
# old_d=os.path.join(hps.model_dir, "D_{}.pth".format(global_step-400))
|
||||
if os.path.exists(old_g):
|
||||
os.remove(old_g)
|
||||
|
||||
+401
@@ -0,0 +1,401 @@
|
||||
import math
|
||||
import torch
|
||||
from torch import nn
|
||||
from torch.nn import functional as F
|
||||
|
||||
import commons
|
||||
import modules
|
||||
import attentions
|
||||
|
||||
from torch.nn import Conv1d, ConvTranspose1d, AvgPool1d, Conv2d
|
||||
from torch.nn.utils import weight_norm, remove_weight_norm, spectral_norm
|
||||
from commons import init_weights, get_padding
|
||||
|
||||
|
||||
class StochasticDurationPredictor(nn.Module):
|
||||
def __init__(self, in_channels, filter_channels, kernel_size, p_dropout, n_flows=4, gin_channels=0):
|
||||
super().__init__()
|
||||
filter_channels = in_channels # it needs to be removed from future version.
|
||||
self.in_channels = in_channels
|
||||
self.filter_channels = filter_channels
|
||||
self.kernel_size = kernel_size
|
||||
self.p_dropout = p_dropout
|
||||
self.n_flows = n_flows
|
||||
self.gin_channels = gin_channels
|
||||
|
||||
self.log_flow = modules.Log()
|
||||
self.flows = nn.ModuleList()
|
||||
self.flows.append(modules.ElementwiseAffine(2))
|
||||
for i in range(n_flows):
|
||||
self.flows.append(modules.ConvFlow(2, filter_channels, kernel_size, n_layers=3))
|
||||
self.flows.append(modules.Flip())
|
||||
|
||||
self.post_pre = nn.Conv1d(1, filter_channels, 1)
|
||||
self.post_proj = nn.Conv1d(filter_channels, filter_channels, 1)
|
||||
self.post_convs = modules.DDSConv(filter_channels, kernel_size, n_layers=3, p_dropout=p_dropout)
|
||||
self.post_flows = nn.ModuleList()
|
||||
self.post_flows.append(modules.ElementwiseAffine(2))
|
||||
for i in range(4):
|
||||
self.post_flows.append(modules.ConvFlow(2, filter_channels, kernel_size, n_layers=3))
|
||||
self.post_flows.append(modules.Flip())
|
||||
|
||||
self.pre = nn.Conv1d(in_channels, filter_channels, 1)
|
||||
self.proj = nn.Conv1d(filter_channels, filter_channels, 1)
|
||||
self.convs = modules.DDSConv(filter_channels, kernel_size, n_layers=3, p_dropout=p_dropout)
|
||||
if gin_channels != 0:
|
||||
self.cond = nn.Conv1d(gin_channels, filter_channels, 1)
|
||||
|
||||
def forward(self, x, x_mask, w=None, g=None, reverse=False, noise_scale=1.0):
|
||||
x = torch.detach(x)
|
||||
x = self.pre(x)
|
||||
if g is not None:
|
||||
g = torch.detach(g)
|
||||
x = x + self.cond(g)
|
||||
x = self.convs(x, x_mask)
|
||||
x = self.proj(x) * x_mask
|
||||
|
||||
if not reverse:
|
||||
flows = self.flows
|
||||
assert w is not None
|
||||
|
||||
logdet_tot_q = 0
|
||||
h_w = self.post_pre(w)
|
||||
h_w = self.post_convs(h_w, x_mask)
|
||||
h_w = self.post_proj(h_w) * x_mask
|
||||
e_q = torch.randn(w.size(0), 2, w.size(2)).to(device=x.device, dtype=x.dtype) * x_mask
|
||||
z_q = e_q
|
||||
for flow in self.post_flows:
|
||||
z_q, logdet_q = flow(z_q, x_mask, g=(x + h_w))
|
||||
logdet_tot_q += logdet_q
|
||||
z_u, z1 = torch.split(z_q, [1, 1], 1)
|
||||
u = torch.sigmoid(z_u) * x_mask
|
||||
z0 = (w - u) * x_mask
|
||||
logdet_tot_q += torch.sum((F.logsigmoid(z_u) + F.logsigmoid(-z_u)) * x_mask, [1,2])
|
||||
logq = torch.sum(-0.5 * (math.log(2*math.pi) + (e_q**2)) * x_mask, [1,2]) - logdet_tot_q
|
||||
|
||||
logdet_tot = 0
|
||||
z0, logdet = self.log_flow(z0, x_mask)
|
||||
logdet_tot += logdet
|
||||
z = torch.cat([z0, z1], 1)
|
||||
for flow in flows:
|
||||
z, logdet = flow(z, x_mask, g=x, reverse=reverse)
|
||||
logdet_tot = logdet_tot + logdet
|
||||
nll = torch.sum(0.5 * (math.log(2*math.pi) + (z**2)) * x_mask, [1,2]) - logdet_tot
|
||||
return nll + logq # [b]
|
||||
else:
|
||||
flows = list(reversed(self.flows))
|
||||
flows = flows[:-2] + [flows[-1]] # remove a useless vflow
|
||||
z = torch.randn(x.size(0), 2, x.size(2)).to(device=x.device, dtype=x.dtype) * noise_scale
|
||||
for flow in flows:
|
||||
z = flow(z, x_mask, g=x, reverse=reverse)
|
||||
z0, z1 = torch.split(z, [1, 1], 1)
|
||||
logw = z0
|
||||
return logw
|
||||
|
||||
|
||||
class DurationPredictor(nn.Module):
|
||||
def __init__(self, in_channels, filter_channels, kernel_size, p_dropout, gin_channels=0):
|
||||
super().__init__()
|
||||
|
||||
self.in_channels = in_channels
|
||||
self.filter_channels = filter_channels
|
||||
self.kernel_size = kernel_size
|
||||
self.p_dropout = p_dropout
|
||||
self.gin_channels = gin_channels
|
||||
|
||||
self.drop = nn.Dropout(p_dropout)
|
||||
self.conv_1 = nn.Conv1d(in_channels, filter_channels, kernel_size, padding=kernel_size//2)
|
||||
self.norm_1 = modules.LayerNorm(filter_channels)
|
||||
self.conv_2 = nn.Conv1d(filter_channels, filter_channels, kernel_size, padding=kernel_size//2)
|
||||
self.norm_2 = modules.LayerNorm(filter_channels)
|
||||
self.proj = nn.Conv1d(filter_channels, 1, 1)
|
||||
|
||||
if gin_channels != 0:
|
||||
self.cond = nn.Conv1d(gin_channels, in_channels, 1)
|
||||
|
||||
def forward(self, x, x_mask, g=None):
|
||||
x = torch.detach(x)
|
||||
if g is not None:
|
||||
g = torch.detach(g)
|
||||
x = x + self.cond(g)
|
||||
x = self.conv_1(x * x_mask)
|
||||
x = torch.relu(x)
|
||||
x = self.norm_1(x)
|
||||
x = self.drop(x)
|
||||
x = self.conv_2(x * x_mask)
|
||||
x = torch.relu(x)
|
||||
x = self.norm_2(x)
|
||||
x = self.drop(x)
|
||||
x = self.proj(x * x_mask)
|
||||
return x * x_mask
|
||||
|
||||
|
||||
class TextEncoder(nn.Module):
|
||||
def __init__(self,
|
||||
n_vocab,
|
||||
out_channels,
|
||||
hidden_channels,
|
||||
filter_channels,
|
||||
n_heads,
|
||||
n_layers,
|
||||
kernel_size,
|
||||
p_dropout):
|
||||
super().__init__()
|
||||
self.n_vocab = n_vocab
|
||||
self.out_channels = out_channels
|
||||
self.hidden_channels = hidden_channels
|
||||
self.filter_channels = filter_channels
|
||||
self.n_heads = n_heads
|
||||
self.n_layers = n_layers
|
||||
self.kernel_size = kernel_size
|
||||
self.p_dropout = p_dropout
|
||||
|
||||
self.emb = nn.Embedding(n_vocab, hidden_channels)
|
||||
nn.init.normal_(self.emb.weight, 0.0, hidden_channels**-0.5)
|
||||
|
||||
self.encoder = attentions.Encoder(
|
||||
hidden_channels,
|
||||
filter_channels,
|
||||
n_heads,
|
||||
n_layers,
|
||||
kernel_size,
|
||||
p_dropout)
|
||||
self.proj= nn.Conv1d(hidden_channels, out_channels * 2, 1)
|
||||
|
||||
def forward(self, x, x_lengths):
|
||||
x = self.emb(x) * math.sqrt(self.hidden_channels) # [b, t, h]
|
||||
x = torch.transpose(x, 1, -1) # [b, h, t]
|
||||
x_mask = torch.unsqueeze(commons.sequence_mask(x_lengths, x.size(2)), 1).to(x.dtype)
|
||||
|
||||
x = self.encoder(x * x_mask, x_mask)
|
||||
stats = self.proj(x) * x_mask
|
||||
|
||||
m, logs = torch.split(stats, self.out_channels, dim=1)
|
||||
return x, m, logs, x_mask
|
||||
|
||||
|
||||
class ResidualCouplingBlock(nn.Module):
|
||||
def __init__(self,
|
||||
channels,
|
||||
hidden_channels,
|
||||
kernel_size,
|
||||
dilation_rate,
|
||||
n_layers,
|
||||
n_flows=4,
|
||||
gin_channels=0):
|
||||
super().__init__()
|
||||
self.channels = channels
|
||||
self.hidden_channels = hidden_channels
|
||||
self.kernel_size = kernel_size
|
||||
self.dilation_rate = dilation_rate
|
||||
self.n_layers = n_layers
|
||||
self.n_flows = n_flows
|
||||
self.gin_channels = gin_channels
|
||||
|
||||
self.flows = nn.ModuleList()
|
||||
for i in range(n_flows):
|
||||
self.flows.append(modules.ResidualCouplingLayer(channels, hidden_channels, kernel_size, dilation_rate, n_layers, gin_channels=gin_channels, mean_only=True))
|
||||
self.flows.append(modules.Flip())
|
||||
|
||||
def forward(self, x, x_mask, g=None, reverse=False):
|
||||
if not reverse:
|
||||
for flow in self.flows:
|
||||
x, _ = flow(x, x_mask, g=g, reverse=reverse)
|
||||
else:
|
||||
for flow in reversed(self.flows):
|
||||
x = flow(x, x_mask, g=g, reverse=reverse)
|
||||
return x
|
||||
|
||||
|
||||
class PosteriorEncoder(nn.Module):
|
||||
def __init__(self,
|
||||
in_channels,
|
||||
out_channels,
|
||||
hidden_channels,
|
||||
kernel_size,
|
||||
dilation_rate,
|
||||
n_layers,
|
||||
gin_channels=0):
|
||||
super().__init__()
|
||||
self.in_channels = in_channels
|
||||
self.out_channels = out_channels
|
||||
self.hidden_channels = hidden_channels
|
||||
self.kernel_size = kernel_size
|
||||
self.dilation_rate = dilation_rate
|
||||
self.n_layers = n_layers
|
||||
self.gin_channels = gin_channels
|
||||
|
||||
self.pre = nn.Conv1d(in_channels, hidden_channels, 1)
|
||||
self.enc = modules.WN(hidden_channels, kernel_size, dilation_rate, n_layers, gin_channels=gin_channels)
|
||||
self.proj = nn.Conv1d(hidden_channels, out_channels * 2, 1)
|
||||
|
||||
def forward(self, x, x_lengths, g=None):
|
||||
x_mask = torch.unsqueeze(commons.sequence_mask(x_lengths, x.size(2)), 1).to(x.dtype)
|
||||
x = self.pre(x) * x_mask
|
||||
x = self.enc(x, x_mask, g=g)
|
||||
stats = self.proj(x) * x_mask
|
||||
m, logs = torch.split(stats, self.out_channels, dim=1)
|
||||
z = (m + torch.randn_like(m) * torch.exp(logs)) * x_mask
|
||||
return z, m, logs, x_mask
|
||||
|
||||
|
||||
class Generator(torch.nn.Module):
|
||||
def __init__(self, initial_channel, resblock, resblock_kernel_sizes, resblock_dilation_sizes, upsample_rates, upsample_initial_channel, upsample_kernel_sizes, gin_channels=0):
|
||||
super(Generator, self).__init__()
|
||||
self.num_kernels = len(resblock_kernel_sizes)
|
||||
self.num_upsamples = len(upsample_rates)
|
||||
self.conv_pre = Conv1d(initial_channel, upsample_initial_channel, 7, 1, padding=3)
|
||||
resblock = modules.ResBlock1 if resblock == '1' else modules.ResBlock2
|
||||
|
||||
self.ups = nn.ModuleList()
|
||||
for i, (u, k) in enumerate(zip(upsample_rates, upsample_kernel_sizes)):
|
||||
self.ups.append(weight_norm(
|
||||
ConvTranspose1d(upsample_initial_channel//(2**i), upsample_initial_channel//(2**(i+1)),
|
||||
k, u, padding=(k-u)//2)))
|
||||
|
||||
self.resblocks = nn.ModuleList()
|
||||
for i in range(len(self.ups)):
|
||||
ch = upsample_initial_channel//(2**(i+1))
|
||||
for j, (k, d) in enumerate(zip(resblock_kernel_sizes, resblock_dilation_sizes)):
|
||||
self.resblocks.append(resblock(ch, k, d))
|
||||
|
||||
self.conv_post = Conv1d(ch, 1, 7, 1, padding=3, bias=False)
|
||||
self.ups.apply(init_weights)
|
||||
|
||||
if gin_channels != 0:
|
||||
self.cond = nn.Conv1d(gin_channels, upsample_initial_channel, 1)
|
||||
|
||||
def forward(self, x, g=None):
|
||||
x = self.conv_pre(x)
|
||||
if g is not None:
|
||||
x = x + self.cond(g)
|
||||
|
||||
for i in range(self.num_upsamples):
|
||||
x = F.leaky_relu(x, modules.LRELU_SLOPE)
|
||||
x = self.ups[i](x)
|
||||
xs = None
|
||||
for j in range(self.num_kernels):
|
||||
if xs is None:
|
||||
xs = self.resblocks[i*self.num_kernels+j](x)
|
||||
else:
|
||||
xs += self.resblocks[i*self.num_kernels+j](x)
|
||||
x = xs / self.num_kernels
|
||||
x = F.leaky_relu(x)
|
||||
x = self.conv_post(x)
|
||||
x = torch.tanh(x)
|
||||
|
||||
return x
|
||||
|
||||
def remove_weight_norm(self):
|
||||
print('Removing weight norm...')
|
||||
for l in self.ups:
|
||||
remove_weight_norm(l)
|
||||
for l in self.resblocks:
|
||||
l.remove_weight_norm()
|
||||
|
||||
|
||||
|
||||
class SynthesizerTrn(nn.Module):
|
||||
"""
|
||||
Synthesizer for Training
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
n_vocab,
|
||||
spec_channels,
|
||||
segment_size,
|
||||
inter_channels,
|
||||
hidden_channels,
|
||||
filter_channels,
|
||||
n_heads,
|
||||
n_layers,
|
||||
kernel_size,
|
||||
p_dropout,
|
||||
resblock,
|
||||
resblock_kernel_sizes,
|
||||
resblock_dilation_sizes,
|
||||
upsample_rates,
|
||||
upsample_initial_channel,
|
||||
upsample_kernel_sizes,
|
||||
n_speakers=0,
|
||||
gin_channels=0,
|
||||
use_sdp=True,
|
||||
**kwargs):
|
||||
|
||||
super().__init__()
|
||||
self.n_vocab = n_vocab
|
||||
self.spec_channels = spec_channels
|
||||
self.inter_channels = inter_channels
|
||||
self.hidden_channels = hidden_channels
|
||||
self.filter_channels = filter_channels
|
||||
self.n_heads = n_heads
|
||||
self.n_layers = n_layers
|
||||
self.kernel_size = kernel_size
|
||||
self.p_dropout = p_dropout
|
||||
self.resblock = resblock
|
||||
self.resblock_kernel_sizes = resblock_kernel_sizes
|
||||
self.resblock_dilation_sizes = resblock_dilation_sizes
|
||||
self.upsample_rates = upsample_rates
|
||||
self.upsample_initial_channel = upsample_initial_channel
|
||||
self.upsample_kernel_sizes = upsample_kernel_sizes
|
||||
self.segment_size = segment_size
|
||||
self.n_speakers = n_speakers
|
||||
self.gin_channels = gin_channels
|
||||
|
||||
self.use_sdp = use_sdp
|
||||
|
||||
self.enc_p = TextEncoder(n_vocab,
|
||||
inter_channels,
|
||||
hidden_channels,
|
||||
filter_channels,
|
||||
n_heads,
|
||||
n_layers,
|
||||
kernel_size,
|
||||
p_dropout)
|
||||
self.dec = Generator(inter_channels, resblock, resblock_kernel_sizes, resblock_dilation_sizes, upsample_rates, upsample_initial_channel, upsample_kernel_sizes, gin_channels=gin_channels)
|
||||
self.enc_q = PosteriorEncoder(spec_channels, inter_channels, hidden_channels, 5, 1, 16, gin_channels=gin_channels)
|
||||
self.flow = ResidualCouplingBlock(inter_channels, hidden_channels, 5, 1, 4, gin_channels=gin_channels)
|
||||
|
||||
if use_sdp:
|
||||
self.dp = StochasticDurationPredictor(hidden_channels, 192, 3, 0.5, 4, gin_channels=gin_channels)
|
||||
else:
|
||||
self.dp = DurationPredictor(hidden_channels, 256, 3, 0.5, gin_channels=gin_channels)
|
||||
|
||||
if n_speakers > 1:
|
||||
self.emb_g = nn.Embedding(n_speakers, gin_channels)
|
||||
|
||||
def infer(self, x, x_lengths, sid=None, noise_scale=1, length_scale=1, noise_scale_w=1., max_len=None):
|
||||
x, m_p, logs_p, x_mask = self.enc_p(x, x_lengths)
|
||||
if self.n_speakers > 0:
|
||||
g = self.emb_g(sid).unsqueeze(-1) # [b, h, 1]
|
||||
else:
|
||||
g = None
|
||||
|
||||
if self.use_sdp:
|
||||
logw = self.dp(x, x_mask, g=g, reverse=True, noise_scale=noise_scale_w)
|
||||
else:
|
||||
logw = self.dp(x, x_mask, g=g)
|
||||
w = torch.exp(logw) * x_mask * length_scale
|
||||
w_ceil = torch.ceil(w)
|
||||
y_lengths = torch.clamp_min(torch.sum(w_ceil, [1, 2]), 1).long()
|
||||
y_mask = torch.unsqueeze(commons.sequence_mask(y_lengths, None), 1).to(x_mask.dtype)
|
||||
attn_mask = torch.unsqueeze(x_mask, 2) * torch.unsqueeze(y_mask, -1)
|
||||
attn = commons.generate_path(w_ceil, attn_mask)
|
||||
|
||||
m_p = torch.matmul(attn.squeeze(1), m_p.transpose(1, 2)).transpose(1, 2) # [b, t', t], [b, t, d] -> [b, d, t']
|
||||
logs_p = torch.matmul(attn.squeeze(1), logs_p.transpose(1, 2)).transpose(1, 2) # [b, t', t], [b, t, d] -> [b, d, t']
|
||||
|
||||
z_p = m_p + torch.randn_like(m_p) * torch.exp(logs_p) * noise_scale
|
||||
z = self.flow(z_p, y_mask, g=g, reverse=True)
|
||||
o = self.dec((z * y_mask)[:,:,:max_len], g=g)
|
||||
return o, attn, y_mask, (z, z_p, m_p, logs_p)
|
||||
|
||||
def voice_conversion(self, y, y_lengths, sid_src, sid_tgt):
|
||||
assert self.n_speakers > 0, "n_speakers have to be larger than 0."
|
||||
g_src = self.emb_g(sid_src).unsqueeze(-1)
|
||||
g_tgt = self.emb_g(sid_tgt).unsqueeze(-1)
|
||||
z, m_q, logs_q, y_mask = self.enc_q(y, y_lengths, g=g_src)
|
||||
z_p = self.flow(z, y_mask, g=g_src)
|
||||
z_hat = self.flow(z_p, y_mask, g=g_tgt, reverse=True)
|
||||
o_hat = self.dec(z_hat * y_mask, g=g_tgt)
|
||||
return o_hat, y_mask, (z, z_p, z_hat)
|
||||
Reference in New Issue
Block a user