FoxLover/RVC_V2_
0
1import subprocess, torch, os, traceback, sys, warnings, shutil, numpy as np2from mega import Mega3os.environ["no_proxy"] = "localhost, 127.0.0.1, ::1"4import threading5from time import sleep6from subprocess import Popen7import faiss8from random import shuffle9import json, datetime, requests10from gtts import gTTS11now_dir = os.getcwd()12sys.path.append(now_dir)13tmp = os.path.join(now_dir, "TEMP")14shutil.rmtree(tmp, ignore_errors=True)15shutil.rmtree("%s/runtime/Lib/site-packages/infer_pack" % (now_dir), ignore_errors=True)16os.makedirs(tmp, exist_ok=True)17os.makedirs(os.path.join(now_dir, "logs"), exist_ok=True)18os.makedirs(os.path.join(now_dir, "weights"), exist_ok=True)19os.environ["TEMP"] = tmp20warnings.filterwarnings("ignore")21torch.manual_seed(114514)22from i18n import I18nAuto23 24import signal25 26import math27 28from utils import load_audio, CSVutil29 30global DoFormant, Quefrency, Timbre31 32if not os.path.isdir('csvdb/'):33 os.makedirs('csvdb')34 frmnt, stp = open("csvdb/formanting.csv", 'w'), open("csvdb/stop.csv", 'w')35 frmnt.close()36 stp.close()37 38try:39 DoFormant, Quefrency, Timbre = CSVutil('csvdb/formanting.csv', 'r', 'formanting')40 DoFormant = (41 lambda DoFormant: True if DoFormant.lower() == 'true' else (False if DoFormant.lower() == 'false' else DoFormant)42 )(DoFormant)43except (ValueError, TypeError, IndexError):44 DoFormant, Quefrency, Timbre = False, 1.0, 1.045 CSVutil('csvdb/formanting.csv', 'w+', 'formanting', DoFormant, Quefrency, Timbre)46 47def download_models():48 # Download hubert base model if not present49 if not os.path.isfile('./hubert_base.pt'):50 response = requests.get('https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/hubert_base.pt')51 52 if response.status_code == 200:53 with open('./hubert_base.pt', 'wb') as f:54 f.write(response.content)55 print("Downloaded hubert base model file successfully. File saved to ./hubert_base.pt.")56 else:57 raise Exception("Failed to download hubert base model file. Status code: " + str(response.status_code) + ".")58 59 # Download rmvpe model if not present60 if not os.path.isfile('./rmvpe.pt'):61 response = requests.get('https://drive.usercontent.google.com/download?id=1Hkn4kNuVFRCNQwyxQFRtmzmMBGpQxptI&export=download&authuser=0&confirm=t&uuid=0b3a40de-465b-4c65-8c41-135b0b45c3f7&at=APZUnTV3lA3LnyTbeuduura6Dmi2:1693724254058')62 63 if response.status_code == 200:64 with open('./rmvpe.pt', 'wb') as f:65 f.write(response.content)66 print("Downloaded rmvpe model file successfully. File saved to ./rmvpe.pt.")67 else:68 raise Exception("Failed to download rmvpe model file. Status code: " + str(response.status_code) + ".")69 70download_models()71 72print("\n-------------------------------\nRVC v2 Easy GUI (Local Edition)\n-------------------------------\n")73 74def formant_apply(qfrency, tmbre):75 Quefrency = qfrency76 Timbre = tmbre77 DoFormant = True78 CSVutil('csvdb/formanting.csv', 'w+', 'formanting', DoFormant, qfrency, tmbre)79 80 return ({"value": Quefrency, "__type__": "update"}, {"value": Timbre, "__type__": "update"})81 82def get_fshift_presets():83 fshift_presets_list = []84 for dirpath, _, filenames in os.walk("./formantshiftcfg/"):85 for filename in filenames:86 if filename.endswith(".txt"):87 fshift_presets_list.append(os.path.join(dirpath,filename).replace('\\','/'))88 89 if len(fshift_presets_list) > 0:90 return fshift_presets_list91 else:92 return ''93 94 95 96def formant_enabled(cbox, qfrency, tmbre, frmntapply, formantpreset, formant_refresh_button):97 98 if (cbox):99 100 DoFormant = True101 CSVutil('csvdb/formanting.csv', 'w+', 'formanting', DoFormant, qfrency, tmbre)102 #print(f"is checked? - {cbox}\ngot {DoFormant}")103 104 return (105 {"value": True, "__type__": "update"},106 {"visible": True, "__type__": "update"},107 {"visible": True, "__type__": "update"},108 {"visible": True, "__type__": "update"},109 {"visible": True, "__type__": "update"},110 {"visible": True, "__type__": "update"},111 )112 113 114 else:115 116 DoFormant = False117 CSVutil('csvdb/formanting.csv', 'w+', 'formanting', DoFormant, qfrency, tmbre)118 119 #print(f"is checked? - {cbox}\ngot {DoFormant}")120 return (121 {"value": False, "__type__": "update"},122 {"visible": False, "__type__": "update"},123 {"visible": False, "__type__": "update"},124 {"visible": False, "__type__": "update"},125 {"visible": False, "__type__": "update"},126 {"visible": False, "__type__": "update"},127 {"visible": False, "__type__": "update"},128 )129 130 131 132def preset_apply(preset, qfer, tmbr):133 if str(preset) != '':134 with open(str(preset), 'r') as p:135 content = p.readlines()136 qfer, tmbr = content[0].split('\n')[0], content[1]137 138 formant_apply(qfer, tmbr)139 else:140 pass141 return ({"value": qfer, "__type__": "update"}, {"value": tmbr, "__type__": "update"})142 143def update_fshift_presets(preset, qfrency, tmbre):144 145 qfrency, tmbre = preset_apply(preset, qfrency, tmbre)146 147 if (str(preset) != ''):148 with open(str(preset), 'r') as p:149 content = p.readlines()150 qfrency, tmbre = content[0].split('\n')[0], content[1]151 152 formant_apply(qfrency, tmbre)153 else:154 pass155 return (156 {"choices": get_fshift_presets(), "__type__": "update"},157 {"value": qfrency, "__type__": "update"},158 {"value": tmbre, "__type__": "update"},159 )160 161i18n = I18nAuto()162#i18n.print()163# 判断是否有能用来训练和加速推理的N卡164ngpu = torch.cuda.device_count()165gpu_infos = []166mem = []167if (not torch.cuda.is_available()) or ngpu == 0:168 if_gpu_ok = False169else:170 if_gpu_ok = False171 for i in range(ngpu):172 gpu_name = torch.cuda.get_device_name(i)173 if (174 "10" in gpu_name175 or "16" in gpu_name176 or "20" in gpu_name177 or "30" in gpu_name178 or "40" in gpu_name179 or "A2" in gpu_name.upper()180 or "A3" in gpu_name.upper()181 or "A4" in gpu_name.upper()182 or "P4" in gpu_name.upper()183 or "A50" in gpu_name.upper()184 or "A60" in gpu_name.upper()185 or "70" in gpu_name186 or "80" in gpu_name187 or "90" in gpu_name188 or "M4" in gpu_name.upper()189 or "T4" in gpu_name.upper()190 or "TITAN" in gpu_name.upper()191 ): # A10#A100#V100#A40#P40#M40#K80#A4500192 if_gpu_ok = True # 至少有一张能用的N卡193 gpu_infos.append("%s\t%s" % (i, gpu_name))194 mem.append(195 int(196 torch.cuda.get_device_properties(i).total_memory197 / 1024198 / 1024199 / 1024200 + 0.4201 )202 )203if if_gpu_ok == True and len(gpu_infos) > 0:204 gpu_info = "\n".join(gpu_infos)205 default_batch_size = min(mem) // 2206else:207 gpu_info = i18n("很遗憾您这没有能用的显卡来支持您训练")208 default_batch_size = 1209gpus = "-".join([i[0] for i in gpu_infos])210from lib.infer_pack.models import (211 SynthesizerTrnMs256NSFsid,212 SynthesizerTrnMs256NSFsid_nono,213 SynthesizerTrnMs768NSFsid,214 SynthesizerTrnMs768NSFsid_nono,215)216import soundfile as sf217from fairseq import checkpoint_utils218import gradio as gr219import logging220from vc_infer_pipeline import VC221from config import Config222 223config = Config()224# from trainset_preprocess_pipeline import PreProcess225logging.getLogger("numba").setLevel(logging.WARNING)226 227hubert_model = None228 229def load_hubert():230 global hubert_model231 models, _, _ = checkpoint_utils.load_model_ensemble_and_task(232 ["hubert_base.pt"],233 suffix="",234 )235 hubert_model = models[0]236 hubert_model = hubert_model.to(config.device)237 if config.is_half:238 hubert_model = hubert_model.half()239 else:240 hubert_model = hubert_model.float()241 hubert_model.eval()242 243 244weight_root = "weights"245index_root = "logs"246names = []247for name in os.listdir(weight_root):248 if name.endswith(".pth"):249 names.append(name)250index_paths = []251for root, dirs, files in os.walk(index_root, topdown=False):252 for name in files:253 if name.endswith(".index") and "trained" not in name:254 index_paths.append("%s/%s" % (root, name))255 256 257 258def vc_single(259 sid,260 input_audio_path,261 f0_up_key,262 f0_file,263 f0_method,264 file_index,265 #file_index2,266 # file_big_npy,267 index_rate,268 filter_radius,269 resample_sr,270 rms_mix_rate,271 protect,272 crepe_hop_length,273): # spk_item, input_audio0, vc_transform0,f0_file,f0method0274 global tgt_sr, net_g, vc, hubert_model, version275 if input_audio_path is None:276 return "You need to upload an audio", None277 f0_up_key = int(f0_up_key)278 try:279 audio = load_audio(input_audio_path, 16000, DoFormant, Quefrency, Timbre)280 audio_max = np.abs(audio).max() / 0.95281 if audio_max > 1:282 audio /= audio_max283 times = [0, 0, 0]284 if hubert_model == None:285 load_hubert()286 if_f0 = cpt.get("f0", 1)287 file_index = (288 (289 file_index.strip(" ")290 .strip('"')291 .strip("\n")292 .strip('"')293 .strip(" ")294 .replace("trained", "added")295 )296 ) # 防止小白写错,自动帮他替换掉297 # file_big_npy = (298 # file_big_npy.strip(" ").strip('"').strip("\n").strip('"').strip(" ")299 # )300 audio_opt = vc.pipeline(301 hubert_model,302 net_g,303 sid,304 audio,305 input_audio_path,306 times,307 f0_up_key,308 f0_method,309 file_index,310 # file_big_npy,311 index_rate,312 if_f0,313 filter_radius,314 tgt_sr,315 resample_sr,316 rms_mix_rate,317 version,318 protect,319 crepe_hop_length,320 f0_file=f0_file,321 )322 if resample_sr >= 16000 and tgt_sr != resample_sr:323 tgt_sr = resample_sr324 index_info = (325 "Using index:%s." % file_index326 if os.path.exists(file_index)327 else "Index not used."328 )329 return "Success.\n %s\nTime:\n npy:%ss, f0:%ss, infer:%ss" % (330 index_info,331 times[0],332 times[1],333 times[2],334 ), (tgt_sr, audio_opt)335 except:336 info = traceback.format_exc()337 print(info)338 return info, (None, None)339 340 341def vc_multi(342 sid,343 dir_path,344 opt_root,345 paths,346 f0_up_key,347 f0_method,348 file_index,349 file_index2,350 # file_big_npy,351 index_rate,352 filter_radius,353 resample_sr,354 rms_mix_rate,355 protect,356 format1,357 crepe_hop_length,358):359 try:360 dir_path = (361 dir_path.strip(" ").strip('"').strip("\n").strip('"').strip(" ")362 ) # 防止小白拷路径头尾带了空格和"和回车363 opt_root = opt_root.strip(" ").strip('"').strip("\n").strip('"').strip(" ")364 os.makedirs(opt_root, exist_ok=True)365 try:366 if dir_path != "":367 paths = [os.path.join(dir_path, name) for name in os.listdir(dir_path)]368 else:369 paths = [path.name for path in paths]370 except:371 traceback.print_exc()372 paths = [path.name for path in paths]373 infos = []374 for path in paths:375 info, opt = vc_single(376 sid,377 path,378 f0_up_key,379 None,380 f0_method,381 file_index,382 # file_big_npy,383 index_rate,384 filter_radius,385 resample_sr,386 rms_mix_rate,387 protect,388 crepe_hop_length389 )390 if "Success" in info:391 try:392 tgt_sr, audio_opt = opt393 if format1 in ["wav", "flac"]:394 sf.write(395 "%s/%s.%s" % (opt_root, os.path.basename(path), format1),396 audio_opt,397 tgt_sr,398 )399 else:400 path = "%s/%s.wav" % (opt_root, os.path.basename(path))401 sf.write(402 path,403 audio_opt,404 tgt_sr,405 )406 if os.path.exists(path):407 os.system(408 "ffmpeg -i %s -vn %s -q:a 2 -y"409 % (path, path[:-4] + ".%s" % format1)410 )411 except:412 info += traceback.format_exc()413 infos.append("%s->%s" % (os.path.basename(path), info))414 yield "\n".join(infos)415 yield "\n".join(infos)416 except:417 yield traceback.format_exc()418 419# 一个选项卡全局只能有一个音色420def get_vc(sid):421 global n_spk, tgt_sr, net_g, vc, cpt, version422 if sid == "" or sid == []:423 global hubert_model424 if hubert_model != None: # 考虑到轮询, 需要加个判断看是否 sid 是由有模型切换到无模型的425 print("clean_empty_cache")426 del net_g, n_spk, vc, hubert_model, tgt_sr # ,cpt427 hubert_model = net_g = n_spk = vc = hubert_model = tgt_sr = None428 if torch.cuda.is_available():429 torch.cuda.empty_cache()430 ###楼下不这么折腾清理不干净431 if_f0 = cpt.get("f0", 1)432 version = cpt.get("version", "v1")433 if version == "v1":434 if if_f0 == 1:435 net_g = SynthesizerTrnMs256NSFsid(436 *cpt["config"], is_half=config.is_half437 )438 else:439 net_g = SynthesizerTrnMs256NSFsid_nono(*cpt["config"])440 elif version == "v2":441 if if_f0 == 1:442 net_g = SynthesizerTrnMs768NSFsid(443 *cpt["config"], is_half=config.is_half444 )445 else:446 net_g = SynthesizerTrnMs768NSFsid_nono(*cpt["config"])447 del net_g, cpt448 if torch.cuda.is_available():449 torch.cuda.empty_cache()450 cpt = None451 return {"visible": False, "__type__": "update"}452 person = "%s/%s" % (weight_root, sid)453 print("loading %s" % person)454 cpt = torch.load(person, map_location="cpu")455 tgt_sr = cpt["config"][-1]456 cpt["config"][-3] = cpt["weight"]["emb_g.weight"].shape[0] # n_spk457 if_f0 = cpt.get("f0", 1)458 version = cpt.get("version", "v1")459 if version == "v1":460 if if_f0 == 1:461 net_g = SynthesizerTrnMs256NSFsid(*cpt["config"], is_half=config.is_half)462 else:463 net_g = SynthesizerTrnMs256NSFsid_nono(*cpt["config"])464 elif version == "v2":465 if if_f0 == 1:466 net_g = SynthesizerTrnMs768NSFsid(*cpt["config"], is_half=config.is_half)467 else:468 net_g = SynthesizerTrnMs768NSFsid_nono(*cpt["config"])469 del net_g.enc_q470 print(net_g.load_state_dict(cpt["weight"], strict=False))471 net_g.eval().to(config.device)472 if config.is_half:473 net_g = net_g.half()474 else:475 net_g = net_g.float()476 vc = VC(tgt_sr, config)477 n_spk = cpt["config"][-3]478 return {"visible": False, "maximum": n_spk, "__type__": "update"}479 480 481def change_choices():482 names = []483 for name in os.listdir(weight_root):484 if name.endswith(".pth"):485 names.append(name)486 index_paths = []487 for root, dirs, files in os.walk(index_root, topdown=False):488 for name in files:489 if name.endswith(".index") and "trained" not in name:490 index_paths.append("%s/%s" % (root, name))491 return {"choices": sorted(names), "__type__": "update"}, {492 "choices": sorted(index_paths),493 "__type__": "update",494 }495 496 497def clean():498 return {"value": "", "__type__": "update"}499 500 501sr_dict = {502 "32k": 32000,503 "40k": 40000,504 "48k": 48000,505}506 507 508def if_done(done, p):509 while 1:510 if p.poll() == None:511 sleep(0.5)512 else:513 break514 done[0] = True515 516 517def if_done_multi(done, ps):518 while 1:519 # poll==None代表进程未结束520 # 只要有一个进程未结束都不停521 flag = 1522 for p in ps:523 if p.poll() == None:524 flag = 0525 sleep(0.5)526 break527 if flag == 1:528 break529 done[0] = True530 531 532def preprocess_dataset(trainset_dir, exp_dir, sr, n_p):533 sr = sr_dict[sr]534 os.makedirs("%s/logs/%s" % (now_dir, exp_dir), exist_ok=True)535 f = open("%s/logs/%s/preprocess.log" % (now_dir, exp_dir), "w")536 f.close()537 cmd = (538 config.python_cmd539 + " trainset_preprocess_pipeline_print.py %s %s %s %s/logs/%s "540 % (trainset_dir, sr, n_p, now_dir, exp_dir)541 + str(config.noparallel)542 )543 print(cmd)544 p = Popen(cmd, shell=True) # , stdin=PIPE, stdout=PIPE,stderr=PIPE,cwd=now_dir545 ###煞笔gr, popen read都非得全跑完了再一次性读取, 不用gr就正常读一句输出一句;只能额外弄出一个文本流定时读546 done = [False]547 threading.Thread(548 target=if_done,549 args=(550 done,551 p,552 ),553 ).start()554 while 1:555 with open("%s/logs/%s/preprocess.log" % (now_dir, exp_dir), "r") as f:556 yield (f.read())557 sleep(1)558 if done[0] == True:559 break560 with open("%s/logs/%s/preprocess.log" % (now_dir, exp_dir), "r") as f:561 log = f.read()562 print(log)563 yield log564 565# but2.click(extract_f0,[gpus6,np7,f0method8,if_f0_3,trainset_dir4],[info2])566def extract_f0_feature(gpus, n_p, f0method, if_f0, exp_dir, version19, echl):567 gpus = gpus.split("-")568 os.makedirs("%s/logs/%s" % (now_dir, exp_dir), exist_ok=True)569 f = open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "w")570 f.close()571 if if_f0:572 cmd = config.python_cmd + " extract_f0_print.py %s/logs/%s %s %s %s" % (573 now_dir,574 exp_dir,575 n_p,576 f0method,577 echl,578 )579 print(cmd)580 p = Popen(cmd, shell=True, cwd=now_dir) # , stdin=PIPE, stdout=PIPE,stderr=PIPE581 ###煞笔gr, popen read都非得全跑完了再一次性读取, 不用gr就正常读一句输出一句;只能额外弄出一个文本流定时读582 done = [False]583 threading.Thread(584 target=if_done,585 args=(586 done,587 p,588 ),589 ).start()590 while 1:591 with open(592 "%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "r"593 ) as f:594 yield (f.read())595 sleep(1)596 if done[0] == True:597 break598 with open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "r") as f:599 log = f.read()600 print(log)601 yield log602 ####对不同part分别开多进程603 """604 n_part=int(sys.argv[1])605 i_part=int(sys.argv[2])606 i_gpu=sys.argv[3]607 exp_dir=sys.argv[4]608 os.environ["CUDA_VISIBLE_DEVICES"]=str(i_gpu)609 """610 leng = len(gpus)611 ps = []612 for idx, n_g in enumerate(gpus):613 cmd = (614 config.python_cmd615 + " extract_feature_print.py %s %s %s %s %s/logs/%s %s"616 % (617 config.device,618 leng,619 idx,620 n_g,621 now_dir,622 exp_dir,623 version19,624 )625 )626 print(cmd)627 p = Popen(628 cmd, shell=True, cwd=now_dir629 ) # , shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=now_dir630 ps.append(p)631 ###煞笔gr, popen read都非得全跑完了再一次性读取, 不用gr就正常读一句输出一句;只能额外弄出一个文本流定时读632 done = [False]633 threading.Thread(634 target=if_done_multi,635 args=(636 done,637 ps,638 ),639 ).start()640 while 1:641 with open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "r") as f:642 yield (f.read())643 sleep(1)644 if done[0] == True:645 break646 with open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "r") as f:647 log = f.read()648 print(log)649 yield log650 651 652def change_sr2(sr2, if_f0_3, version19):653 path_str = "" if version19 == "v1" else "_v2"654 f0_str = "f0" if if_f0_3 else ""655 if_pretrained_generator_exist = os.access("pretrained%s/%sG%s.pth" % (path_str, f0_str, sr2), os.F_OK)656 if_pretrained_discriminator_exist = os.access("pretrained%s/%sD%s.pth" % (path_str, f0_str, sr2), os.F_OK)657 if (if_pretrained_generator_exist == False):658 print("pretrained%s/%sG%s.pth" % (path_str, f0_str, sr2), "not exist, will not use pretrained model")659 if (if_pretrained_discriminator_exist == False):660 print("pretrained%s/%sD%s.pth" % (path_str, f0_str, sr2), "not exist, will not use pretrained model")661 return (662 ("pretrained%s/%sG%s.pth" % (path_str, f0_str, sr2)) if if_pretrained_generator_exist else "",663 ("pretrained%s/%sD%s.pth" % (path_str, f0_str, sr2)) if if_pretrained_discriminator_exist else "",664 {"visible": True, "__type__": "update"}665 )666 667def change_version19(sr2, if_f0_3, version19):668 path_str = "" if version19 == "v1" else "_v2"669 f0_str = "f0" if if_f0_3 else ""670 if_pretrained_generator_exist = os.access("pretrained%s/%sG%s.pth" % (path_str, f0_str, sr2), os.F_OK)671 if_pretrained_discriminator_exist = os.access("pretrained%s/%sD%s.pth" % (path_str, f0_str, sr2), os.F_OK)672 if (if_pretrained_generator_exist == False):673 print("pretrained%s/%sG%s.pth" % (path_str, f0_str, sr2), "not exist, will not use pretrained model")674 if (if_pretrained_discriminator_exist == False):675 print("pretrained%s/%sD%s.pth" % (path_str, f0_str, sr2), "not exist, will not use pretrained model")676 return (677 ("pretrained%s/%sG%s.pth" % (path_str, f0_str, sr2)) if if_pretrained_generator_exist else "",678 ("pretrained%s/%sD%s.pth" % (path_str, f0_str, sr2)) if if_pretrained_discriminator_exist else "",679 )680 681 682def change_f0(if_f0_3, sr2, version19): # f0method8,pretrained_G14,pretrained_D15683 path_str = "" if version19 == "v1" else "_v2"684 if_pretrained_generator_exist = os.access("pretrained%s/f0G%s.pth" % (path_str, sr2), os.F_OK)685 if_pretrained_discriminator_exist = os.access("pretrained%s/f0D%s.pth" % (path_str, sr2), os.F_OK)686 if (if_pretrained_generator_exist == False):687 print("pretrained%s/f0G%s.pth" % (path_str, sr2), "not exist, will not use pretrained model")688 if (if_pretrained_discriminator_exist == False):689 print("pretrained%s/f0D%s.pth" % (path_str, sr2), "not exist, will not use pretrained model")690 if if_f0_3:691 return (692 {"visible": True, "__type__": "update"},693 "pretrained%s/f0G%s.pth" % (path_str, sr2) if if_pretrained_generator_exist else "",694 "pretrained%s/f0D%s.pth" % (path_str, sr2) if if_pretrained_discriminator_exist else "",695 )696 return (697 {"visible": False, "__type__": "update"},698 ("pretrained%s/G%s.pth" % (path_str, sr2)) if if_pretrained_generator_exist else "",699 ("pretrained%s/D%s.pth" % (path_str, sr2)) if if_pretrained_discriminator_exist else "",700 )701 702 703global log_interval704 705 706def set_log_interval(exp_dir, batch_size12):707 log_interval = 1708 709 folder_path = os.path.join(exp_dir, "1_16k_wavs")710 711 if os.path.exists(folder_path) and os.path.isdir(folder_path):712 wav_files = [f for f in os.listdir(folder_path) if f.endswith(".wav")]713 if wav_files:714 sample_size = len(wav_files)715 log_interval = math.ceil(sample_size / batch_size12)716 if log_interval > 1:717 log_interval += 1718 return log_interval719 720# but3.click(click_train,[exp_dir1,sr2,if_f0_3,save_epoch10,total_epoch11,batch_size12,if_save_latest13,pretrained_G14,pretrained_D15,gpus16])721def click_train(722 exp_dir1,723 sr2,724 if_f0_3,725 spk_id5,726 save_epoch10,727 total_epoch11,728 batch_size12,729 if_save_latest13,730 pretrained_G14,731 pretrained_D15,732 gpus16,733 if_cache_gpu17,734 if_save_every_weights18,735 version19,736):737 CSVutil('csvdb/stop.csv', 'w+', 'formanting', False)738 # 生成filelist739 exp_dir = "%s/logs/%s" % (now_dir, exp_dir1)740 os.makedirs(exp_dir, exist_ok=True)741 gt_wavs_dir = "%s/0_gt_wavs" % (exp_dir)742 feature_dir = (743 "%s/3_feature256" % (exp_dir)744 if version19 == "v1"745 else "%s/3_feature768" % (exp_dir)746 )747 748 log_interval = set_log_interval(exp_dir, batch_size12)749 750 if if_f0_3:751 f0_dir = "%s/2a_f0" % (exp_dir)752 f0nsf_dir = "%s/2b-f0nsf" % (exp_dir)753 names = (754 set([name.split(".")[0] for name in os.listdir(gt_wavs_dir)])755 & set([name.split(".")[0] for name in os.listdir(feature_dir)])756 & set([name.split(".")[0] for name in os.listdir(f0_dir)])757 & set([name.split(".")[0] for name in os.listdir(f0nsf_dir)])758 )759 else:760 names = set([name.split(".")[0] for name in os.listdir(gt_wavs_dir)]) & set(761 [name.split(".")[0] for name in os.listdir(feature_dir)]762 )763 opt = []764 for name in names:765 if if_f0_3:766 opt.append(767 "%s/%s.wav|%s/%s.npy|%s/%s.wav.npy|%s/%s.wav.npy|%s"768 % (769 gt_wavs_dir.replace("\\", "\\\\"),770 name,771 feature_dir.replace("\\", "\\\\"),772 name,773 f0_dir.replace("\\", "\\\\"),774 name,775 f0nsf_dir.replace("\\", "\\\\"),776 name,777 spk_id5,778 )779 )780 else:781 opt.append(782 "%s/%s.wav|%s/%s.npy|%s"783 % (784 gt_wavs_dir.replace("\\", "\\\\"),785 name,786 feature_dir.replace("\\", "\\\\"),787 name,788 spk_id5,789 )790 )791 fea_dim = 256 if version19 == "v1" else 768792 if if_f0_3:793 for _ in range(2):794 opt.append(795 "%s/logs/mute/0_gt_wavs/mute%s.wav|%s/logs/mute/3_feature%s/mute.npy|%s/logs/mute/2a_f0/mute.wav.npy|%s/logs/mute/2b-f0nsf/mute.wav.npy|%s"796 % (now_dir, sr2, now_dir, fea_dim, now_dir, now_dir, spk_id5)797 )798 else:799 for _ in range(2):800 opt.append(801 "%s/logs/mute/0_gt_wavs/mute%s.wav|%s/logs/mute/3_feature%s/mute.npy|%s"802 % (now_dir, sr2, now_dir, fea_dim, spk_id5)803 )804 shuffle(opt)805 with open("%s/filelist.txt" % exp_dir, "w") as f:806 f.write("\n".join(opt))807 print("write filelist done")808 # 生成config#无需生成config809 # cmd = python_cmd + " train_nsf_sim_cache_sid_load_pretrain.py -e mi-test -sr 40k -f0 1 -bs 4 -g 0 -te 10 -se 5 -pg pretrained/f0G40k.pth -pd pretrained/f0D40k.pth -l 1 -c 0"810 print("use gpus:", gpus16)811 if pretrained_G14 == "":812 print("no pretrained Generator")813 if pretrained_D15 == "":814 print("no pretrained Discriminator")815 if gpus16:816 cmd = (817 config.python_cmd818 + " train_nsf_sim_cache_sid_load_pretrain.py -e %s -sr %s -f0 %s -bs %s -g %s -te %s -se %s %s %s -l %s -c %s -sw %s -v %s -li %s"819 % (820 exp_dir1,821 sr2,822 1 if if_f0_3 else 0,823 batch_size12,824 gpus16,825 total_epoch11,826 save_epoch10,827 ("-pg %s" % pretrained_G14) if pretrained_G14 != "" else "",828 ("-pd %s" % pretrained_D15) if pretrained_D15 != "" else "",829 1 if if_save_latest13 == True else 0,830 1 if if_cache_gpu17 == True else 0,831 1 if if_save_every_weights18 == True else 0,832 version19,833 log_interval,834 )835 )836 else:837 cmd = (838 config.python_cmd839 + " train_nsf_sim_cache_sid_load_pretrain.py -e %s -sr %s -f0 %s -bs %s -te %s -se %s %s %s -l %s -c %s -sw %s -v %s -li %s"840 % (841 exp_dir1,842 sr2,843 1 if if_f0_3 else 0,844 batch_size12,845 total_epoch11,846 save_epoch10,847 ("-pg %s" % pretrained_G14) if pretrained_G14 != "" else "\b",848 ("-pd %s" % pretrained_D15) if pretrained_D15 != "" else "\b",849 1 if if_save_latest13 == True else 0,850 1 if if_cache_gpu17 == True else 0,851 1 if if_save_every_weights18 == True else 0,852 version19,853 log_interval,854 )855 )856 print(cmd)857 p = Popen(cmd, shell=True, cwd=now_dir)858 global PID859 PID = p.pid860 p.wait()861 return ("训练结束, 您可查看控制台训练日志或实验文件夹下的train.log", {"visible": False, "__type__": "update"}, {"visible": True, "__type__": "update"})862 863 864# but4.click(train_index, [exp_dir1], info3)865def train_index(exp_dir1, version19):866 exp_dir = "%s/logs/%s" % (now_dir, exp_dir1)867 os.makedirs(exp_dir, exist_ok=True)868 feature_dir = (869 "%s/3_feature256" % (exp_dir)870 if version19 == "v1"871 else "%s/3_feature768" % (exp_dir)872 )873 if os.path.exists(feature_dir) == False:874 return "请先进行特征提取!"875 listdir_res = list(os.listdir(feature_dir))876 if len(listdir_res) == 0:877 return "请先进行特征提取!"878 npys = []879 for name in sorted(listdir_res):880 phone = np.load("%s/%s" % (feature_dir, name))881 npys.append(phone)882 big_npy = np.concatenate(npys, 0)883 big_npy_idx = np.arange(big_npy.shape[0])884 np.random.shuffle(big_npy_idx)885 big_npy = big_npy[big_npy_idx]886 np.save("%s/total_fea.npy" % exp_dir, big_npy)887 # n_ivf = big_npy.shape[0] // 39888 n_ivf = min(int(16 * np.sqrt(big_npy.shape[0])), big_npy.shape[0] // 39)889 infos = []890 infos.append("%s,%s" % (big_npy.shape, n_ivf))891 yield "\n".join(infos)892 index = faiss.index_factory(256 if version19 == "v1" else 768, "IVF%s,Flat" % n_ivf)893 # index = faiss.index_factory(256if version19=="v1"else 768, "IVF%s,PQ128x4fs,RFlat"%n_ivf)894 infos.append("training")895 yield "\n".join(infos)896 index_ivf = faiss.extract_index_ivf(index) #897 index_ivf.nprobe = 1898 index.train(big_npy)899 faiss.write_index(900 index,901 "%s/trained_IVF%s_Flat_nprobe_%s_%s_%s.index"902 % (exp_dir, n_ivf, index_ivf.nprobe, exp_dir1, version19),903 )904 # faiss.write_index(index, '%s/trained_IVF%s_Flat_FastScan_%s.index'%(exp_dir,n_ivf,version19))905 infos.append("adding")906 yield "\n".join(infos)907 batch_size_add = 8192908 for i in range(0, big_npy.shape[0], batch_size_add):909 index.add(big_npy[i : i + batch_size_add])910 faiss.write_index(911 index,912 "%s/added_IVF%s_Flat_nprobe_%s_%s_%s.index"913 % (exp_dir, n_ivf, index_ivf.nprobe, exp_dir1, version19),914 )915 infos.append(916 "成功构建索引,added_IVF%s_Flat_nprobe_%s_%s_%s.index"917 % (n_ivf, index_ivf.nprobe, exp_dir1, version19)918 )919 # faiss.write_index(index, '%s/added_IVF%s_Flat_FastScan_%s.index'%(exp_dir,n_ivf,version19))920 # infos.append("成功构建索引,added_IVF%s_Flat_FastScan_%s.index"%(n_ivf,version19))921 yield "\n".join(infos)922 923 924# but5.click(train1key, [exp_dir1, sr2, if_f0_3, trainset_dir4, spk_id5, gpus6, np7, f0method8, save_epoch10, total_epoch11, batch_size12, if_save_latest13, pretrained_G14, pretrained_D15, gpus16, if_cache_gpu17], info3)925def train1key(926 exp_dir1,927 sr2,928 if_f0_3,929 trainset_dir4,930 spk_id5,931 np7,932 f0method8,933 save_epoch10,934 total_epoch11,935 batch_size12,936 if_save_latest13,937 pretrained_G14,938 pretrained_D15,939 gpus16,940 if_cache_gpu17,941 if_save_every_weights18,942 version19,943 echl944):945 infos = []946 947 def get_info_str(strr):948 infos.append(strr)949 return "\n".join(infos)950 951 model_log_dir = "%s/logs/%s" % (now_dir, exp_dir1)952 preprocess_log_path = "%s/preprocess.log" % model_log_dir953 extract_f0_feature_log_path = "%s/extract_f0_feature.log" % model_log_dir954 gt_wavs_dir = "%s/0_gt_wavs" % model_log_dir955 feature_dir = (956 "%s/3_feature256" % model_log_dir957 if version19 == "v1"958 else "%s/3_feature768" % model_log_dir959 )960 961 os.makedirs(model_log_dir, exist_ok=True)962 #########step1:处理数据963 open(preprocess_log_path, "w").close()964 cmd = (965 config.python_cmd966 + " trainset_preprocess_pipeline_print.py %s %s %s %s "967 % (trainset_dir4, sr_dict[sr2], np7, model_log_dir)968 + str(config.noparallel)969 )970 yield get_info_str(i18n("step1:正在处理数据"))971 yield get_info_str(cmd)972 p = Popen(cmd, shell=True)973 p.wait()974 with open(preprocess_log_path, "r") as f:975 print(f.read())976 #########step2a:提取音高977 open(extract_f0_feature_log_path, "w")978 if if_f0_3:979 yield get_info_str("step2a:正在提取音高")980 cmd = config.python_cmd + " extract_f0_print.py %s %s %s %s" % (981 model_log_dir,982 np7,983 f0method8,984 echl985 )986 yield get_info_str(cmd)987 p = Popen(cmd, shell=True, cwd=now_dir)988 p.wait()989 with open(extract_f0_feature_log_path, "r") as f:990 print(f.read())991 else:992 yield get_info_str(i18n("step2a:无需提取音高"))993 #######step2b:提取特征994 yield get_info_str(i18n("step2b:正在提取特征"))995 gpus = gpus16.split("-")996 leng = len(gpus)997 ps = []998 for idx, n_g in enumerate(gpus):999 cmd = config.python_cmd + " extract_feature_print.py %s %s %s %s %s %s" % (1000 config.device,1001 leng,1002 idx,1003 n_g,1004 model_log_dir,1005 version19,1006 )1007 yield get_info_str(cmd)1008 p = Popen(1009 cmd, shell=True, cwd=now_dir1010 ) # , shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=now_dir1011 ps.append(p)1012 for p in ps:1013 p.wait()1014 with open(extract_f0_feature_log_path, "r") as f:1015 print(f.read())1016 #######step3a:训练模型1017 yield get_info_str(i18n("step3a:正在训练模型"))1018 # 生成filelist1019 if if_f0_3:1020 f0_dir = "%s/2a_f0" % model_log_dir1021 f0nsf_dir = "%s/2b-f0nsf" % model_log_dir1022 names = (1023 set([name.split(".")[0] for name in os.listdir(gt_wavs_dir)])1024 & set([name.split(".")[0] for name in os.listdir(feature_dir)])1025 & set([name.split(".")[0] for name in os.listdir(f0_dir)])1026 & set([name.split(".")[0] for name in os.listdir(f0nsf_dir)])1027 )1028 else:1029 names = set([name.split(".")[0] for name in os.listdir(gt_wavs_dir)]) & set(1030 [name.split(".")[0] for name in os.listdir(feature_dir)]1031 )1032 opt = []1033 for name in names:1034 if if_f0_3:1035 opt.append(1036 "%s/%s.wav|%s/%s.npy|%s/%s.wav.npy|%s/%s.wav.npy|%s"1037 % (1038 gt_wavs_dir.replace("\\", "\\\\"),1039 name,1040 feature_dir.replace("\\", "\\\\"),1041 name,1042 f0_dir.replace("\\", "\\\\"),1043 name,1044 f0nsf_dir.replace("\\", "\\\\"),1045 name,1046 spk_id5,1047 )1048 )1049 else:1050 opt.append(1051 "%s/%s.wav|%s/%s.npy|%s"1052 % (1053 gt_wavs_dir.replace("\\", "\\\\"),1054 name,1055 feature_dir.replace("\\", "\\\\"),1056 name,1057 spk_id5,1058 )1059 )1060 fea_dim = 256 if version19 == "v1" else 7681061 if if_f0_3:1062 for _ in range(2):1063 opt.append(1064 "%s/logs/mute/0_gt_wavs/mute%s.wav|%s/logs/mute/3_feature%s/mute.npy|%s/logs/mute/2a_f0/mute.wav.npy|%s/logs/mute/2b-f0nsf/mute.wav.npy|%s"1065 % (now_dir, sr2, now_dir, fea_dim, now_dir, now_dir, spk_id5)1066 )1067 else:1068 for _ in range(2):1069 opt.append(1070 "%s/logs/mute/0_gt_wavs/mute%s.wav|%s/logs/mute/3_feature%s/mute.npy|%s"1071 % (now_dir, sr2, now_dir, fea_dim, spk_id5)1072 )1073 shuffle(opt)1074 with open("%s/filelist.txt" % model_log_dir, "w") as f:1075 f.write("\n".join(opt))1076 yield get_info_str("write filelist done")1077 if gpus16:1078 cmd = (1079 config.python_cmd1080 +" train_nsf_sim_cache_sid_load_pretrain.py -e %s -sr %s -f0 %s -bs %s -g %s -te %s -se %s %s %s -l %s -c %s -sw %s -v %s"1081 % (1082 exp_dir1,1083 sr2,1084 1 if if_f0_3 else 0,1085 batch_size12,1086 gpus16,1087 total_epoch11,1088 save_epoch10,1089 ("-pg %s" % pretrained_G14) if pretrained_G14 != "" else "",1090 ("-pd %s" % pretrained_D15) if pretrained_D15 != "" else "",1091 1 if if_save_latest13 == True else 0,1092 1 if if_cache_gpu17 == True else 0,1093 1 if if_save_every_weights18 == True else 0,1094 version19,1095 )1096 )1097 else:1098 cmd = (1099 config.python_cmd1100 + " train_nsf_sim_cache_sid_load_pretrain.py -e %s -sr %s -f0 %s -bs %s -te %s -se %s %s %s -l %s -c %s -sw %s -v %s"1101 % (1102 exp_dir1,1103 sr2,1104 1 if if_f0_3 else 0,1105 batch_size12,1106 total_epoch11,1107 save_epoch10,1108 ("-pg %s" % pretrained_G14) if pretrained_G14 != "" else "",1109 ("-pd %s" % pretrained_D15) if pretrained_D15 != "" else "",1110 1 if if_save_latest13 == True else 0,1111 1 if if_cache_gpu17 == True else 0,1112 1 if if_save_every_weights18 == True else 0,1113 version19,1114 )1115 )1116 yield get_info_str(cmd)1117 p = Popen(cmd, shell=True, cwd=now_dir)1118 p.wait()1119 yield get_info_str(i18n("训练结束, 您可查看控制台训练日志或实验文件夹下的train.log"))1120 #######step3b:训练索引1121 npys = []1122 listdir_res = list(os.listdir(feature_dir))1123 for name in sorted(listdir_res):1124 phone = np.load("%s/%s" % (feature_dir, name))1125 npys.append(phone)1126 big_npy = np.concatenate(npys, 0)1127 1128 big_npy_idx = np.arange(big_npy.shape[0])1129 np.random.shuffle(big_npy_idx)1130 big_npy = big_npy[big_npy_idx]1131 np.save("%s/total_fea.npy" % model_log_dir, big_npy)1132 1133 # n_ivf = big_npy.shape[0] // 391134 n_ivf = min(int(16 * np.sqrt(big_npy.shape[0])), big_npy.shape[0] // 39)1135 yield get_info_str("%s,%s" % (big_npy.shape, n_ivf))1136 index = faiss.index_factory(256 if version19 == "v1" else 768, "IVF%s,Flat" % n_ivf)1137 yield get_info_str("training index")1138 index_ivf = faiss.extract_index_ivf(index) #1139 index_ivf.nprobe = 11140 index.train(big_npy)1141 faiss.write_index(1142 index,1143 "%s/trained_IVF%s_Flat_nprobe_%s_%s_%s.index"1144 % (model_log_dir, n_ivf, index_ivf.nprobe, exp_dir1, version19),1145 )1146 yield get_info_str("adding index")1147 batch_size_add = 81921148 for i in range(0, big_npy.shape[0], batch_size_add):1149 index.add(big_npy[i : i + batch_size_add])1150 faiss.write_index(1151 index,1152 "%s/added_IVF%s_Flat_nprobe_%s_%s_%s.index"1153 % (model_log_dir, n_ivf, index_ivf.nprobe, exp_dir1, version19),1154 )1155 yield get_info_str(1156 "成功构建索引, added_IVF%s_Flat_nprobe_%s_%s_%s.index"1157 % (n_ivf, index_ivf.nprobe, exp_dir1, version19)1158 )1159 yield get_info_str(i18n("全流程结束!"))1160 1161 1162def whethercrepeornah(radio):1163 mango = True if radio == 'mangio-crepe' or radio == 'mangio-crepe-tiny' else False1164 return ({"visible": mango, "__type__": "update"})1165 1166# ckpt_path2.change(change_info_,[ckpt_path2],[sr__,if_f0__])1167def change_info_(ckpt_path):1168 if (1169 os.path.exists(ckpt_path.replace(os.path.basename(ckpt_path), "train.log"))1170 == False1171 ):1172 return {"__type__": "update"}, {"__type__": "update"}, {"__type__": "update"}1173 try:1174 with open(1175 ckpt_path.replace(os.path.basename(ckpt_path), "train.log"), "r"1176 ) as f:1177 info = eval(f.read().strip("\n").split("\n")[0].split("\t")[-1])1178 sr, f0 = info["sample_rate"], info["if_f0"]1179 version = "v2" if ("version" in info and info["version"] == "v2") else "v1"1180 return sr, str(f0), version1181 except:1182 traceback.print_exc()1183 return {"__type__": "update"}, {"__type__": "update"}, {"__type__": "update"}1184 1185 1186from lib.infer_pack.models_onnx import SynthesizerTrnMsNSFsidM1187 1188 1189def export_onnx(ModelPath, ExportedPath, MoeVS=True):1190 cpt = torch.load(ModelPath, map_location="cpu")1191 cpt["config"][-3] = cpt["weight"]["emb_g.weight"].shape[0] # n_spk1192 hidden_channels = 256 if cpt.get("version","v1")=="v1"else 768#cpt["config"][-2] # hidden_channels,为768Vec做准备1193 1194 test_phone = torch.rand(1, 200, hidden_channels) # hidden unit1195 test_phone_lengths = torch.tensor([200]).long() # hidden unit 长度(貌似没啥用)1196 test_pitch = torch.randint(size=(1, 200), low=5, high=255) # 基频(单位赫兹)1197 test_pitchf = torch.rand(1, 200) # nsf基频1198 test_ds = torch.LongTensor([0]) # 说话人ID1199 test_rnd = torch.rand(1, 192, 200) # 噪声(加入随机因子)1200 