CoolFace
Apppublic

ChazzyG/Retrieval-based-Voice-Conversion-WebUI

sourceHugging Faceapache-2.0updated 9mo agoView on Hugging Face
0likes
infer-web.py1548 linesDownload Raw Back to root
1from multiprocessing import cpu_count2import threading, pdb, librosa3from time import sleep4from subprocess import Popen5from time import sleep6import torch, os, traceback, sys, warnings, shutil, numpy as np7import faiss8from random import shuffle9 10now_dir = os.getcwd()11sys.path.append(now_dir)12tmp = os.path.join(now_dir, "TEMP")13shutil.rmtree(tmp, ignore_errors=True)14os.makedirs(tmp, exist_ok=True)15os.makedirs(os.path.join(now_dir, "logs"), exist_ok=True)16os.makedirs(os.path.join(now_dir, "weights"), exist_ok=True)17os.environ["TEMP"] = tmp18warnings.filterwarnings("ignore")19torch.manual_seed(114514)20from i18n import I18nAuto21import ffmpeg22 23i18n = I18nAuto()24# 判断是否有能用来训练和加速推理的N卡25ncpu = cpu_count()26ngpu = torch.cuda.device_count()27gpu_infos = []28mem = []29if (not torch.cuda.is_available()) or ngpu == 0:30    if_gpu_ok = False31else:32    if_gpu_ok = False33    for i in range(ngpu):34        gpu_name = torch.cuda.get_device_name(i)35        if (36            "10" in gpu_name37            or "16" in gpu_name38            or "20" in gpu_name39            or "30" in gpu_name40            or "40" in gpu_name41            or "A2" in gpu_name.upper()42            or "A3" in gpu_name.upper()43            or "A4" in gpu_name.upper()44            or "P4" in gpu_name.upper()45            or "A50" in gpu_name.upper()46            or "70" in gpu_name47            or "80" in gpu_name48            or "90" in gpu_name49            or "M4" in gpu_name.upper()50            or "T4" in gpu_name.upper()51            or "TITAN" in gpu_name.upper()52        ):  # A10#A100#V100#A40#P40#M40#K80#A450053            if_gpu_ok = True  # 至少有一张能用的N卡54            gpu_infos.append("%s\t%s" % (i, gpu_name))55            mem.append(56                int(57                    torch.cuda.get_device_properties(i).total_memory58                    / 102459                    / 102460                    / 102461                    + 0.462                )63            )64if if_gpu_ok == True and len(gpu_infos) > 0:65    gpu_info = "\n".join(gpu_infos)66    default_batch_size = min(mem) // 267else:68    gpu_info = i18n("很遗憾您这没有能用的显卡来支持您训练")69    default_batch_size = 170gpus = "-".join([i[0] for i in gpu_infos])71from infer_pack.models import SynthesizerTrnMs256NSFsid, SynthesizerTrnMs256NSFsid_nono72from scipy.io import wavfile73from fairseq import checkpoint_utils74import gradio as gr75import logging76from vc_infer_pipeline import VC77from config import Config78from infer_uvr5 import _audio_pre_79from my_utils import load_audio80from train.process_ckpt import show_info, change_info, merge, extract_small_model81 82config = Config()83# from trainset_preprocess_pipeline import PreProcess84logging.getLogger("numba").setLevel(logging.WARNING)85 86 87class ToolButton(gr.Button, gr.components.FormComponent):88    """Small button with single emoji as text, fits inside gradio forms"""89 90    def __init__(self, **kwargs):91        super().__init__(variant="tool", **kwargs)92 93    def get_block_name(self):94        return "button"95 96 97hubert_model = None98 99 100def load_hubert():101    global hubert_model102    models, _, _ = checkpoint_utils.load_model_ensemble_and_task(103        ["hubert_base.pt"],104        suffix="",105    )106    hubert_model = models[0]107    hubert_model = hubert_model.to(config.device)108    if config.is_half:109        hubert_model = hubert_model.half()110    else:111        hubert_model = hubert_model.float()112    hubert_model.eval()113 114 115weight_root = "weights"116weight_uvr5_root = "uvr5_weights"117names = []118for name in os.listdir(weight_root):119    if name.endswith(".pth"):120        names.append(name)121uvr5_names = []122for name in os.listdir(weight_uvr5_root):123    if name.endswith(".pth"):124        uvr5_names.append(name.replace(".pth", ""))125 126 127def vc_single(128    sid,129    input_audio,130    f0_up_key,131    f0_file,132    f0_method,133    file_index,134    # file_big_npy,135    index_rate,136):  # spk_item, input_audio0, vc_transform0,f0_file,f0method0137    global tgt_sr, net_g, vc, hubert_model138    if input_audio is None:139        return "You need to upload an audio", None140    f0_up_key = int(f0_up_key)141    try:142        audio = load_audio(input_audio, 16000)143        times = [0, 0, 0]144        if hubert_model == None:145            load_hubert()146        if_f0 = cpt.get("f0", 1)147        file_index = (148            file_index.strip(" ")149            .strip('"')150            .strip("\n")151            .strip('"')152            .strip(" ")153            .replace("trained", "added")154        )  # 防止小白写错,自动帮他替换掉155        # file_big_npy = (156        #     file_big_npy.strip(" ").strip('"').strip("\n").strip('"').strip(" ")157        # )158        audio_opt = vc.pipeline(159            hubert_model,160            net_g,161            sid,162            audio,163            times,164            f0_up_key,165            f0_method,166            file_index,167            # file_big_npy,168            index_rate,169            if_f0,170            f0_file=f0_file,171        )172        print(173            "npy: ", times[0], "s, f0: ", times[1], "s, infer: ", times[2], "s", sep=""174        )175        return "Success", (tgt_sr, audio_opt)176    except:177        info = traceback.format_exc()178        print(info)179        return info, (None, None)180 181 182def vc_multi(183    sid,184    dir_path,185    opt_root,186    paths,187    f0_up_key,188    f0_method,189    file_index,190    # file_big_npy,191    index_rate,192):193    try:194        dir_path = (195            dir_path.strip(" ").strip('"').strip("\n").strip('"').strip(" ")196        )  # 防止小白拷路径头尾带了空格和"和回车197        opt_root = opt_root.strip(" ").strip('"').strip("\n").strip('"').strip(" ")198        os.makedirs(opt_root, exist_ok=True)199        try:200            if dir_path != "":201                paths = [os.path.join(dir_path, name) for name in os.listdir(dir_path)]202            else:203                paths = [path.name for path in paths]204        except:205            traceback.print_exc()206            paths = [path.name for path in paths]207        infos = []208        file_index = (209            file_index.strip(" ")210            .strip('"')211            .strip("\n")212            .strip('"')213            .strip(" ")214            .replace("trained", "added")215        )  # 防止小白写错,自动帮他替换掉216        for path in paths:217            info, opt = vc_single(218                sid,219                path,220                f0_up_key,221                None,222                f0_method,223                file_index,224                # file_big_npy,225                index_rate,226            )227            if info == "Success":228                try:229                    tgt_sr, audio_opt = opt230                    wavfile.write(231                        "%s/%s" % (opt_root, os.path.basename(path)), tgt_sr, audio_opt232                    )233                except:234                    info = traceback.format_exc()235            infos.append("%s->%s" % (os.path.basename(path), info))236            yield "\n".join(infos)237        yield "\n".join(infos)238    except:239        yield traceback.format_exc()240 241 242def uvr(model_name, inp_root, save_root_vocal, paths, save_root_ins, agg):243    infos = []244    try:245        inp_root = inp_root.strip(" ").strip('"').strip("\n").strip('"').strip(" ")246        save_root_vocal = (247            save_root_vocal.strip(" ").strip('"').strip("\n").strip('"').strip(" ")248        )249        save_root_ins = (250            save_root_ins.strip(" ").strip('"').strip("\n").strip('"').strip(" ")251        )252        pre_fun = _audio_pre_(253            agg=int(agg),254            model_path=os.path.join(weight_uvr5_root, model_name + ".pth"),255            device=config.device,256            is_half=config.is_half,257        )258        if inp_root != "":259            paths = [os.path.join(inp_root, name) for name in os.listdir(inp_root)]260        else:261            paths = [path.name for path in paths]262        for path in paths:263            inp_path = os.path.join(inp_root, path)264            need_reformat = 1265            done = 0266            try:267                info = ffmpeg.probe(inp_path, cmd="ffprobe")268                if (269                    info["streams"][0]["channels"] == 2270                    and info["streams"][0]["sample_rate"] == "44100"271                ):272                    need_reformat = 0273                    pre_fun._path_audio_(inp_path, save_root_ins, save_root_vocal)274                    done = 1275            except:276                need_reformat = 1277                traceback.print_exc()278            if need_reformat == 1:279                tmp_path = "%s/%s.reformatted.wav" % (tmp, os.path.basename(inp_path))280                os.system(281                    "ffmpeg -i %s -vn -acodec pcm_s16le -ac 2 -ar 44100 %s -y"282                    % (inp_path, tmp_path)283                )284                inp_path = tmp_path285            try:286                if done == 0:287                    pre_fun._path_audio_(inp_path, save_root_ins, save_root_vocal)288                infos.append("%s->Success" % (os.path.basename(inp_path)))289                yield "\n".join(infos)290            except:291                infos.append(292                    "%s->%s" % (os.path.basename(inp_path), traceback.format_exc())293                )294                yield "\n".join(infos)295    except:296        infos.append(traceback.format_exc())297        yield "\n".join(infos)298    finally:299        try:300            del pre_fun.model301            del pre_fun302        except:303            traceback.print_exc()304        print("clean_empty_cache")305        if torch.cuda.is_available():306            torch.cuda.empty_cache()307    yield "\n".join(infos)308 309 310# 一个选项卡全局只能有一个音色311def get_vc(sid):312    global n_spk, tgt_sr, net_g, vc, cpt313    if sid == []:314        global hubert_model315        if hubert_model != None:  # 考虑到轮询, 需要加个判断看是否 sid 是由有模型切换到无模型的316            print("clean_empty_cache")317            del net_g, n_spk, vc, hubert_model, tgt_sr  # ,cpt318            hubert_model = net_g = n_spk = vc = hubert_model = tgt_sr = None319            if torch.cuda.is_available():320                torch.cuda.empty_cache()321            ###楼下不这么折腾清理不干净322            if_f0 = cpt.get("f0", 1)323            if if_f0 == 1:324                net_g = SynthesizerTrnMs256NSFsid(325                    *cpt["config"], is_half=config.is_half326                )327            else:328                net_g = SynthesizerTrnMs256NSFsid_nono(*cpt["config"])329            del net_g, cpt330            if torch.cuda.is_available():331                torch.cuda.empty_cache()332            cpt = None333        return {"visible": False, "__type__": "update"}334    person = "%s/%s" % (weight_root, sid)335    print("loading %s" % person)336    cpt = torch.load(person, map_location="cpu")337    tgt_sr = cpt["config"][-1]338    cpt["config"][-3] = cpt["weight"]["emb_g.weight"].shape[0]  # n_spk339    if_f0 = cpt.get("f0", 1)340    if if_f0 == 1:341        net_g = SynthesizerTrnMs256NSFsid(*cpt["config"], is_half=config.is_half)342    else:343        net_g = SynthesizerTrnMs256NSFsid_nono(*cpt["config"])344    del net_g.enc_q345    print(net_g.load_state_dict(cpt["weight"], strict=False))  # 不加这一行清不干净, 真奇葩346    net_g.eval().to(config.device)347    if config.is_half:348        net_g = net_g.half()349    else:350        net_g = net_g.float()351    vc = VC(tgt_sr, config)352    n_spk = cpt["config"][-3]353    return {"visible": True, "maximum": n_spk, "__type__": "update"}354 355 356def change_choices():357    names = []358    for name in os.listdir(weight_root):359        if name.endswith(".pth"):360            names.append(name)361    return {"choices": sorted(names), "__type__": "update"}362 363 364def clean():365    return {"value": "", "__type__": "update"}366 367 368def change_f0(if_f0_3, sr2):  # np7, f0method8,pretrained_G14,pretrained_D15369    if if_f0_3 == i18n("是"):370        return (371            {"visible": True, "__type__": "update"},372            {"visible": True, "__type__": "update"},373            "pretrained/f0G%s.pth" % sr2,374            "pretrained/f0D%s.pth" % sr2,375        )376    return (377        {"visible": False, "__type__": "update"},378        {"visible": False, "__type__": "update"},379        "pretrained/G%s.pth" % sr2,380        "pretrained/D%s.pth" % sr2,381    )382 383 384sr_dict = {385    "32k": 32000,386    "40k": 40000,387    "48k": 48000,388}389 390 391def if_done(done, p):392    while 1:393        if p.poll() == None:394            sleep(0.5)395        else:396            break397    done[0] = True398 399 400def if_done_multi(done, ps):401    while 1:402        # poll==None代表进程未结束403        # 只要有一个进程未结束都不停404        flag = 1405        for p in ps:406            if p.poll() == None:407                flag = 0408                sleep(0.5)409                break410        if flag == 1:411            break412    done[0] = True413 414 415def preprocess_dataset(trainset_dir, exp_dir, sr, n_p=ncpu):416    sr = sr_dict[sr]417    os.makedirs("%s/logs/%s" % (now_dir, exp_dir), exist_ok=True)418    f = open("%s/logs/%s/preprocess.log" % (now_dir, exp_dir), "w")419    f.close()420    cmd = (421        config.python_cmd422        + " trainset_preprocess_pipeline_print.py %s %s %s %s/logs/%s "423        % (trainset_dir, sr, n_p, now_dir, exp_dir)424        + str(config.noparallel)425    )426    print(cmd)427    p = Popen(cmd, shell=True)  # , stdin=PIPE, stdout=PIPE,stderr=PIPE,cwd=now_dir428    ###煞笔gr, popen read都非得全跑完了再一次性读取, 不用gr就正常读一句输出一句;只能额外弄出一个文本流定时读429    done = [False]430    threading.Thread(431        target=if_done,432        args=(433            done,434            p,435        ),436    ).start()437    while 1:438        with open("%s/logs/%s/preprocess.log" % (now_dir, exp_dir), "r") as f:439            yield (f.read())440        sleep(1)441        if done[0] == True:442            break443    with open("%s/logs/%s/preprocess.log" % (now_dir, exp_dir), "r") as f:444        log = f.read()445    print(log)446    yield log447 448 449# but2.click(extract_f0,[gpus6,np7,f0method8,if_f0_3,trainset_dir4],[info2])450def extract_f0_feature(gpus, n_p, f0method, if_f0, exp_dir):451    gpus = gpus.split("-")452    os.makedirs("%s/logs/%s" % (now_dir, exp_dir), exist_ok=True)453    f = open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "w")454    f.close()455    if if_f0 == i18n("是"):456        cmd = config.python_cmd + " extract_f0_print.py %s/logs/%s %s %s" % (457            now_dir,458            exp_dir,459            n_p,460            f0method,461        )462        print(cmd)463        p = Popen(cmd, shell=True, cwd=now_dir)  # , stdin=PIPE, stdout=PIPE,stderr=PIPE464        ###煞笔gr, popen read都非得全跑完了再一次性读取, 不用gr就正常读一句输出一句;只能额外弄出一个文本流定时读465        done = [False]466        threading.Thread(467            target=if_done,468            args=(469                done,470                p,471            ),472        ).start()473        while 1:474            with open(475                "%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "r"476            ) as f:477                yield (f.read())478            sleep(1)479            if done[0] == True:480                break481        with open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "r") as f:482            log = f.read()483        print(log)484        yield log485    ####对不同part分别开多进程486    """487    n_part=int(sys.argv[1])488    i_part=int(sys.argv[2])489    i_gpu=sys.argv[3]490    exp_dir=sys.argv[4]491    os.environ["CUDA_VISIBLE_DEVICES"]=str(i_gpu)492    """493    leng = len(gpus)494    ps = []495    for idx, n_g in enumerate(gpus):496        cmd = config.python_cmd + " extract_feature_print.py %s %s %s %s %s/logs/%s" % (497            config.device,498            leng,499            idx,500            n_g,501            now_dir,502            exp_dir,503        )504        print(cmd)505        p = Popen(506            cmd, shell=True, cwd=now_dir507        )  # , shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=now_dir508        ps.append(p)509    ###煞笔gr, popen read都非得全跑完了再一次性读取, 不用gr就正常读一句输出一句;只能额外弄出一个文本流定时读510    done = [False]511    threading.Thread(512        target=if_done_multi,513        args=(514            done,515            ps,516        ),517    ).start()518    while 1:519        with open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "r") as f:520            yield (f.read())521        sleep(1)522        if done[0] == True:523            break524    with open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir), "r") as f:525        log = f.read()526    print(log)527    yield log528 529 530def change_sr2(sr2, if_f0_3):531    if if_f0_3 == i18n("是"):532        return "pretrained/f0G%s.pth" % sr2, "pretrained/f0D%s.pth" % sr2533    else:534        return "pretrained/G%s.pth" % sr2, "pretrained/D%s.pth" % sr2535 536 537# but3.click(click_train,[exp_dir1,sr2,if_f0_3,save_epoch10,total_epoch11,batch_size12,if_save_latest13,pretrained_G14,pretrained_D15,gpus16])538def click_train(539    exp_dir1,540    sr2,541    if_f0_3,542    spk_id5,543    save_epoch10,544    total_epoch11,545    batch_size12,546    if_save_latest13,547    pretrained_G14,548    pretrained_D15,549    gpus16,550    if_cache_gpu17,551):552    # 生成filelist553    exp_dir = "%s/logs/%s" % (now_dir, exp_dir1)554    os.makedirs(exp_dir, exist_ok=True)555    gt_wavs_dir = "%s/0_gt_wavs" % (exp_dir)556    co256_dir = "%s/3_feature256" % (exp_dir)557    if if_f0_3 == i18n("是"):558        f0_dir = "%s/2a_f0" % (exp_dir)559        f0nsf_dir = "%s/2b-f0nsf" % (exp_dir)560        names = (561            set([name.split(".")[0] for name in os.listdir(gt_wavs_dir)])562            & set([name.split(".")[0] for name in os.listdir(co256_dir)])563            & set([name.split(".")[0] for name in os.listdir(f0_dir)])564            & set([name.split(".")[0] for name in os.listdir(f0nsf_dir)])565        )566    else:567        names = set([name.split(".")[0] for name in os.listdir(gt_wavs_dir)]) & set(568            [name.split(".")[0] for name in os.listdir(co256_dir)]569        )570    opt = []571    for name in names:572        if if_f0_3 == i18n("是"):573            opt.append(574                "%s/%s.wav|%s/%s.npy|%s/%s.wav.npy|%s/%s.wav.npy|%s"575                % (576                    gt_wavs_dir.replace("\\", "\\\\"),577                    name,578                    co256_dir.replace("\\", "\\\\"),579                    name,580                    f0_dir.replace("\\", "\\\\"),581                    name,582                    f0nsf_dir.replace("\\", "\\\\"),583                    name,584                    spk_id5,585                )586            )587        else:588            opt.append(589                "%s/%s.wav|%s/%s.npy|%s"590                % (591                    gt_wavs_dir.replace("\\", "\\\\"),592                    name,593                    co256_dir.replace("\\", "\\\\"),594                    name,595                    spk_id5,596                )597            )598    if if_f0_3 == i18n("是"):599        for _ in range(2):600            opt.append(601                "%s/logs/mute/0_gt_wavs/mute%s.wav|%s/logs/mute/3_feature256/mute.npy|%s/logs/mute/2a_f0/mute.wav.npy|%s/logs/mute/2b-f0nsf/mute.wav.npy|%s"602                % (now_dir, sr2, now_dir, now_dir, now_dir, spk_id5)603            )604    else:605        for _ in range(2):606            opt.append(607                "%s/logs/mute/0_gt_wavs/mute%s.wav|%s/logs/mute/3_feature256/mute.npy|%s"608                % (now_dir, sr2, now_dir, spk_id5)609            )610    shuffle(opt)611    with open("%s/filelist.txt" % exp_dir, "w") as f:612        f.write("\n".join(opt))613    print("write filelist done")614    # 生成config#无需生成config615    # 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"616    print("use gpus:", gpus16)617    if gpus16:618        cmd = (619            config.python_cmd620            + " train_nsf_sim_cache_sid_load_pretrain.py -e %s -sr %s -f0 %s -bs %s -g %s -te %s -se %s -pg %s -pd %s -l %s -c %s"621            % (622                exp_dir1,623                sr2,624                1 if if_f0_3 == i18n("是") else 0,625                batch_size12,626                gpus16,627                total_epoch11,628                save_epoch10,629                pretrained_G14,630                pretrained_D15,631                1 if if_save_latest13 == i18n("是") else 0,632                1 if if_cache_gpu17 == i18n("是") else 0,633            )634        )635    else:636        cmd = (637            config.python_cmd638            + " train_nsf_sim_cache_sid_load_pretrain.py -e %s -sr %s -f0 %s -bs %s -te %s -se %s -pg %s -pd %s -l %s -c %s"639            % (640                exp_dir1,641                sr2,642                1 if if_f0_3 == i18n("是") else 0,643                batch_size12,644                total_epoch11,645                save_epoch10,646                pretrained_G14,647                pretrained_D15,648                1 if if_save_latest13 == i18n("是") else 0,649                1 if if_cache_gpu17 == i18n("是") else 0,650            )651        )652    print(cmd)653    p = Popen(cmd, shell=True, cwd=now_dir)654    p.wait()655    return "训练结束, 您可查看控制台训练日志或实验文件夹下的train.log"656 657 658# but4.click(train_index, [exp_dir1], info3)659def train_index(exp_dir1):660    exp_dir = "%s/logs/%s" % (now_dir, exp_dir1)661    os.makedirs(exp_dir, exist_ok=True)662    feature_dir = "%s/3_feature256" % (exp_dir)663    if os.path.exists(feature_dir) == False:664        return "请先进行特征提取!"665    listdir_res = list(os.listdir(feature_dir))666    if len(listdir_res) == 0:667        return "请先进行特征提取!"668    npys = []669    for name in sorted(listdir_res):670        phone = np.load("%s/%s" % (feature_dir, name))671        npys.append(phone)672    big_npy = np.concatenate(npys, 0)673    big_npy_idx = np.arange(big_npy.shape[0])674    np.random.shuffle(big_npy_idx)675    big_npy = big_npy[big_npy_idx]676    np.save("%s/total_fea.npy" % exp_dir, big_npy)677    # n_ivf =  big_npy.shape[0] // 39678    n_ivf = min(int(16 * np.sqrt(big_npy.shape[0])), big_npy.shape[0] // 39)679    infos = []680    infos.append("%s,%s" % (big_npy.shape, n_ivf))681    yield "\n".join(infos)682    index = faiss.index_factory(256, "IVF%s,Flat" % n_ivf)683    # index = faiss.index_factory(256, "IVF%s,PQ128x4fs,RFlat"%n_ivf)684    infos.append("training")685    yield "\n".join(infos)686    index_ivf = faiss.extract_index_ivf(index)  #687    # index_ivf.nprobe = int(np.power(n_ivf,0.3))688    index_ivf.nprobe = 1689    index.train(big_npy)690    faiss.write_index(691        index,692        "%s/trained_IVF%s_Flat_nprobe_%s.index" % (exp_dir, n_ivf, index_ivf.nprobe),693    )694    # faiss.write_index(index, '%s/trained_IVF%s_Flat_FastScan.index'%(exp_dir,n_ivf))695    infos.append("adding")696    yield "\n".join(infos)697    batch_size_add = 8192698    for i in range(0, big_npy.shape[0], batch_size_add):699        index.add(big_npy[i : i + batch_size_add])700    faiss.write_index(701        index,702        "%s/added_IVF%s_Flat_nprobe_%s.index" % (exp_dir, n_ivf, index_ivf.nprobe),703    )704    infos.append("成功构建索引,added_IVF%s_Flat_nprobe_%s.index" % (n_ivf, index_ivf.nprobe))705    # faiss.write_index(index, '%s/added_IVF%s_Flat_FastScan.index'%(exp_dir,n_ivf))706    # infos.append("成功构建索引,added_IVF%s_Flat_FastScan.index"%(n_ivf))707    yield "\n".join(infos)708 709 710# 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)711def train1key(712    exp_dir1,713    sr2,714    if_f0_3,715    trainset_dir4,716    spk_id5,717    gpus6,718    np7,719    f0method8,720    save_epoch10,721    total_epoch11,722    batch_size12,723    if_save_latest13,724    pretrained_G14,725    pretrained_D15,726    gpus16,727    if_cache_gpu17,728):729    infos = []730 731    def get_info_str(strr):732        infos.append(strr)733        return "\n".join(infos)734 735    os.makedirs("%s/logs/%s" % (now_dir, exp_dir1), exist_ok=True)736    #########step1:处理数据737    open("%s/logs/%s/preprocess.log" % (now_dir, exp_dir1), "w").close()738    cmd = (739        config.python_cmd740        + " trainset_preprocess_pipeline_print.py %s %s %s %s/logs/%s "741        % (trainset_dir4, sr_dict[sr2], ncpu, now_dir, exp_dir1)742        + str(config.noparallel)743    )744    yield get_info_str(i18n("step1:正在处理数据"))745    yield get_info_str(cmd)746    p = Popen(cmd, shell=True)747    p.wait()748    with open("%s/logs/%s/preprocess.log" % (now_dir, exp_dir1), "r") as f:749        print(f.read())750    #########step2a:提取音高751    open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir1), "w")752    if if_f0_3 == i18n("是"):753        yield get_info_str("step2a:正在提取音高")754        cmd = config.python_cmd + " extract_f0_print.py %s/logs/%s %s %s" % (755            now_dir,756            exp_dir1,757            np7,758            f0method8,759        )760        yield get_info_str(cmd)761        p = Popen(cmd, shell=True, cwd=now_dir)762        p.wait()763        with open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir1), "r") as f:764            print(f.read())765    else:766        yield get_info_str(i18n("step2a:无需提取音高"))767    #######step2b:提取特征768    yield get_info_str(i18n("step2b:正在提取特征"))769    gpus = gpus16.split("-")770    leng = len(gpus)771    ps = []772    for idx, n_g in enumerate(gpus):773        cmd = config.python_cmd + " extract_feature_print.py %s %s %s %s %s/logs/%s" % (774            config.device,775            leng,776            idx,777            n_g,778            now_dir,779            exp_dir1,780        )781        yield get_info_str(cmd)782        p = Popen(783            cmd, shell=True, cwd=now_dir784        )  # , shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=now_dir785        ps.append(p)786    for p in ps:787        p.wait()788    with open("%s/logs/%s/extract_f0_feature.log" % (now_dir, exp_dir1), "r") as f:789        print(f.read())790    #######step3a:训练模型791    yield get_info_str(i18n("step3a:正在训练模型"))792    # 生成filelist793    exp_dir = "%s/logs/%s" % (now_dir, exp_dir1)794    gt_wavs_dir = "%s/0_gt_wavs" % (exp_dir)795    co256_dir = "%s/3_feature256" % (exp_dir)796    if if_f0_3 == i18n("是"):797        f0_dir = "%s/2a_f0" % (exp_dir)798        f0nsf_dir = "%s/2b-f0nsf" % (exp_dir)799        names = (800            set([name.split(".")[0] for name in os.listdir(gt_wavs_dir)])801            & set([name.split(".")[0] for name in os.listdir(co256_dir)])802            & set([name.split(".")[0] for name in os.listdir(f0_dir)])803            & set([name.split(".")[0] for name in os.listdir(f0nsf_dir)])804        )805    else:806        names = set([name.split(".")[0] for name in os.listdir(gt_wavs_dir)]) & set(807            [name.split(".")[0] for name in os.listdir(co256_dir)]808        )809    opt = []810    for name in names:811        if if_f0_3 == i18n("是"):812            opt.append(813                "%s/%s.wav|%s/%s.npy|%s/%s.wav.npy|%s/%s.wav.npy|%s"814                % (815                    gt_wavs_dir.replace("\\", "\\\\"),816                    name,817                    co256_dir.replace("\\", "\\\\"),818                    name,819                    f0_dir.replace("\\", "\\\\"),820                    name,821                    f0nsf_dir.replace("\\", "\\\\"),822                    name,823                    spk_id5,824                )825            )826        else:827            opt.append(828                "%s/%s.wav|%s/%s.npy|%s"829                % (830                    gt_wavs_dir.replace("\\", "\\\\"),831                    name,832                    co256_dir.replace("\\", "\\\\"),833                    name,834                    spk_id5,835                )836            )837    if if_f0_3 == i18n("是"):838        for _ in range(2):839            opt.append(840                "%s/logs/mute/0_gt_wavs/mute%s.wav|%s/logs/mute/3_feature256/mute.npy|%s/logs/mute/2a_f0/mute.wav.npy|%s/logs/mute/2b-f0nsf/mute.wav.npy|%s"841                % (now_dir, sr2, now_dir, now_dir, now_dir, spk_id5)842            )843    else:844        for _ in range(2):845            opt.append(846                "%s/logs/mute/0_gt_wavs/mute%s.wav|%s/logs/mute/3_feature256/mute.npy|%s"847                % (now_dir, sr2, now_dir, spk_id5)848            )849    shuffle(opt)850    with open("%s/filelist.txt" % exp_dir, "w") as f:851        f.write("\n".join(opt))852    yield get_info_str("write filelist done")853    if gpus16:854        cmd = (855            config.python_cmd856            + " train_nsf_sim_cache_sid_load_pretrain.py -e %s -sr %s -f0 %s -bs %s -g %s -te %s -se %s -pg %s -pd %s -l %s -c %s"857            % (858                exp_dir1,859                sr2,860                1 if if_f0_3 == i18n("是") else 0,861                batch_size12,862                gpus16,863                total_epoch11,864                save_epoch10,865                pretrained_G14,866                pretrained_D15,867                1 if if_save_latest13 == i18n("是") else 0,868                1 if if_cache_gpu17 == i18n("是") else 0,869            )870        )871    else:872        cmd = (873            config.python_cmd874            + " train_nsf_sim_cache_sid_load_pretrain.py -e %s -sr %s -f0 %s -bs %s -te %s -se %s -pg %s -pd %s -l %s -c %s"875            % (876                exp_dir1,877                sr2,878                1 if if_f0_3 == i18n("是") else 0,879                batch_size12,880                total_epoch11,881                save_epoch10,882                pretrained_G14,883                pretrained_D15,884                1 if if_save_latest13 == i18n("是") else 0,885                1 if if_cache_gpu17 == i18n("是") else 0,886            )887        )888    yield get_info_str(cmd)889    p = Popen(cmd, shell=True, cwd=now_dir)890    p.wait()891    yield get_info_str(i18n("训练结束, 您可查看控制台训练日志或实验文件夹下的train.log"))892    #######step3b:训练索引893    feature_dir = "%s/3_feature256" % (exp_dir)894    npys = []895    listdir_res = list(os.listdir(feature_dir))896    for name in sorted(listdir_res):897        phone = np.load("%s/%s" % (feature_dir, name))898        npys.append(phone)899    big_npy = np.concatenate(npys, 0)900    big_npy_idx = np.arange(big_npy.shape[0])901    np.random.shuffle(big_npy_idx)902    big_npy = big_npy[big_npy_idx]903    np.save("%s/total_fea.npy" % exp_dir, big_npy)904    # n_ivf =  big_npy.shape[0] // 39905    n_ivf = min(int(16 * np.sqrt(big_npy.shape[0])), big_npy.shape[0] // 39)906    yield get_info_str("%s,%s" % (big_npy.shape, n_ivf))907    index = faiss.index_factory(256, "IVF%s,Flat" % n_ivf)908    yield get_info_str("training index")909    index_ivf = faiss.extract_index_ivf(index)  #910    # index_ivf.nprobe = int(np.power(n_ivf,0.3))911    index_ivf.nprobe = 1912    index.train(big_npy)913    faiss.write_index(914        index,915        "%s/trained_IVF%s_Flat_nprobe_%s.index" % (exp_dir, n_ivf, index_ivf.nprobe),916    )917    yield get_info_str("adding index")918    batch_size_add = 8192919    for i in range(0, big_npy.shape[0], batch_size_add):920        index.add(big_npy[i : i + batch_size_add])921    faiss.write_index(922        index,923        "%s/added_IVF%s_Flat_nprobe_%s.index" % (exp_dir, n_ivf, index_ivf.nprobe),924    )925    yield get_info_str(926        "成功构建索引, added_IVF%s_Flat_nprobe_%s.index" % (n_ivf, index_ivf.nprobe)927    )928    yield get_info_str(i18n("全流程结束!"))929 930 931#                    ckpt_path2.change(change_info_,[ckpt_path2],[sr__,if_f0__])932def change_info_(ckpt_path):933    if (934        os.path.exists(ckpt_path.replace(os.path.basename(ckpt_path), "train.log"))935        == False936    ):937        return {"__type__": "update"}, {"__type__": "update"}938    try:939        with open(940            ckpt_path.replace(os.path.basename(ckpt_path), "train.log"), "r"941        ) as f:942            info = eval(f.read().strip("\n").split("\n")[0].split("\t")[-1])943            sr, f0 = info["sample_rate"], info["if_f0"]944            return sr, str(f0)945    except:946        traceback.print_exc()947        return {"__type__": "update"}, {"__type__": "update"}948 949 950from infer_pack.models_onnx_moess import SynthesizerTrnMs256NSFsidM951from infer_pack.models_onnx import SynthesizerTrnMs256NSFsidO952 953 954def export_onnx(ModelPath, ExportedPath, MoeVS=True):955    hidden_channels = 256  # hidden_channels,为768Vec做准备956    cpt = torch.load(ModelPath, map_location="cpu")957    cpt["config"][-3] = cpt["weight"]["emb_g.weight"].shape[0]  # n_spk958    print(*cpt["config"])959 960    test_phone = torch.rand(1, 200, hidden_channels)  # hidden unit961    test_phone_lengths = torch.tensor([200]).long()  # hidden unit 长度(貌似没啥用)962    test_pitch = torch.randint(size=(1, 200), low=5, high=255)  # 基频(单位赫兹)963    test_pitchf = torch.rand(1, 200)  # nsf基频964    test_ds = torch.LongTensor([0])  # 说话人ID965    test_rnd = torch.rand(1, 192, 200)  # 噪声(加入随机因子)966 967    device = "cpu"  # 导出时设备(不影响使用模型)968 969    if MoeVS:970        net_g = SynthesizerTrnMs256NSFsidM(971            *cpt["config"], is_half=False972        )  # fp32导出(C++要支持fp16必须手动将内存重新排列所以暂时不用fp16)973        net_g.load_state_dict(cpt["weight"], strict=False)974        input_names = ["phone", "phone_lengths", "pitch", "pitchf", "ds", "rnd"]975        output_names = [976            "audio",977        ]978        torch.onnx.export(979            net_g,980            (981                test_phone.to(device),982                test_phone_lengths.to(device),983                test_pitch.to(device),984                test_pitchf.to(device),985                test_ds.to(device),986                test_rnd.to(device),987            ),988            ExportedPath,989            dynamic_axes={990                "phone": [1],991                "pitch": [1],992                "pitchf": [1],993                "rnd": [2],994            },995            do_constant_folding=False,996            opset_version=16,997            verbose=False,998            input_names=input_names,999            output_names=output_names,1000        )1001    else:1002        net_g = SynthesizerTrnMs256NSFsidO(1003            *cpt["config"], is_half=False1004        )  # fp32导出(C++要支持fp16必须手动将内存重新排列所以暂时不用fp16)1005        net_g.load_state_dict(cpt["weight"], strict=False)1006        input_names = ["phone", "phone_lengths", "pitch", "pitchf", "ds"]1007        output_names = [1008            "audio",1009        ]1010        torch.onnx.export(1011            net_g,1012            (1013                test_phone.to(device),1014                test_phone_lengths.to(device),1015                test_pitch.to(device),1016                test_pitchf.to(device),1017                test_ds.to(device),1018            ),1019            ExportedPath,1020            dynamic_axes={1021                "phone": [1],1022                "pitch": [1],1023                "pitchf": [1],1024            },1025            do_constant_folding=False,1026            opset_version=16,1027            verbose=False,1028            input_names=input_names,1029            output_names=output_names,1030        )1031    return "Finished"1032 1033 1034with gr.Blocks() as app:1035    gr.Markdown(1036        value=i18n(1037            "本软件以MIT协议开源, 作者不对软件具备任何控制力, 使用软件者、传播软件导出的声音者自负全责. <br>如不认可该条款, 则不能使用或引用软件包内任何代码和文件. 详见根目录<b>使用需遵守的协议-LICENSE.txt</b>."1038        )1039    )1040    with gr.Tabs():1041        with gr.TabItem(i18n("模型推理")):1042            with gr.Row():1043                sid0 = gr.Dropdown(label=i18n("推理音色"), choices=sorted(names))1044                refresh_button = gr.Button(i18n("刷新音色列表"), variant="primary")1045                refresh_button.click(fn=change_choices, inputs=[], outputs=[sid0])1046                clean_button = gr.Button(i18n("卸载音色省显存"), variant="primary")1047                spk_item = gr.Slider(1048                    minimum=0,1049                    maximum=2333,1050                    step=1,1051                    label=i18n("请选择说话人id"),1052                    value=0,1053                    visible=False,1054                    interactive=True,1055                )1056                clean_button.click(fn=clean, inputs=[], outputs=[sid0])1057                sid0.change(1058                    fn=get_vc,1059                    inputs=[sid0],1060                    outputs=[spk_item],1061                )1062            with gr.Group():1063                gr.Markdown(1064                    value=i18n("男转女推荐+12key, 女转男推荐-12key, 如果音域爆炸导致音色失真也可以自己调整到合适音域. ")1065                )1066                with gr.Row():1067                    with gr.Column():1068                        vc_transform0 = gr.Number(1069                            label=i18n("变调(整数, 半音数量, 升八度12降八度-12)"), value=01070                        )1071                        input_audio0 = gr.Textbox(1072                            label=i18n("输入待处理音频文件路径(默认是正确格式示例)"),1073                            value="E:\\codes\\py39\\vits_vc_gpu_train\\todo-songs\\冬之花clip1.wav",1074                        )1075                        f0method0 = gr.Radio(1076                            label=i18n("选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比"),1077                            choices=["pm", "harvest"],1078                            value="pm",1079                            interactive=True,1080                        )1081                    with gr.Column():1082                        file_index1 = gr.Textbox(1083                            label=i18n("特征检索库文件路径"),1084                            value="E:\\codes\\py39\\vits_vc_gpu_train\\logs\\mi-test-1key\\added_IVF677_Flat_nprobe_7.index",1085                            interactive=True,1086                        )1087                        # file_big_npy1 = gr.Textbox(1088                        #     label=i18n("特征文件路径"),1089                        #     value="E:\\codes\py39\\vits_vc_gpu_train\\logs\\mi-test-1key\\total_fea.npy",1090                        #     interactive=True,1091                        # )1092                        index_rate1 = gr.Slider(1093                            minimum=0,1094                            maximum=1,1095                            label=i18n("检索特征占比"),1096                            value=0.76,1097                            interactive=True,1098                        )1099                    f0_file = gr.File(label=i18n("F0曲线文件, 可选, 一行一个音高, 代替默认F0及升降调"))1100                    but0 = gr.Button(i18n("转换"), variant="primary")1101                    with gr.Column():1102                        vc_output1 = gr.Textbox(label=i18n("输出信息"))1103                        vc_output2 = gr.Audio(label=i18n("输出音频(右下角三个点,点了可以下载)"))1104                    but0.click(1105                        vc_single,1106                        [1107                            spk_item,1108                            input_audio0,1109                            vc_transform0,1110                            f0_file,1111                            f0method0,1112                            file_index1,1113                            # file_big_npy1,1114                            index_rate1,1115                        ],1116                        [vc_output1, vc_output2],1117                    )1118            with gr.Group():1119                gr.Markdown(1120                    value=i18n("批量转换, 输入待转换音频文件夹, 或上传多个音频文件, 在指定文件夹(默认opt)下输出转换的音频. ")1121                )1122                with gr.Row():1123                    with gr.Column():1124                        vc_transform1 = gr.Number(1125                            label=i18n("变调(整数, 半音数量, 升八度12降八度-12)"), value=01126                        )1127                        opt_input = gr.Textbox(label=i18n("指定输出文件夹"), value="opt")1128                        f0method1 = gr.Radio(1129                            label=i18n("选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比"),1130                            choices=["pm", "harvest"],1131                            value="pm",1132                            interactive=True,1133                        )1134                    with gr.Column():1135                        file_index2 = gr.Textbox(1136                            label=i18n("特征检索库文件路径"),1137                            value="E:\\codes\\py39\\vits_vc_gpu_train\\logs\\mi-test-1key\\added_IVF677_Flat_nprobe_7.index",1138                            interactive=True,1139                        )1140                        # file_big_npy2 = gr.Textbox(1141                        #     label=i18n("特征文件路径"),1142                        #     value="E:\\codes\\py39\\vits_vc_gpu_train\\logs\\mi-test-1key\\total_fea.npy",1143                        #     interactive=True,1144                        # )1145                        index_rate2 = gr.Slider(1146                            minimum=0,1147                            maximum=1,1148                            label=i18n("检索特征占比"),1149                            value=1,1150                            interactive=True,1151                        )1152                    with gr.Column():1153                        dir_input = gr.Textbox(1154                            label=i18n("输入待处理音频文件夹路径(去文件管理器地址栏拷就行了)"),1155                            value="E:\codes\py39\\vits_vc_gpu_train\\todo-songs",1156                        )1157                        inputs = gr.File(1158                            file_count="multiple", label=i18n("也可批量输入音频文件, 二选一, 优先读文件夹")1159                        )1160                    but1 = gr.Button(i18n("转换"), variant="primary")1161                    vc_output3 = gr.Textbox(label=i18n("输出信息"))1162                    but1.click(1163                        vc_multi,1164                        [1165                            spk_item,1166                            dir_input,1167                            opt_input,1168                            inputs,1169                            vc_transform1,1170                            f0method1,1171                            file_index2,1172                            # file_big_npy2,1173                            index_rate2,1174                        ],1175                        [vc_output3],1176                    )1177        with gr.TabItem(i18n("伴奏人声分离")):1178            with gr.Group():1179                gr.Markdown(1180                    value=i18n(1181                        "人声伴奏分离批量处理, 使用UVR5模型. <br>不带和声用HP2, 带和声且提取的人声不需要和声用HP5<br>合格的文件夹路径格式举例: E:\\codes\\py39\\vits_vc_gpu\\白鹭霜华测试样例(去文件管理器地址栏拷就行了)"1182                    )1183                )1184                with gr.Row():1185                    with gr.Column():1186                        dir_wav_input = gr.Textbox(1187                            label=i18n("输入待处理音频文件夹路径"),1188                            value="E:\\codes\\py39\\vits_vc_gpu_train\\todo-songs",1189                        )1190                        wav_inputs = gr.File(1191                            file_count="multiple", label=i18n("也可批量输入音频文件, 二选一, 优先读文件夹")1192                        )1193                    with gr.Column():1194                        model_choose = gr.Dropdown(label=i18n("模型"), choices=uvr5_names)1195                        agg = gr.Slider(1196                            minimum=0,1197                            maximum=20,1198                            step=1,1199                            label="人声提取激进程度",1200                            value=10,

Showing the first 1,200 of 1548 lines. Download the file for the rest.