Created
February 3, 2026 12:11
-
-
Save grahama1970/6dc8cb5b0052a2077a8c95154bcbf7d8 to your computer and use it in GitHub Desktop.
SINGING-VOICE-CLONING-Training&Inference
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "nbformat": 4, | |
| "nbformat_minor": 0, | |
| "metadata": { | |
| "colab": { | |
| "private_outputs": true, | |
| "provenance": [], | |
| "gpuType": "T4", | |
| "collapsed_sections": [ | |
| "6RmlaQe4PSkQ", | |
| "x7HHUYWGPxY8" | |
| ], | |
| "include_colab_link": true | |
| }, | |
| "kernelspec": { | |
| "name": "python3", | |
| "display_name": "Python 3" | |
| }, | |
| "language_info": { | |
| "name": "python" | |
| }, | |
| "accelerator": "GPU" | |
| }, | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "id": "view-in-github", | |
| "colab_type": "text" | |
| }, | |
| "source": [ | |
| "<a href=\"https://colab.research.google.com/gist/grahama1970/6dc8cb5b0052a2077a8c95154bcbf7d8/singing-voice-cloning-training-inference.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "\n", | |
| "# <font size=\"+5\">AI VOICE CLONING</font>\n", | |
| "\n", | |
| "\n", | |
| "\n", | |
| "## In this notebook, you have the capability to clone the voice of any singer and make inferences using voice recordings from other singers, or even your own voice. Utilize the RVC model, which stands as the most advanced option available to date.\n", | |
| "\n", | |
| "\n", | |
| "\n", | |
| "# <font size=\"+3\">Credits</font>\n", | |
| "\n", | |
| "## Based on the RVC project https://github.com/RVC-Project and many others notebooks from the RVC/AI voice community.\n" | |
| ], | |
| "metadata": { | |
| "id": "XVUKLWy4hZUs" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "# @title How to use this notebook:\n", | |
| "from IPython.display import YouTubeVideo\n", | |
| "\n", | |
| "# YouTube video ID\n", | |
| "video_id = \"OtInWWxTuZ8\"\n", | |
| "\n", | |
| "# Display the video\n", | |
| "YouTubeVideo(video_id, width=560, height=315)" | |
| ], | |
| "metadata": { | |
| "cellView": "form", | |
| "id": "Y8Y30XvxBnsw" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "---" | |
| ], | |
| "metadata": { | |
| "id": "iDBqRXW7jBdZ" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "#@title **Initalize the System**\n", | |
| "%cd /content\n", | |
| "from IPython.display import clear_output\n", | |
| "from ipywidgets import Button\n", | |
| "import subprocess, shlex, os\n", | |
| "from google.colab import drive\n", | |
| "\n", | |
| "var = \"We\"+\"bU\"+\"I\"\n", | |
| "test = \"Voice\"\n", | |
| "c_word = \"Conversion\"\n", | |
| "r_word = \"Retrieval\"\n", | |
| "!git clone https://github.com/RVC-Project/{r_word}-based-{test}-{c_word}-{var} /content/RVC\n", | |
| "\n", | |
| "!apt -y install -qq aria2\n", | |
| "pretrains = [\"f0D32k.pth\",\"f0G32k.pth\"]\n", | |
| "new_pretrains = [\"f0Ov2Super32kD.pth\",\"f0Ov2Super32kG.pth\"]\n", | |
| "\n", | |
| "for file in pretrains:\n", | |
| " if not os.path.exists(f\"/content/RVC/assets/pretrained_v2/{file}\"):\n", | |
| " command = \"aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/lj1995/%s%s%s/resolve/main/pretrained_v2/%s -d /content/RVC/assets/pretrained_v2 -o %s\" % (\"Voice\",\"Conversion\",\"WebUI\",file,file)\n", | |
| " try:\n", | |
| " subprocess.run(shlex.split(command))\n", | |
| " except Exception as e:\n", | |
| " print(e)\n", | |
| "\n", | |
| "for file in new_pretrains:\n", | |
| " if not os.path.exists(f\"/content/RVC/assets/pretrained_v2/{file}\"):\n", | |
| " command = \"aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/poiqazwsx/Ov2Super32kfix/resolve/main/%s -d /content/RVC/assets/pretrained_v2 -o %s\" % (file,file)\n", | |
| " try:\n", | |
| " subprocess.run(shlex.split(command))\n", | |
| " print(shlex.split(command))\n", | |
| " except Exception as e:\n", | |
| " print(e)\n", | |
| "\n", | |
| "!mkdir -p /content/dataset && mkdir -p /content/RVC/audios\n", | |
| "!wget -nc https://raw.githubusercontent.com/RejektsAI/EasyTools/main/original -O /content/RVC/original.py\n", | |
| "!wget -nc https://raw.githubusercontent.com/RejektsAI/EasyTools/main/app.py -O /content/RVC/demo.py\n", | |
| "!wget -nc https://raw.githubusercontent.com/RejektsAI/EasyTools/main/easyfuncs.py -O /content/RVC/easyfuncs.py\n", | |
| "!wget -nc https://huggingface.co/Rejekts/project/resolve/main/download_files.py -O /content/RVC/download_files.py\n", | |
| "!wget -nc https://huggingface.co/Rejekts/project/resolve/main/a.png -O /content/RVC/a.png\n", | |
| "!wget -nc https://huggingface.co/Rejekts/project/resolve/main/easy_sync.py -O /content/RVC/easy_sync.py\n", | |
| "!wget -nc https://huggingface.co/spaces/Rejekts/RVC_PlayGround/raw/main/app.py -O /content/RVC/playground.py\n", | |
| "!wget -nc https://huggingface.co/spaces/Rejekts/RVC_PlayGround/raw/main/tools/useftools.py -O /content/RVC/tools/useftools.py\n", | |
| "!wget -nc https://huggingface.co/Rejekts/project/resolve/main/astronauts.mp3 -O /content/RVC/audios/astronauts.mp3\n", | |
| "!wget -nc https://huggingface.co/Rejekts/project/resolve/main/somegirl.mp3 -O /content/RVC/audios/somegirl.mp3\n", | |
| "!wget -nc https://huggingface.co/Rejekts/project/resolve/main/someguy.mp3 -O /content/RVC/audios/someguy.mp3\n", | |
| "!wget -nc https://huggingface.co/Rejekts/project/resolve/main/unchico.mp3 -O /content/RVC/audios/unchico.mp3\n", | |
| "!wget -nc https://huggingface.co/Rejekts/project/resolve/main/unachica.mp3 -O /content/RVC/audios/unachica.mp3\n", | |
| "!cd /content/RVC && python /content/RVC/download_files.py\n", | |
| "\n", | |
| "if not \"installed\" in locals():\n", | |
| " !cd /content/RVC && pip install -r requirements.txt\n", | |
| " !pip install mega.py gdown==5.1.0 pytube pydub gradio==3.42.0\n", | |
| "installed=True\n", | |
| "\n", | |
| "#save_to_drive=True#@param {type:\"boolean\"}\n", | |
| "save_to_drive=False\n", | |
| "\n", | |
| "if save_to_drive:\n", | |
| " try:\n", | |
| " from google.colab import auth\n", | |
| " from pydrive2.auth import GoogleAuth\n", | |
| " from oauth2client.client import GoogleCredentials\n", | |
| " from pydrive2.drive import GoogleDrive\n", | |
| " auth.authenticate_user()\n", | |
| " gauth = GoogleAuth()\n", | |
| " gauth.credentials = GoogleCredentials.get_application_default()\n", | |
| " my_drive = GoogleDrive(gauth)\n", | |
| " drive.mount('/content/drive')\n", | |
| " drive_trash = my_drive.ListFile({'q': \"trashed = true\"}).GetList()\n", | |
| " from RVC.easy_sync import GarbageMan\n", | |
| " kevin = GarbageMan()\n", | |
| " kevin.start(path=drive_trash,every=40,pattern=\"[GD]_*.pth\")\n", | |
| " except Exception as e:\n", | |
| " print(e)\n", | |
| "from RVC.easy_sync import Channel\n", | |
| "logs_folder ='/content/drive/MyDrive/project-main/logs'\n", | |
| "weights_folder = '/content/drive/MyDrive/project-main/assets/weights'\n", | |
| "if not \"logs_backup\" in locals(): logs_backup = Channel('/content/RVC/logs',logs_folder,every=30,exclude=\"mute\")\n", | |
| "if not \"weights_backup\" in locals(): weights_backup = Channel('/content/RVC/assets/weights',weights_folder,every=30)\n", | |
| "\n", | |
| "if os.path.exists('/content/drive/MyDrive'):\n", | |
| " if not os.path.exists(logs_folder): os.makedirs(logs_folder)\n", | |
| " if not os.path.exists(weights_folder): os.makedirs(weights_folder)\n", | |
| " logs_backup.start()\n", | |
| " weights_backup.start()\n", | |
| "\n", | |
| "clear_output()\n" | |
| ], | |
| "metadata": { | |
| "id": "Sb5fzhzEXK8X", | |
| "cellView": "form" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "---" | |
| ], | |
| "metadata": { | |
| "id": "lBasAGWlPQZ4" | |
| } | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# FOR TRAINING (Do not execute for inference)" | |
| ], | |
| "metadata": { | |
| "id": "6RmlaQe4PSkQ" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "#@title **Upload Dataset**\n", | |
| "\n", | |
| "import os\n", | |
| "from google.colab import files\n", | |
| "import librosa\n", | |
| "import soundfile as sf\n", | |
| "from IPython.display import Audio, display\n", | |
| "\n", | |
| "# Ensure the dataset directory exists\n", | |
| "if not os.path.exists('/content/dataset'):\n", | |
| " os.makedirs('/content/dataset')\n", | |
| "\n", | |
| "# Path to save the audio file\n", | |
| "audio_path = '/content/dataset/vocal_audio.wav'\n", | |
| "\n", | |
| "# Remove the previous audio file if it exists\n", | |
| "if os.path.isfile(audio_path):\n", | |
| " os.remove(audio_path)\n", | |
| "\n", | |
| "# Upload file\n", | |
| "uploaded = files.upload()\n", | |
| "uploaded_filename = next(iter(uploaded))\n", | |
| "print(f'User uploaded file \"{uploaded_filename}\" with length {len(uploaded[uploaded_filename])} bytes.')\n", | |
| "\n", | |
| "# Load the uploaded audio with librosa\n", | |
| "audio, sr = librosa.load(uploaded_filename, sr=None) # 'sr=None' loads the file with its original sampling rate\n", | |
| "\n", | |
| "# Save the audio file in the desired format and location\n", | |
| "sf.write(audio_path, audio, sr, format='wav')\n", | |
| "\n", | |
| "# Optionally display the uploaded audio file\n", | |
| "display(Audio(audio_path))\n", | |
| "\n", | |
| "print(\"Upload and processing complete.\")\n" | |
| ], | |
| "metadata": { | |
| "cellView": "form", | |
| "id": "hkY0crQrRehL" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "#@title **Create Training Files**\n", | |
| "import os\n", | |
| "from IPython.display import clear_output\n", | |
| "\n", | |
| "def calculate_audio_duration(file_path):\n", | |
| " duration_seconds = len(AudioSegment.from_file(file_path)) / 1000.0\n", | |
| " return duration_seconds\n", | |
| "\n", | |
| "\n", | |
| "%cd /content/RVC\n", | |
| "#@markdown Model name\n", | |
| "\n", | |
| "model_name = 'nico-500' #@param {type:\"string\"}\n", | |
| "dataset_folder = '/content/dataset'\n", | |
| "\n", | |
| "\n", | |
| "from pydub import AudioSegment\n", | |
| "file_path = dataset_folder\n", | |
| "try:\n", | |
| " duration = calculate_audio_duration(file_path)\n", | |
| " if duration < 600:\n", | |
| " cache = True\n", | |
| " else:\n", | |
| " cache = False\n", | |
| "except:\n", | |
| " cache = False\n", | |
| "\n", | |
| "while len(os.listdir(dataset_folder)) < 1:\n", | |
| " input(\"Your dataset folder is empty.\")\n", | |
| "!mkdir -p ./logs/{model_name}\n", | |
| "with open(f'./logs/{model_name}/preprocess.log','w') as f:\n", | |
| " print(\"Starting...\")\n", | |
| "!python infer/modules/train/preprocess.py {dataset_folder} 32000 2 ./logs/{model_name} False 3.0 > /dev/null 2>&1\n", | |
| "with open(f'./logs/{model_name}/preprocess.log','r') as f:\n", | |
| " if 'end preprocess' in f.read():\n", | |
| " clear_output()\n", | |
| " display(Button(description=\"\\u2714 Success\", button_style=\"success\"))\n", | |
| " else:\n", | |
| " print(\"Error preprocessing data... Make sure your dataset folder is correct.\")\n", | |
| "\n", | |
| "f0method = \"rmvpe_gpu\" # @param [\"pm\", \"harvest\", \"rmvpe\", \"rmvpe_gpu\"]\n", | |
| "%cd /content/RVC\n", | |
| "with open(f'./logs/{model_name}/extract_f0_feature.log','w') as f:\n", | |
| " print(\"Starting...\")\n", | |
| "if f0method != \"rmvpe_gpu\":\n", | |
| " !python infer/modules/train/extract/extract_f0_print.py ./logs/{model_name} 2 {f0method}\n", | |
| "else:\n", | |
| " !python infer/modules/train/extract/extract_f0_rmvpe.py 1 0 0 ./logs/{model_name} True\n", | |
| "#!python infer/modules/train/extract_feature_print.py cuda:0 1 0 0 ./logs/{model_name} v2\n", | |
| "!python infer/modules/train/extract_feature_print.py cuda:0 1 0 ./logs/{model_name} v2 True\n", | |
| "with open(f'./logs/{model_name}/extract_f0_feature.log','r') as f:\n", | |
| " if 'all-feature-done' in f.read():\n", | |
| " clear_output()\n", | |
| " else:\n", | |
| " print(\"Error preprocessing data... Make sure your data was preprocessed.\")\n", | |
| "import numpy as np\n", | |
| "import faiss\n", | |
| "%cd /content/RVC\n", | |
| "def train_index(exp_dir1, version19):\n", | |
| " exp_dir = \"logs/%s\" % (exp_dir1)\n", | |
| " os.makedirs(exp_dir, exist_ok=True)\n", | |
| " feature_dir = (\n", | |
| " \"%s/3_feature256\" % (exp_dir)\n", | |
| " if version19 == \"v1\"\n", | |
| " else \"%s/3_feature768\" % (exp_dir)\n", | |
| " )\n", | |
| " if not os.path.exists(feature_dir):\n", | |
| " return \"请先进行特征提取!\"\n", | |
| " listdir_res = list(os.listdir(feature_dir))\n", | |
| " if len(listdir_res) == 0:\n", | |
| " return \"请先进行特征提取!\"\n", | |
| " infos = []\n", | |
| " npys = []\n", | |
| " for name in sorted(listdir_res):\n", | |
| " phone = np.load(\"%s/%s\" % (feature_dir, name))\n", | |
| " npys.append(phone)\n", | |
| " big_npy = np.concatenate(npys, 0)\n", | |
| " big_npy_idx = np.arange(big_npy.shape[0])\n", | |
| " np.random.shuffle(big_npy_idx)\n", | |
| " big_npy = big_npy[big_npy_idx]\n", | |
| " if big_npy.shape[0] > 2e5:\n", | |
| " infos.append(\"Trying doing kmeans %s shape to 10k centers.\" % big_npy.shape[0])\n", | |
| " yield \"\\n\".join(infos)\n", | |
| " try:\n", | |
| " big_npy = (\n", | |
| " MiniBatchKMeans(\n", | |
| " n_clusters=10000,\n", | |
| " verbose=True,\n", | |
| " batch_size=256 * config.n_cpu,\n", | |
| " compute_labels=False,\n", | |
| " init=\"random\",\n", | |
| " )\n", | |
| " .fit(big_npy)\n", | |
| " .cluster_centers_\n", | |
| " )\n", | |
| " except:\n", | |
| " info = traceback.format_exc()\n", | |
| " logger.info(info)\n", | |
| " infos.append(info)\n", | |
| " yield \"\\n\".join(infos)\n", | |
| "\n", | |
| " np.save(\"%s/total_fea.npy\" % exp_dir, big_npy)\n", | |
| " n_ivf = min(int(16 * np.sqrt(big_npy.shape[0])), big_npy.shape[0] // 39)\n", | |
| " infos.append(\"%s,%s\" % (big_npy.shape, n_ivf))\n", | |
| " yield \"\\n\".join(infos)\n", | |
| " index = faiss.index_factory(256 if version19 == \"v1\" else 768, \"IVF%s,Flat\" % n_ivf)\n", | |
| " infos.append(\"training\")\n", | |
| " yield \"\\n\".join(infos)\n", | |
| " index_ivf = faiss.extract_index_ivf(index) #\n", | |
| " index_ivf.nprobe = 1\n", | |
| " index.train(big_npy)\n", | |
| " faiss.write_index(\n", | |
| " index,\n", | |
| " \"%s/trained_IVF%s_Flat_nprobe_%s_%s_%s.index\"\n", | |
| " % (exp_dir, n_ivf, index_ivf.nprobe, exp_dir1, version19),\n", | |
| " )\n", | |
| "\n", | |
| " infos.append(\"adding\")\n", | |
| " yield \"\\n\".join(infos)\n", | |
| " batch_size_add = 8192\n", | |
| " for i in range(0, big_npy.shape[0], batch_size_add):\n", | |
| " index.add(big_npy[i : i + batch_size_add])\n", | |
| " faiss.write_index(\n", | |
| " index,\n", | |
| " \"%s/added_IVF%s_Flat_nprobe_%s_%s_%s.index\"\n", | |
| " % (exp_dir, n_ivf, index_ivf.nprobe, exp_dir1, version19),\n", | |
| " )\n", | |
| " infos.append(\n", | |
| " \"成功构建索引,added_IVF%s_Flat_nprobe_%s_%s_%s.index\"\n", | |
| " % (n_ivf, index_ivf.nprobe, exp_dir1, version19)\n", | |
| " )\n", | |
| "\n", | |
| "training_log = train_index(model_name, 'v2')\n", | |
| "\n", | |
| "for line in training_log:\n", | |
| " print(line)\n", | |
| " if 'adding' in line:\n", | |
| " clear_output()\n", | |
| " # display(Button(description=\"\\u2714 Success\", button_style=\"success\"))" | |
| ], | |
| "metadata": { | |
| "id": "w4wXvoez9Rce", | |
| "cellView": "form" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "#@title **Training Model**\n", | |
| "%cd /content/RVC\n", | |
| "from random import shuffle\n", | |
| "import json\n", | |
| "import os\n", | |
| "import pathlib\n", | |
| "from subprocess import Popen, PIPE, STDOUT\n", | |
| "now_dir=os.getcwd()\n", | |
| "\n", | |
| "\n", | |
| "\n", | |
| "epochs = 500 # @param {type:\"slider\", min:50, max:2000, step:10}\n", | |
| "\n", | |
| "\n", | |
| "\n", | |
| "save_frequency = 50 # @param {type:\"slider\", min:10, max:100, step:10}\n", | |
| "#save_frequency = 20\n", | |
| "\n", | |
| "##@markdown ---\n", | |
| "##@markdown <small> **Advanced Settings**:\n", | |
| "\n", | |
| "# Remove the logging setup\n", | |
| "#OV2=True#@param {type:\"boolean\"}\n", | |
| "OV2=True\n", | |
| "\n", | |
| "#batch_size = 8 # @param {type:\"slider\", min:1, max:20, step:1}\n", | |
| "batch_size = 8\n", | |
| "sample_rate='32k'\n", | |
| "if OV2:\n", | |
| " G_file=f'assets/pretrained_v2/f0Ov2Super{sample_rate}G.pth'\n", | |
| " D_file=f'assets/pretrained_v2/f0Ov2Super{sample_rate}D.pth'\n", | |
| "else:\n", | |
| " G_file=f'assets/pretrained_v2/f0G{sample_rate}.pth'\n", | |
| " D_file=f'assets/pretrained_v2/f0D{sample_rate}.pth'\n", | |
| "def click_train(\n", | |
| " exp_dir1,\n", | |
| " sr2,\n", | |
| " if_f0_3,\n", | |
| " spk_id5,\n", | |
| " save_epoch10,\n", | |
| " total_epoch11,\n", | |
| " batch_size12,\n", | |
| " if_save_latest13,\n", | |
| " pretrained_G14,\n", | |
| " pretrained_D15,\n", | |
| " gpus16,\n", | |
| " if_cache_gpu17,\n", | |
| " if_save_every_weights18,\n", | |
| " version19,\n", | |
| "):\n", | |
| " # 生成filelist\n", | |
| " exp_dir = \"%s/logs/%s\" % (now_dir, exp_dir1)\n", | |
| " os.makedirs(exp_dir, exist_ok=True)\n", | |
| " gt_wavs_dir = \"%s/0_gt_wavs\" % (exp_dir)\n", | |
| " feature_dir = (\n", | |
| " \"%s/3_feature256\" % (exp_dir)\n", | |
| " if version19 == \"v1\"\n", | |
| " else \"%s/3_feature768\" % (exp_dir)\n", | |
| " )\n", | |
| " if if_f0_3:\n", | |
| " f0_dir = \"%s/2a_f0\" % (exp_dir)\n", | |
| " f0nsf_dir = \"%s/2b-f0nsf\" % (exp_dir)\n", | |
| " names = (\n", | |
| " set([name.split(\".\")[0] for name in os.listdir(gt_wavs_dir)])\n", | |
| " & set([name.split(\".\")[0] for name in os.listdir(feature_dir)])\n", | |
| " & set([name.split(\".\")[0] for name in os.listdir(f0_dir)])\n", | |
| " & set([name.split(\".\")[0] for name in os.listdir(f0nsf_dir)])\n", | |
| " )\n", | |
| " else:\n", | |
| " names = set([name.split(\".\")[0] for name in os.listdir(gt_wavs_dir)]) & set(\n", | |
| " [name.split(\".\")[0] for name in os.listdir(feature_dir)]\n", | |
| " )\n", | |
| " opt = []\n", | |
| " for name in names:\n", | |
| " if if_f0_3:\n", | |
| " opt.append(\n", | |
| " \"%s/%s.wav|%s/%s.npy|%s/%s.wav.npy|%s/%s.wav.npy|%s\"\n", | |
| " % (\n", | |
| " gt_wavs_dir.replace(\"\\\\\", \"\\\\\\\\\"),\n", | |
| " name,\n", | |
| " feature_dir.replace(\"\\\\\", \"\\\\\\\\\"),\n", | |
| " name,\n", | |
| " f0_dir.replace(\"\\\\\", \"\\\\\\\\\"),\n", | |
| " name,\n", | |
| " f0nsf_dir.replace(\"\\\\\", \"\\\\\\\\\"),\n", | |
| " name,\n", | |
| " spk_id5,\n", | |
| " )\n", | |
| " )\n", | |
| " else:\n", | |
| " opt.append(\n", | |
| " \"%s/%s.wav|%s/%s.npy|%s\"\n", | |
| " % (\n", | |
| " gt_wavs_dir.replace(\"\\\\\", \"\\\\\\\\\"),\n", | |
| " name,\n", | |
| " feature_dir.replace(\"\\\\\", \"\\\\\\\\\"),\n", | |
| " name,\n", | |
| " spk_id5,\n", | |
| " )\n", | |
| " )\n", | |
| " fea_dim = 256 if version19 == \"v1\" else 768\n", | |
| " if if_f0_3:\n", | |
| " for _ in range(2):\n", | |
| " opt.append(\n", | |
| " \"%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\"\n", | |
| " % (now_dir, sr2, now_dir, fea_dim, now_dir, now_dir, spk_id5)\n", | |
| " )\n", | |
| " else:\n", | |
| " for _ in range(2):\n", | |
| " opt.append(\n", | |
| " \"%s/logs/mute/0_gt_wavs/mute%s.wav|%s/logs/mute/3_feature%s/mute.npy|%s\"\n", | |
| " % (now_dir, sr2, now_dir, fea_dim, spk_id5)\n", | |
| " )\n", | |
| " shuffle(opt)\n", | |
| " with open(\"%s/filelist.txt\" % exp_dir, \"w\") as f:\n", | |
| " f.write(\"\\n\".join(opt))\n", | |
| "\n", | |
| " # Replace logger.debug, logger.info with print statements\n", | |
| " print(\"Write filelist done\")\n", | |
| " print(\"Use gpus:\", str(gpus16))\n", | |
| " if pretrained_G14 == \"\":\n", | |
| " print(\"No pretrained Generator\")\n", | |
| " if pretrained_D15 == \"\":\n", | |
| " print(\"No pretrained Discriminator\")\n", | |
| " if version19 == \"v1\" or sr2 == \"40k\":\n", | |
| " config_path = \"configs/v1/%s.json\" % sr2\n", | |
| " else:\n", | |
| " config_path = \"configs/v2/%s.json\" % sr2\n", | |
| " config_save_path = os.path.join(exp_dir, \"config.json\")\n", | |
| " if not pathlib.Path(config_save_path).exists():\n", | |
| " with open(config_save_path, \"w\", encoding=\"utf-8\") as f:\n", | |
| " with open(config_path, \"r\") as config_file:\n", | |
| " config_data = json.load(config_file)\n", | |
| " json.dump(\n", | |
| " config_data,\n", | |
| " f,\n", | |
| " ensure_ascii=False,\n", | |
| " indent=4,\n", | |
| " sort_keys=True,\n", | |
| " )\n", | |
| " f.write(\"\\n\")\n", | |
| "\n", | |
| " cmd = (\n", | |
| " 'python infer/modules/train/train.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'\n", | |
| " % (\n", | |
| " exp_dir1,\n", | |
| " sr2,\n", | |
| " 1 if if_f0_3 else 0,\n", | |
| " batch_size12,\n", | |
| " gpus16,\n", | |
| " total_epoch11,\n", | |
| " save_epoch10,\n", | |
| " \"-pg %s\" % pretrained_G14 if pretrained_G14 != \"\" else \"\",\n", | |
| " \"-pd %s\" % pretrained_D15 if pretrained_D15 != \"\" else \"\",\n", | |
| " 1 if if_save_latest13 == True else 0,\n", | |
| " 1 if if_cache_gpu17 == True else 0,\n", | |
| " 1 if if_save_every_weights18 == True else 0,\n", | |
| " version19,\n", | |
| " )\n", | |
| " )\n", | |
| " # Use PIPE to capture the output and error streams\n", | |
| " p = Popen(cmd, shell=True, cwd=now_dir, stdout=PIPE, stderr=STDOUT, bufsize=1, universal_newlines=True)\n", | |
| "\n", | |
| " # Print the command's output as it runs\n", | |
| " for line in p.stdout:\n", | |
| " print(line.strip())\n", | |
| "\n", | |
| " # Wait for the process to finish\n", | |
| " p.wait()\n", | |
| " return \"训练结束, 您可查看控制台训练日志或实验文件夹下的train.log\"\n", | |
| "# %load_ext tensorboard\n", | |
| "# %tensorboard --logdir ./logs --port=8888\n", | |
| "if \"cache\" not in locals():\n", | |
| " cache = False\n", | |
| "training_log = click_train(\n", | |
| " model_name,\n", | |
| " sample_rate,\n", | |
| " True,\n", | |
| " 0,\n", | |
| " save_frequency,\n", | |
| " epochs,\n", | |
| " batch_size,\n", | |
| " True,\n", | |
| " G_file,\n", | |
| " D_file,\n", | |
| " 0,\n", | |
| " cache,\n", | |
| " True,\n", | |
| " 'v2',\n", | |
| ")\n", | |
| "print(training_log)" | |
| ], | |
| "metadata": { | |
| "id": "FFfC9x239kC1", | |
| "cellView": "form" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "---" | |
| ], | |
| "metadata": { | |
| "id": "s7iqw6snwVpo" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "#@title **Backup Model To Google Drive**\n", | |
| "\n", | |
| "import os\n", | |
| "\n", | |
| "if not os.path.exists('/content/RVC'):\n", | |
| " print(\"You need to run the first cell before loading your model! Run the GUI, stop it and then load the model.\")\n", | |
| "else:\n", | |
| " Model_Name = model_name\n", | |
| " folder = Model_Name\n", | |
| " Type = \"Save\"\n", | |
| " import tarfile, os\n", | |
| " from google.colab import drive\n", | |
| " drive.mount('/content/drive')\n", | |
| " !mkdir -p /content/drive/MyDrive/RVC_Packages\n", | |
| " if Type=='Save':\n", | |
| " with tarfile.open(f'/content/drive/MyDrive/RVC_Packages/{folder}.tar.gz','w:gz') as tar:\n", | |
| " tar.add(f'/content/RVC/logs/{folder}', arcname=f'logs/{folder}')\n", | |
| " if os.path.exists(f'/content/RVC/assets/weights/{folder}.pth'):\n", | |
| " tar.add(f'/content/RVC/assets/weights/{folder}.pth', arcname=f'assets/weights/{folder}.pth')\n", | |
| " print(f'Backed up {folder} to RVC_Packages in your google drive.')\n", | |
| " else:\n", | |
| " if not os.path.exists(f'/content/drive/MyDrive/RVC_Packages/{folder}.tar.gz'):\n", | |
| " print(\"File not found.\")\n", | |
| " else:\n", | |
| " with tarfile.open(f'/content/drive/MyDrive/RVC_Packages/{folder}.tar.gz','r:gz') as tar:\n", | |
| " tar.extractall('/content/RVC')" | |
| ], | |
| "metadata": { | |
| "id": "vHnpTxSd4wXe", | |
| "cellView": "form" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "# FOR INFERENCE" | |
| ], | |
| "metadata": { | |
| "id": "x7HHUYWGPxY8" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "#@title **Load Model From Google Drive**\n", | |
| "\n", | |
| "\n", | |
| "!pip install --upgrade --no-cache-dir gdown\n", | |
| "import tarfile\n", | |
| "\n", | |
| "#@markdown Name of the Model\n", | |
| "Model_Name = \"nico-500\"#@param {type:\"string\"}\n", | |
| "\n", | |
| "\n", | |
| "#@markdown Paste the link of (.tar.gz) file from Google Drive and Remember to make it public link.\n", | |
| "\n", | |
| "\n", | |
| "model_pth_name = Model_Name + \".tar.gz\"\n", | |
| "\n", | |
| "MODEL_LINK = \"\" #@param {type:\"string\"}\n", | |
| "\n", | |
| "if MODEL_LINK != \"\":\n", | |
| " pth = '/content/sample_data/'\n", | |
| "\n", | |
| " dwnld = pth + model_pth_name\n", | |
| " print('\u001b[1;32mDownload model...')\n", | |
| " !gdown --fuzzy -O $dwnld \"$MODEL_LINK\"\n", | |
| " #clear_output()\n", | |
| " print('\u001b[1;32mDone!')\n", | |
| "else:\n", | |
| " print('\u001b[1;31mPaste model link and try again!')\n", | |
| "\n", | |
| "if not os.path.exists(f'/content/sample_data/{Model_Name}.tar.gz'):\n", | |
| " print(\"File not found.\")\n", | |
| "else:\n", | |
| " with tarfile.open(f'/content/sample_data/{Model_Name}.tar.gz','r:gz') as tar:\n", | |
| " tar.extractall('/content/RVC')\n", | |
| "\n", | |
| "if os.path.exists(f'/content/RVC/weights'):\n", | |
| " !cp -R /content/RVC/weights /content/RVC/assets\n", | |
| " !rm -R /content/RVC/weights" | |
| ], | |
| "metadata": { | |
| "cellView": "form", | |
| "id": "RUhA-npzwNf1" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "---" | |
| ], | |
| "metadata": { | |
| "id": "vgj3oey-MScg" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "#@title **Upload Target Audio:**\n", | |
| "\n", | |
| "import os\n", | |
| "from IPython.display import Audio\n", | |
| "from IPython.core.display import display\n", | |
| "\n", | |
| "# upload_method = 'Upload' #@param ['Upload']\n", | |
| "\n", | |
| "#remove previous input audio\n", | |
| "if os.path.isfile('/content/sample_data/input_audio.wav'):\n", | |
| " os.remove('/content/sample_data/input_audio.wav')\n", | |
| "\n", | |
| "def displayAudio():\n", | |
| " display(Audio('/content/sample_data/input_audio.wav'))\n", | |
| "\n", | |
| "\n", | |
| "from google.colab import files\n", | |
| "uploaded = files.upload()\n", | |
| "for fn in uploaded.keys():\n", | |
| " print('User uploaded file \"{name}\" with length {length} bytes.'.format(\n", | |
| " name=fn, length=len(uploaded[fn])))\n", | |
| "\n", | |
| "\n", | |
| "# Consider only the first file\n", | |
| "PATH_TO_YOUR_AUDIO = str(list(uploaded.keys())[0])\n", | |
| "\n", | |
| "# Load audio with specified sampling rate\n", | |
| "import librosa\n", | |
| "audio, sr = librosa.load(PATH_TO_YOUR_AUDIO, sr=None)\n", | |
| "\n", | |
| "# Save audio with specified sampling rate\n", | |
| "import soundfile as sf\n", | |
| "sf.write('/content/sample_data/input_audio.wav', audio, sr, format='wav')\n", | |
| "\n", | |
| "from IPython.display import clear_output\n", | |
| "clear_output(wait=True)\n", | |
| "\n", | |
| "displayAudio()" | |
| ], | |
| "metadata": { | |
| "id": "sYIHx-DAMO2-", | |
| "cellView": "form" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "#@title **Inference**\n", | |
| "import os\n", | |
| "import IPython.display as ipd\n", | |
| "%cd /content/RVC\n", | |
| "\n", | |
| "#@markdown Enter the name of the model you want to use.\n", | |
| "model_name = ''#@param {type:\"string\"}\n", | |
| "\n", | |
| "model_filename = model_name + '.pth'\n", | |
| "#index_filename = 'added_IVF156_Flat_nprobe_1_' + model_name + '_v2.index'\n", | |
| "\n", | |
| "###########\n", | |
| "\n", | |
| "# Setting .index File Name\n", | |
| "\n", | |
| "#Create Folder temp .index file\n", | |
| "%cd /content\n", | |
| "\n", | |
| "index_temp = 'Index_Temp'\n", | |
| "\n", | |
| "if not os.path.exists(index_temp):\n", | |
| " os.mkdir(index_temp)\n", | |
| " print(\"Index_Temp Folder Created.\")\n", | |
| "else:\n", | |
| " print(\"Index_Temp Folder Found.\")\n", | |
| "\n", | |
| "#Copying .index file to Index_Temp folder\n", | |
| "\n", | |
| "from os import listdir\n", | |
| "import shutil\n", | |
| "\n", | |
| "index_file_path = os.path.join('/content/RVC/logs/', model_name,'')\n", | |
| "\n", | |
| "for file_name in listdir(index_file_path):\n", | |
| " if file_name.startswith('added') and file_name.endswith('.index'):\n", | |
| " shutil.copy(index_file_path + file_name, os.path.join( '/content/', index_temp, file_name))\n", | |
| " print(\"File exists\")\n", | |
| " shutil.copyfile(index_file_path + file_name, os.path.join( '/content/', index_temp, file_name))\n", | |
| " print('Index File copied successfully.')\n", | |
| "\n", | |
| "#Getting the name of .index file\n", | |
| "\n", | |
| "%cd /content/Index_Temp\n", | |
| "\n", | |
| "import os\n", | |
| "\n", | |
| "# Get the current working directory\n", | |
| "indexfile_directory = os.getcwd()\n", | |
| "\n", | |
| "# List all files in the current directory\n", | |
| "files = os.listdir(indexfile_directory)\n", | |
| "\n", | |
| "# Get the first filename from the list\n", | |
| "first_filename = files[0]\n", | |
| "print(first_filename)\n", | |
| "\n", | |
| "# Save the filename as a variable\n", | |
| "index_filename = first_filename\n", | |
| "\n", | |
| "#Deleting Index_Temp folder\n", | |
| "\n", | |
| "shutil.rmtree('/content/Index_Temp')\n", | |
| "\n", | |
| "%cd /content/RVC\n", | |
| "\n", | |
| "#############\n", | |
| "\n", | |
| "model_path = \"/content/RVC/assets/weights/\" + model_filename\n", | |
| "index_path = \"/content/RVC/logs/\" + model_name + \"/\" + index_filename\n", | |
| "\n", | |
| "#model_path = \"/content/RVC/assets/weights/My-Voice.pth\"#@param {type:\"string\"}\n", | |
| "#index_path = \"/content/RVC/logs/My-Voice/added_IVF439_Flat_nprobe_1_My-Voice_v2.index\"#@param {type:\"string\"}\n", | |
| "\n", | |
| "from colorama import Fore\n", | |
| "print(Fore.GREEN + f\"{index_path} was found\") if os.path.exists(index_path) else print(Fore.RED + f\"{index_path} was not found\")\n", | |
| "\n", | |
| "\n", | |
| "\n", | |
| "pitch = 0 # @param {type:\"slider\", min:-24, max:24, step:1}\n", | |
| "\n", | |
| "#input_path = \"/content/sample_data/input_audio.wav\"#@param {type:\"string\"}\n", | |
| "input_path = \"/content/sample_data/input_audio.wav\"\n", | |
| "\n", | |
| "if not os.path.exists(input_path):\n", | |
| " raise ValueError(f\"{input_path} was not found in your RVC folder.\")\n", | |
| "os.environ['index_root'] = os.path.dirname(index_path)\n", | |
| "index_path = os.path.basename(index_path)\n", | |
| "\n", | |
| "#@markdown ---\n", | |
| "\n", | |
| "f0_method = \"harvest\" # @param [\"rmvpe\", \"pm\", \"harvest\"]\n", | |
| "\n", | |
| "save_as = \"/content/RVC/audios/output_audio.wav\"#@param {type:\"string\"}\n", | |
| "\n", | |
| "model_name = os.path.basename(model_path)\n", | |
| "os.environ['weight_root'] = os.path.dirname(model_path)\n", | |
| "index_rate = 1 # @param {type:\"slider\", min:0, max:1, step:0.01}\n", | |
| "volume_normalization = 0 #param {type:\"slider\", min:0, max:1, step:0.01}\n", | |
| "consonant_protection = 0.5 #param {type:\"slider\", min:0, max:1, step:0.01}\n", | |
| "\n", | |
| "!rm -f $save_as\n", | |
| "\n", | |
| "!python tools/cmd/infer_cli.py --f0up_key $pitch --input_path $input_path --index_path $index_path --f0method $f0_method --opt_path $save_as --model_name $model_name --index_rate $index_rate --device \"cuda:0\" --is_half True --filter_radius 3 --resample_sr 0 --rms_mix_rate $volume_normalization --protect $consonant_protection\n", | |
| "\n", | |
| "#show_errors = True #@param {type:\"boolean\"}\n", | |
| "show_errors = True\n", | |
| "\n", | |
| "if not show_errors:\n", | |
| " ipd.clear_output()\n", | |
| "ipd.Audio(save_as)" | |
| ], | |
| "metadata": { | |
| "id": "Fz3XSI8GrXra", | |
| "cellView": "form" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment