refactored training params to node
This commit is contained in:
+40
-22
@@ -8,7 +8,7 @@ import torch
|
||||
|
||||
from . import BASE_DIR
|
||||
|
||||
from ..lib.train.utils import HParams
|
||||
from ..lib.train.utils import HParams, DEFAULT_TRAINING_PARAMS
|
||||
|
||||
from ..training_cli import train_model
|
||||
|
||||
@@ -153,13 +153,9 @@ class LoadRVCModelNode:
|
||||
|
||||
class RVCNode:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
|
||||
|
||||
return {
|
||||
"required": {
|
||||
"audio": (MultipleTypeProxy('AUDIO,VHS_AUDIO'),),
|
||||
@@ -213,9 +209,6 @@ class RVCNode:
|
||||
|
||||
class RVCProcessDatasetNode:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
|
||||
@@ -358,10 +351,36 @@ class RVCProcessDatasetNode:
|
||||
),)
|
||||
|
||||
|
||||
class RVCTrainModelNode:
|
||||
class RVCTrainParamsNode:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
|
||||
return {
|
||||
"optional": dict(
|
||||
batch_size=("INT",dict(default=4,min=1,max=64,step=1)),
|
||||
c_mel=("FLOAT",dict(default=45.,min=0.,max=100.,step=.1)),
|
||||
c_kl=("FLOAT",dict(default=1.,min=0.,max=100.,step=.1)),
|
||||
c_fm=("FLOAT",dict(default=2.,min=0.,max=100.,step=.1)),
|
||||
c_mfcc=("FLOAT",dict(default=0.,min=0.,max=100.,step=.1)),
|
||||
c_lfcc=("FLOAT",dict(default=0.,min=0.,max=100.,step=.1)),
|
||||
c_hd=("FLOAT",dict(default=0.,min=0.,max=100.,step=.1)),
|
||||
c_sts=("FLOAT",dict(default=0.,min=0.,max=100.,step=.1)),
|
||||
c_gp=("FLOAT",dict(default=0.,min=0.,max=100.,step=.1)),
|
||||
)
|
||||
}
|
||||
|
||||
RETURN_TYPES = ('RVC_TRAINING_PARAMS', )
|
||||
RETURN_NAMES = ("rvc_training_params", )
|
||||
|
||||
FUNCTION = "init"
|
||||
|
||||
CATEGORY = CATEGORY
|
||||
|
||||
def init(self,batch_size=4,c_mel=45,c_kl=1.,c_fm=1.,c_mfcc=0.,c_lfcc=0.,c_hd=0.,c_sts=0.,c_gp=0.,):
|
||||
return (dict(batch_size=batch_size,c_mel=c_mel,c_kl=c_kl,c_fm=c_fm,c_mfcc=c_mfcc,c_gp=c_gp,c_lfcc=c_lfcc,c_hd=c_hd,c_sts=c_sts),)
|
||||
|
||||
class RVCTrainModelNode:
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -374,10 +393,10 @@ class RVCTrainModelNode:
|
||||
return {
|
||||
"required": {
|
||||
"rvc_dataset_pipe": ("RVC_DATASET_PIPE",),
|
||||
"rvc_training_params": ("RVC_TRAINING_PARAMS",dict(default=DEFAULT_TRAINING_PARAMS)),
|
||||
},
|
||||
"optional": dict(
|
||||
gpu=(DEVICES, {"default": DEVICES[0]}),
|
||||
batch_size=("INT",dict(default=4,min=1,max=64,step=1)),
|
||||
total_epoch=("INT",dict(default=100,min=10,max=1000,step=10)),
|
||||
save_every_epoch=("INT",dict(default=0,min=0,max=100)),
|
||||
pretrained_G=(PRETRAINED_G,{"default": PRETRAINED_G[0]}),
|
||||
@@ -388,9 +407,8 @@ class RVCTrainModelNode:
|
||||
train_index=("BOOLEAN",{"default": True}),
|
||||
retrain=("BOOLEAN",{"default": False}),
|
||||
save_best_model=("BOOLEAN",{"default": True}),
|
||||
best_model_threshold=("INT",dict(default=50,min=20,max=80)),
|
||||
log_every_epoch=("FLOAT",dict(default=1.,min=0.,max=2.,step=.5)),
|
||||
gradient_lambda=("FLOAT",dict(default=0.,min=0.,max=100.,step=.1)),
|
||||
timbre_lambda=("FLOAT",dict(default=0.,min=0.,max=100.,step=.1)),
|
||||
num_workers=("INT",dict(default=1,min=1,max=16))
|
||||
)
|
||||
}
|
||||
@@ -406,8 +424,8 @@ class RVCTrainModelNode:
|
||||
|
||||
def train_model(self,
|
||||
rvc_dataset_pipe,
|
||||
rvc_training_params,
|
||||
gpu="0",
|
||||
batch_size=4,
|
||||
total_epoch=100,
|
||||
save_every_epoch=0,
|
||||
pretrained_G="",
|
||||
@@ -418,15 +436,14 @@ class RVCTrainModelNode:
|
||||
train_index=True,
|
||||
retrain=False,
|
||||
save_best_model=True,
|
||||
best_model_threshold=50,
|
||||
log_every_epoch=1.,
|
||||
gradient_lambda=0.,
|
||||
timbre_lambda=0.,
|
||||
num_workers=1):
|
||||
|
||||
sample_rate = rvc_dataset_pipe["sample_rate"]
|
||||
name = rvc_dataset_pipe["name"]
|
||||
dataset_dir = rvc_dataset_pipe["dataset_dir"]
|
||||
cache_name = get_hash(batch_size,pretrained_G,pretrained_D,gradient_lambda,timbre_lambda)
|
||||
cache_name = get_hash(pretrained_G,pretrained_D,*rvc_training_params.items())
|
||||
model_dir = os.path.join(output_path,"logs",cache_name)
|
||||
if_f0 = rvc_dataset_pipe["if_f0"]
|
||||
|
||||
@@ -444,7 +461,6 @@ class RVCTrainModelNode:
|
||||
hparams.pretrainD = model_downloader(pretrained_D)
|
||||
hparams.version = "v2"
|
||||
hparams.gpus = gpu
|
||||
hparams.train.batch_size = max(batch_size,1)
|
||||
hparams.sample_rate = sample_rate
|
||||
hparams.if_f0 = if_f0
|
||||
hparams.if_latest = if_save_latest
|
||||
@@ -452,10 +468,10 @@ class RVCTrainModelNode:
|
||||
hparams.if_cache_data_in_gpu = if_cache_gpu
|
||||
hparams.data.training_files = rvc_dataset_pipe["training_files"]
|
||||
hparams.save_best_model = save_best_model
|
||||
hparams.best_model_threshold = best_model_threshold
|
||||
hparams.log_every_epoch = log_every_epoch
|
||||
hparams.train.gradient_lambda = gradient_lambda
|
||||
hparams.train.num_workers = num_workers
|
||||
hparams.train.timbre_lambda = timbre_lambda
|
||||
hparams.train.update(rvc_training_params)
|
||||
|
||||
file_index = self.train_index(dataset_dir, sample_rate, name) if train_index else None
|
||||
model_path = os.path.join(BASE_MODELS_DIR,"RVC",f"{name}_{sample_rate}.pth")
|
||||
@@ -531,7 +547,8 @@ NODE_CLASS_MAPPINGS = {
|
||||
"LoadHubertModel": LoadHubertModel,
|
||||
"LoadPitchExtractionParams": LoadPitchExtractionParams,
|
||||
"RVCProcessDatasetNode": RVCProcessDatasetNode,
|
||||
"RVCTrainModelNode": RVCTrainModelNode
|
||||
"RVCTrainModelNode": RVCTrainModelNode,
|
||||
"RVCTrainParamsNode": RVCTrainParamsNode
|
||||
}
|
||||
|
||||
# A dictionary that contains the friendly/humanly readable titles for the nodes
|
||||
@@ -542,4 +559,5 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"LoadPitchExtractionParams": "🌺Load Pitch Extraction Params",
|
||||
"RVCProcessDatasetNode": "🌺Process RVC Dataset",
|
||||
"RVCTrainModelNode": "🌺Train RVC Model",
|
||||
"RVCTrainParamsNode": "🌺RVC Training Params"
|
||||
}
|
||||
+1
-1
@@ -35,7 +35,7 @@ def feature_loss(fmap_r, fmap_g):
|
||||
gl = gl.float()
|
||||
loss += torch.mean(torch.abs(rl - gl))
|
||||
|
||||
return loss * 2
|
||||
return loss
|
||||
|
||||
|
||||
def discriminator_loss(disc_real_outputs, disc_generated_outputs):
|
||||
|
||||
+23
-37
@@ -1,4 +1,4 @@
|
||||
import os, traceback
|
||||
import os
|
||||
import glob
|
||||
import sys
|
||||
import argparse
|
||||
@@ -10,6 +10,17 @@ from scipy.io.wavfile import read
|
||||
import torch
|
||||
|
||||
MATPLOTLIB_FLAG = False
|
||||
DEFAULT_TRAINING_PARAMS = dict(
|
||||
batch_size=4,
|
||||
c_mel=45,
|
||||
c_kl=1.,
|
||||
c_fm=2.,
|
||||
c_gp=0.,
|
||||
c_mfcc=0.,
|
||||
c_lfcc=0.,
|
||||
c_hd=0.,
|
||||
c_sts=0.
|
||||
)
|
||||
|
||||
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
|
||||
logger = logging
|
||||
@@ -63,36 +74,6 @@ def load_checkpoint_d(checkpoint_path, combd, sbd, optimizer=None, load_opt=1):
|
||||
logger.info("Loaded checkpoint '{}' (epoch {})".format(checkpoint_path, iteration))
|
||||
return model, optimizer, learning_rate, iteration
|
||||
|
||||
|
||||
# def load_checkpoint(checkpoint_path, model, optimizer=None):
|
||||
# assert os.path.isfile(checkpoint_path)
|
||||
# checkpoint_dict = torch.load(checkpoint_path, map_location='cpu')
|
||||
# iteration = checkpoint_dict['iteration']
|
||||
# learning_rate = checkpoint_dict['learning_rate']
|
||||
# if optimizer is not None:
|
||||
# optimizer.load_state_dict(checkpoint_dict['optimizer'])
|
||||
# # print(1111)
|
||||
# saved_state_dict = checkpoint_dict['model']
|
||||
# # print(1111)
|
||||
#
|
||||
# if hasattr(model, 'module'):
|
||||
# state_dict = model.module.state_dict()
|
||||
# else:
|
||||
# state_dict = model.state_dict()
|
||||
# new_state_dict= {}
|
||||
# for k, v in state_dict.items():
|
||||
# try:
|
||||
# new_state_dict[k] = saved_state_dict[k]
|
||||
# except:
|
||||
# logger.info("%s is not in the checkpoint" % k)
|
||||
# new_state_dict[k] = v
|
||||
# if hasattr(model, 'module'):
|
||||
# model.module.load_state_dict(new_state_dict)
|
||||
# else:
|
||||
# model.load_state_dict(new_state_dict)
|
||||
# logger.info("Loaded checkpoint '{}' (epoch {})" .format(
|
||||
# checkpoint_path, iteration))
|
||||
# return model, optimizer, learning_rate, iteration
|
||||
def load_checkpoint(checkpoint_path, model, optimizer=None, load_opt=1):
|
||||
assert os.path.isfile(checkpoint_path)
|
||||
checkpoint_dict = torch.load(checkpoint_path, map_location="cpu")
|
||||
@@ -382,10 +363,9 @@ def get_hparams(init=True):
|
||||
hparams.if_cache_data_in_gpu = args.if_cache_data_in_gpu
|
||||
hparams.data.training_files = os.path.join(experiment_dir,"filelist.txt")
|
||||
hparams.save_best_model = True
|
||||
hparams.train.gradient_lambda = 0.
|
||||
hparams.train.num_workers = 4
|
||||
hparams.train.timbre_lambda = 0.
|
||||
hparams.model_path = None
|
||||
hparams.best_model_threshold = 50
|
||||
return hparams
|
||||
|
||||
|
||||
@@ -449,11 +429,10 @@ def get_logger(model_dir, filename="train.log"):
|
||||
return logger
|
||||
|
||||
|
||||
class HParams:
|
||||
class HParams():
|
||||
def __init__(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
if isinstance(v, dict):
|
||||
v = HParams(**v)
|
||||
if isinstance(v, dict): v = HParams(**v)
|
||||
self[k] = v
|
||||
|
||||
def keys(self):
|
||||
@@ -483,7 +462,14 @@ class HParams:
|
||||
def get(self, key, default=None):
|
||||
try: return self[key]
|
||||
except: return default
|
||||
|
||||
def update(self, data={}, **kwargs):
|
||||
data.update(kwargs)
|
||||
for k, v in data.items():
|
||||
if isinstance(v, dict): v = HParams(**v)
|
||||
if k in self and hasattr(self[k], "update") and isinstance(v, HParams): self[k].update(v)
|
||||
else: self[k] = v
|
||||
|
||||
def sync_log_interval(self, dataset_length):
|
||||
log_interval = getattr(self,"log_every_epoch",1)
|
||||
log_interval = getattr(self,"log_every_epoch",1.)
|
||||
self.train.log_interval = int(dataset_length*log_interval)
|
||||
+10
-10
@@ -127,10 +127,10 @@ def run(rank, n_gpus, hps, device):
|
||||
if os.path.isfile(loss_file):
|
||||
with open(loss_file,"r") as f:
|
||||
data: dict = json.load(f)
|
||||
least_loss = data.get("least_loss",50)
|
||||
least_loss = data.get("least_loss",hps.best_model_threshold)
|
||||
best_model_name = data.get("best_model_name","")
|
||||
else:
|
||||
least_loss = 50
|
||||
least_loss = hps.best_model_threshold
|
||||
best_model_name = ""
|
||||
|
||||
if hps.version == "v1":
|
||||
@@ -481,7 +481,7 @@ def train_and_evaluate(
|
||||
|
||||
with autocast(enabled=False):
|
||||
gradient_penalty = torch.Tensor([0.]).to(wave.device)
|
||||
if hps.train.get("gradient_lambda",0.)>0:
|
||||
if hps.train.get("c_gp",0.)>0:
|
||||
# Compute the gradient penalty
|
||||
# Randomly interpolate between real and generated data
|
||||
size = [1]*wave.ndim
|
||||
@@ -502,10 +502,10 @@ def train_and_evaluate(
|
||||
)[0]
|
||||
gradient = gradient.view(gradient.size(0), -1)
|
||||
gradient_penalty += torch.log(gradient.norm(2,dim=-1)).abs().mean() # force gradnorm=1
|
||||
gradient_penalty *= hps.train.gradient_lambda/len(disc_interpolated_output)
|
||||
gradient_penalty *= hps.train.c_gp/len(disc_interpolated_output)
|
||||
|
||||
loss_mfcc = torch.Tensor([0.]).to(wave.device)
|
||||
if hps.train.get("timbre_lambda",0)>0:
|
||||
if hps.train.get("c_mfcc",0)>0:
|
||||
loss_mfcc = mfcc_loss(wave, gen_wave, SR_MAP[hps.sample_rate],
|
||||
n_fft=hps.data.filter_length,
|
||||
hop_length=hps.data.hop_length,
|
||||
@@ -514,7 +514,7 @@ def train_and_evaluate(
|
||||
norm="slaney",
|
||||
f_min=hps.data.mel_fmin,
|
||||
f_max=hps.data.mel_fmax
|
||||
) * hps.train.timbre_lambda
|
||||
) * hps.train.c_mfcc
|
||||
|
||||
loss_mfcc = loss_mfcc.squeeze()
|
||||
gradient_penalty = gradient_penalty.squeeze()
|
||||
@@ -531,9 +531,9 @@ def train_and_evaluate(
|
||||
# Generator
|
||||
y_d_hat_r, y_d_hat_g, fmap_r, fmap_g = net_d(wave, y_hat)
|
||||
with autocast(enabled=False):
|
||||
loss_mel = F.smooth_l1_loss(y_mel, y_hat_mel) * hps.train.c_mel
|
||||
loss_kl = kl_loss(z_p, logs_q, m_p, logs_p, z_mask) * hps.train.c_kl
|
||||
loss_fm = feature_loss(fmap_r, fmap_g)
|
||||
loss_mel = F.smooth_l1_loss(y_mel, y_hat_mel) * hps.train.get("c_mel",45.)
|
||||
loss_kl = kl_loss(z_p, logs_q, m_p, logs_p, z_mask) * hps.train.get("c_kl",1.)
|
||||
loss_fm = feature_loss(fmap_r, fmap_g) * hps.train.get("c_fm",2.)
|
||||
loss_gen, losses_gen = generator_loss(y_d_hat_g)
|
||||
loss_gen_all = loss_gen + loss_fm + loss_mel + loss_kl
|
||||
|
||||
@@ -556,7 +556,7 @@ def train_and_evaluate(
|
||||
else:
|
||||
ckpt = net_g.state_dict()
|
||||
|
||||
best_model_name = f"{hps.name}_loss{least_loss:2.0f}" if hps.if_save_latest else f"{hps.name}_e{epoch}_s{global_step}_loss{least_loss:2.0f}"
|
||||
best_model_name = f"{hps.name}_e{epoch}_s{global_step}_loss{least_loss:2.0f}" if hps.save_every_weights else f"{hps.name}_loss{least_loss:2.0f}"
|
||||
status = save_checkpoint(ckpt,best_model_name,epoch,hps)
|
||||
logger.info(f"=== saving best model {best_model_name}: {status=} ===")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user