Refactor: Use PathConfig and pathlib instead of paths.yml loading
This commit is contained in:
10
app.py
10
app.py
@@ -3,7 +3,6 @@ from pathlib import Path
|
|||||||
|
|
||||||
import gradio as gr
|
import gradio as gr
|
||||||
import torch
|
import torch
|
||||||
import yaml
|
|
||||||
|
|
||||||
from gradio_tabs.dataset import create_dataset_app
|
from gradio_tabs.dataset import create_dataset_app
|
||||||
from gradio_tabs.inference import create_inference_app
|
from gradio_tabs.inference import create_inference_app
|
||||||
@@ -14,6 +13,7 @@ from style_bert_vits2.constants import GRADIO_THEME, VERSION
|
|||||||
from style_bert_vits2.nlp.japanese import pyopenjtalk_worker
|
from style_bert_vits2.nlp.japanese import pyopenjtalk_worker
|
||||||
from style_bert_vits2.nlp.japanese.user_dict import update_dict
|
from style_bert_vits2.nlp.japanese.user_dict import update_dict
|
||||||
from style_bert_vits2.tts_model import TTSModelHolder
|
from style_bert_vits2.tts_model import TTSModelHolder
|
||||||
|
from config import get_path_config
|
||||||
|
|
||||||
|
|
||||||
# このプロセスからはワーカーを起動して辞書を使いたいので、ここで初期化
|
# このプロセスからはワーカーを起動して辞書を使いたいので、ここで初期化
|
||||||
@@ -22,11 +22,6 @@ pyopenjtalk_worker.initialize_worker()
|
|||||||
# dict_data/ 以下の辞書データを pyopenjtalk に適用
|
# dict_data/ 以下の辞書データを pyopenjtalk に適用
|
||||||
update_dict()
|
update_dict()
|
||||||
|
|
||||||
# Get path settings
|
|
||||||
with Path("configs/paths.yml").open("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"]
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("--device", type=str, default="cuda")
|
parser.add_argument("--device", type=str, default="cuda")
|
||||||
@@ -40,7 +35,8 @@ device = args.device
|
|||||||
if device == "cuda" and not torch.cuda.is_available():
|
if device == "cuda" and not torch.cuda.is_available():
|
||||||
device = "cpu"
|
device = "cpu"
|
||||||
|
|
||||||
model_holder = TTSModelHolder(Path(assets_root), device)
|
path_config = get_path_config()
|
||||||
|
model_holder = TTSModelHolder(Path(path_config.assets_root), device)
|
||||||
|
|
||||||
with gr.Blocks(theme=GRADIO_THEME) as app:
|
with gr.Blocks(theme=GRADIO_THEME) as app:
|
||||||
gr.Markdown(f"# Style-Bert-VITS2 WebUI (version {VERSION})")
|
gr.Markdown(f"# Style-Bert-VITS2 WebUI (version {VERSION})")
|
||||||
|
|||||||
@@ -5,13 +5,12 @@ import torch
|
|||||||
import torch.multiprocessing as mp
|
import torch.multiprocessing as mp
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from config import config
|
from config import get_config
|
||||||
from style_bert_vits2.constants import Languages
|
from style_bert_vits2.constants import Languages
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.models import commons
|
from style_bert_vits2.models import commons
|
||||||
from style_bert_vits2.models.hyper_parameters import HyperParameters
|
from style_bert_vits2.models.hyper_parameters import HyperParameters
|
||||||
from style_bert_vits2.nlp import (
|
from style_bert_vits2.nlp import (
|
||||||
bert_models,
|
|
||||||
cleaned_text_to_sequence,
|
cleaned_text_to_sequence,
|
||||||
extract_bert_feature,
|
extract_bert_feature,
|
||||||
)
|
)
|
||||||
@@ -20,6 +19,7 @@ from style_bert_vits2.nlp.japanese.user_dict import update_dict
|
|||||||
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
||||||
|
|
||||||
|
|
||||||
|
config = get_config()
|
||||||
# このプロセスからはワーカーを起動して辞書を使いたいので、ここで初期化
|
# このプロセスからはワーカーを起動して辞書を使いたいので、ここで初期化
|
||||||
pyopenjtalk_worker.initialize_worker()
|
pyopenjtalk_worker.initialize_worker()
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ def process_line(x: tuple[str, bool]):
|
|||||||
bert = torch.load(bert_path)
|
bert = torch.load(bert_path)
|
||||||
assert bert.shape[-1] == len(phone)
|
assert bert.shape[-1] == len(phone)
|
||||||
except Exception:
|
except Exception:
|
||||||
bert = extract_bert_feature(text, word2ph, language_str, device)
|
bert = extract_bert_feature(text, word2ph, Languages(language_str), device)
|
||||||
assert bert.shape[-1] == len(phone)
|
assert bert.shape[-1] == len(phone)
|
||||||
torch.save(bert, bert_path)
|
torch.save(bert, bert_path)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Style-Bert-VITS2 (ver 2.4.1) のGoogle Colabでの学習\n",
|
"# Style-Bert-VITS2 (ver 2.5.0) のGoogle Colabでの学習\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Google Colab上でStyle-Bert-VITS2の学習を行うことができます。\n",
|
"Google Colab上でStyle-Bert-VITS2の学習を行うことができます。\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
|||||||
163
config.py
163
config.py
@@ -2,9 +2,9 @@
|
|||||||
@Desc: 全局配置文件读取
|
@Desc: 全局配置文件读取
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
from typing import Dict, List
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
import yaml
|
import yaml
|
||||||
@@ -12,6 +12,12 @@ import yaml
|
|||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
|
|
||||||
|
|
||||||
|
class PathConfig:
|
||||||
|
def __init__(self, dataset_root: str, assets_root: str):
|
||||||
|
self.dataset_root = Path(dataset_root)
|
||||||
|
self.assets_root = Path(assets_root)
|
||||||
|
|
||||||
|
|
||||||
# If not cuda available, set possible devices to cpu
|
# If not cuda available, set possible devices to cpu
|
||||||
cuda_available = torch.cuda.is_available()
|
cuda_available = torch.cuda.is_available()
|
||||||
|
|
||||||
@@ -20,17 +26,17 @@ class Resample_config:
|
|||||||
"""重采样配置"""
|
"""重采样配置"""
|
||||||
|
|
||||||
def __init__(self, in_dir: str, out_dir: str, sampling_rate: int = 44100):
|
def __init__(self, in_dir: str, out_dir: str, sampling_rate: int = 44100):
|
||||||
self.sampling_rate: int = sampling_rate # 目标采样率
|
self.sampling_rate = sampling_rate # 目标采样率
|
||||||
self.in_dir: str = in_dir # 待处理音频目录路径
|
self.in_dir = Path(in_dir) # 待处理音频目录路径
|
||||||
self.out_dir: str = out_dir # 重采样输出路径
|
self.out_dir = Path(out_dir) # 重采样输出路径
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
def from_dict(cls, dataset_path: Path, data: dict[str, Any]):
|
||||||
"""从字典中生成实例"""
|
"""从字典中生成实例"""
|
||||||
|
|
||||||
# 不检查路径是否有效,此逻辑在resample.py中处理
|
# 不检查路径是否有效,此逻辑在resample.py中处理
|
||||||
data["in_dir"] = os.path.join(dataset_path, data["in_dir"])
|
data["in_dir"] = dataset_path / data["in_dir"]
|
||||||
data["out_dir"] = os.path.join(dataset_path, data["out_dir"])
|
data["out_dir"] = dataset_path / data["out_dir"]
|
||||||
|
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
@@ -49,39 +55,27 @@ class Preprocess_text_config:
|
|||||||
max_val_total: int = 10000,
|
max_val_total: int = 10000,
|
||||||
clean: bool = True,
|
clean: bool = True,
|
||||||
):
|
):
|
||||||
self.transcription_path: str = (
|
self.transcription_path = Path(transcription_path)
|
||||||
transcription_path # 原始文本文件路径,文本格式应为{wav_path}|{speaker_name}|{language}|{text}。
|
self.cleaned_path = Path(cleaned_path)
|
||||||
)
|
self.train_path = Path(train_path)
|
||||||
self.cleaned_path: str = (
|
self.val_path = Path(val_path)
|
||||||
cleaned_path # 数据清洗后文本路径,可以不填。不填则将在原始文本目录生成
|
self.config_path = Path(config_path)
|
||||||
)
|
self.val_per_lang = val_per_lang
|
||||||
self.train_path: str = (
|
self.max_val_total = max_val_total
|
||||||
train_path # 训练集路径,可以不填。不填则将在原始文本目录生成
|
self.clean = clean
|
||||||
)
|
|
||||||
self.val_path: str = (
|
|
||||||
val_path # 验证集路径,可以不填。不填则将在原始文本目录生成
|
|
||||||
)
|
|
||||||
self.config_path: str = config_path # 配置文件路径
|
|
||||||
self.val_per_lang: int = val_per_lang # 每个speaker的验证集条数
|
|
||||||
self.max_val_total: int = (
|
|
||||||
max_val_total # 验证集最大条数,多于的会被截断并放到训练集中
|
|
||||||
)
|
|
||||||
self.clean: bool = clean # 是否进行数据清洗
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
def from_dict(cls, dataset_path: Path, data: dict[str, Any]):
|
||||||
"""从字典中生成实例"""
|
"""从字典中生成实例"""
|
||||||
|
|
||||||
data["transcription_path"] = os.path.join(
|
data["transcription_path"] = dataset_path / data["transcription_path"]
|
||||||
dataset_path, data["transcription_path"]
|
|
||||||
)
|
|
||||||
if data["cleaned_path"] == "" or data["cleaned_path"] is None:
|
if data["cleaned_path"] == "" or data["cleaned_path"] is None:
|
||||||
data["cleaned_path"] = None
|
data["cleaned_path"] = None
|
||||||
else:
|
else:
|
||||||
data["cleaned_path"] = os.path.join(dataset_path, data["cleaned_path"])
|
data["cleaned_path"] = dataset_path / data["cleaned_path"]
|
||||||
data["train_path"] = os.path.join(dataset_path, data["train_path"])
|
data["train_path"] = dataset_path / data["train_path"]
|
||||||
data["val_path"] = os.path.join(dataset_path, data["val_path"])
|
data["val_path"] = dataset_path / data["val_path"]
|
||||||
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
data["config_path"] = dataset_path / data["config_path"]
|
||||||
|
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
@@ -96,7 +90,7 @@ class Bert_gen_config:
|
|||||||
device: str = "cuda",
|
device: str = "cuda",
|
||||||
use_multi_device: bool = False,
|
use_multi_device: bool = False,
|
||||||
):
|
):
|
||||||
self.config_path = config_path
|
self.config_path = Path(config_path)
|
||||||
self.num_processes = num_processes
|
self.num_processes = num_processes
|
||||||
if not cuda_available:
|
if not cuda_available:
|
||||||
device = "cpu"
|
device = "cpu"
|
||||||
@@ -104,8 +98,8 @@ class Bert_gen_config:
|
|||||||
self.use_multi_device = use_multi_device
|
self.use_multi_device = use_multi_device
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
def from_dict(cls, dataset_path: Path, data: dict[str, Any]):
|
||||||
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
data["config_path"] = dataset_path / data["config_path"]
|
||||||
|
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
@@ -119,15 +113,15 @@ class Style_gen_config:
|
|||||||
num_processes: int = 4,
|
num_processes: int = 4,
|
||||||
device: str = "cuda",
|
device: str = "cuda",
|
||||||
):
|
):
|
||||||
self.config_path = config_path
|
self.config_path = Path(config_path)
|
||||||
self.num_processes = num_processes
|
self.num_processes = num_processes
|
||||||
if not cuda_available:
|
if not cuda_available:
|
||||||
device = "cpu"
|
device = "cpu"
|
||||||
self.device = device
|
self.device = device
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
def from_dict(cls, dataset_path: Path, data: dict[str, Any]):
|
||||||
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
data["config_path"] = dataset_path / data["config_path"]
|
||||||
|
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
@@ -138,7 +132,7 @@ class Train_ms_config:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
config_path: str,
|
config_path: str,
|
||||||
env: Dict[str, any],
|
env: dict[str, Any],
|
||||||
# base: Dict[str, any],
|
# base: Dict[str, any],
|
||||||
model_dir: str,
|
model_dir: str,
|
||||||
num_workers: int,
|
num_workers: int,
|
||||||
@@ -147,16 +141,18 @@ class Train_ms_config:
|
|||||||
):
|
):
|
||||||
self.env = env # 需要加载的环境变量
|
self.env = env # 需要加载的环境变量
|
||||||
# self.base = base # 底模配置
|
# self.base = base # 底模配置
|
||||||
self.model_dir = model_dir # 训练模型存储目录,该路径为相对于dataset_path的路径,而非项目根目录
|
self.model_dir = Path(
|
||||||
self.config_path = config_path # 配置文件路径
|
model_dir
|
||||||
|
) # 训练模型存储目录,该路径为相对于dataset_path的路径,而非项目根目录
|
||||||
|
self.config_path = Path(config_path) # 配置文件路径
|
||||||
self.num_workers = num_workers # worker数量
|
self.num_workers = num_workers # worker数量
|
||||||
self.spec_cache = spec_cache # 是否启用spec缓存
|
self.spec_cache = spec_cache # 是否启用spec缓存
|
||||||
self.keep_ckpts = keep_ckpts # ckpt数量
|
self.keep_ckpts = keep_ckpts # ckpt数量
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
def from_dict(cls, dataset_path: Path, data: dict[str, Any]):
|
||||||
# data["model"] = os.path.join(dataset_path, data["model"])
|
# data["model"] = os.path.join(dataset_path, data["model"])
|
||||||
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
data["config_path"] = dataset_path / data["config_path"]
|
||||||
|
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
@@ -176,20 +172,18 @@ class Webui_config:
|
|||||||
):
|
):
|
||||||
if not cuda_available:
|
if not cuda_available:
|
||||||
device = "cpu"
|
device = "cpu"
|
||||||
self.device: str = device
|
self.device = device
|
||||||
self.model: str = model # 端口号
|
self.model = Path(model)
|
||||||
self.config_path: str = config_path # 是否公开部署,对外网开放
|
self.config_path = Path(config_path)
|
||||||
self.port: int = port # 是否开启debug模式
|
self.port: int = port
|
||||||
self.share: bool = share # 模型路径
|
self.share: bool = share
|
||||||
self.debug: bool = debug # 配置文件路径
|
self.debug: bool = debug
|
||||||
self.language_identification_library: str = (
|
self.language_identification_library: str = language_identification_library
|
||||||
language_identification_library # 语种识别库
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dataset_path: str, data: Dict[str, any]):
|
def from_dict(cls, dataset_path: Path, data: dict[str, Any]):
|
||||||
data["config_path"] = os.path.join(dataset_path, data["config_path"])
|
data["config_path"] = dataset_path / data["config_path"]
|
||||||
data["model"] = os.path.join(dataset_path, data["model"])
|
data["model"] = dataset_path / data["model"]
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
|
|
||||||
@@ -200,7 +194,7 @@ class Server_config:
|
|||||||
device: str = "cuda",
|
device: str = "cuda",
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
language: str = "JP",
|
language: str = "JP",
|
||||||
origins: List[str] = None,
|
origins: list[str] = ["*"],
|
||||||
):
|
):
|
||||||
self.port: int = port
|
self.port: int = port
|
||||||
if not cuda_available:
|
if not cuda_available:
|
||||||
@@ -208,10 +202,10 @@ class Server_config:
|
|||||||
self.device: str = device
|
self.device: str = device
|
||||||
self.language: str = language
|
self.language: str = language
|
||||||
self.limit: int = limit
|
self.limit: int = limit
|
||||||
self.origins: List[str] = origins
|
self.origins: list[str] = origins
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, data: Dict[str, any]):
|
def from_dict(cls, data: dict[str, Any]):
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
|
|
||||||
@@ -223,32 +217,32 @@ class Translate_config:
|
|||||||
self.secret_key = secret_key
|
self.secret_key = secret_key
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, data: Dict[str, any]):
|
def from_dict(cls, data: dict[str, Any]):
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
def __init__(self, config_path: str, path_config: dict[str, str]):
|
def __init__(self, config_path: str, path_config: PathConfig):
|
||||||
if not os.path.isfile(config_path) and os.path.isfile("default_config.yml"):
|
if not Path(config_path).exists():
|
||||||
shutil.copy(src="default_config.yml", dst=config_path)
|
shutil.copy(src="default_config.yml", dst=config_path)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"A configuration file {config_path} has been generated based on the default configuration file default_config.yml."
|
f"A configuration file {config_path} has been generated based on the default configuration file default_config.yml."
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
"If you have no special needs, please do not modify default_config.yml."
|
"Please do not modify default_config.yml. Instead, modify config.yml."
|
||||||
)
|
)
|
||||||
# sys.exit(0)
|
# sys.exit(0)
|
||||||
with open(config_path, "r", encoding="utf-8") as file:
|
with open(config_path, "r", encoding="utf-8") as file:
|
||||||
yaml_config: Dict[str, any] = yaml.safe_load(file.read())
|
yaml_config: dict[str, Any] = yaml.safe_load(file.read())
|
||||||
model_name: str = yaml_config["model_name"]
|
model_name: str = yaml_config["model_name"]
|
||||||
self.model_name: str = model_name
|
self.model_name: str = model_name
|
||||||
if "dataset_path" in yaml_config:
|
if "dataset_path" in yaml_config:
|
||||||
dataset_path = yaml_config["dataset_path"]
|
dataset_path = Path(yaml_config["dataset_path"])
|
||||||
else:
|
else:
|
||||||
dataset_path = os.path.join(path_config["dataset_root"], model_name)
|
dataset_path = path_config.dataset_root / model_name
|
||||||
self.dataset_path: str = dataset_path
|
self.dataset_path = dataset_path
|
||||||
self.assets_root: str = path_config["assets_root"]
|
self.assets_root = path_config.assets_root
|
||||||
self.out_dir = os.path.join(self.assets_root, model_name)
|
self.out_dir = 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"]
|
||||||
)
|
)
|
||||||
@@ -277,16 +271,31 @@ class Config:
|
|||||||
# )
|
# )
|
||||||
|
|
||||||
|
|
||||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
# Load and initialize the configuration
|
||||||
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"
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
def get_path_config() -> PathConfig:
|
||||||
|
path_config_path = Path("configs/paths.yml")
|
||||||
|
if not path_config_path.exists():
|
||||||
|
shutil.copy(src="configs/default_paths.yml", dst=path_config_path)
|
||||||
|
logger.info(
|
||||||
|
f"A configuration file {path_config_path} has been generated based on the default configuration file default_paths.yml."
|
||||||
|
)
|
||||||
|
logger.info(
|
||||||
|
"Please do not modify configs/default_paths.yml. Instead, modify configs/paths.yml."
|
||||||
|
)
|
||||||
|
with open(path_config_path, "r", encoding="utf-8") as file:
|
||||||
|
path_config_dict: dict[str, str] = yaml.safe_load(file.read())
|
||||||
|
return PathConfig(**path_config_dict)
|
||||||
|
|
||||||
|
|
||||||
|
def get_config() -> Config:
|
||||||
|
path_config = get_path_config()
|
||||||
|
try:
|
||||||
config = Config("config.yml", path_config)
|
config = Config("config.yml", path_config)
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
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", path_config)
|
config = Config("config.yml", path_config)
|
||||||
|
|
||||||
|
return config
|
||||||
|
|||||||
@@ -69,5 +69,5 @@
|
|||||||
"use_spectral_norm": false,
|
"use_spectral_norm": false,
|
||||||
"gin_channels": 256
|
"gin_channels": 256
|
||||||
},
|
},
|
||||||
"version": "2.4.1"
|
"version": "2.5.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,5 +76,5 @@
|
|||||||
"initial_channel": 64
|
"initial_channel": 64
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version": "2.4.1-JP-Extra"
|
"version": "2.5.0-JP-Extra"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
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 get_path_config
|
||||||
from style_bert_vits2.constants import DEFAULT_STYLE, GRADIO_THEME
|
from style_bert_vits2.constants import DEFAULT_STYLE, GRADIO_THEME
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.tts_model import TTSModel, TTSModelHolder
|
from style_bert_vits2.tts_model import TTSModel, TTSModelHolder
|
||||||
@@ -20,15 +19,17 @@ speech_style_keys = ["enc_p"]
|
|||||||
tempo_keys = ["sdp", "dp"]
|
tempo_keys = ["sdp", "dp"]
|
||||||
|
|
||||||
device = "cuda" if torch.cuda.is_available() else "cpu"
|
device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||||
|
path_config = get_path_config()
|
||||||
# Get path settings
|
assets_root = path_config.assets_root
|
||||||
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 merge_style(model_name_a, model_name_b, weight, output_name, style_triple_list):
|
def merge_style(
|
||||||
|
model_name_a: str,
|
||||||
|
model_name_b: str,
|
||||||
|
weight: float,
|
||||||
|
output_name: str,
|
||||||
|
style_triple_list: list[tuple[str, str, str]],
|
||||||
|
) -> tuple[Path, list[str]]:
|
||||||
"""
|
"""
|
||||||
style_triple_list: list[(model_aでのスタイル名, model_bでのスタイル名, 出力するスタイル名)]
|
style_triple_list: list[(model_aでのスタイル名, model_bでのスタイル名, 出力するスタイル名)]
|
||||||
"""
|
"""
|
||||||
@@ -41,18 +42,14 @@ def merge_style(model_name_a, model_name_b, weight, output_name, style_triple_li
|
|||||||
raise ValueError(f"No element with {DEFAULT_STYLE} output style name found.")
|
raise ValueError(f"No element with {DEFAULT_STYLE} output style name found.")
|
||||||
|
|
||||||
style_vectors_a = np.load(
|
style_vectors_a = np.load(
|
||||||
os.path.join(assets_root, model_name_a, "style_vectors.npy")
|
assets_root / model_name_a / "style_vectors.npy"
|
||||||
) # (style_num_a, 256)
|
) # (style_num_a, 256)
|
||||||
style_vectors_b = np.load(
|
style_vectors_b = np.load(
|
||||||
os.path.join(assets_root, model_name_b, "style_vectors.npy")
|
assets_root / model_name_b / "style_vectors.npy"
|
||||||
) # (style_num_b, 256)
|
) # (style_num_b, 256)
|
||||||
with open(
|
with open(assets_root / model_name_a / "config.json", "r", encoding="utf-8") as f:
|
||||||
os.path.join(assets_root, model_name_a, "config.json"), "r", encoding="utf-8"
|
|
||||||
) as f:
|
|
||||||
config_a = json.load(f)
|
config_a = json.load(f)
|
||||||
with open(
|
with open(assets_root / model_name_b / "config.json", "r", encoding="utf-8") as f:
|
||||||
os.path.join(assets_root, model_name_b, "config.json"), "r", encoding="utf-8"
|
|
||||||
) as f:
|
|
||||||
config_b = json.load(f)
|
config_b = json.load(f)
|
||||||
style2id_a = config_a["data"]["style2id"]
|
style2id_a = config_a["data"]["style2id"]
|
||||||
style2id_b = config_b["data"]["style2id"]
|
style2id_b = config_b["data"]["style2id"]
|
||||||
@@ -73,21 +70,19 @@ 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_style2id[style_out] = len(new_style_vecs) - 1
|
||||||
new_style_vecs = np.array(new_style_vecs)
|
new_style_vecs = np.array(new_style_vecs)
|
||||||
|
|
||||||
output_style_path = os.path.join(assets_root, output_name, "style_vectors.npy")
|
output_style_path = assets_root / output_name / "style_vectors.npy"
|
||||||
np.save(output_style_path, new_style_vecs)
|
np.save(output_style_path, new_style_vecs)
|
||||||
|
|
||||||
new_config = config_a.copy()
|
new_config = config_a.copy()
|
||||||
new_config["data"]["num_styles"] = len(new_style2id)
|
new_config["data"]["num_styles"] = len(new_style2id)
|
||||||
new_config["data"]["style2id"] = new_style2id
|
new_config["data"]["style2id"] = new_style2id
|
||||||
new_config["model_name"] = output_name
|
new_config["model_name"] = output_name
|
||||||
with open(
|
with open(assets_root / output_name / "config.json", "w", encoding="utf-8") as f:
|
||||||
os.path.join(assets_root, output_name, "config.json"), "w", encoding="utf-8"
|
|
||||||
) as f:
|
|
||||||
json.dump(new_config, f, indent=2, ensure_ascii=False)
|
json.dump(new_config, f, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
# recipe.jsonを読み込んで、style_triple_listを追記
|
# recipe.jsonを読み込んで、style_triple_listを追記
|
||||||
info_path = os.path.join(assets_root, output_name, "recipe.json")
|
info_path = assets_root / output_name / "recipe.json"
|
||||||
if os.path.exists(info_path):
|
if info_path.exists():
|
||||||
with open(info_path, "r", encoding="utf-8") as f:
|
with open(info_path, "r", encoding="utf-8") as f:
|
||||||
info = json.load(f)
|
info = json.load(f)
|
||||||
else:
|
else:
|
||||||
@@ -99,11 +94,13 @@ def merge_style(model_name_a, model_name_b, weight, output_name, style_triple_li
|
|||||||
return output_style_path, list(new_style2id.keys())
|
return output_style_path, list(new_style2id.keys())
|
||||||
|
|
||||||
|
|
||||||
def lerp_tensors(t, v0, v1):
|
def lerp_tensors(t: float, v0: torch.Tensor, v1: torch.Tensor):
|
||||||
return v0 * (1 - t) + v1 * t
|
return v0 * (1 - t) + v1 * t
|
||||||
|
|
||||||
|
|
||||||
def slerp_tensors(t, v0, v1, dot_thres=0.998):
|
def slerp_tensors(
|
||||||
|
t: float, v0: torch.Tensor, v1: torch.Tensor, dot_thres: float = 0.998
|
||||||
|
):
|
||||||
device = v0.device
|
device = v0.device
|
||||||
v0c = v0.cpu().numpy()
|
v0c = v0.cpu().numpy()
|
||||||
v1c = v1.cpu().numpy()
|
v1c = v1.cpu().numpy()
|
||||||
@@ -123,23 +120,23 @@ def slerp_tensors(t, v0, v1, dot_thres=0.998):
|
|||||||
|
|
||||||
|
|
||||||
def merge_models(
|
def merge_models(
|
||||||
model_path_a,
|
model_path_a: str,
|
||||||
model_path_b,
|
model_path_b: str,
|
||||||
voice_weight,
|
voice_weight: float,
|
||||||
voice_pitch_weight,
|
voice_pitch_weight: float,
|
||||||
speech_style_weight,
|
speech_style_weight: float,
|
||||||
tempo_weight,
|
tempo_weight: float,
|
||||||
output_name,
|
output_name: str,
|
||||||
use_slerp_instead_of_lerp,
|
use_slerp_instead_of_lerp: bool,
|
||||||
):
|
):
|
||||||
"""model Aを起点に、model Bの各要素を重み付けしてマージする。
|
"""model Aを起点に、model Bの各要素を重み付けしてマージする。
|
||||||
safetensors形式を前提とする。"""
|
safetensors形式を前提とする。"""
|
||||||
model_a_weight = {}
|
model_a_weight: dict[str, torch.Tensor] = {}
|
||||||
with safe_open(model_path_a, framework="pt", device="cpu") as f:
|
with safe_open(model_path_a, framework="pt", device="cpu") as f:
|
||||||
for k in f.keys():
|
for k in f.keys():
|
||||||
model_a_weight[k] = f.get_tensor(k)
|
model_a_weight[k] = f.get_tensor(k)
|
||||||
|
|
||||||
model_b_weight = {}
|
model_b_weight: dict[str, torch.Tensor] = {}
|
||||||
with safe_open(model_path_b, framework="pt", device="cpu") as f:
|
with safe_open(model_path_b, framework="pt", device="cpu") as f:
|
||||||
for k in f.keys():
|
for k in f.keys():
|
||||||
model_b_weight[k] = f.get_tensor(k)
|
model_b_weight[k] = f.get_tensor(k)
|
||||||
@@ -161,10 +158,8 @@ def merge_models(
|
|||||||
slerp_tensors if use_slerp_instead_of_lerp else lerp_tensors
|
slerp_tensors if use_slerp_instead_of_lerp else lerp_tensors
|
||||||
)(weight, model_a_weight[key], model_b_weight[key])
|
)(weight, model_a_weight[key], model_b_weight[key])
|
||||||
|
|
||||||
merged_model_path = os.path.join(
|
merged_model_path = assets_root / output_name / f"{output_name}.safetensors"
|
||||||
assets_root, output_name, f"{output_name}.safetensors"
|
merged_model_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
)
|
|
||||||
os.makedirs(os.path.dirname(merged_model_path), exist_ok=True)
|
|
||||||
save_file(merged_model_weight, merged_model_path)
|
save_file(merged_model_weight, merged_model_path)
|
||||||
|
|
||||||
info = {
|
info = {
|
||||||
@@ -175,24 +170,22 @@ def merge_models(
|
|||||||
"speech_style_weight": speech_style_weight,
|
"speech_style_weight": speech_style_weight,
|
||||||
"tempo_weight": tempo_weight,
|
"tempo_weight": tempo_weight,
|
||||||
}
|
}
|
||||||
with open(
|
with open(assets_root / output_name / "recipe.json", "w", encoding="utf-8") as f:
|
||||||
os.path.join(assets_root, output_name, "recipe.json"), "w", encoding="utf-8"
|
|
||||||
) as f:
|
|
||||||
json.dump(info, f, indent=2, ensure_ascii=False)
|
json.dump(info, f, indent=2, ensure_ascii=False)
|
||||||
return merged_model_path
|
return merged_model_path
|
||||||
|
|
||||||
|
|
||||||
def merge_models_gr(
|
def merge_models_gr(
|
||||||
model_name_a,
|
model_name_a: str,
|
||||||
model_path_a,
|
model_path_a: str,
|
||||||
model_name_b,
|
model_name_b: str,
|
||||||
model_path_b,
|
model_path_b: str,
|
||||||
output_name,
|
output_name: str,
|
||||||
voice_weight,
|
voice_weight: float,
|
||||||
voice_pitch_weight,
|
voice_pitch_weight: float,
|
||||||
speech_style_weight,
|
speech_style_weight: float,
|
||||||
tempo_weight,
|
tempo_weight: float,
|
||||||
use_slerp_instead_of_lerp,
|
use_slerp_instead_of_lerp: bool,
|
||||||
):
|
):
|
||||||
if output_name == "":
|
if output_name == "":
|
||||||
return "Error: 新しいモデル名を入力してください。"
|
return "Error: 新しいモデル名を入力してください。"
|
||||||
@@ -210,10 +203,10 @@ def merge_models_gr(
|
|||||||
|
|
||||||
|
|
||||||
def merge_style_gr(
|
def merge_style_gr(
|
||||||
model_name_a,
|
model_name_a: str,
|
||||||
model_name_b,
|
model_name_b: str,
|
||||||
weight,
|
weight: float,
|
||||||
output_name,
|
output_name: str,
|
||||||
style_triple_list_str: str,
|
style_triple_list_str: str,
|
||||||
):
|
):
|
||||||
if output_name == "":
|
if output_name == "":
|
||||||
@@ -245,12 +238,14 @@ def merge_style_gr(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def simple_tts(model_name, text, style=DEFAULT_STYLE, style_weight=1.0):
|
def simple_tts(
|
||||||
model_path = os.path.join(assets_root, model_name, f"{model_name}.safetensors")
|
model_name: str, text: str, style: str = DEFAULT_STYLE, style_weight: float = 1.0
|
||||||
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_path = assets_root / model_name / f"{model_name}.safetensors"
|
||||||
|
config_path = assets_root / model_name / "config.json"
|
||||||
|
style_vec_path = assets_root / model_name / "style_vectors.npy"
|
||||||
|
|
||||||
model = TTSModel(Path(model_path), Path(config_path), Path(style_vec_path), device)
|
model = TTSModel(model_path, config_path, style_vec_path, device)
|
||||||
return model.infer(text, style=style, style_weight=style_weight)
|
return model.infer(text, style=style, style_weight=style_weight)
|
||||||
|
|
||||||
|
|
||||||
@@ -259,13 +254,13 @@ def update_two_model_names_dropdown(model_holder: TTSModelHolder):
|
|||||||
return new_names, new_files, new_names, new_files
|
return new_names, new_files, new_names, new_files
|
||||||
|
|
||||||
|
|
||||||
def load_styles_gr(model_name_a, model_name_b):
|
def load_styles_gr(model_name_a: str, model_name_b: str):
|
||||||
config_path_a = os.path.join(assets_root, model_name_a, "config.json")
|
config_path_a = assets_root / model_name_a / "config.json"
|
||||||
with open(config_path_a, "r", encoding="utf-8") as f:
|
with open(config_path_a, "r", encoding="utf-8") as f:
|
||||||
config_a = json.load(f)
|
config_a = json.load(f)
|
||||||
styles_a = list(config_a["data"]["style2id"].keys())
|
styles_a = list(config_a["data"]["style2id"].keys())
|
||||||
|
|
||||||
config_path_b = os.path.join(assets_root, model_name_b, "config.json")
|
config_path_b = assets_root / model_name_b / "config.json"
|
||||||
with open(config_path_b, "r", encoding="utf-8") as f:
|
with open(config_path_b, "r", encoding="utf-8") as f:
|
||||||
config_b = json.load(f)
|
config_b = json.load(f)
|
||||||
styles_b = list(config_b["data"]["style2id"].keys())
|
styles_b = list(config_b["data"]["style2id"].keys())
|
||||||
@@ -336,7 +331,10 @@ def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
|
|||||||
)
|
)
|
||||||
return app
|
return app
|
||||||
initial_id = 0
|
initial_id = 0
|
||||||
initial_model_files = model_holder.model_files_dict[model_names[initial_id]]
|
# initial_model_files = model_holder.model_files_dict[model_names[initial_id]]
|
||||||
|
initial_model_files = [
|
||||||
|
str(f) for f in model_holder.model_files_dict[model_names[initial_id]]
|
||||||
|
]
|
||||||
|
|
||||||
with gr.Blocks(theme=GRADIO_THEME) as app:
|
with gr.Blocks(theme=GRADIO_THEME) as app:
|
||||||
gr.Markdown(
|
gr.Markdown(
|
||||||
|
|||||||
@@ -1,27 +1,23 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import gradio as gr
|
import gradio as gr
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import yaml
|
|
||||||
from scipy.spatial.distance import pdist, squareform
|
from scipy.spatial.distance import pdist, squareform
|
||||||
from sklearn.cluster import DBSCAN, AgglomerativeClustering, KMeans
|
from sklearn.cluster import DBSCAN, AgglomerativeClustering, KMeans
|
||||||
from sklearn.manifold import TSNE
|
from sklearn.manifold import TSNE
|
||||||
from umap import UMAP
|
from umap import UMAP
|
||||||
|
|
||||||
from config import config
|
from config import get_path_config
|
||||||
from style_bert_vits2.constants import DEFAULT_STYLE, GRADIO_THEME
|
from style_bert_vits2.constants import DEFAULT_STYLE, GRADIO_THEME
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
|
|
||||||
|
|
||||||
# Get path settings
|
path_config = get_path_config()
|
||||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
dataset_root = path_config.dataset_root
|
||||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
assets_root = path_config.assets_root
|
||||||
dataset_root = Path(path_config["dataset_root"])
|
|
||||||
# assets_root = path_config["assets_root"]
|
|
||||||
|
|
||||||
MAX_CLUSTER_NUM = 10
|
MAX_CLUSTER_NUM = 10
|
||||||
MAX_AUDIO_NUM = 10
|
MAX_AUDIO_NUM = 10
|
||||||
@@ -39,11 +35,7 @@ centroids = []
|
|||||||
|
|
||||||
def load(model_name: str, reduction_method: str):
|
def load(model_name: str, reduction_method: str):
|
||||||
global wav_files, x, x_reduced, mean
|
global wav_files, x, x_reduced, mean
|
||||||
# wavs_dir = os.path.join(dataset_root, model_name, "wavs")
|
|
||||||
wavs_dir = dataset_root / model_name / "wavs"
|
wavs_dir = dataset_root / model_name / "wavs"
|
||||||
# style_vector_files = [
|
|
||||||
# os.path.join(wavs_dir, f) for f in os.listdir(wavs_dir) if f.endswith(".npy")
|
|
||||||
# ]
|
|
||||||
style_vector_files = [f for f in wavs_dir.rglob("*.npy") if f.is_file()]
|
style_vector_files = [f for f in wavs_dir.rglob("*.npy") if f.is_file()]
|
||||||
# foo.wav.npy -> foo.wav
|
# foo.wav.npy -> foo.wav
|
||||||
wav_files = [f.with_suffix("") for f in style_vector_files]
|
wav_files = [f.with_suffix("") for f in style_vector_files]
|
||||||
@@ -196,21 +188,21 @@ def do_clustering_gradio(n_clusters=4, method="KMeans"):
|
|||||||
] * MAX_AUDIO_NUM
|
] * MAX_AUDIO_NUM
|
||||||
|
|
||||||
|
|
||||||
def save_style_vectors_from_clustering(model_name, style_names_str: str):
|
def save_style_vectors_from_clustering(model_name: str, style_names_str: str):
|
||||||
"""centerとcentroidsを保存する"""
|
"""centerとcentroidsを保存する"""
|
||||||
result_dir = os.path.join(config.assets_root, model_name)
|
result_dir = assets_root / model_name
|
||||||
os.makedirs(result_dir, exist_ok=True)
|
result_dir.mkdir(parents=True, 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 = result_dir / "style_vectors.npy"
|
||||||
if os.path.exists(style_vector_path):
|
if style_vector_path.exists():
|
||||||
logger.info(f"Backup {style_vector_path} to {style_vector_path}.bak")
|
logger.info(f"Backup {style_vector_path} to {style_vector_path}.bak")
|
||||||
shutil.copy(style_vector_path, f"{style_vector_path}.bak")
|
shutil.copy(style_vector_path, f"{style_vector_path}.bak")
|
||||||
np.save(style_vector_path, style_vectors)
|
np.save(style_vector_path, style_vectors)
|
||||||
logger.success(f"Saved style vectors to {style_vector_path}")
|
logger.success(f"Saved style vectors to {style_vector_path}")
|
||||||
|
|
||||||
# config.jsonの更新
|
# config.jsonの更新
|
||||||
config_path = os.path.join(result_dir, "config.json")
|
config_path = result_dir / "config.json"
|
||||||
if not os.path.exists(config_path):
|
if not config_path.exists():
|
||||||
return f"{config_path}が存在しません。"
|
return f"{config_path}が存在しません。"
|
||||||
style_names = [name.strip() for name in style_names_str.split(",")]
|
style_names = [name.strip() for name in style_names_str.split(",")]
|
||||||
style_name_list = [DEFAULT_STYLE] + style_names
|
style_name_list = [DEFAULT_STYLE] + style_names
|
||||||
@@ -233,7 +225,7 @@ def save_style_vectors_from_clustering(model_name, style_names_str: str):
|
|||||||
|
|
||||||
|
|
||||||
def save_style_vectors_from_files(
|
def save_style_vectors_from_files(
|
||||||
model_name, audio_files_str: str, style_names_str: str
|
model_name: str, audio_files_str: str, style_names_str: str
|
||||||
):
|
):
|
||||||
"""音声ファイルからスタイルベクトルを作成して保存する"""
|
"""音声ファイルからスタイルベクトルを作成して保存する"""
|
||||||
global mean
|
global mean
|
||||||
@@ -241,8 +233,8 @@ def save_style_vectors_from_files(
|
|||||||
return "Error: スタイルベクトルを読み込んでください。"
|
return "Error: スタイルベクトルを読み込んでください。"
|
||||||
mean = np.mean(x, axis=0)
|
mean = np.mean(x, axis=0)
|
||||||
|
|
||||||
result_dir = os.path.join(config.assets_root, model_name)
|
result_dir = assets_root / model_name
|
||||||
os.makedirs(result_dir, exist_ok=True)
|
result_dir.mkdir(parents=True, exist_ok=True)
|
||||||
audio_files = [name.strip() for name in audio_files_str.split(",")]
|
audio_files = [name.strip() for name in audio_files_str.split(",")]
|
||||||
style_names = [name.strip() for name in style_names_str.split(",")]
|
style_names = [name.strip() for name in style_names_str.split(",")]
|
||||||
if len(audio_files) != len(style_names):
|
if len(audio_files) != len(style_names):
|
||||||
@@ -252,23 +244,23 @@ def save_style_vectors_from_files(
|
|||||||
return "スタイル名が重複しています。"
|
return "スタイル名が重複しています。"
|
||||||
style_vectors = [mean]
|
style_vectors = [mean]
|
||||||
|
|
||||||
wavs_dir = os.path.join(dataset_root, model_name, "wavs")
|
wavs_dir = dataset_root / model_name / "wavs"
|
||||||
for audio_file in audio_files:
|
for audio_file in audio_files:
|
||||||
path = os.path.join(wavs_dir, audio_file)
|
path = wavs_dir / audio_file
|
||||||
if not os.path.exists(path):
|
if not path.exists():
|
||||||
return f"{path}が存在しません。"
|
return f"{path}が存在しません。"
|
||||||
style_vectors.append(np.load(f"{path}.npy"))
|
style_vectors.append(np.load(f"{path}.npy"))
|
||||||
style_vectors = np.stack(style_vectors)
|
style_vectors = np.stack(style_vectors)
|
||||||
assert len(style_name_list) == len(style_vectors)
|
assert len(style_name_list) == len(style_vectors)
|
||||||
style_vector_path = os.path.join(result_dir, "style_vectors.npy")
|
style_vector_path = result_dir / "style_vectors.npy"
|
||||||
if os.path.exists(style_vector_path):
|
if style_vector_path.exists():
|
||||||
logger.info(f"Backup {style_vector_path} to {style_vector_path}.bak")
|
logger.info(f"Backup {style_vector_path} to {style_vector_path}.bak")
|
||||||
shutil.copy(style_vector_path, f"{style_vector_path}.bak")
|
shutil.copy(style_vector_path, f"{style_vector_path}.bak")
|
||||||
np.save(style_vector_path, style_vectors)
|
np.save(style_vector_path, style_vectors)
|
||||||
|
|
||||||
# config.jsonの更新
|
# config.jsonの更新
|
||||||
config_path = os.path.join(result_dir, "config.json")
|
config_path = result_dir / "config.json"
|
||||||
if not os.path.exists(config_path):
|
if not config_path.exists():
|
||||||
return f"{config_path}が存在しません。"
|
return f"{config_path}が存在しません。"
|
||||||
logger.info(f"Backup {config_path} to {config_path}.bak")
|
logger.info(f"Backup {config_path} to {config_path}.bak")
|
||||||
shutil.copy(config_path, f"{config_path}.bak")
|
shutil.copy(config_path, f"{config_path}.bak")
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -12,7 +11,8 @@ from pathlib import Path
|
|||||||
|
|
||||||
import gradio as gr
|
import gradio as gr
|
||||||
import yaml
|
import yaml
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from config import get_path_config
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
||||||
from style_bert_vits2.utils.subprocess import run_script_with_log, second_elem_of
|
from style_bert_vits2.utils.subprocess import run_script_with_log, second_elem_of
|
||||||
@@ -21,20 +21,27 @@ from style_bert_vits2.utils.subprocess import run_script_with_log, second_elem_o
|
|||||||
logger_handler = None
|
logger_handler = None
|
||||||
tensorboard_executed = False
|
tensorboard_executed = False
|
||||||
|
|
||||||
# Get path settings
|
path_config = get_path_config()
|
||||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
dataset_root = path_config.dataset_root
|
||||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
|
||||||
dataset_root = Path(path_config["dataset_root"])
|
|
||||||
|
|
||||||
|
|
||||||
def get_path(model_name: str) -> tuple[Path, Path, Path, Path, Path]:
|
@dataclass
|
||||||
|
class PathsForPreprocess:
|
||||||
|
dataset_path: Path
|
||||||
|
esd_path: Path
|
||||||
|
train_path: Path
|
||||||
|
val_path: Path
|
||||||
|
config_path: Path
|
||||||
|
|
||||||
|
|
||||||
|
def get_path(model_name: str) -> PathsForPreprocess:
|
||||||
assert model_name != "", "モデル名は空にできません"
|
assert model_name != "", "モデル名は空にできません"
|
||||||
dataset_path = dataset_root / model_name
|
dataset_path = dataset_root / model_name
|
||||||
lbl_path = dataset_path / "esd.list"
|
esd_path = dataset_path / "esd.list"
|
||||||
train_path = dataset_path / "train.list"
|
train_path = dataset_path / "train.list"
|
||||||
val_path = dataset_path / "val.list"
|
val_path = dataset_path / "val.list"
|
||||||
config_path = dataset_path / "config.json"
|
config_path = dataset_path / "config.json"
|
||||||
return dataset_path, lbl_path, train_path, val_path, config_path
|
return PathsForPreprocess(dataset_path, esd_path, train_path, val_path, config_path)
|
||||||
|
|
||||||
|
|
||||||
def initialize(
|
def initialize(
|
||||||
@@ -51,14 +58,14 @@ def initialize(
|
|||||||
log_interval: int,
|
log_interval: int,
|
||||||
):
|
):
|
||||||
global logger_handler
|
global logger_handler
|
||||||
dataset_path, _, train_path, val_path, config_path = get_path(model_name)
|
paths = get_path(model_name)
|
||||||
|
|
||||||
# 前処理のログをファイルに保存する
|
# 前処理のログをファイルに保存する
|
||||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
file_name = f"preprocess_{timestamp}.log"
|
file_name = f"preprocess_{timestamp}.log"
|
||||||
if logger_handler is not None:
|
if logger_handler is not None:
|
||||||
logger.remove(logger_handler)
|
logger.remove(logger_handler)
|
||||||
logger_handler = logger.add(os.path.join(dataset_path, file_name))
|
logger_handler = logger.add(paths.dataset_path / file_name)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Step 1: start initialization...\nmodel_name: {model_name}, batch_size: {batch_size}, epochs: {epochs}, save_every_steps: {save_every_steps}, freeze_ZH_bert: {freeze_ZH_bert}, freeze_JP_bert: {freeze_JP_bert}, freeze_EN_bert: {freeze_EN_bert}, freeze_style: {freeze_style}, freeze_decoder: {freeze_decoder}, use_jp_extra: {use_jp_extra}"
|
f"Step 1: start initialization...\nmodel_name: {model_name}, batch_size: {batch_size}, epochs: {epochs}, save_every_steps: {save_every_steps}, freeze_ZH_bert: {freeze_ZH_bert}, freeze_JP_bert: {freeze_JP_bert}, freeze_EN_bert: {freeze_EN_bert}, freeze_style: {freeze_style}, freeze_decoder: {freeze_decoder}, use_jp_extra: {use_jp_extra}"
|
||||||
@@ -71,8 +78,8 @@ def initialize(
|
|||||||
with open(default_config_path, "r", encoding="utf-8") as f:
|
with open(default_config_path, "r", encoding="utf-8") as f:
|
||||||
config = json.load(f)
|
config = json.load(f)
|
||||||
config["model_name"] = model_name
|
config["model_name"] = model_name
|
||||||
config["data"]["training_files"] = str(train_path)
|
config["data"]["training_files"] = str(paths.train_path)
|
||||||
config["data"]["validation_files"] = str(val_path)
|
config["data"]["validation_files"] = str(paths.val_path)
|
||||||
config["train"]["batch_size"] = batch_size
|
config["train"]["batch_size"] = batch_size
|
||||||
config["train"]["epochs"] = epochs
|
config["train"]["epochs"] = epochs
|
||||||
config["train"]["eval_interval"] = save_every_steps
|
config["train"]["eval_interval"] = save_every_steps
|
||||||
@@ -89,14 +96,14 @@ def initialize(
|
|||||||
# 今はデフォルトであるが、以前は非JP-Extra版になくバグの原因になるので念のため
|
# 今はデフォルトであるが、以前は非JP-Extra版になくバグの原因になるので念のため
|
||||||
config["data"]["use_jp_extra"] = use_jp_extra
|
config["data"]["use_jp_extra"] = use_jp_extra
|
||||||
|
|
||||||
model_path = dataset_path / "models"
|
model_path = paths.dataset_path / "models"
|
||||||
if model_path.exists():
|
if model_path.exists():
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Step 1: {model_path} already exists, so copy it to backup to {model_path}_backup"
|
f"Step 1: {model_path} already exists, so copy it to backup to {model_path}_backup"
|
||||||
)
|
)
|
||||||
shutil.copytree(
|
shutil.copytree(
|
||||||
src=model_path,
|
src=model_path,
|
||||||
dst=dataset_path / "models_backup",
|
dst=paths.dataset_path / "models_backup",
|
||||||
dirs_exist_ok=True,
|
dirs_exist_ok=True,
|
||||||
)
|
)
|
||||||
shutil.rmtree(model_path)
|
shutil.rmtree(model_path)
|
||||||
@@ -110,14 +117,14 @@ def initialize(
|
|||||||
logger.error(f"Step 1: {pretrained_dir} folder not found.")
|
logger.error(f"Step 1: {pretrained_dir} folder not found.")
|
||||||
return False, f"Step 1, Error: {pretrained_dir}フォルダが見つかりません。"
|
return False, f"Step 1, Error: {pretrained_dir}フォルダが見つかりません。"
|
||||||
|
|
||||||
with open(config_path, "w", encoding="utf-8") as f:
|
with open(paths.config_path, "w", encoding="utf-8") as f:
|
||||||
json.dump(config, f, indent=2, ensure_ascii=False)
|
json.dump(config, f, indent=2, ensure_ascii=False)
|
||||||
if not Path("config.yml").exists():
|
if not Path("config.yml").exists():
|
||||||
shutil.copy(src="default_config.yml", dst="config.yml")
|
shutil.copy(src="default_config.yml", dst="config.yml")
|
||||||
with open("config.yml", "r", encoding="utf-8") as f:
|
with open("config.yml", "r", encoding="utf-8") as f:
|
||||||
yml_data = yaml.safe_load(f)
|
yml_data = yaml.safe_load(f)
|
||||||
yml_data["model_name"] = model_name
|
yml_data["model_name"] = model_name
|
||||||
yml_data["dataset_path"] = str(dataset_path)
|
yml_data["dataset_path"] = str(paths.dataset_path)
|
||||||
with open("config.yml", "w", encoding="utf-8") as f:
|
with open("config.yml", "w", encoding="utf-8") as f:
|
||||||
yaml.dump(yml_data, f, allow_unicode=True)
|
yaml.dump(yml_data, f, allow_unicode=True)
|
||||||
logger.success("Step 1: initialization finished.")
|
logger.success("Step 1: initialization finished.")
|
||||||
@@ -126,7 +133,7 @@ def initialize(
|
|||||||
|
|
||||||
def resample(model_name: str, normalize: bool, trim: bool, num_processes: int):
|
def resample(model_name: str, normalize: bool, trim: bool, num_processes: int):
|
||||||
logger.info("Step 2: start resampling...")
|
logger.info("Step 2: start resampling...")
|
||||||
dataset_path, _, _, _, _ = get_path(model_name)
|
dataset_path = get_path(model_name).dataset_path
|
||||||
input_dir = dataset_path / "raw"
|
input_dir = dataset_path / "raw"
|
||||||
output_dir = dataset_path / "wavs"
|
output_dir = dataset_path / "wavs"
|
||||||
cmd = [
|
cmd = [
|
||||||
@@ -159,21 +166,24 @@ def preprocess_text(
|
|||||||
model_name: str, use_jp_extra: bool, val_per_lang: int, yomi_error: str
|
model_name: str, use_jp_extra: bool, val_per_lang: int, yomi_error: str
|
||||||
):
|
):
|
||||||
logger.info("Step 3: start preprocessing text...")
|
logger.info("Step 3: start preprocessing text...")
|
||||||
_, lbl_path, train_path, val_path, config_path = get_path(model_name)
|
paths = get_path(model_name)
|
||||||
if not lbl_path.exists():
|
if not paths.esd_path.exists():
|
||||||
logger.error(f"Step 3: {lbl_path} not found.")
|
logger.error(f"Step 3: {paths.esd_path} not found.")
|
||||||
return False, f"Step 3, Error: 書き起こしファイル {lbl_path} が見つかりません。"
|
return (
|
||||||
|
False,
|
||||||
|
f"Step 3, Error: 書き起こしファイル {paths.esd_path} が見つかりません。",
|
||||||
|
)
|
||||||
|
|
||||||
cmd = [
|
cmd = [
|
||||||
"preprocess_text.py",
|
"preprocess_text.py",
|
||||||
"--config-path",
|
"--config-path",
|
||||||
str(config_path),
|
str(paths.config_path),
|
||||||
"--transcription-path",
|
"--transcription-path",
|
||||||
str(lbl_path),
|
str(paths.esd_path),
|
||||||
"--train-path",
|
"--train-path",
|
||||||
str(train_path),
|
str(paths.train_path),
|
||||||
"--val-path",
|
"--val-path",
|
||||||
str(val_path),
|
str(paths.val_path),
|
||||||
"--val-per-lang",
|
"--val-per-lang",
|
||||||
str(val_per_lang),
|
str(val_per_lang),
|
||||||
"--yomi_error",
|
"--yomi_error",
|
||||||
@@ -201,7 +211,7 @@ def preprocess_text(
|
|||||||
|
|
||||||
def bert_gen(model_name: str):
|
def bert_gen(model_name: str):
|
||||||
logger.info("Step 4: start bert_gen...")
|
logger.info("Step 4: start bert_gen...")
|
||||||
_, _, _, _, config_path = get_path(model_name)
|
config_path = get_path(model_name).config_path
|
||||||
success, message = run_script_with_log(
|
success, message = run_script_with_log(
|
||||||
["bert_gen.py", "--config", str(config_path)]
|
["bert_gen.py", "--config", str(config_path)]
|
||||||
)
|
)
|
||||||
@@ -220,7 +230,7 @@ def bert_gen(model_name: str):
|
|||||||
|
|
||||||
def style_gen(model_name: str, num_processes: int):
|
def style_gen(model_name: str, num_processes: int):
|
||||||
logger.info("Step 5: start style_gen...")
|
logger.info("Step 5: start style_gen...")
|
||||||
_, _, _, _, config_path = get_path(model_name)
|
config_path = get_path(model_name).config_path
|
||||||
success, message = run_script_with_log(
|
success, message = run_script_with_log(
|
||||||
[
|
[
|
||||||
"style_gen.py",
|
"style_gen.py",
|
||||||
@@ -319,17 +329,23 @@ def train(
|
|||||||
use_jp_extra: bool = True,
|
use_jp_extra: bool = True,
|
||||||
speedup: bool = False,
|
speedup: bool = False,
|
||||||
):
|
):
|
||||||
dataset_path, _, _, _, config_path = get_path(model_name)
|
paths = get_path(model_name)
|
||||||
# 学習再開の場合を考えて念のためconfig.ymlの名前等を更新
|
# 学習再開の場合を考えて念のためconfig.ymlの名前等を更新
|
||||||
with open("config.yml", "r", encoding="utf-8") as f:
|
with open("config.yml", "r", encoding="utf-8") as f:
|
||||||
yml_data = yaml.safe_load(f)
|
yml_data = yaml.safe_load(f)
|
||||||
yml_data["model_name"] = model_name
|
yml_data["model_name"] = model_name
|
||||||
yml_data["dataset_path"] = str(dataset_path)
|
yml_data["dataset_path"] = str(paths.dataset_path)
|
||||||
with open("config.yml", "w", encoding="utf-8") as f:
|
with open("config.yml", "w", encoding="utf-8") as f:
|
||||||
yaml.dump(yml_data, f, allow_unicode=True)
|
yaml.dump(yml_data, f, allow_unicode=True)
|
||||||
|
|
||||||
train_py = "train_ms.py" if not use_jp_extra else "train_ms_jp_extra.py"
|
train_py = "train_ms.py" if not use_jp_extra else "train_ms_jp_extra.py"
|
||||||
cmd = [train_py, "--config", str(config_path), "--model", str(dataset_path)]
|
cmd = [
|
||||||
|
train_py,
|
||||||
|
"--config",
|
||||||
|
str(paths.config_path),
|
||||||
|
"--model",
|
||||||
|
str(paths.dataset_path),
|
||||||
|
]
|
||||||
if skip_style:
|
if skip_style:
|
||||||
cmd.append("--skip_default_style")
|
cmd.append("--skip_default_style")
|
||||||
if speedup:
|
if speedup:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from typing import Optional
|
|||||||
|
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from config import Preprocess_text_config, config
|
from config import get_config
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.nlp import clean_text
|
from style_bert_vits2.nlp import clean_text
|
||||||
from style_bert_vits2.nlp.japanese import pyopenjtalk_worker
|
from style_bert_vits2.nlp.japanese import pyopenjtalk_worker
|
||||||
@@ -22,7 +22,7 @@ pyopenjtalk_worker.initialize_worker()
|
|||||||
update_dict()
|
update_dict()
|
||||||
|
|
||||||
|
|
||||||
preprocess_text_config: Preprocess_text_config = config.preprocess_text_config
|
preprocess_text_config = get_config().preprocess_text_config
|
||||||
|
|
||||||
|
|
||||||
# Count lines for tqdm
|
# Count lines for tqdm
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ matplotlib
|
|||||||
num2words
|
num2words
|
||||||
numba
|
numba
|
||||||
numpy
|
numpy
|
||||||
|
protobuf==4.25
|
||||||
psutil
|
psutil
|
||||||
pyannote.audio>=3.1.0
|
pyannote.audio>=3.1.0
|
||||||
pydantic>=2.0
|
pydantic>=2.0
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import soundfile
|
|||||||
from numpy.typing import NDArray
|
from numpy.typing import NDArray
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from config import config
|
from config import get_config
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
||||||
|
|
||||||
@@ -70,6 +70,7 @@ def resample(
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
config = get_config()
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--sr",
|
"--sr",
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import numpy as np
|
|||||||
import requests
|
import requests
|
||||||
import torch
|
import torch
|
||||||
import uvicorn
|
import uvicorn
|
||||||
import yaml
|
|
||||||
from fastapi import APIRouter, FastAPI, HTTPException, status
|
from fastapi import APIRouter, FastAPI, HTTPException, status
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.responses import JSONResponse, Response
|
from fastapi.responses import JSONResponse, Response
|
||||||
@@ -30,6 +29,7 @@ from fastapi.staticfiles import StaticFiles
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from scipy.io import wavfile
|
from scipy.io import wavfile
|
||||||
|
|
||||||
|
from config import get_path_config
|
||||||
from style_bert_vits2.constants import (
|
from style_bert_vits2.constants import (
|
||||||
DEFAULT_ASSIST_TEXT_WEIGHT,
|
DEFAULT_ASSIST_TEXT_WEIGHT,
|
||||||
DEFAULT_NOISE,
|
DEFAULT_NOISE,
|
||||||
@@ -174,22 +174,14 @@ origins = [
|
|||||||
"http://127.0.0.1:8000",
|
"http://127.0.0.1:8000",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Get path settings
|
path_config = get_path_config()
|
||||||
with open(Path("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"]
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("--model_dir", type=str, default="model_assets/")
|
parser.add_argument("--model_dir", type=str, default=path_config.assets_root)
|
||||||
parser.add_argument("--device", type=str, default="cuda")
|
parser.add_argument("--device", type=str, default="cuda")
|
||||||
parser.add_argument("--port", type=int, default=8000)
|
parser.add_argument("--port", type=int, default=8000)
|
||||||
parser.add_argument("--inbrowser", action="store_true")
|
parser.add_argument("--inbrowser", action="store_true")
|
||||||
parser.add_argument("--line_length", type=int, default=None)
|
parser.add_argument("--line_length", type=int, default=None)
|
||||||
parser.add_argument("--line_count", type=int, default=None)
|
parser.add_argument("--line_count", type=int, default=None)
|
||||||
parser.add_argument(
|
|
||||||
"--dir", "-d", type=str, help="Model directory", default=assets_root
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
device = args.device
|
device = args.device
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from fastapi.middleware.cors import CORSMiddleware
|
|||||||
from fastapi.responses import FileResponse, Response
|
from fastapi.responses import FileResponse, Response
|
||||||
from scipy.io import wavfile
|
from scipy.io import wavfile
|
||||||
|
|
||||||
from config import config
|
from config import get_config
|
||||||
from style_bert_vits2.constants import (
|
from style_bert_vits2.constants import (
|
||||||
DEFAULT_ASSIST_TEXT_WEIGHT,
|
DEFAULT_ASSIST_TEXT_WEIGHT,
|
||||||
DEFAULT_LENGTH,
|
DEFAULT_LENGTH,
|
||||||
@@ -40,6 +40,7 @@ from style_bert_vits2.nlp.japanese.user_dict import update_dict
|
|||||||
from style_bert_vits2.tts_model import TTSModel, TTSModelHolder
|
from style_bert_vits2.tts_model import TTSModel, TTSModelHolder
|
||||||
|
|
||||||
|
|
||||||
|
config = get_config()
|
||||||
ln = config.server_config.language
|
ln = config.server_config.language
|
||||||
|
|
||||||
|
|
||||||
@@ -113,6 +114,9 @@ if __name__ == "__main__":
|
|||||||
load_models(model_holder)
|
load_models(model_holder)
|
||||||
|
|
||||||
limit = config.server_config.limit
|
limit = config.server_config.limit
|
||||||
|
logger.info(
|
||||||
|
f"The maximum length of the text is {limit}. If you want to change it, modify config.yml"
|
||||||
|
)
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
allow_origins = config.server_config.origins
|
allow_origins = config.server_config.origins
|
||||||
if allow_origins:
|
if allow_origins:
|
||||||
|
|||||||
8
slice.py
8
slice.py
@@ -10,6 +10,7 @@ import torch
|
|||||||
import yaml
|
import yaml
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
from config import get_path_config
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
||||||
|
|
||||||
@@ -150,13 +151,12 @@ if __name__ == "__main__":
|
|||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
with open(Path("configs/paths.yml"), "r", encoding="utf-8") as f:
|
path_config = get_path_config()
|
||||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
dataset_root = path_config.dataset_root
|
||||||
dataset_root = path_config["dataset_root"]
|
|
||||||
|
|
||||||
model_name = str(args.model_name)
|
model_name = str(args.model_name)
|
||||||
input_dir = Path(args.input_dir)
|
input_dir = Path(args.input_dir)
|
||||||
output_dir = Path(dataset_root) / model_name / "raw"
|
output_dir = dataset_root / model_name / "raw"
|
||||||
min_sec: float = args.min_sec
|
min_sec: float = args.min_sec
|
||||||
max_sec: float = args.max_sec
|
max_sec: float = args.max_sec
|
||||||
min_silence_dur_ms: int = args.min_silence_dur_ms
|
min_silence_dur_ms: int = args.min_silence_dur_ms
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import pandas as pd
|
|||||||
import torch
|
import torch
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from config import config
|
from config import get_path_config
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.tts_model import TTSModel
|
from style_bert_vits2.tts_model import TTSModel
|
||||||
|
|
||||||
@@ -35,6 +35,8 @@ test_texts = [
|
|||||||
"この分野の最新の研究成果を使うと、より自然で表現豊かな音声の生成が可能である。深層学習の応用により、感情やアクセントを含む声質の微妙な変化も再現することが出来る。",
|
"この分野の最新の研究成果を使うと、より自然で表現豊かな音声の生成が可能である。深層学習の応用により、感情やアクセントを含む声質の微妙な変化も再現することが出来る。",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
path_config = get_path_config()
|
||||||
|
|
||||||
predictor = torch.hub.load(
|
predictor = torch.hub.load(
|
||||||
"tarepan/SpeechMOS:v1.2.0", "utmos22_strong", trust_repo=True
|
"tarepan/SpeechMOS:v1.2.0", "utmos22_strong", trust_repo=True
|
||||||
)
|
)
|
||||||
@@ -48,17 +50,16 @@ args = parser.parse_args()
|
|||||||
model_name: str = args.model_name
|
model_name: str = args.model_name
|
||||||
device: str = args.device
|
device: str = args.device
|
||||||
|
|
||||||
model_path = Path(config.assets_root) / model_name
|
model_path = path_config.assets_root / model_name
|
||||||
|
|
||||||
# .safetensorsファイルを検索
|
# .safetensorsファイルを検索
|
||||||
safetensors_files = model_path.glob("*.safetensors")
|
safetensors_files = model_path.glob("*.safetensors")
|
||||||
|
|
||||||
|
|
||||||
def get_model(model_file: Path):
|
def get_model(model_file: Path):
|
||||||
return TTSModel(
|
return TTSModel(
|
||||||
model_path=str(model_file),
|
model_path=model_file,
|
||||||
config_path=str(model_file.parent / "config.json"),
|
config_path=model_file.parent / "config.json",
|
||||||
style_vec_path=str(model_file.parent / "style_vectors.npy"),
|
style_vec_path=model_file.parent / "style_vectors.npy",
|
||||||
device=device,
|
device=device,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from style_bert_vits2.utils.strenum import StrEnum
|
|||||||
|
|
||||||
|
|
||||||
# Style-Bert-VITS2 のバージョン
|
# Style-Bert-VITS2 のバージョン
|
||||||
VERSION = "2.4.1"
|
VERSION = "2.5.0"
|
||||||
|
|
||||||
# Style-Bert-VITS2 のベースディレクトリ
|
# Style-Bert-VITS2 のベースディレクトリ
|
||||||
BASE_DIR = Path(__file__).parent.parent
|
BASE_DIR = Path(__file__).parent.parent
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ from numpy.typing import NDArray
|
|||||||
from pyannote.audio import Inference, Model
|
from pyannote.audio import Inference, Model
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from config import config
|
from config import get_config
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.models.hyper_parameters import HyperParameters
|
from style_bert_vits2.models.hyper_parameters import HyperParameters
|
||||||
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
||||||
|
|
||||||
|
|
||||||
|
config = get_config()
|
||||||
|
|
||||||
model = Model.from_pretrained("pyannote/wespeaker-voxceleb-resnet34-LM")
|
model = Model.from_pretrained("pyannote/wespeaker-voxceleb-resnet34-LM")
|
||||||
inference = Inference(model, window="whole")
|
inference = Inference(model, window="whole")
|
||||||
device = torch.device(config.style_gen_config.device)
|
device = torch.device(config.style_gen_config.device)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from tqdm import tqdm
|
|||||||
|
|
||||||
# logging.getLogger("numba").setLevel(logging.WARNING)
|
# logging.getLogger("numba").setLevel(logging.WARNING)
|
||||||
import default_style
|
import default_style
|
||||||
from config import config
|
from config import get_config
|
||||||
from data_utils import (
|
from data_utils import (
|
||||||
DistributedBucketSampler,
|
DistributedBucketSampler,
|
||||||
TextAudioSpeakerCollate,
|
TextAudioSpeakerCollate,
|
||||||
@@ -48,7 +48,7 @@ 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)
|
||||||
|
|
||||||
|
config = get_config()
|
||||||
global_step = 0
|
global_step = 0
|
||||||
|
|
||||||
api = HfApi()
|
api = HfApi()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from tqdm import tqdm
|
|||||||
|
|
||||||
# logging.getLogger("numba").setLevel(logging.WARNING)
|
# logging.getLogger("numba").setLevel(logging.WARNING)
|
||||||
import default_style
|
import default_style
|
||||||
from config import config
|
from config import get_config
|
||||||
from data_utils import (
|
from data_utils import (
|
||||||
DistributedBucketSampler,
|
DistributedBucketSampler,
|
||||||
TextAudioSpeakerCollate,
|
TextAudioSpeakerCollate,
|
||||||
@@ -48,6 +48,8 @@ torch.backends.cuda.enable_flash_sdp(True)
|
|||||||
torch.backends.cuda.enable_mem_efficient_sdp(
|
torch.backends.cuda.enable_mem_efficient_sdp(
|
||||||
True
|
True
|
||||||
) # Not available if torch version is lower than 2.0
|
) # Not available if torch version is lower than 2.0
|
||||||
|
|
||||||
|
config = get_config()
|
||||||
global_step = 0
|
global_step = 0
|
||||||
|
|
||||||
api = HfApi()
|
api = HfApi()
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import yaml
|
|||||||
from torch.utils.data import Dataset
|
from torch.utils.data import Dataset
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
from config import get_path_config
|
||||||
from style_bert_vits2.constants import Languages
|
from style_bert_vits2.constants import Languages
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
|
||||||
@@ -124,9 +125,8 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument("--no_repeat_ngram_size", type=int, default=10)
|
parser.add_argument("--no_repeat_ngram_size", type=int, default=10)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
path_config = get_path_config()
|
||||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
dataset_root = path_config.dataset_root
|
||||||
dataset_root = Path(path_config["dataset_root"])
|
|
||||||
|
|
||||||
model_name = str(args.model_name)
|
model_name = str(args.model_name)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user