|
import os
|
|
import sys
|
|
import time
|
|
import shutil
|
|
import codecs
|
|
import threading
|
|
import subprocess
|
|
|
|
sys.path.append(os.getcwd())
|
|
|
|
from main.tools import huggingface
|
|
from main.app.core.ui import gr_info, gr_warning
|
|
from main.app.variables import python, translations, configs
|
|
|
|
def if_done(done, p):
|
|
while 1:
|
|
if p.poll() is None: time.sleep(0.5)
|
|
else: break
|
|
|
|
done[0] = True
|
|
|
|
def log_read(done, name):
|
|
log_file = os.path.join(configs["logs_path"], "app.log")
|
|
|
|
f = open(log_file, "w", encoding="utf-8")
|
|
f.close()
|
|
|
|
while 1:
|
|
with open(log_file, "r", encoding="utf-8") as f:
|
|
yield "".join(line for line in f.readlines() if "DEBUG" not in line and name in line and line.strip() != "")
|
|
|
|
time.sleep(1)
|
|
if done[0]: break
|
|
|
|
with open(log_file, "r", encoding="utf-8") as f:
|
|
log = "".join(line for line in f.readlines() if "DEBUG" not in line and line.strip() != "")
|
|
|
|
yield log
|
|
|
|
def create_dataset(input_audio, output_dataset, clean_dataset, clean_strength, separator_reverb, kim_vocals_version, overlap, segments_size, denoise_mdx, skip, skip_start, skip_end, hop_length, batch_size, sample_rate):
|
|
version = 1 if kim_vocals_version == "Version-1" else 2
|
|
gr_info(translations["start"].format(start=translations["create"]))
|
|
|
|
p = subprocess.Popen(f'{python} {configs["create_dataset_path"]} --input_audio "{input_audio}" --output_dataset "{output_dataset}" --clean_dataset {clean_dataset} --clean_strength {clean_strength} --separator_reverb {separator_reverb} --kim_vocal_version {version} --overlap {overlap} --segments_size {segments_size} --mdx_hop_length {hop_length} --mdx_batch_size {batch_size} --denoise_mdx {denoise_mdx} --skip {skip} --skip_start_audios "{skip_start}" --skip_end_audios "{skip_end}" --sample_rate {sample_rate}', shell=True)
|
|
done = [False]
|
|
|
|
threading.Thread(target=if_done, args=(done, p)).start()
|
|
|
|
for log in log_read(done, "create_dataset"):
|
|
yield log
|
|
|
|
def preprocess(model_name, sample_rate, cpu_core, cut_preprocess, process_effects, dataset, clean_dataset, clean_strength):
|
|
sr = int(float(sample_rate.rstrip("k")) * 1000)
|
|
|
|
if not model_name: return gr_warning(translations["provide_name"])
|
|
if not os.path.exists(dataset) or not any(f.lower().endswith(("wav", "mp3", "flac", "ogg", "opus", "m4a", "mp4", "aac", "alac", "wma", "aiff", "webm", "ac3")) for f in os.listdir(dataset) if os.path.isfile(os.path.join(dataset, f))): return gr_warning(translations["not_found_data"])
|
|
|
|
model_dir = os.path.join(configs["logs_path"], model_name)
|
|
if os.path.exists(model_dir): shutil.rmtree(model_dir, ignore_errors=True)
|
|
|
|
p = subprocess.Popen(f'{python} {configs["preprocess_path"]} --model_name "{model_name}" --dataset_path "{dataset}" --sample_rate {sr} --cpu_cores {cpu_core} --cut_preprocess {cut_preprocess} --process_effects {process_effects} --clean_dataset {clean_dataset} --clean_strength {clean_strength}', shell=True)
|
|
done = [False]
|
|
|
|
threading.Thread(target=if_done, args=(done, p)).start()
|
|
os.makedirs(model_dir, exist_ok=True)
|
|
|
|
for log in log_read(done, "preprocess"):
|
|
yield log
|
|
|
|
def extract(model_name, version, method, pitch_guidance, hop_length, cpu_cores, gpu, sample_rate, embedders, custom_embedders, onnx_f0_mode, embedders_mode, f0_autotune, f0_autotune_strength, hybrid_method, rms_extract):
|
|
f0method, embedder_model = (method if method != "hybrid" else hybrid_method), (embedders if embedders != "custom" else custom_embedders)
|
|
sr = int(float(sample_rate.rstrip("k")) * 1000)
|
|
|
|
if not model_name: return gr_warning(translations["provide_name"])
|
|
model_dir = os.path.join(configs["logs_path"], model_name)
|
|
|
|
try:
|
|
if not any(os.path.isfile(os.path.join(model_dir, "sliced_audios", f)) for f in os.listdir(os.path.join(model_dir, "sliced_audios"))) or not any(os.path.isfile(os.path.join(model_dir, "sliced_audios_16k", f)) for f in os.listdir(os.path.join(model_dir, "sliced_audios_16k"))): return gr_warning(translations["not_found_data_preprocess"])
|
|
except:
|
|
return gr_warning(translations["not_found_data_preprocess"])
|
|
|
|
p = subprocess.Popen(f'{python} {configs["extract_path"]} --model_name "{model_name}" --rvc_version {version} --f0_method {f0method} --pitch_guidance {pitch_guidance} --hop_length {hop_length} --cpu_cores {cpu_cores} --gpu {gpu} --sample_rate {sr} --embedder_model {embedder_model} --f0_onnx {onnx_f0_mode} --embedders_mode {embedders_mode} --f0_autotune {f0_autotune} --f0_autotune_strength {f0_autotune_strength} --rms_extract {rms_extract}', shell=True)
|
|
done = [False]
|
|
|
|
threading.Thread(target=if_done, args=(done, p)).start()
|
|
os.makedirs(model_dir, exist_ok=True)
|
|
|
|
for log in log_read(done, "extract"):
|
|
yield log
|
|
|
|
def create_index(model_name, rvc_version, index_algorithm):
|
|
if not model_name: return gr_warning(translations["provide_name"])
|
|
model_dir = os.path.join(configs["logs_path"], model_name)
|
|
|
|
try:
|
|
if not any(os.path.isfile(os.path.join(model_dir, f"{rvc_version}_extracted", f)) for f in os.listdir(os.path.join(model_dir, f"{rvc_version}_extracted"))): return gr_warning(translations["not_found_data_extract"])
|
|
except:
|
|
return gr_warning(translations["not_found_data_extract"])
|
|
|
|
p = subprocess.Popen(f'{python} {configs["create_index_path"]} --model_name "{model_name}" --rvc_version {rvc_version} --index_algorithm {index_algorithm}', shell=True)
|
|
done = [False]
|
|
|
|
threading.Thread(target=if_done, args=(done, p)).start()
|
|
os.makedirs(model_dir, exist_ok=True)
|
|
|
|
for log in log_read(done, "create_index"):
|
|
yield log
|
|
|
|
def training(model_name, rvc_version, save_every_epoch, save_only_latest, save_every_weights, total_epoch, sample_rate, batch_size, gpu, pitch_guidance, not_pretrain, custom_pretrained, pretrain_g, pretrain_d, detector, threshold, clean_up, cache, model_author, vocoder, checkpointing, deterministic, benchmark, optimizer, energy_use):
|
|
sr = int(float(sample_rate.rstrip("k")) * 1000)
|
|
if not model_name: return gr_warning(translations["provide_name"])
|
|
|
|
model_dir = os.path.join(configs["logs_path"], model_name)
|
|
if os.path.exists(os.path.join(model_dir, "train_pid.txt")): os.remove(os.path.join(model_dir, "train_pid.txt"))
|
|
|
|
try:
|
|
if not any(os.path.isfile(os.path.join(model_dir, f"{rvc_version}_extracted", f)) for f in os.listdir(os.path.join(model_dir, f"{rvc_version}_extracted"))): return gr_warning(translations["not_found_data_extract"])
|
|
except:
|
|
return gr_warning(translations["not_found_data_extract"])
|
|
|
|
if not not_pretrain:
|
|
if not custom_pretrained:
|
|
pretrain_dir = configs["pretrained_v2_path"] if rvc_version == 'v2' else configs["pretrained_v1_path"]
|
|
download_version = codecs.decode(f"uggcf://uhttvatsnpr.pb/NauC/Ivrganzrfr-EIP-Cebwrpg/erfbyir/znva/cergenvarq_i{'2' if rvc_version == 'v2' else '1'}/", "rot13")
|
|
|
|
pretrained_selector = {
|
|
True: {
|
|
32000: ("f0G32k.pth", "f0D32k.pth"),
|
|
40000: ("f0G40k.pth", "f0D40k.pth"),
|
|
48000: ("f0G48k.pth", "f0D48k.pth")
|
|
},
|
|
False: {
|
|
32000: ("G32k.pth", "D32k.pth"),
|
|
40000: ("G40k.pth", "D40k.pth"),
|
|
48000: ("G48k.pth", "D48k.pth")
|
|
}
|
|
}
|
|
|
|
pg2, pd2 = "", ""
|
|
pg, pd = pretrained_selector[pitch_guidance][sr]
|
|
|
|
if energy_use: pg2, pd2 = pg2 + "ENERGY_", pd2 + "ENERGY_"
|
|
if vocoder != 'Default': pg2, pd2 = pg2 + vocoder + "_", pd2 + vocoder + "_"
|
|
|
|
pg2, pd2 = pg2 + pg, pd2 + pd
|
|
pretrained_G, pretrained_D = (
|
|
os.path.join(
|
|
pretrain_dir,
|
|
pg2
|
|
),
|
|
os.path.join(
|
|
pretrain_dir,
|
|
pd2
|
|
)
|
|
)
|
|
|
|
try:
|
|
if not os.path.exists(pretrained_G):
|
|
gr_info(translations["download_pretrained"].format(dg="G", rvc_version=rvc_version))
|
|
huggingface.HF_download_file(
|
|
"".join(
|
|
[
|
|
download_version,
|
|
pg2
|
|
]
|
|
),
|
|
os.path.join(
|
|
pretrain_dir,
|
|
pg2
|
|
)
|
|
)
|
|
|
|
if not os.path.exists(pretrained_D):
|
|
gr_info(translations["download_pretrained"].format(dg="D", rvc_version=rvc_version))
|
|
huggingface.HF_download_file(
|
|
"".join(
|
|
[
|
|
download_version,
|
|
pd2
|
|
]
|
|
),
|
|
os.path.join(
|
|
pretrain_dir,
|
|
pd2
|
|
)
|
|
)
|
|
except:
|
|
gr_warning(translations["not_use_pretrain_error_download"])
|
|
pretrained_G = pretrained_D = None
|
|
else:
|
|
if not pretrain_g: return gr_warning(translations["provide_pretrained"].format(dg="G"))
|
|
if not pretrain_d: return gr_warning(translations["provide_pretrained"].format(dg="D"))
|
|
|
|
pg2, pd2 = pretrain_g, pretrain_d
|
|
pretrained_G, pretrained_D = (
|
|
(os.path.join(configs["pretrained_custom_path"], pg2) if not os.path.exists(pg2) else pg2),
|
|
(os.path.join(configs["pretrained_custom_path"], pd2) if not os.path.exists(pd2) else pd2)
|
|
)
|
|
|
|
if not os.path.exists(pretrained_G): return gr_warning(translations["not_found_pretrain"].format(dg="G"))
|
|
if not os.path.exists(pretrained_D): return gr_warning(translations["not_found_pretrain"].format(dg="D"))
|
|
else:
|
|
pretrained_G = pretrained_D = None
|
|
gr_warning(translations["not_use_pretrain"])
|
|
|
|
gr_info(translations["start"].format(start=translations["training"]))
|
|
|
|
p = subprocess.Popen(f'{python} {configs["train_path"]} --model_name "{model_name}" --rvc_version {rvc_version} --save_every_epoch {save_every_epoch} --save_only_latest {save_only_latest} --save_every_weights {save_every_weights} --total_epoch {total_epoch} --sample_rate {sr} --batch_size {batch_size} --gpu {gpu} --pitch_guidance {pitch_guidance} --overtraining_detector {detector} --overtraining_threshold {threshold} --cleanup {clean_up} --cache_data_in_gpu {cache} --g_pretrained_path "{pretrained_G}" --d_pretrained_path "{pretrained_D}" --model_author "{model_author}" --vocoder "{vocoder}" --checkpointing {checkpointing} --deterministic {deterministic} --benchmark {benchmark} --optimizer {optimizer} --energy_use {energy_use}', shell=True)
|
|
done = [False]
|
|
|
|
with open(os.path.join(model_dir, "train_pid.txt"), "w") as pid_file:
|
|
pid_file.write(str(p.pid))
|
|
|
|
threading.Thread(target=if_done, args=(done, p)).start()
|
|
|
|
for log in log_read(done, "train"):
|
|
lines = log.splitlines()
|
|
if len(lines) > 100: log = "\n".join(lines[-100:])
|
|
yield log |