Refactor: dataset_root and assets_root in configs/paths.yml

This commit is contained in:
litagin02
2024-01-02 22:51:17 +09:00
parent a1069c73d2
commit 98ee6f4c69
12 changed files with 209 additions and 162 deletions

2
.gitignore vendored
View File

@@ -17,3 +17,5 @@ venv/
/scripts/test/ /scripts/test/
*.zip *.zip
*.csv
*.bak

12
app.py
View File

@@ -4,9 +4,8 @@ import os
import sys import sys
import gradio as gr import gradio as gr
import numpy as np
import torch import torch
from gradio.processing_utils import convert_to_16_bit_wav import yaml
from common.constants import ( from common.constants import (
DEFAULT_ASSIST_TEXT_WEIGHT, DEFAULT_ASSIST_TEXT_WEIGHT,
@@ -22,7 +21,12 @@ from common.constants import (
) )
from common.log import logger from common.log import logger
from common.tts_model import ModelHolder 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] languages = [l.value for l in Languages]
@@ -182,7 +186,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--cpu", action="store_true", help="Use CPU instead of GPU") parser.add_argument("--cpu", action="store_true", help="Use CPU instead of GPU")
parser.add_argument( 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( parser.add_argument(
"--share", action="store_true", help="Share this app publicly", default=False "--share", action="store_true", help="Share this app publicly", default=False

View File

@@ -6,9 +6,10 @@
"source": [ "source": [
"# Style-Bert-VITS2 (ver 1.2) のGoogle Colabでの学習\n", "# Style-Bert-VITS2 (ver 1.2) のGoogle Colabでの学習\n",
"\n", "\n",
"Google driveと連携することで、Google Colab上でStyle-Bert-VITS2の学習を行うことができます。\n", "Google Colab上でStyle-Bert-VITS2の学習を行うことができます。\n",
"\n", "\n",
"このnotebookでは、あなたのGoogle Driveにフォルダ`Style-Bert-VITS2`を作り、その内部での作業を行います。他のフォルダには触れません。\n", "このnotebookでは、通常使用ではあなたのGoogle Driveにフォルダ`Style-Bert-VITS2`を作り、その内部での作業を行います。他のフォルダには触れません。\n",
"Google Driveを使わない場合は、初期設定のところで適切なパスを指定してください。\n",
"\n", "\n",
"## 流れ\n", "## 流れ\n",
"\n", "\n",
@@ -16,16 +17,75 @@
"上から順に実行していけばいいです。音声合成に必要なファイルはGoogle Driveの`Style-Bert-VITS2/model_assets/`に保存されます。また、途中経過も`Style-Bert-VITS2/Data/`に保存されるので、学習を中断したり、途中から再開することもできます。\n", "上から順に実行していけばいいです。音声合成に必要なファイルはGoogle Driveの`Style-Bert-VITS2/model_assets/`に保存されます。また、途中経過も`Style-Bert-VITS2/Data/`に保存されるので、学習を中断したり、途中から再開することもできます。\n",
"\n", "\n",
"### 学習を途中から再開したいとき\n", "### 学習を途中から再開したいとき\n",
"1と2を行い、3の前処理は飛ばして、4から始めてください。\n" "0と1と2を行い、3の前処理は飛ばして、4から始めてください。\n"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## 1. Google Driveとの連携とデータの配置\n", "## 0. 環境構築\n",
"\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", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"次のセルを実行して、Google driveの中にStyle-Bert-VITS2フォルダと、学習データをいれるDataフォルダを作成します。" "次のセルを実行して、学習データをいれるフォルダ1で設定した`dataset_root`を作成します。"
] ]
}, },
{ {
@@ -61,7 +121,7 @@
"source": [ "source": [
"import os\n", "import os\n",
"\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", "cell_type": "markdown",
"metadata": { "metadata": {
@@ -178,7 +189,8 @@
"# 学習のバッチサイズ。4ぐらいが最適か。VRAMのはみ出具合に応じて調整してください。\n", "# 学習のバッチサイズ。4ぐらいが最適か。VRAMのはみ出具合に応じて調整してください。\n",
"batch_size = 4\n", "batch_size = 4\n",
"\n", "\n",
"# 学習のエポック数(データセットを合計何周するか)。100ぐらいで十分だと思われます。\n", "# 学習のエポック数(データセットを合計何周するか)。\n",
"# 100ぐらいで十分かもしれませんが、もっと多くやると質が上がるのかもしれません。\n",
"epochs = 100\n", "epochs = 100\n",
"\n", "\n",
"# 保存頻度。何ステップごとにモデルを保存するか。分からなければデフォルトのままで。\n", "# 保存頻度。何ステップごとにモデルを保存するか。分からなければデフォルトのままで。\n",
@@ -256,15 +268,15 @@
"from webui_train import get_path\n", "from webui_train import get_path\n",
"\n", "\n",
"dataset_path, _, _, _, config_path = get_path(model_name)\n", "dataset_path, _, _, _, config_path = get_path(model_name)\n",
"\n",
"with open(\"default_config.yml\", \"r\", encoding=\"utf-8\") as f:\n", "with open(\"default_config.yml\", \"r\", encoding=\"utf-8\") as f:\n",
" yml_data = yaml.safe_load(f)\n", " yml_data = yaml.safe_load(f)\n",
"yml_data[\"model_name\"] = model_name\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", "with open(\"config.yml\", \"w\", encoding=\"utf-8\") as f:\n",
" yaml.dump(yml_data, f, allow_unicode=True)\n", " yaml.dump(yml_data, f, allow_unicode=True)\n",
"\n", "\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": [], "outputs": [],
"source": [ "source": [
"#@title 学習結果を試すならここから\n", "#@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" "name": "python3"
}, },
"language_info": { "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, "nbformat": 4,

View File

@@ -205,7 +205,7 @@ class Translate_config:
class 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"): if not os.path.isfile(config_path) and os.path.isfile("default_config.yml"):
shutil.copy(src="default_config.yml", dst=config_path) shutil.copy(src="default_config.yml", dst=config_path)
print( print(
@@ -222,12 +222,10 @@ class Config:
if "dataset_path" in yaml_config: if "dataset_path" in yaml_config:
dataset_path = yaml_config["dataset_path"] dataset_path = yaml_config["dataset_path"]
else: else:
dataset_path = f"Data/{model_name}" dataset_path = os.path.join(path_config["dataset_root"], model_name)
self.out_dir = yaml_config["out_dir"]
# openi_token: str = yaml_config["openi_token"]
self.dataset_path: str = dataset_path self.dataset_path: str = dataset_path
# self.mirror: str = yaml_config["mirror"] self.assets_root: str = path_config["assets_root"]
# self.openi_token: str = openi_token self.out_dir = os.path.join(self.assets_root, model_name)
self.resample_config: Resample_config = Resample_config.from_dict( self.resample_config: Resample_config = Resample_config.from_dict(
dataset_path, yaml_config["resample"] 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() parser = argparse.ArgumentParser()
# 为避免与以前的config.json起冲突将其更名如下 # 为避免与以前的config.json起冲突将其更名如下
parser.add_argument("-y", "--yml_config", type=str, default="config.yml") parser.add_argument(
args, _ = parser.parse_known_args() "-y",
"--yml_config",
type=str,
default="config.yml",
help="Path to setting yaml file.",
)
args = parser.parse_args()
try: try:
config = Config(args.yml_config) config = Config(args.yml_config, path_config)
except TypeError: except TypeError:
logger.warning("Old config.yml found. Replace it with default_config.yml.") logger.warning("Old config.yml found. Replace it with default_config.yml.")
shutil.copy(src="default_config.yml", dst="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
View 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

View File

@@ -1,24 +1,20 @@
# Global configuration file for Bert-VITS2
model_name: "model_name" model_name: "model_name"
out_dir: "model_assets"
# If you want to use a specific dataset path, uncomment the following line. # 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" # dataset_path: "your/dataset/path"
resample: resample:
sampling_rate: 44100 sampling_rate: 44100
in_dir: "audios/raw" in_dir: "raw"
out_dir: "audios/wavs" out_dir: "wavs"
preprocess_text: preprocess_text:
transcription_path: "filelists/esd.list" transcription_path: "esd.list"
cleaned_path: "" cleaned_path: ""
train_path: "filelists/train.list" train_path: "train.list"
val_path: "filelists/val.list" val_path: "val.list"
config_path: "config.json" config_path: "config.json"
val_per_lang: 4 val_per_lang: 4
max_val_total: 12 max_val_total: 12
@@ -42,13 +38,13 @@ train_ms:
WORLD_SIZE: 1 WORLD_SIZE: 1
LOCAL_RANK: 0 LOCAL_RANK: 0
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" config_path: "config.json"
num_workers: 16 num_workers: 16
spec_cache: True spec_cache: True
keep_ckpts: 1 # Set this to 0 to keep all checkpoints 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" device: "cuda"
# 模型路径 # 模型路径

View File

@@ -67,7 +67,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--cpu", action="store_true", help="Use CPU instead of GPU") parser.add_argument("--cpu", action="store_true", help="Use CPU instead of GPU")
parser.add_argument( 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() args = parser.parse_args()

View File

@@ -19,6 +19,8 @@ from tqdm import tqdm
import commons import commons
import default_style import default_style
import utils import utils
from common.log import logger
from common.stdout_wrapper import SAFE_STDOUT
from config import config from config import config
from data_utils import ( from data_utils import (
DistributedBucketSampler, 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 mel_processing import mel_spectrogram_torch, spec_to_mel_torch
from models import DurationDiscriminator, MultiPeriodDiscriminator, SynthesizerTrn from models import DurationDiscriminator, MultiPeriodDiscriminator, SynthesizerTrn
from text.symbols import symbols 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.cuda.matmul.allow_tf32 = True
torch.backends.cudnn.allow_tf32 = ( 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 ) # Not available if torch version is lower than 2.0
torch.backends.cuda.enable_math_sdp(True) torch.backends.cuda.enable_math_sdp(True)
try:
import google.colab
IS_COLAB = True
except ImportError:
IS_COLAB = False
global_step = 0 global_step = 0
@@ -86,7 +80,7 @@ def run():
# 命令行/config.yml配置解析 # 命令行/config.yml配置解析
# hps = utils.get_hparams() # hps = utils.get_hparams()
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
# 非必要不建议使用命令行配置,请使用config.yml文件 # Command line configuration is not recommended unless necessary, use config.yml
parser.add_argument( parser.add_argument(
"-c", "-c",
"--config", "--config",
@@ -102,12 +96,26 @@ def run():
help="数据集文件夹路径,请注意,数据不再默认放在/logs文件夹下。如果需要用命令行配置请声明相对于根目录的路径", help="数据集文件夹路径,请注意,数据不再默认放在/logs文件夹下。如果需要用命令行配置请声明相对于根目录的路径",
default=config.dataset_path, 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() args = parser.parse_args()
model_dir = os.path.join(args.model, config.train_ms_config.model) model_dir = os.path.join(args.model, config.train_ms_config.model)
if not os.path.exists(model_dir): if not os.path.exists(model_dir):
os.makedirs(model_dir) os.makedirs(model_dir)
hps = utils.get_hparams_from_file(args.config) 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 hps.model_dir = model_dir
# 比较路径是否相同 # 比较路径是否相同
if os.path.realpath(args.config) != os.path.realpath( if os.path.realpath(args.config) != os.path.realpath(
config.train_ms_config.config_path config.train_ms_config.config_path
@@ -125,30 +133,26 @@ def run():
args.model: For saving all info needed for training. args.model: For saving all info needed for training.
default: `Data/{model_name}`. 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`. 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. args.assets_root: The root directory of model assets needed for inference.
default: `model_assets`. default: config.assets_root == `model_assets`.
out_dir: For saving resulting models (for inference). config.out_dir: The directory for model assets of this model (for inference).
default: `model_assets/{model_name}`, which is used 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) 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 # 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( default_style.save_mean_vector(
os.path.join(args.model, "wavs"), 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) torch.manual_seed(hps.train.seed)
@@ -158,10 +162,10 @@ def run():
if rank == 0: if rank == 0:
# logger = utils.get_logger(hps.model_dir) # logger = utils.get_logger(hps.model_dir)
# logger.info(hps) # logger.info(hps)
logger.add(os.path.join(hps.model_dir, "train.log")) logger.add(os.path.join(model_dir, "train.log"))
utils.check_git_hash(hps.model_dir) utils.check_git_hash(model_dir)
writer = SummaryWriter(log_dir=hps.model_dir) writer = SummaryWriter(log_dir=model_dir)
writer_eval = SummaryWriter(log_dir=os.path.join(hps.model_dir, "eval")) writer_eval = SummaryWriter(log_dir=os.path.join(model_dir, "eval"))
train_dataset = TextAudioSpeakerLoader(hps.data.training_files, hps.data) train_dataset = TextAudioSpeakerLoader(hps.data.training_files, hps.data)
train_sampler = DistributedBucketSampler( train_sampler = DistributedBucketSampler(
train_dataset, train_dataset,
@@ -284,10 +288,10 @@ def run():
net_dur_disc, device_ids=[local_rank], find_unused_parameters=True 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: if net_dur_disc is not None:
_, _, dur_resume_lr, epoch_str = utils.load_checkpoint( _, _, 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, net_dur_disc,
optim_dur_disc, optim_dur_disc,
skip_optimizer=hps.train.skip_optimizer skip_optimizer=hps.train.skip_optimizer
@@ -297,7 +301,7 @@ def run():
if not optim_dur_disc.param_groups[0].get("initial_lr"): if not optim_dur_disc.param_groups[0].get("initial_lr"):
optim_dur_disc.param_groups[0]["initial_lr"] = dur_resume_lr optim_dur_disc.param_groups[0]["initial_lr"] = dur_resume_lr
_, optim_g, g_resume_lr, epoch_str = utils.load_checkpoint( _, 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, net_g,
optim_g, optim_g,
skip_optimizer=hps.train.skip_optimizer skip_optimizer=hps.train.skip_optimizer
@@ -305,7 +309,7 @@ def run():
else True, else True,
) )
_, optim_d, d_resume_lr, epoch_str = utils.load_checkpoint( _, 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, net_d,
optim_d, optim_d,
skip_optimizer=hps.train.skip_optimizer skip_optimizer=hps.train.skip_optimizer
@@ -320,7 +324,7 @@ def run():
epoch_str = max(epoch_str, 1) epoch_str = max(epoch_str, 1)
# global_step = (epoch_str - 1) * len(train_loader) # global_step = (epoch_str - 1) * len(train_loader)
global_step = int( 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( logger.info(
f"******************检测到模型存在epoch为 {epoch_str}gloabl step为 {global_step}*********************" f"******************检测到模型存在epoch为 {epoch_str}gloabl step为 {global_step}*********************"
@@ -328,14 +332,14 @@ def run():
else: else:
try: try:
_ = utils.load_safetensors( _ = 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( _ = 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: if net_dur_disc is not None:
_ = utils.load_safetensors( _ = 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.") logger.info("Loaded the pretrained models.")
except Exception as e: except Exception as e:
@@ -402,14 +406,14 @@ def run():
optim_g, optim_g,
hps.train.learning_rate, hps.train.learning_rate,
epoch, 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( utils.save_checkpoint(
net_d, net_d,
optim_d, optim_d,
hps.train.learning_rate, hps.train.learning_rate,
epoch, 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: if net_dur_disc is not None:
utils.save_checkpoint( utils.save_checkpoint(
@@ -417,13 +421,13 @@ def run():
optim_dur_disc, optim_dur_disc,
hps.train.learning_rate, hps.train.learning_rate,
epoch, 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( utils.save_safetensors(
net_g, net_g,
epoch, epoch,
os.path.join( os.path.join(
out_dir, config.out_dir,
f"{config.model_name}_e{epoch}_s{global_step}.safetensors", f"{config.model_name}_e{epoch}_s{global_step}.safetensors",
), ),
for_infer=True, for_infer=True,
@@ -690,12 +694,12 @@ def train_and_evaluate(
n_ckpts_to_keep=keep_ckpts, n_ckpts_to_keep=keep_ckpts,
sort_by_time=True, sort_by_time=True,
) )
# Save safetensors (for inference) to `model_assets/{model_name}`
utils.save_safetensors( utils.save_safetensors(
net_g, net_g,
epoch, epoch,
os.path.join( os.path.join(
config.out_dir, config.out_dir,
config.model_name,
f"{config.model_name}_e{epoch}_s{global_step}.safetensors", f"{config.model_name}_e{epoch}_s{global_step}.safetensors",
), ),
for_infer=True, for_infer=True,

View File

@@ -1,15 +1,22 @@
import os import os
import gradio as gr import gradio as gr
import yaml
from common.log import logger 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, normalize): def do_slice(model_name, normalize):
logger.info("Start slicing...") logger.info("Start slicing...")
input_dir = "inputs" input_dir = "inputs"
output_dir = os.path.join("Data", model_name, "raw") output_dir = os.path.join(dataset_root, model_name, "raw")
cmd = [ cmd = [
"slice.py", "slice.py",
"--input_dir", "--input_dir",
@@ -26,8 +33,8 @@ def do_slice(model_name, normalize):
def do_transcribe(model_name): def do_transcribe(model_name):
input_dir = os.path.join("Data", model_name, "raw") input_dir = os.path.join(dataset_root, model_name, "raw")
output_file = os.path.join("Data", model_name, "esd.list") output_file = os.path.join(dataset_root, model_name, "esd.list")
result = run_script_with_log( result = run_script_with_log(
[ [
"transcribe.py", "transcribe.py",

View File

@@ -5,14 +5,13 @@ import sys
import gradio as gr import gradio as gr
import numpy as np import numpy as np
import torch import torch
import yaml
from safetensors import safe_open from safetensors import safe_open
from safetensors.torch import save_file 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.constants import DEFAULT_STYLE
from common.log import logger
from common.tts_model import Model, ModelHolder
voice_keys = ["dec", "flow"] voice_keys = ["dec", "flow"]
speech_style_keys = ["enc_p"] speech_style_keys = ["enc_p"]
@@ -20,8 +19,13 @@ tempo_keys = ["sdp", "dp"]
device = "cuda" if torch.cuda.is_available() else "cpu" device = "cuda" if torch.cuda.is_available() else "cpu"
model_dir = config.out_dir # Get path settings
model_holder = ModelHolder(model_dir, device) 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): def merge_style(model_name_a, model_name_b, weight, output_name, style_triple_list):

View File

@@ -115,7 +115,7 @@ def do_clustering_gradio(n_clusters=4, method="KMeans"):
def save_style_vectors(model_name, style_names: str): def save_style_vectors(model_name, style_names: str):
"""centerとcentroidsを保存する""" """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) os.makedirs(result_dir, exist_ok=True)
style_vectors = np.stack([mean] + centroids) style_vectors = np.stack([mean] + centroids)
style_vector_path = os.path.join(result_dir, "style_vectors.npy") style_vector_path = os.path.join(result_dir, "style_vectors.npy")
@@ -148,7 +148,7 @@ def save_style_vectors_from_files(model_name, audio_files_text, style_names_text
return "Error: スタイルベクトルを読み込んでください。" return "Error: スタイルベクトルを読み込んでください。"
mean = np.mean(x, axis=0) 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) os.makedirs(result_dir, exist_ok=True)
audio_files = audio_files_text.split(",") audio_files = audio_files_text.split(",")
style_names = style_names_text.split(",") style_names = style_names_text.split(",")

View File

@@ -1,7 +1,6 @@
import json import json
import os import os
import shutil import shutil
import sys
from multiprocessing import cpu_count from multiprocessing import cpu_count
import gradio as gr import gradio as gr
@@ -10,24 +9,16 @@ import yaml
from common.log import logger 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, second_elem_of
try: # Get path settings
import google.colab with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
path_config: dict[str, str] = yaml.safe_load(f.read())
IS_COLAB = True dataset_root = path_config["dataset_root"]
except ImportError: # assets_root = path_config["assets_root"]
IS_COLAB = False
def get_path(model_name): def get_path(model_name):
assert model_name != "", "モデル名は空にできません" assert model_name != "", "モデル名は空にできません"
if IS_COLAB: dataset_path = os.path.join(dataset_root, model_name)
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)
lbl_path = os.path.join(dataset_path, "esd.list") lbl_path = os.path.join(dataset_path, "esd.list")
train_path = os.path.join(dataset_path, "train.list") train_path = os.path.join(dataset_path, "train.list")
val_path = os.path.join(dataset_path, "val.list") val_path = os.path.join(dataset_path, "val.list")
@@ -61,7 +52,6 @@ def initialize(model_name, batch_size, epochs, save_every_steps, bf16_run):
) )
except FileExistsError: except FileExistsError:
logger.warning(f"Step 1: {model_path} already exists.") logger.warning(f"Step 1: {model_path} already exists.")
return False, f"Step1, Error: モデルフォルダ {model_path} が既に存在します。問題なければ削除してください。"
except FileNotFoundError: except FileNotFoundError:
logger.error("Step 1: `pretrained` folder not found.") logger.error("Step 1: `pretrained` folder not found.")
return False, "Step 1, Error: pretrainedフォルダが見つかりません。" return False, "Step 1, Error: pretrainedフォルダが見つかりません。"