import subprocess import faiss import os import numpy as np from random import shuffle from sklearn.cluster import MiniBatchKMeans import sys os.setpgrp() print(f"************ Trainer starts ************") trainset_dir = sys.argv[1] sr = 48000 sr_k = "48k" exp_root = sys.argv[3] exp_name = sys.argv[2] exp_dir = f"{exp_root}/logs/{exp_name}" is_half = False world_size = 1 rank = 0 gpu_id = 0 batch_size = int(os.getenv("RVC_BATCH_SIZE", "12")) pretrained_G = "assets/pretrained_v2/f0G48k.pth" pretrained_D = "assets/pretrained_v2/f0D48k.pth" os.makedirs(exp_dir, exist_ok=True) os.makedirs(f"{exp_root}/assets/weights", exist_ok=True) gt_wavs_dir = f"{exp_dir}/0_gt_wavs" f0_dir = f"{exp_dir}/2a_f0" f0nsf_dir = f"{exp_dir}/2b-f0nsf" feature_dir = f"{exp_dir}/3_feature768" subprocess.run( [ "python", "infer/modules/train/preprocess.py", trainset_dir, f"{sr}", "1", exp_dir, "True", f"{3.0 if is_half else 3.7}", ], check=True, ) subprocess.run( [ "python", "infer/modules/train/extract/extract_f0_rmvpe.py", f"{world_size}", f"{rank}", f"{gpu_id}", exp_dir, f"{is_half}", ], check=True, ) subprocess.run( [ "python", "infer/modules/train/extract_feature_print.py", "cuda", f"{world_size}", f"{rank}", f"{gpu_id}", exp_dir, "v2", ], check=True, ) train_names = set.intersection( *( set(name.split(".")[0] for name in os.listdir(d)) for d in [gt_wavs_dir, feature_dir, f0_dir, f0nsf_dir] ) ) train_set = [ f"{gt_wavs_dir}/{name}.wav|{feature_dir}/{name}.npy|{f0_dir}/{name}.wav.npy|{f0nsf_dir}/{name}.wav.npy|0" for name in train_names ] for _ in range(2): train_set.append( f"logs/mute/0_gt_wavs/mute{sr_k}.wav|logs/mute/3_feature768/mute.npy|logs/mute/2a_f0/mute.wav.npy|logs/mute/2b-f0nsf/mute.wav.npy|0" ) # train for about 10,000 clip-epochs (max of 200 epochs) total_epoch = min(200, 10000 // len(train_set) + 1) save_epoch = total_epoch print(f"************ Training for {total_epoch} epochs ************") shuffle(train_set) with open(f"{exp_dir}/filelist.txt", "w") as f: f.write("\n".join(train_set)) with open(f"configs/v2/{sr_k}.json", "r") as config_in, open( f"{exp_dir}/config.json", "w" ) as config_out: config_out.write(config_in.read()) subprocess.run( [ "python", "infer/modules/train/train.py", "-r", exp_root, "-e", exp_name, "-sr", f"{sr_k}", "-f0", "1", "-bs", f"{batch_size}", "-g", "1", "-te", f"{total_epoch}", "-se", f"{save_epoch}", "-pg", pretrained_G, "-pd", pretrained_D, "-l", "1", "-c", "1", # cache entire dataset in gpu memory "-sw", "0", "-v", "v2", ], check=True, ) big_npy = np.concatenate( [np.load(f"{feature_dir}/{f}") for f in os.listdir(feature_dir)], 0 ) big_npy_idx = np.arange(big_npy.shape[0]) np.random.shuffle(big_npy_idx) big_npy = big_npy[big_npy_idx] if big_npy.shape[0] > 2e5: big_npy = ( MiniBatchKMeans( n_clusters=10000, verbose=True, batch_size=256, compute_labels=False, init="random", ) .fit(big_npy) .cluster_centers_ ) n_ivf = min(int(16 * np.sqrt(big_npy.shape[0])), big_npy.shape[0] // 39) index = faiss.index_factory(768, f"IVF{n_ivf},Flat") index_ivf = faiss.extract_index_ivf(index) index_ivf.nprobe = 1 index.train(big_npy) faiss.write_index( index, f"{exp_dir}/trained_IVF{n_ivf}_Flat_nprobe_{index_ivf.nprobe}_{exp_name}_v2.index", ) batch_size_add = 8192 for i in range(0, big_npy.shape[0], batch_size_add): index.add(big_npy[i : i + batch_size_add]) faiss.write_index( index, f"{exp_dir}/added_IVF{n_ivf}_Flat_nprobe_{index_ivf.nprobe}_{exp_name}_v2.index", )