Merge branch 'dev-colab' into dev
This commit is contained in:
12
app.py
12
app.py
@@ -4,9 +4,8 @@ import os
|
||||
import sys
|
||||
|
||||
import gradio as gr
|
||||
import numpy as np
|
||||
import torch
|
||||
from gradio.processing_utils import convert_to_16_bit_wav
|
||||
import yaml
|
||||
|
||||
from common.constants import (
|
||||
DEFAULT_ASSIST_TEXT_WEIGHT,
|
||||
@@ -22,7 +21,12 @@ from common.constants import (
|
||||
)
|
||||
from common.log import logger
|
||||
from common.tts_model import ModelHolder
|
||||
from config import config
|
||||
|
||||
# Get path settings
|
||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
||||
# dataset_root = path_config["dataset_root"]
|
||||
assets_root = path_config["assets_root"]
|
||||
|
||||
languages = [l.value for l in Languages]
|
||||
|
||||
@@ -182,7 +186,7 @@ if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--cpu", action="store_true", help="Use CPU instead of GPU")
|
||||
parser.add_argument(
|
||||
"--dir", "-d", type=str, help="Model directory", default=config.out_dir
|
||||
"--dir", "-d", type=str, help="Model directory", default=assets_root
|
||||
)
|
||||
parser.add_argument(
|
||||
"--share", action="store_true", help="Share this app publicly", default=False
|
||||
|
||||
143
colab.ipynb
143
colab.ipynb
@@ -6,9 +6,10 @@
|
||||
"source": [
|
||||
"# Style-Bert-VITS2 (ver 1.2) のGoogle Colabでの学習\n",
|
||||
"\n",
|
||||
"Google driveと連携することで、Google Colab上でStyle-Bert-VITS2の学習を行うことができます。\n",
|
||||
"Google Colab上でStyle-Bert-VITS2の学習を行うことができます。\n",
|
||||
"\n",
|
||||
"このnotebookでは、あなたのGoogle Driveにフォルダ`Style-Bert-VITS2`を作り、その内部での作業を行います。他のフォルダには触れません。\n",
|
||||
"このnotebookでは、通常使用ではあなたのGoogle Driveにフォルダ`Style-Bert-VITS2`を作り、その内部での作業を行います。他のフォルダには触れません。\n",
|
||||
"Google Driveを使わない場合は、初期設定のところで適切なパスを指定してください。\n",
|
||||
"\n",
|
||||
"## 流れ\n",
|
||||
"\n",
|
||||
@@ -16,16 +17,75 @@
|
||||
"上から順に実行していけばいいです。音声合成に必要なファイルはGoogle Driveの`Style-Bert-VITS2/model_assets/`に保存されます。また、途中経過も`Style-Bert-VITS2/Data/`に保存されるので、学習を中断したり、途中から再開することもできます。\n",
|
||||
"\n",
|
||||
"### 学習を途中から再開したいとき\n",
|
||||
"1と2を行い、3の前処理は飛ばして、4から始めてください。\n"
|
||||
"0と1と2を行い、3の前処理は飛ばして、4から始めてください。\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1. Google Driveとの連携とデータの配置\n",
|
||||
"## 0. 環境構築\n",
|
||||
"\n",
|
||||
"次のセルを実行して、Google driveと連携します。"
|
||||
"Style-Bert-VITS2の環境をcolab上に構築します。グラボモードが有効になっていることを確認し、以下のセルを順に実行してください。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#@title このセルを実行して環境構築してください。\n",
|
||||
"#@markdown 最後に赤文字でエラーや警告が出ても何故かうまくいくみたいです。\n",
|
||||
"\n",
|
||||
"!git clone https://github.com/litagin02/Style-Bert-VITS2.git\n",
|
||||
"%cd Style-Bert-VITS2/\n",
|
||||
"!pip install -r requirements.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#@title 必要なモデルのダウンロード\n",
|
||||
"\n",
|
||||
"!python initialize.py"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1. 初期設定\n",
|
||||
"\n",
|
||||
"学習とその結果を保存するディレクトリ名を指定します。\n",
|
||||
"Google driveの場合はそのまま実行、カスタマイズしたい方は変更して実行してください。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dataset_root = \"/content/drive/MyDrive/Style-Bert-VITS2/Data\"\n",
|
||||
"assets_root = \"/content/drive/MyDrive/Style-Bert-VITS2/model_assets\"\n",
|
||||
"\n",
|
||||
"import yaml\n",
|
||||
"\n",
|
||||
"with open(\"configs/paths.yml\", \"w\", encoding=\"utf-8\") as f:\n",
|
||||
" yaml.dump({\"dataset_root\": dataset_root, \"assets_root\": assets_root}, f)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2. Google Driveとの連携とデータの配置\n",
|
||||
"\n",
|
||||
"Google driveにデータを保存する方は、次のセルを実行して、Google driveと連携します。"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -48,7 +108,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"次のセルを実行して、Google driveの中にStyle-Bert-VITS2フォルダと、学習データをいれるDataフォルダを作成します。"
|
||||
"次のセルを実行して、学習データをいれるフォルダ(1で設定した`dataset_root`)を作成します。"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -61,7 +121,7 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.makedirs((\"/content/drive/MyDrive/Style-Bert-VITS2/Data/\"), exist_ok=True)"
|
||||
"os.makedirs(dataset_root, exist_ok=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -104,55 +164,6 @@
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2. 環境構築\n",
|
||||
"\n",
|
||||
"Style-Bert-VITS2の環境をcolab上に構築します。グラボモードが有効になっていることを確認し、以下のセルを順に実行してください。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"cellView": "form",
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 1000
|
||||
},
|
||||
"id": "0CH9aI_MOmTA",
|
||||
"outputId": "34cf1e8f-23b9-4d2b-e040-ea5a3ec44a82"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#@title このセルを実行して環境構築してください。\n",
|
||||
"#@markdown 最後に赤文字でエラーや警告が出ても何故かうまくいくみたいです。\n",
|
||||
"\n",
|
||||
"!git clone https://github.com/litagin02/Style-Bert-VITS2.git\n",
|
||||
"%cd Style-Bert-VITS2/\n",
|
||||
"!pip install -r requirements.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"cellView": "form",
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "CpLs5YoNPe4Z",
|
||||
"outputId": "0edd3309-08d1-4372-e47a-6a805a74b620"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#@title 必要なモデルのダウンロード\n",
|
||||
"\n",
|
||||
"!python initialize.py"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -178,7 +189,8 @@
|
||||
"# 学習のバッチサイズ。4ぐらいが最適か。VRAMのはみ出具合に応じて調整してください。\n",
|
||||
"batch_size = 4\n",
|
||||
"\n",
|
||||
"# 学習のエポック数(データセットを合計何周するか)。100ぐらいで十分だと思われます。\n",
|
||||
"# 学習のエポック数(データセットを合計何周するか)。\n",
|
||||
"# 100ぐらいで十分かもしれませんが、もっと多くやると質が上がるのかもしれません。\n",
|
||||
"epochs = 100\n",
|
||||
"\n",
|
||||
"# 保存頻度。何ステップごとにモデルを保存するか。分からなければデフォルトのままで。\n",
|
||||
@@ -256,15 +268,15 @@
|
||||
"from webui_train import get_path\n",
|
||||
"\n",
|
||||
"dataset_path, _, _, _, config_path = get_path(model_name)\n",
|
||||
"\n",
|
||||
"with open(\"default_config.yml\", \"r\", encoding=\"utf-8\") as f:\n",
|
||||
" yml_data = yaml.safe_load(f)\n",
|
||||
"yml_data[\"model_name\"] = model_name\n",
|
||||
"yml_data[\"dataset_path\"] = dataset_path\n",
|
||||
"with open(\"config.yml\", \"w\", encoding=\"utf-8\") as f:\n",
|
||||
" yaml.dump(yml_data, f, allow_unicode=True)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"!python train_ms.py --config {config_path} --model {dataset_path}"
|
||||
"!python train_ms.py --config {config_path} --model {dataset_path} --asset_root {assets_root}"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -280,7 +292,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#@title 学習結果を試すならここから\n",
|
||||
"!python app.py --share --dir \"/content/drive/MyDrive/Style-Bert-VITS2/model_assets/\""
|
||||
"!python app.py --share --dir {assets_root}"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -295,7 +307,16 @@
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
31
config.py
31
config.py
@@ -205,7 +205,7 @@ class Translate_config:
|
||||
|
||||
|
||||
class Config:
|
||||
def __init__(self, config_path: str):
|
||||
def __init__(self, config_path: str, path_config: dict[str, str]):
|
||||
if not os.path.isfile(config_path) and os.path.isfile("default_config.yml"):
|
||||
shutil.copy(src="default_config.yml", dst=config_path)
|
||||
print(
|
||||
@@ -222,12 +222,10 @@ class Config:
|
||||
if "dataset_path" in yaml_config:
|
||||
dataset_path = yaml_config["dataset_path"]
|
||||
else:
|
||||
dataset_path = f"Data/{model_name}"
|
||||
self.out_dir = yaml_config["out_dir"]
|
||||
# openi_token: str = yaml_config["openi_token"]
|
||||
dataset_path = os.path.join(path_config["dataset_root"], model_name)
|
||||
self.dataset_path: str = dataset_path
|
||||
# self.mirror: str = yaml_config["mirror"]
|
||||
# self.openi_token: str = openi_token
|
||||
self.assets_root: str = path_config["assets_root"]
|
||||
self.out_dir = os.path.join(self.assets_root, model_name)
|
||||
self.resample_config: Resample_config = Resample_config.from_dict(
|
||||
dataset_path, yaml_config["resample"]
|
||||
)
|
||||
@@ -256,14 +254,27 @@ class Config:
|
||||
# )
|
||||
|
||||
|
||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
||||
# Should contain the following keys:
|
||||
# - dataset_root: the root directory of the dataset, default to "Data"
|
||||
# - assets_root: the root directory of the assets, default to "model_assets"
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
# 为避免与以前的config.json起冲突,将其更名如下
|
||||
parser.add_argument("-y", "--yml_config", type=str, default="config.yml")
|
||||
args, _ = parser.parse_known_args()
|
||||
parser.add_argument(
|
||||
"-y",
|
||||
"--yml_config",
|
||||
type=str,
|
||||
default="config.yml",
|
||||
help="Path to setting yaml file.",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
config = Config(args.yml_config)
|
||||
config = Config(args.yml_config, path_config)
|
||||
except TypeError:
|
||||
logger.warning("Old config.yml found. Replace it with default_config.yml.")
|
||||
shutil.copy(src="default_config.yml", dst="config.yml")
|
||||
config = Config("config.yml")
|
||||
config = Config("config.yml", path_config)
|
||||
|
||||
8
configs/paths.yml
Normal file
8
configs/paths.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
# Root directory of the training dataset.
|
||||
# The training dataset of {model_name} should be placed in {dataset_root}/{model_name}.
|
||||
dataset_root: Data
|
||||
|
||||
# Root directory of the model assets (for inference).
|
||||
# In training, the model assets will be saved to {assets_root}/{model_name},
|
||||
# and in inference, we load all the models from {assets_root}.
|
||||
assets_root: model_assets
|
||||
@@ -1,24 +1,20 @@
|
||||
# Global configuration file for Bert-VITS2
|
||||
|
||||
model_name: "model_name"
|
||||
|
||||
out_dir: "model_assets"
|
||||
|
||||
# If you want to use a specific dataset path, uncomment the following line.
|
||||
# Otherwise, the dataset path is `Data/{model_name}`.
|
||||
# Otherwise, the dataset path is `{dataset_root}/{model_name}`.
|
||||
|
||||
# dataset_path: "your/dataset/path"
|
||||
|
||||
resample:
|
||||
sampling_rate: 44100
|
||||
in_dir: "audios/raw"
|
||||
out_dir: "audios/wavs"
|
||||
in_dir: "raw"
|
||||
out_dir: "wavs"
|
||||
|
||||
preprocess_text:
|
||||
transcription_path: "filelists/esd.list"
|
||||
transcription_path: "esd.list"
|
||||
cleaned_path: ""
|
||||
train_path: "filelists/train.list"
|
||||
val_path: "filelists/val.list"
|
||||
train_path: "train.list"
|
||||
val_path: "val.list"
|
||||
config_path: "config.json"
|
||||
val_per_lang: 4
|
||||
max_val_total: 12
|
||||
@@ -42,13 +38,13 @@ train_ms:
|
||||
WORLD_SIZE: 1
|
||||
LOCAL_RANK: 0
|
||||
RANK: 0
|
||||
model: "models"
|
||||
model_dir: "models" # The directory to save the model (for training), relative to `{dataset_root}/{model_name}`.
|
||||
config_path: "config.json"
|
||||
num_workers: 16
|
||||
spec_cache: True
|
||||
keep_ckpts: 1 # Set this to 0 to keep all checkpoints
|
||||
|
||||
webui:
|
||||
webui: # For `webui.py`, which is not supported yet in Style-Bert-VITS2.
|
||||
# 推理设备
|
||||
device: "cuda"
|
||||
# 模型路径
|
||||
|
||||
@@ -12,7 +12,7 @@ def set_style_config(json_path, output_path):
|
||||
json_dict["data"]["num_styles"] = 1
|
||||
json_dict["data"]["style2id"] = {DEFAULT_STYLE: 0}
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
json.dump(json_dict, f, indent=2)
|
||||
json.dump(json_dict, f, indent=2, ensure_ascii=False)
|
||||
logger.info(f"Save style config (only {DEFAULT_STYLE}) to {output_path}")
|
||||
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--cpu", action="store_true", help="Use CPU instead of GPU")
|
||||
parser.add_argument(
|
||||
"--dir", "-d", type=str, help="Model directory", default=config.out_dir
|
||||
"--dir", "-d", type=str, help="Model directory", default=config.assets_root
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
86
train_ms.py
86
train_ms.py
@@ -19,6 +19,8 @@ from tqdm import tqdm
|
||||
import commons
|
||||
import default_style
|
||||
import utils
|
||||
from common.log import logger
|
||||
from common.stdout_wrapper import SAFE_STDOUT
|
||||
from config import config
|
||||
from data_utils import (
|
||||
DistributedBucketSampler,
|
||||
@@ -29,8 +31,6 @@ from losses import discriminator_loss, feature_loss, generator_loss, kl_loss
|
||||
from mel_processing import mel_spectrogram_torch, spec_to_mel_torch
|
||||
from models import DurationDiscriminator, MultiPeriodDiscriminator, SynthesizerTrn
|
||||
from text.symbols import symbols
|
||||
from common.log import logger
|
||||
from common.stdout_wrapper import SAFE_STDOUT
|
||||
|
||||
torch.backends.cuda.matmul.allow_tf32 = True
|
||||
torch.backends.cudnn.allow_tf32 = (
|
||||
@@ -44,12 +44,6 @@ torch.backends.cuda.enable_mem_efficient_sdp(
|
||||
) # Not available if torch version is lower than 2.0
|
||||
torch.backends.cuda.enable_math_sdp(True)
|
||||
|
||||
try:
|
||||
import google.colab
|
||||
|
||||
IS_COLAB = True
|
||||
except ImportError:
|
||||
IS_COLAB = False
|
||||
|
||||
global_step = 0
|
||||
|
||||
@@ -86,7 +80,7 @@ def run():
|
||||
# 命令行/config.yml配置解析
|
||||
# hps = utils.get_hparams()
|
||||
parser = argparse.ArgumentParser()
|
||||
# 非必要不建议使用命令行配置,请使用config.yml文件
|
||||
# Command line configuration is not recommended unless necessary, use config.yml
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
@@ -102,12 +96,26 @@ def run():
|
||||
help="数据集文件夹路径,请注意,数据不再默认放在/logs文件夹下。如果需要用命令行配置,请声明相对于根目录的路径",
|
||||
default=config.dataset_path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--assets_root",
|
||||
type=str,
|
||||
help="Root directory of model assets needed for inference.",
|
||||
default=config.assets_root,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip_default_style",
|
||||
action="store_true",
|
||||
help="Skip saving default style config and mean vector.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
model_dir = os.path.join(args.model, config.train_ms_config.model)
|
||||
if not os.path.exists(model_dir):
|
||||
os.makedirs(model_dir)
|
||||
hps = utils.get_hparams_from_file(args.config)
|
||||
|
||||
# This is needed because we have to pass `model_dir` to `train_and_evaluate()`
|
||||
hps.model_dir = model_dir
|
||||
|
||||
# 比较路径是否相同
|
||||
if os.path.realpath(args.config) != os.path.realpath(
|
||||
config.train_ms_config.config_path
|
||||
@@ -125,30 +133,26 @@ def run():
|
||||
|
||||
args.model: For saving all info needed for training.
|
||||
default: `Data/{model_name}`.
|
||||
hps.model_dir = model_dir: For saving checkpoints (for resuming training).
|
||||
hps.model_dir := model_dir: For saving checkpoints (for resuming training).
|
||||
default: `Data/{model_name}/models`.
|
||||
(Use `hps` since we have to pass `model_dir` to `train_and_evaluate()`.
|
||||
|
||||
config.out_dir: Root directory of model assets needed for inference.
|
||||
default: `model_assets`.
|
||||
args.assets_root: The root directory of model assets needed for inference.
|
||||
default: config.assets_root == `model_assets`.
|
||||
|
||||
out_dir: For saving resulting models (for inference).
|
||||
default: `model_assets/{model_name}`, which is used for inference.
|
||||
config.out_dir: The directory for model assets of this model (for inference).
|
||||
default: `model_assets/{model_name}`.
|
||||
"""
|
||||
if IS_COLAB:
|
||||
config.out_dir = "/content/drive/MyDrive/Style-Bert-VITS2/model_assets"
|
||||
logger.info(
|
||||
"Colab detected, so use mounted Google Drive as directory for saving resulting models:"
|
||||
)
|
||||
logger.info(config.out_dir)
|
||||
os.makedirs(config.out_dir, exist_ok=True)
|
||||
out_dir = os.path.join(config.out_dir, config.model_name)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
if not args.skip_default_style:
|
||||
# Save default style to out_dir
|
||||
default_style.set_style_config(args.config, os.path.join(out_dir, "config.json"))
|
||||
default_style.set_style_config(
|
||||
args.config, os.path.join(config.out_dir, "config.json")
|
||||
)
|
||||
default_style.save_mean_vector(
|
||||
os.path.join(args.model, "wavs"),
|
||||
os.path.join(out_dir, "style_vectors.npy"),
|
||||
os.path.join(config.out_dir, "style_vectors.npy"),
|
||||
)
|
||||
|
||||
torch.manual_seed(hps.train.seed)
|
||||
@@ -158,10 +162,10 @@ def run():
|
||||
if rank == 0:
|
||||
# logger = utils.get_logger(hps.model_dir)
|
||||
# logger.info(hps)
|
||||
logger.add(os.path.join(hps.model_dir, "train.log"))
|
||||
utils.check_git_hash(hps.model_dir)
|
||||
writer = SummaryWriter(log_dir=hps.model_dir)
|
||||
writer_eval = SummaryWriter(log_dir=os.path.join(hps.model_dir, "eval"))
|
||||
logger.add(os.path.join(model_dir, "train.log"))
|
||||
utils.check_git_hash(model_dir)
|
||||
writer = SummaryWriter(log_dir=model_dir)
|
||||
writer_eval = SummaryWriter(log_dir=os.path.join(model_dir, "eval"))
|
||||
train_dataset = TextAudioSpeakerLoader(hps.data.training_files, hps.data)
|
||||
train_sampler = DistributedBucketSampler(
|
||||
train_dataset,
|
||||
@@ -284,10 +288,10 @@ def run():
|
||||
net_dur_disc, device_ids=[local_rank], find_unused_parameters=True
|
||||
)
|
||||
|
||||
if utils.is_resuming(hps.model_dir):
|
||||
if utils.is_resuming(model_dir):
|
||||
if net_dur_disc is not None:
|
||||
_, _, dur_resume_lr, epoch_str = utils.load_checkpoint(
|
||||
utils.latest_checkpoint_path(hps.model_dir, "DUR_*.pth"),
|
||||
utils.latest_checkpoint_path(model_dir, "DUR_*.pth"),
|
||||
net_dur_disc,
|
||||
optim_dur_disc,
|
||||
skip_optimizer=hps.train.skip_optimizer
|
||||
@@ -297,7 +301,7 @@ def run():
|
||||
if not optim_dur_disc.param_groups[0].get("initial_lr"):
|
||||
optim_dur_disc.param_groups[0]["initial_lr"] = dur_resume_lr
|
||||
_, optim_g, g_resume_lr, epoch_str = utils.load_checkpoint(
|
||||
utils.latest_checkpoint_path(hps.model_dir, "G_*.pth"),
|
||||
utils.latest_checkpoint_path(model_dir, "G_*.pth"),
|
||||
net_g,
|
||||
optim_g,
|
||||
skip_optimizer=hps.train.skip_optimizer
|
||||
@@ -305,7 +309,7 @@ def run():
|
||||
else True,
|
||||
)
|
||||
_, optim_d, d_resume_lr, epoch_str = utils.load_checkpoint(
|
||||
utils.latest_checkpoint_path(hps.model_dir, "D_*.pth"),
|
||||
utils.latest_checkpoint_path(model_dir, "D_*.pth"),
|
||||
net_d,
|
||||
optim_d,
|
||||
skip_optimizer=hps.train.skip_optimizer
|
||||
@@ -320,7 +324,7 @@ def run():
|
||||
epoch_str = max(epoch_str, 1)
|
||||
# global_step = (epoch_str - 1) * len(train_loader)
|
||||
global_step = int(
|
||||
utils.get_steps(utils.latest_checkpoint_path(hps.model_dir, "G_*.pth"))
|
||||
utils.get_steps(utils.latest_checkpoint_path(model_dir, "G_*.pth"))
|
||||
)
|
||||
logger.info(
|
||||
f"******************检测到模型存在,epoch为 {epoch_str},gloabl step为 {global_step}*********************"
|
||||
@@ -328,14 +332,14 @@ def run():
|
||||
else:
|
||||
try:
|
||||
_ = utils.load_safetensors(
|
||||
os.path.join(hps.model_dir, "G_0.safetensors"), net_g
|
||||
os.path.join(model_dir, "G_0.safetensors"), net_g
|
||||
)
|
||||
_ = utils.load_safetensors(
|
||||
os.path.join(hps.model_dir, "D_0.safetensors"), net_d
|
||||
os.path.join(model_dir, "D_0.safetensors"), net_d
|
||||
)
|
||||
if net_dur_disc is not None:
|
||||
_ = utils.load_safetensors(
|
||||
os.path.join(hps.model_dir, "DUR_0.safetensors"), net_dur_disc
|
||||
os.path.join(model_dir, "DUR_0.safetensors"), net_dur_disc
|
||||
)
|
||||
logger.info("Loaded the pretrained models.")
|
||||
except Exception as e:
|
||||
@@ -402,14 +406,14 @@ def run():
|
||||
optim_g,
|
||||
hps.train.learning_rate,
|
||||
epoch,
|
||||
os.path.join(hps.model_dir, "G_{}.pth".format(global_step)),
|
||||
os.path.join(model_dir, "G_{}.pth".format(global_step)),
|
||||
)
|
||||
utils.save_checkpoint(
|
||||
net_d,
|
||||
optim_d,
|
||||
hps.train.learning_rate,
|
||||
epoch,
|
||||
os.path.join(hps.model_dir, "D_{}.pth".format(global_step)),
|
||||
os.path.join(model_dir, "D_{}.pth".format(global_step)),
|
||||
)
|
||||
if net_dur_disc is not None:
|
||||
utils.save_checkpoint(
|
||||
@@ -417,13 +421,13 @@ def run():
|
||||
optim_dur_disc,
|
||||
hps.train.learning_rate,
|
||||
epoch,
|
||||
os.path.join(hps.model_dir, "DUR_{}.pth".format(global_step)),
|
||||
os.path.join(model_dir, "DUR_{}.pth".format(global_step)),
|
||||
)
|
||||
utils.save_safetensors(
|
||||
net_g,
|
||||
epoch,
|
||||
os.path.join(
|
||||
out_dir,
|
||||
config.out_dir,
|
||||
f"{config.model_name}_e{epoch}_s{global_step}.safetensors",
|
||||
),
|
||||
for_infer=True,
|
||||
@@ -690,12 +694,12 @@ def train_and_evaluate(
|
||||
n_ckpts_to_keep=keep_ckpts,
|
||||
sort_by_time=True,
|
||||
)
|
||||
# Save safetensors (for inference) to `model_assets/{model_name}`
|
||||
utils.save_safetensors(
|
||||
net_g,
|
||||
epoch,
|
||||
os.path.join(
|
||||
config.out_dir,
|
||||
config.model_name,
|
||||
f"{config.model_name}_e{epoch}_s{global_step}.safetensors",
|
||||
),
|
||||
for_infer=True,
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import os
|
||||
|
||||
import gradio as gr
|
||||
import yaml
|
||||
|
||||
from common.log import logger
|
||||
from common.subprocess_utils import run_script_with_log, second_elem_of
|
||||
from common.subprocess_utils import run_script_with_log
|
||||
|
||||
# Get path settings
|
||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
||||
dataset_root = path_config["dataset_root"]
|
||||
# assets_root = path_config["assets_root"]
|
||||
|
||||
|
||||
def do_slice(model_name: str, min_sec: float, max_sec: float, input_dir="inputs"):
|
||||
logger.info("Start slicing...")
|
||||
output_dir = os.path.join("Data", model_name, "raw")
|
||||
input_dir = "inputs"
|
||||
output_dir = os.path.join(dataset_root, model_name, "raw")
|
||||
cmd = [
|
||||
"slice.py",
|
||||
"--input_dir",
|
||||
@@ -30,8 +38,8 @@ def do_transcribe(model_name, whisper_model, compute_type, language, initial_pro
|
||||
if initial_prompt == "":
|
||||
initial_prompt = "こんにちは。元気、ですかー?私は……ちゃんと元気だよ!"
|
||||
logger.debug(f"initial_prompt: {initial_prompt}")
|
||||
input_dir = os.path.join("Data", model_name, "raw")
|
||||
output_file = os.path.join("Data", model_name, "esd.list")
|
||||
input_dir = os.path.join(dataset_root, model_name, "raw")
|
||||
output_file = os.path.join(dataset_root, model_name, "esd.list")
|
||||
result = run_script_with_log(
|
||||
[
|
||||
"transcribe.py",
|
||||
|
||||
@@ -5,14 +5,13 @@ import sys
|
||||
import gradio as gr
|
||||
import numpy as np
|
||||
import torch
|
||||
import yaml
|
||||
from safetensors import safe_open
|
||||
from safetensors.torch import save_file
|
||||
|
||||
|
||||
from config import config
|
||||
from common.tts_model import Model, ModelHolder
|
||||
from common.log import logger
|
||||
from common.constants import DEFAULT_STYLE
|
||||
from common.log import logger
|
||||
from common.tts_model import Model, ModelHolder
|
||||
|
||||
voice_keys = ["dec", "flow"]
|
||||
speech_style_keys = ["enc_p"]
|
||||
@@ -20,8 +19,13 @@ tempo_keys = ["sdp", "dp"]
|
||||
|
||||
device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||
|
||||
model_dir = config.out_dir
|
||||
model_holder = ModelHolder(model_dir, device)
|
||||
# Get path settings
|
||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
||||
# dataset_root = path_config["dataset_root"]
|
||||
assets_root = path_config["assets_root"]
|
||||
|
||||
model_holder = ModelHolder(assets_root, device)
|
||||
|
||||
|
||||
def merge_style(model_name_a, model_name_b, weight, output_name, style_triple_list):
|
||||
@@ -37,17 +41,17 @@ def merge_style(model_name_a, model_name_b, weight, output_name, style_triple_li
|
||||
raise ValueError("No element with {DEFAULT_STYLE} output style name found.")
|
||||
|
||||
style_vectors_a = np.load(
|
||||
os.path.join(model_dir, model_name_a, "style_vectors.npy")
|
||||
os.path.join(assets_root, model_name_a, "style_vectors.npy")
|
||||
) # (style_num_a, 256)
|
||||
style_vectors_b = np.load(
|
||||
os.path.join(model_dir, model_name_b, "style_vectors.npy")
|
||||
os.path.join(assets_root, model_name_b, "style_vectors.npy")
|
||||
) # (style_num_b, 256)
|
||||
with open(
|
||||
os.path.join(model_dir, model_name_a, "config.json"), encoding="utf-8"
|
||||
os.path.join(assets_root, model_name_a, "config.json"), encoding="utf-8"
|
||||
) as f:
|
||||
config_a = json.load(f)
|
||||
with open(
|
||||
os.path.join(model_dir, model_name_b, "config.json"), encoding="utf-8"
|
||||
os.path.join(assets_root, model_name_b, "config.json"), encoding="utf-8"
|
||||
) as f:
|
||||
config_b = json.load(f)
|
||||
style2id_a = config_a["data"]["style2id"]
|
||||
@@ -69,7 +73,7 @@ def merge_style(model_name_a, model_name_b, weight, output_name, style_triple_li
|
||||
new_style2id[style_out] = len(new_style_vecs) - 1
|
||||
new_style_vecs = np.array(new_style_vecs)
|
||||
|
||||
output_style_path = os.path.join(model_dir, output_name, "style_vectors.npy")
|
||||
output_style_path = os.path.join(assets_root, output_name, "style_vectors.npy")
|
||||
np.save(output_style_path, new_style_vecs)
|
||||
|
||||
new_config = config_a.copy()
|
||||
@@ -77,9 +81,9 @@ def merge_style(model_name_a, model_name_b, weight, output_name, style_triple_li
|
||||
new_config["data"]["style2id"] = new_style2id
|
||||
new_config["model_name"] = output_name
|
||||
with open(
|
||||
os.path.join(model_dir, output_name, "config.json"), "w", encoding="utf-8"
|
||||
os.path.join(assets_root, output_name, "config.json"), "w", encoding="utf-8"
|
||||
) as f:
|
||||
json.dump(new_config, f, indent=2)
|
||||
json.dump(new_config, f, indent=2, ensure_ascii=False)
|
||||
|
||||
return output_style_path, list(new_style2id.keys())
|
||||
|
||||
@@ -120,7 +124,7 @@ def merge_models(
|
||||
)
|
||||
|
||||
merged_model_path = os.path.join(
|
||||
model_dir, output_name, f"{output_name}.safetensors"
|
||||
assets_root, output_name, f"{output_name}.safetensors"
|
||||
)
|
||||
os.makedirs(os.path.dirname(merged_model_path), exist_ok=True)
|
||||
save_file(merged_model_weight, merged_model_path)
|
||||
@@ -180,9 +184,9 @@ def merge_style_gr(
|
||||
|
||||
|
||||
def simple_tts(model_name, text, style=DEFAULT_STYLE, emotion_weight=1.0):
|
||||
model_path = os.path.join(model_dir, model_name, f"{model_name}.safetensors")
|
||||
config_path = os.path.join(model_dir, model_name, "config.json")
|
||||
style_vec_path = os.path.join(model_dir, model_name, "style_vectors.npy")
|
||||
model_path = os.path.join(assets_root, model_name, f"{model_name}.safetensors")
|
||||
config_path = os.path.join(assets_root, model_name, "config.json")
|
||||
style_vec_path = os.path.join(assets_root, model_name, "style_vectors.npy")
|
||||
|
||||
model = Model(model_path, config_path, style_vec_path, device)
|
||||
return model.infer(text, style=style, style_weight=emotion_weight)
|
||||
@@ -194,12 +198,12 @@ def update_two_model_names_dropdown():
|
||||
|
||||
|
||||
def load_styles_gr(model_name_a, model_name_b):
|
||||
config_path_a = os.path.join(model_dir, model_name_a, "config.json")
|
||||
config_path_a = os.path.join(assets_root, model_name_a, "config.json")
|
||||
with open(config_path_a, encoding="utf-8") as f:
|
||||
config_a = json.load(f)
|
||||
styles_a = list(config_a["data"]["style2id"].keys())
|
||||
|
||||
config_path_b = os.path.join(model_dir, model_name_b, "config.json")
|
||||
config_path_b = os.path.join(assets_root, model_name_b, "config.json")
|
||||
with open(config_path_b, encoding="utf-8") as f:
|
||||
config_b = json.load(f)
|
||||
styles_b = list(config_b["data"]["style2id"].keys())
|
||||
@@ -245,7 +249,7 @@ Happy, Surprise, HappySurprise
|
||||
|
||||
model_names = model_holder.model_names
|
||||
if len(model_names) == 0:
|
||||
logger.error(f"モデルが見つかりませんでした。{model_dir}にモデルを置いてください。")
|
||||
logger.error(f"モデルが見つかりませんでした。{assets_root}にモデルを置いてください。")
|
||||
sys.exit(1)
|
||||
initial_id = 0
|
||||
initial_model_files = model_holder.model_files_dict[model_names[initial_id]]
|
||||
|
||||
@@ -114,7 +114,7 @@ def do_clustering_gradio(n_clusters=4, method="KMeans"):
|
||||
|
||||
def save_style_vectors(model_name, style_names: str):
|
||||
"""centerとcentroidsを保存する"""
|
||||
result_dir = os.path.join(config.out_dir, model_name)
|
||||
result_dir = os.path.join(config.assets_root, model_name)
|
||||
os.makedirs(result_dir, exist_ok=True)
|
||||
style_vectors = np.stack([mean] + centroids)
|
||||
style_vector_path = os.path.join(result_dir, "style_vectors.npy")
|
||||
@@ -136,7 +136,7 @@ def save_style_vectors(model_name, style_names: str):
|
||||
style_dict = {name: i for i, name in enumerate(style_name_list)}
|
||||
json_dict["data"]["style2id"] = style_dict
|
||||
with open(config_path, "w", encoding="utf-8") as f:
|
||||
json.dump(json_dict, f, indent=2)
|
||||
json.dump(json_dict, f, indent=2, ensure_ascii=False)
|
||||
return f"成功!\n{style_vector_path}に保存し{config_path}を更新しました。"
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ def save_style_vectors_from_files(model_name, audio_files_text, style_names_text
|
||||
return "Error: スタイルベクトルを読み込んでください。"
|
||||
mean = np.mean(x, axis=0)
|
||||
|
||||
result_dir = os.path.join(config.out_dir, model_name)
|
||||
result_dir = os.path.join(config.assets_root, model_name)
|
||||
os.makedirs(result_dir, exist_ok=True)
|
||||
audio_files = audio_files_text.split(",")
|
||||
style_names = style_names_text.split(",")
|
||||
@@ -182,7 +182,7 @@ def save_style_vectors_from_files(model_name, audio_files_text, style_names_text
|
||||
json_dict["data"]["style2id"] = style_dict
|
||||
|
||||
with open(config_path, "w", encoding="utf-8") as f:
|
||||
json.dump(json_dict, f, indent=2)
|
||||
json.dump(json_dict, f, indent=2, ensure_ascii=False)
|
||||
return f"成功!\n{style_vector_path}に保存し{config_path}を更新しました。"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
from multiprocessing import cpu_count
|
||||
|
||||
import gradio as gr
|
||||
@@ -10,24 +9,16 @@ import yaml
|
||||
from common.log import logger
|
||||
from common.subprocess_utils import run_script_with_log, second_elem_of
|
||||
|
||||
try:
|
||||
import google.colab
|
||||
|
||||
IS_COLAB = True
|
||||
except ImportError:
|
||||
IS_COLAB = False
|
||||
# Get path settings
|
||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
||||
dataset_root = path_config["dataset_root"]
|
||||
# assets_root = path_config["assets_root"]
|
||||
|
||||
|
||||
def get_path(model_name):
|
||||
assert model_name != "", "モデル名は空にできません"
|
||||
if IS_COLAB:
|
||||
logger.info("Colab detected, so use mounted Google Drive as dataset path:")
|
||||
dataset_path = os.path.join(
|
||||
"/content/drive/MyDrive/Style-Bert-VITS2/Data", model_name
|
||||
)
|
||||
logger.info(dataset_path)
|
||||
else:
|
||||
dataset_path = os.path.join("Data", model_name)
|
||||
dataset_path = os.path.join(dataset_root, model_name)
|
||||
lbl_path = os.path.join(dataset_path, "esd.list")
|
||||
train_path = os.path.join(dataset_path, "train.list")
|
||||
val_path = os.path.join(dataset_path, "val.list")
|
||||
@@ -61,13 +52,12 @@ def initialize(model_name, batch_size, epochs, save_every_steps, bf16_run):
|
||||
)
|
||||
except FileExistsError:
|
||||
logger.warning(f"Step 1: {model_path} already exists.")
|
||||
return False, f"Step1, Error: モデルフォルダ {model_path} が既に存在します。問題なければ削除してください。"
|
||||
except FileNotFoundError:
|
||||
logger.error("Step 1: `pretrained` folder not found.")
|
||||
return False, "Step 1, Error: pretrainedフォルダが見つかりません。"
|
||||
|
||||
with open(config_path, "w", encoding="utf-8") as f:
|
||||
json.dump(config, f, indent=2)
|
||||
json.dump(config, f, indent=2, ensure_ascii=False)
|
||||
if not os.path.exists("config.yml"):
|
||||
shutil.copy(src="default_config.yml", dst="config.yml")
|
||||
# yml_data = safe_load(open("config.yml", "r", encoding="utf-8"))
|
||||
|
||||
Reference in New Issue
Block a user