From 2274087da4ed7d456aa6ce57617c4281000421a2 Mon Sep 17 00:00:00 2001 From: litagin02 Date: Sat, 25 May 2024 18:15:36 +0900 Subject: [PATCH] Fmt only (maybe) --- app.py | 2 +- bert_gen.py | 9 +- config.py | 14 +- data_utils.py | 7 +- default_style.py | 6 +- gen_yaml.py | 2 +- gradio_tabs/merge.py | 12 +- gradio_tabs/train.py | 9 +- initialize.py | 4 +- preprocess_text.py | 2 +- pyproject.toml | 74 ++++------ server_editor.py | 2 +- slice.py | 1 - style_bert_vits2/models/hyper_parameters.py | 2 +- style_bert_vits2/models/models.py | 2 +- style_bert_vits2/models/models_jp_extra.py | 2 +- style_bert_vits2/models/utils/__init__.py | 12 +- style_bert_vits2/models/utils/safetensors.py | 2 +- style_bert_vits2/nlp/chinese/g2p.py | 10 +- style_bert_vits2/nlp/chinese/normalizer.py | 2 +- style_bert_vits2/nlp/chinese/tone_sandhi.py | 54 ++++---- style_bert_vits2/nlp/english/cmudict.py | 2 +- style_bert_vits2/nlp/english/g2p.py | 126 ++++++++++++++---- style_bert_vits2/nlp/english/normalizer.py | 2 +- style_bert_vits2/nlp/japanese/g2p.py | 2 - style_bert_vits2/nlp/japanese/normalizer.py | 2 +- .../japanese/pyopenjtalk_worker/__init__.py | 4 +- .../nlp/japanese/user_dict/word_model.py | 2 +- style_bert_vits2/tts_model.py | 2 +- style_bert_vits2/utils/subprocess.py | 1 + style_gen.py | 1 - train_ms_jp_extra.py | 6 +- transcribe.py | 2 - 33 files changed, 216 insertions(+), 166 deletions(-) diff --git a/app.py b/app.py index 2df9386..d363a57 100644 --- a/app.py +++ b/app.py @@ -4,6 +4,7 @@ from pathlib import Path import gradio as gr import torch +from config import get_path_config from gradio_tabs.dataset import create_dataset_app from gradio_tabs.inference import create_inference_app from gradio_tabs.merge import create_merge_app @@ -13,7 +14,6 @@ from style_bert_vits2.constants import GRADIO_THEME, VERSION from style_bert_vits2.nlp.japanese import pyopenjtalk_worker from style_bert_vits2.nlp.japanese.user_dict import update_dict from style_bert_vits2.tts_model import TTSModelHolder -from config import get_path_config # このプロセスからはワーカーを起動して辞書を使いたいので、ここで初期化 diff --git a/bert_gen.py b/bert_gen.py index af50b60..c4995cb 100644 --- a/bert_gen.py +++ b/bert_gen.py @@ -10,10 +10,7 @@ from style_bert_vits2.constants import Languages from style_bert_vits2.logging import logger from style_bert_vits2.models import commons from style_bert_vits2.models.hyper_parameters import HyperParameters -from style_bert_vits2.nlp import ( - cleaned_text_to_sequence, - extract_bert_feature, -) +from style_bert_vits2.nlp import cleaned_text_to_sequence, extract_bert_feature from style_bert_vits2.nlp.japanese import pyopenjtalk_worker from style_bert_vits2.nlp.japanese.user_dict import update_dict from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT @@ -77,10 +74,10 @@ if __name__ == "__main__": config_path = args.config hps = HyperParameters.load_from_json(config_path) lines: list[str] = [] - with open(hps.data.training_files, "r", encoding="utf-8") as f: + with open(hps.data.training_files, encoding="utf-8") as f: lines.extend(f.readlines()) - with open(hps.data.validation_files, "r", encoding="utf-8") as f: + with open(hps.data.validation_files, encoding="utf-8") as f: lines.extend(f.readlines()) add_blank = [hps.data.add_blank] * len(lines) diff --git a/config.py b/config.py index 51e05d4..4ce32f8 100644 --- a/config.py +++ b/config.py @@ -56,8 +56,13 @@ class Preprocess_text_config: clean: bool = True, ): self.transcription_path = Path(transcription_path) - self.cleaned_path = Path(cleaned_path) self.train_path = Path(train_path) + if cleaned_path == "" or cleaned_path is None: + self.cleaned_path = self.transcription_path.with_name( + self.transcription_path.name + ".cleaned" + ) + else: + self.cleaned_path = Path(cleaned_path) self.val_path = Path(val_path) self.config_path = Path(config_path) self.val_per_lang = val_per_lang @@ -70,7 +75,7 @@ class Preprocess_text_config: data["transcription_path"] = dataset_path / data["transcription_path"] if data["cleaned_path"] == "" or data["cleaned_path"] is None: - data["cleaned_path"] = None + data["cleaned_path"] = "" else: data["cleaned_path"] = dataset_path / data["cleaned_path"] data["train_path"] = dataset_path / data["train_path"] @@ -232,7 +237,7 @@ class Config: "Please do not modify default_config.yml. Instead, modify config.yml." ) # sys.exit(0) - with open(config_path, "r", encoding="utf-8") as file: + with open(config_path, encoding="utf-8") as file: yaml_config: dict[str, Any] = yaml.safe_load(file.read()) model_name: str = yaml_config["model_name"] self.model_name: str = model_name @@ -241,6 +246,7 @@ class Config: else: dataset_path = path_config.dataset_root / model_name self.dataset_path = dataset_path + self.dataset_root = path_config.dataset_root self.assets_root = path_config.assets_root self.out_dir = self.assets_root / model_name self.resample_config: Resample_config = Resample_config.from_dict( @@ -284,7 +290,7 @@ def get_path_config() -> PathConfig: 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: + with open(path_config_path, encoding="utf-8") as file: path_config_dict: dict[str, str] = yaml.safe_load(file.read()) return PathConfig(**path_config_dict) diff --git a/data_utils.py b/data_utils.py index 73d4303..4121e35 100644 --- a/data_utils.py +++ b/data_utils.py @@ -7,7 +7,7 @@ import torch import torch.utils.data from tqdm import tqdm -from config import config +from config import get_config from mel_processing import mel_spectrogram_torch, spectrogram_torch from style_bert_vits2.logging import logger from style_bert_vits2.models import commons @@ -16,6 +16,7 @@ from style_bert_vits2.models.utils import load_filepaths_and_text, load_wav_to_t from style_bert_vits2.nlp import cleaned_text_to_sequence +config = get_config() """Multi speaker version""" @@ -120,9 +121,7 @@ class TextAudioSpeakerLoader(torch.utils.data.Dataset): audio, sampling_rate = load_wav_to_torch(filename) if sampling_rate != self.sampling_rate: raise ValueError( - "{} {} SR doesn't match target {} SR".format( - filename, sampling_rate, self.sampling_rate - ) + f"{filename} {sampling_rate} SR doesn't match target {self.sampling_rate} SR" ) audio_norm = audio / self.max_wav_value audio_norm = audio_norm.unsqueeze(0) diff --git a/default_style.py b/default_style.py index de28564..abad90e 100644 --- a/default_style.py +++ b/default_style.py @@ -33,7 +33,7 @@ def save_neutral_vector(wav_dir: Union[Path, str], output_path: Union[Path, str] np.save(output_path, only_mean) logger.info(f"Saved mean style vector to {output_path}") - with open(json_path, "r", encoding="utf-8") as f: + with open(json_path, encoding="utf-8") as f: json_dict = json.load(f) json_dict["data"]["num_styles"] = 1 json_dict["data"]["style2id"] = {DEFAULT_STYLE: 0} @@ -50,7 +50,7 @@ def save_styles_by_dirs(wav_dir: Union[Path, str], output_dir: Union[Path, str]) subdirs = [d for d in wav_dir.iterdir() if d.is_dir()] subdirs.sort() - if len(subdirs) in (0, 1): + if not subdirs: logger.warning("No style directories found. Saving only neutral style.") save_neutral_vector(wav_dir, output_dir) @@ -85,7 +85,7 @@ def save_styles_by_dirs(wav_dir: Union[Path, str], output_dir: Union[Path, str]) # Save style2id config to json style2id = {name: i for i, name in enumerate(names)} - with open(json_path, "r", encoding="utf-8") as f: + with open(json_path, encoding="utf-8") as f: json_dict = json.load(f) json_dict["data"]["num_styles"] = len(names) json_dict["data"]["style2id"] = style2id diff --git a/gen_yaml.py b/gen_yaml.py index ac27103..18e3115 100644 --- a/gen_yaml.py +++ b/gen_yaml.py @@ -22,7 +22,7 @@ args = parser.parse_args() def gen_yaml(model_name, dataset_path): if not os.path.exists("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", encoding="utf-8") as f: yml_data = yaml.safe_load(f) yml_data["model_name"] = model_name yml_data["dataset_path"] = dataset_path diff --git a/gradio_tabs/merge.py b/gradio_tabs/merge.py index c6348dd..750f310 100644 --- a/gradio_tabs/merge.py +++ b/gradio_tabs/merge.py @@ -47,9 +47,9 @@ def merge_style( style_vectors_b = np.load( assets_root / model_name_b / "style_vectors.npy" ) # (style_num_b, 256) - with open(assets_root / model_name_a / "config.json", "r", encoding="utf-8") as f: + with open(assets_root / model_name_a / "config.json", encoding="utf-8") as f: config_a = json.load(f) - with open(assets_root / model_name_b / "config.json", "r", encoding="utf-8") as f: + with open(assets_root / model_name_b / "config.json", encoding="utf-8") as f: config_b = json.load(f) style2id_a = config_a["data"]["style2id"] style2id_b = config_b["data"]["style2id"] @@ -83,7 +83,7 @@ def merge_style( # recipe.jsonを読み込んで、style_triple_listを追記 info_path = assets_root / output_name / "recipe.json" if info_path.exists(): - with open(info_path, "r", encoding="utf-8") as f: + with open(info_path, encoding="utf-8") as f: info = json.load(f) else: info = {} @@ -143,7 +143,7 @@ def merge_models( merged_model_weight = model_a_weight.copy() - for key in model_a_weight.keys(): + for key in model_a_weight: if any([key.startswith(prefix) for prefix in voice_keys]): weight = voice_weight elif any([key.startswith(prefix) for prefix in voice_pitch_keys]): @@ -256,12 +256,12 @@ def update_two_model_names_dropdown(model_holder: TTSModelHolder): def load_styles_gr(model_name_a: str, model_name_b: str): 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, encoding="utf-8") as f: config_a = json.load(f) styles_a = list(config_a["data"]["style2id"].keys()) 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, encoding="utf-8") as f: config_b = json.load(f) styles_b = list(config_b["data"]["style2id"].keys()) diff --git a/gradio_tabs/train.py b/gradio_tabs/train.py index e3b130e..8237797 100644 --- a/gradio_tabs/train.py +++ b/gradio_tabs/train.py @@ -5,13 +5,14 @@ import subprocess import sys import time import webbrowser +from dataclasses import dataclass from datetime import datetime from multiprocessing import cpu_count from pathlib import Path import gradio as gr import yaml -from dataclasses import dataclass + from config import get_path_config from style_bert_vits2.logging import logger from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT @@ -75,7 +76,7 @@ def initialize( "configs/config.json" if not use_jp_extra else "configs/config_jp_extra.json" ) - with open(default_config_path, "r", encoding="utf-8") as f: + with open(default_config_path, encoding="utf-8") as f: config = json.load(f) config["model_name"] = model_name config["data"]["training_files"] = str(paths.train_path) @@ -121,7 +122,7 @@ def initialize( json.dump(config, f, indent=2, ensure_ascii=False) if not Path("config.yml").exists(): shutil.copy(src="default_config.yml", dst="config.yml") - with open("config.yml", "r", encoding="utf-8") as f: + with open("config.yml", encoding="utf-8") as f: yml_data = yaml.safe_load(f) yml_data["model_name"] = model_name yml_data["dataset_path"] = str(paths.dataset_path) @@ -331,7 +332,7 @@ def train( ): paths = get_path(model_name) # 学習再開の場合を考えて念のためconfig.ymlの名前等を更新 - with open("config.yml", "r", encoding="utf-8") as f: + with open("config.yml", encoding="utf-8") as f: yml_data = yaml.safe_load(f) yml_data["model_name"] = model_name yml_data["dataset_path"] = str(paths.dataset_path) diff --git a/initialize.py b/initialize.py index 664d570..2bb0680 100644 --- a/initialize.py +++ b/initialize.py @@ -10,7 +10,7 @@ from style_bert_vits2.logging import logger def download_bert_models(): - with open("bert/bert_models.json", "r", encoding="utf-8") as fp: + with open("bert/bert_models.json", encoding="utf-8") as fp: models = json.load(fp) for k, v in models.items(): local_path = Path("bert").joinpath(k) @@ -113,7 +113,7 @@ def main(): return # Change default paths if necessary - with open(paths_yml, "r", encoding="utf-8") as f: + with open(paths_yml, encoding="utf-8") as f: yml_data = yaml.safe_load(f) if args.assets_root is not None: yml_data["assets_root"] = args.assets_root diff --git a/preprocess_text.py b/preprocess_text.py index 99badd4..5120a1f 100644 --- a/preprocess_text.py +++ b/preprocess_text.py @@ -145,7 +145,7 @@ def preprocess( spk_utt_map[spk].append(line) # 新しい話者が出てきたら話者IDを割り当て、current_sidを1増やす - if spk not in spk_id_map.keys(): + if spk not in spk_id_map: spk_id_map[spk] = current_sid current_sid += 1 if count_same > 0 or count_not_found > 0: diff --git a/pyproject.toml b/pyproject.toml index 77306ad..c292b50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "style-bert-vits2" dynamic = ["version"] -description = 'Style-Bert-VITS2: Bert-VITS2 with more controllable voice styles.' +description = "Style-Bert-VITS2: Bert-VITS2 with more controllable voice styles." readme = "README.md" requires-python = ">=3.9" license = "AGPL-3.0" @@ -22,21 +22,21 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", ] dependencies = [ - 'cmudict', - 'cn2an', - 'g2p_en', - 'jieba', - 'loguru', - 'num2words', - 'numba', - 'numpy', - 'pydantic>=2.0', - 'pyopenjtalk-dict', - 'pypinyin', - 'pyworld-prebuilt', - 'safetensors', - 'torch>=2.1', - 'transformers', + "cmudict", + "cn2an", + "g2p_en", + "jieba", + "loguru", + "num2words", + "numba", + "numpy", + "pydantic>=2.0", + "pyopenjtalk-dict", + "pypinyin", + "pyworld-prebuilt", + "safetensors", + "torch>=2.1", + "transformers", ] [project.urls] @@ -59,42 +59,26 @@ only-include = [ "pyproject.toml", "README.md", ] -exclude = [ - ".git", - ".gitignore", - ".gitattributes", -] +exclude = [".git", ".gitignore", ".gitattributes"] [tool.hatch.build.targets.wheel] packages = ["style_bert_vits2"] [tool.hatch.envs.test] -dependencies = [ - "coverage[toml]>=6.5", - "pytest", -] +dependencies = ["coverage[toml]>=6.5", "pytest"] [tool.hatch.envs.test.scripts] # Usage: `hatch run test:test` test = "pytest {args:tests}" # Usage: `hatch run test:coverage` test-cov = "coverage run -m pytest {args:tests}" # Usage: `hatch run test:cov-report` -cov-report = [ - "- coverage combine", - "coverage report", -] +cov-report = ["- coverage combine", "coverage report"] # Usage: `hatch run test:cov` -cov = [ - "test-cov", - "cov-report", -] +cov = ["test-cov", "cov-report"] [tool.hatch.envs.style] detached = true -dependencies = [ - "black", - "isort", -] +dependencies = ["black", "isort"] [tool.hatch.envs.style.scripts] check = [ "black --check --diff .", @@ -113,17 +97,17 @@ python = ["3.9", "3.10", "3.11"] source_pkgs = ["style_bert_vits2", "tests"] branch = true parallel = true -omit = [ - "style_bert_vits2/constants.py", -] +omit = ["style_bert_vits2/constants.py"] [tool.coverage.paths] style_bert_vits2 = ["style_bert_vits2", "*/style-bert-vits2/style_bert_vits2"] tests = ["tests", "*/style-bert-vits2/tests"] [tool.coverage.report] -exclude_lines = [ - "no cov", - "if __name__ == .__main__.:", - "if TYPE_CHECKING:", -] +exclude_lines = ["no cov", "if __name__ == .__main__.:", "if TYPE_CHECKING:"] + +[tool.ruff] +extend-select = ["I"] + +[tool.ruff.lint.isort] +lines-after-imports = 2 \ No newline at end of file diff --git a/server_editor.py b/server_editor.py index cf70feb..e0028c1 100644 --- a/server_editor.py +++ b/server_editor.py @@ -127,7 +127,7 @@ def download_and_extract(url, extract_to: Path): def new_release_available(latest_release): if LAST_DOWNLOAD_FILE.exists(): - with open(LAST_DOWNLOAD_FILE, "r") as file: + with open(LAST_DOWNLOAD_FILE) as file: last_download_str = file.read().strip() # 'Z'を除去して日時オブジェクトに変換 last_download_str = last_download_str.replace("Z", "+00:00") diff --git a/slice.py b/slice.py index bf28bf6..3f9fcc1 100644 --- a/slice.py +++ b/slice.py @@ -7,7 +7,6 @@ from typing import Any, Optional import soundfile as sf import torch -import yaml from tqdm import tqdm from config import get_path_config diff --git a/style_bert_vits2/models/hyper_parameters.py b/style_bert_vits2/models/hyper_parameters.py index feb6bfb..827ce6d 100644 --- a/style_bert_vits2/models/hyper_parameters.py +++ b/style_bert_vits2/models/hyper_parameters.py @@ -125,5 +125,5 @@ class HyperParameters(BaseModel): HyperParameters: ハイパーパラメータ """ - with open(json_path, "r", encoding="utf-8") as f: + with open(json_path, encoding="utf-8") as f: return HyperParameters.model_validate_json(f.read()) diff --git a/style_bert_vits2/models/models.py b/style_bert_vits2/models/models.py index 56fb27c..eaff2fa 100644 --- a/style_bert_vits2/models/models.py +++ b/style_bert_vits2/models/models.py @@ -786,7 +786,7 @@ class ReferenceEncoder(nn.Module): for i in range(K) ] self.convs = nn.ModuleList(convs) - # self.wns = nn.ModuleList([weight_norm(num_features=ref_enc_filters[i]) for i in range(K)]) # noqa: E501 + # self.wns = nn.ModuleList([weight_norm(num_features=ref_enc_filters[i]) for i in range(K)]) out_channels = self.calculate_channels(spec_channels, 3, 2, 1, K) self.gru = nn.GRU( diff --git a/style_bert_vits2/models/models_jp_extra.py b/style_bert_vits2/models/models_jp_extra.py index 2850baf..e8df7d9 100644 --- a/style_bert_vits2/models/models_jp_extra.py +++ b/style_bert_vits2/models/models_jp_extra.py @@ -844,7 +844,7 @@ class ReferenceEncoder(nn.Module): for i in range(K) ] self.convs = nn.ModuleList(convs) - # self.wns = nn.ModuleList([weight_norm(num_features=ref_enc_filters[i]) for i in range(K)]) # noqa: E501 + # self.wns = nn.ModuleList([weight_norm(num_features=ref_enc_filters[i]) for i in range(K)]) out_channels = self.calculate_channels(spec_channels, 3, 2, 1, K) self.gru = nn.GRU( diff --git a/style_bert_vits2/models/utils/__init__.py b/style_bert_vits2/models/utils/__init__.py index 2e750c8..b91c74a 100644 --- a/style_bert_vits2/models/utils/__init__.py +++ b/style_bert_vits2/models/utils/__init__.py @@ -186,7 +186,7 @@ def load_filepaths_and_text( list[list[str]]: ファイルパスとテキストのリスト """ - with open(filename, "r", encoding="utf-8") as f: + with open(filename, encoding="utf-8") as f: filepaths_and_text = [line.strip().split(split) for line in f] return filepaths_and_text @@ -245,9 +245,7 @@ def check_git_hash(model_dir_path: Union[str, Path]) -> None: source_dir = os.path.dirname(os.path.realpath(__file__)) if not os.path.exists(os.path.join(source_dir, ".git")): logger.warning( - "{} is not a git repository, therefore hash value comparison will be ignored.".format( - source_dir - ) + f"{source_dir} is not a git repository, therefore hash value comparison will be ignored." ) return @@ -255,13 +253,11 @@ def check_git_hash(model_dir_path: Union[str, Path]) -> None: path = os.path.join(model_dir_path, "githash") if os.path.exists(path): - with open(path, "r", encoding="utf-8") as f: + with open(path, encoding="utf-8") as f: saved_hash = f.read() if saved_hash != cur_hash: logger.warning( - "git hash values are different. {}(saved) != {}(current)".format( - saved_hash[:8], cur_hash[:8] - ) + f"git hash values are different. {saved_hash[:8]}(saved) != {cur_hash[:8]}(current)" ) else: with open(path, "w", encoding="utf-8") as f: diff --git a/style_bert_vits2/models/utils/safetensors.py b/style_bert_vits2/models/utils/safetensors.py index 52ab115..4b4ef3f 100644 --- a/style_bert_vits2/models/utils/safetensors.py +++ b/style_bert_vits2/models/utils/safetensors.py @@ -77,7 +77,7 @@ def save_safetensors( keys = [] for k in state_dict: if "enc_q" in k and for_infer: - continue # noqa: E701 + continue keys.append(k) new_dict = ( diff --git a/style_bert_vits2/nlp/chinese/g2p.py b/style_bert_vits2/nlp/chinese/g2p.py index f38e09f..1f0894f 100644 --- a/style_bert_vits2/nlp/chinese/g2p.py +++ b/style_bert_vits2/nlp/chinese/g2p.py @@ -8,7 +8,7 @@ from style_bert_vits2.nlp.chinese.tone_sandhi import ToneSandhi from style_bert_vits2.nlp.symbols import PUNCTUATIONS -with open(Path(__file__).parent / "opencpop-strict.txt", "r", encoding="utf-8") as f: +with open(Path(__file__).parent / "opencpop-strict.txt", encoding="utf-8") as f: __PINYIN_TO_SYMBOL_MAP = { line.split("\t")[0]: line.strip().split("\t")[1] for line in f.readlines() } @@ -73,7 +73,7 @@ def __g2p(segments: list[str]) -> tuple[list[str], list[int], list[int]]: "iou": "iu", "uen": "un", } - if v_without_tone in v_rep_map.keys(): + if v_without_tone in v_rep_map: pinyin = c + v_rep_map[v_without_tone] else: # 单音节 @@ -83,7 +83,7 @@ def __g2p(segments: list[str]) -> tuple[list[str], list[int], list[int]]: "in": "yin", "u": "wu", } - if pinyin in pinyin_rep_map.keys(): + if pinyin in pinyin_rep_map: pinyin = pinyin_rep_map[pinyin] else: single_rep_map = { @@ -92,10 +92,10 @@ def __g2p(segments: list[str]) -> tuple[list[str], list[int], list[int]]: "i": "y", "u": "w", } - if pinyin[0] in single_rep_map.keys(): + if pinyin[0] in single_rep_map: pinyin = single_rep_map[pinyin[0]] + pinyin[1:] - assert pinyin in __PINYIN_TO_SYMBOL_MAP.keys(), ( + assert pinyin in __PINYIN_TO_SYMBOL_MAP, ( pinyin, seg, raw_pinyin, diff --git a/style_bert_vits2/nlp/chinese/normalizer.py b/style_bert_vits2/nlp/chinese/normalizer.py index 8239bc7..c076408 100644 --- a/style_bert_vits2/nlp/chinese/normalizer.py +++ b/style_bert_vits2/nlp/chinese/normalizer.py @@ -51,7 +51,7 @@ def normalize_text(text: str) -> str: def replace_punctuation(text: str) -> str: text = text.replace("嗯", "恩").replace("呣", "母") - pattern = re.compile("|".join(re.escape(p) for p in __REPLACE_MAP.keys())) + pattern = re.compile("|".join(re.escape(p) for p in __REPLACE_MAP)) replaced_text = pattern.sub(lambda x: __REPLACE_MAP[x.group()], text) diff --git a/style_bert_vits2/nlp/chinese/tone_sandhi.py b/style_bert_vits2/nlp/chinese/tone_sandhi.py index 552cb0d..4945ab9 100644 --- a/style_bert_vits2/nlp/chinese/tone_sandhi.py +++ b/style_bert_vits2/nlp/chinese/tone_sandhi.py @@ -471,26 +471,27 @@ class ToneSandhi: ): finals[j] = finals[j][:-1] + "5" ge_idx = word.find("个") - if len(word) >= 1 and word[-1] in "吧呢啊呐噻嘛吖嗨呐哦哒额滴哩哟喽啰耶喔诶": - finals[-1] = finals[-1][:-1] + "5" - elif len(word) >= 1 and word[-1] in "的地得": - finals[-1] = finals[-1][:-1] + "5" - # e.g. 走了, 看着, 去过 - # elif len(word) == 1 and word in "了着过" and pos in {"ul", "uz", "ug"}: - # finals[-1] = finals[-1][:-1] + "5" - elif ( - len(word) > 1 - and word[-1] in "们子" - and pos in {"r", "n"} - and word not in self.must_not_neural_tone_words + if ( + len(word) >= 1 + and word[-1] in "吧呢啊呐噻嘛吖嗨呐哦哒额滴哩哟喽啰耶喔诶" + or len(word) >= 1 + and word[-1] in "的地得" + or ( + ( + len(word) > 1 + and word[-1] in "们子" + and pos in {"r", "n"} + and word not in self.must_not_neural_tone_words + ) + or len(word) > 1 + and word[-1] in "上下里" + and pos in {"s", "l", "f"} + ) + or len(word) > 1 + and word[-1] in "来去" + and word[-2] in "上下进出回过起开" ): finals[-1] = finals[-1][:-1] + "5" - # e.g. 桌上, 地下, 家里 - elif len(word) > 1 and word[-1] in "上下里" and pos in {"s", "l", "f"}: - finals[-1] = finals[-1][:-1] + "5" - # e.g. 上来, 下去 - elif len(word) > 1 and word[-1] in "来去" and word[-2] in "上下进出回过起开": - finals[-1] = finals[-1][:-1] + "5" # 个做量词 elif ( ge_idx >= 1 @@ -500,12 +501,11 @@ class ToneSandhi: ) ) or word == "个": finals[ge_idx] = finals[ge_idx][:-1] + "5" - else: - if ( - word in self.must_neural_tone_words - or word[-2:] in self.must_neural_tone_words - ): - finals[-1] = finals[-1][:-1] + "5" + elif ( + word in self.must_neural_tone_words + or word[-2:] in self.must_neural_tone_words + ): + finals[-1] = finals[-1][:-1] + "5" word_list = self._split_word(word) finals_list = [finals[: len(word_list[0])], finals[len(word_list[0]) :]] @@ -549,10 +549,8 @@ class ToneSandhi: if finals[i + 1][-1] == "4": finals[i] = finals[i][:-1] + "2" # "一" before non-tone4 should be yi4, e.g. 一天 - else: - # "一" 后面如果是标点,还读一声 - if word[i + 1] not in self.punc: - finals[i] = finals[i][:-1] + "4" + elif word[i + 1] not in self.punc: + finals[i] = finals[i][:-1] + "4" return finals def _split_word(self, word: str) -> list[str]: diff --git a/style_bert_vits2/nlp/english/cmudict.py b/style_bert_vits2/nlp/english/cmudict.py index 7772e77..fd17405 100644 --- a/style_bert_vits2/nlp/english/cmudict.py +++ b/style_bert_vits2/nlp/english/cmudict.py @@ -20,7 +20,7 @@ def get_dict() -> dict[str, list[list[str]]]: def read_dict() -> dict[str, list[list[str]]]: g2p_dict = {} start_line = 49 - with open(CMU_DICT_PATH, "r", encoding="utf-8") as f: + with open(CMU_DICT_PATH, encoding="utf-8") as f: line = f.readline() line_index = 1 while line: diff --git a/style_bert_vits2/nlp/english/g2p.py b/style_bert_vits2/nlp/english/g2p.py index deeef3f..4e3f9b3 100644 --- a/style_bert_vits2/nlp/english/g2p.py +++ b/style_bert_vits2/nlp/english/g2p.py @@ -1,23 +1,91 @@ import re + from g2p_en import G2p + from style_bert_vits2.constants import Languages from style_bert_vits2.nlp import bert_models from style_bert_vits2.nlp.english.cmudict import get_dict from style_bert_vits2.nlp.symbols import PUNCTUATIONS, SYMBOLS + # Initialize global variables once ARPA = { - "AH0", "S", "AH1", "EY2", "AE2", "EH0", "OW2", "UH0", "NG", "B", "G", "AY0", - "M", "AA0", "F", "AO0", "ER2", "UH1", "IY1", "AH2", "DH", "IY0", "EY1", - "IH0", "K", "N", "W", "IY2", "T", "AA1", "ER1", "EH2", "OY0", "UH2", "UW1", - "Z", "AW2", "AW1", "V", "UW2", "AA2", "ER", "AW0", "UW0", "R", "OW1", "EH1", - "ZH", "AE0", "IH2", "IH", "Y", "JH", "P", "AY1", "EY0", "OY2", "TH", "HH", - "D", "ER0", "CH", "AO1", "AE1", "AO2", "OY1", "AY2", "IH1", "OW0", "L", - "SH" + "AH0", + "S", + "AH1", + "EY2", + "AE2", + "EH0", + "OW2", + "UH0", + "NG", + "B", + "G", + "AY0", + "M", + "AA0", + "F", + "AO0", + "ER2", + "UH1", + "IY1", + "AH2", + "DH", + "IY0", + "EY1", + "IH0", + "K", + "N", + "W", + "IY2", + "T", + "AA1", + "ER1", + "EH2", + "OY0", + "UH2", + "UW1", + "Z", + "AW2", + "AW1", + "V", + "UW2", + "AA2", + "ER", + "AW0", + "UW0", + "R", + "OW1", + "EH1", + "ZH", + "AE0", + "IH2", + "IH", + "Y", + "JH", + "P", + "AY1", + "EY0", + "OY2", + "TH", + "HH", + "D", + "ER0", + "CH", + "AO1", + "AE1", + "AO2", + "OY1", + "AY2", + "IH1", + "OW0", + "L", + "SH", } _g2p = G2p() eng_dict = get_dict() + def g2p(text: str) -> tuple[list[str], list[int], list[int]]: phones = [] tones = [] @@ -51,7 +119,7 @@ def g2p(text: str) -> tuple[list[str], list[int], list[int]]: tns.append(0) temp_phones += [__post_replace_ph(i) for i in phns] temp_tones += tns - + phones += temp_phones tones += temp_tones phone_len.append(len(temp_phones)) @@ -72,9 +140,19 @@ def g2p(text: str) -> tuple[list[str], list[int], list[int]]: def __post_replace_ph(ph: str) -> str: REPLACE_MAP = { - ":": ",", ";": ",", ",": ",", "。": ".", "!": "!", "?": "?", - "\n": ".", "·": ",", "、": ",", "…": "...", "···": "...", - "・・・": "...", "v": "V" + ":": ",", + ";": ",", + ",": ",", + "。": ".", + "!": "!", + "?": "?", + "\n": ".", + "·": ",", + "、": ",", + "…": "...", + "···": "...", + "・・・": "...", + "v": "V", } if ph in REPLACE_MAP: ph = REPLACE_MAP[ph] @@ -120,21 +198,22 @@ def __text_to_words(text: str) -> list[list[str]]: for idx, t in enumerate(tokens): if t.startswith("▁"): words.append([t[1:]]) - else: - if t in PUNCTUATIONS: - if idx == len(tokens) - 1: - words.append([f"{t}"]) - else: - if not tokens[idx + 1].startswith("▁") and tokens[idx + 1] not in PUNCTUATIONS: - if idx == 0: - words.append([]) - words[-1].append(f"{t}") - else: - words.append([f"{t}"]) - else: + elif t in PUNCTUATIONS: + if idx == len(tokens) - 1: + words.append([f"{t}"]) + elif ( + not tokens[idx + 1].startswith("▁") + and tokens[idx + 1] not in PUNCTUATIONS + ): if idx == 0: words.append([]) words[-1].append(f"{t}") + else: + words.append([f"{t}"]) + else: + if idx == 0: + words.append([]) + words[-1].append(f"{t}") return words @@ -149,4 +228,3 @@ if __name__ == "__main__": # for ph in group: # all_phones.add(ph) # print(all_phones) - diff --git a/style_bert_vits2/nlp/english/normalizer.py b/style_bert_vits2/nlp/english/normalizer.py index f6ddc90..88cec02 100644 --- a/style_bert_vits2/nlp/english/normalizer.py +++ b/style_bert_vits2/nlp/english/normalizer.py @@ -58,7 +58,7 @@ def replace_punctuation(text: str) -> str: "「": "'", "」": "'", } - pattern = re.compile("|".join(re.escape(p) for p in REPLACE_MAP.keys())) + pattern = re.compile("|".join(re.escape(p) for p in REPLACE_MAP)) replaced_text = pattern.sub(lambda x: REPLACE_MAP[x.group()], text) # replaced_text = re.sub( # r"[^\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF\u3400-\u4DBF\u3005" diff --git a/style_bert_vits2/nlp/japanese/g2p.py b/style_bert_vits2/nlp/japanese/g2p.py index 54270ba..dab3dbf 100644 --- a/style_bert_vits2/nlp/japanese/g2p.py +++ b/style_bert_vits2/nlp/japanese/g2p.py @@ -719,5 +719,3 @@ class YomiError(Exception): 基本的に「学習の前処理のテキスト処理時」には発生させ、そうでない場合は、 ignore_yomi_error=True にしておいて、この例外を発生させないようにする。 """ - - pass diff --git a/style_bert_vits2/nlp/japanese/normalizer.py b/style_bert_vits2/nlp/japanese/normalizer.py index edb394e..7ecbfb6 100644 --- a/style_bert_vits2/nlp/japanese/normalizer.py +++ b/style_bert_vits2/nlp/japanese/normalizer.py @@ -60,7 +60,7 @@ __REPLACE_MAP = { "」": "'", } # 記号類の正規化パターン -__REPLACE_PATTERN = re.compile("|".join(re.escape(p) for p in __REPLACE_MAP.keys())) +__REPLACE_PATTERN = re.compile("|".join(re.escape(p) for p in __REPLACE_MAP)) # 句読点等の正規化パターン __PUNCTUATION_CLEANUP_PATTERN = re.compile( # ↓ ひらがな、カタカナ、漢字 diff --git a/style_bert_vits2/nlp/japanese/pyopenjtalk_worker/__init__.py b/style_bert_vits2/nlp/japanese/pyopenjtalk_worker/__init__.py index 3a146b6..d866467 100644 --- a/style_bert_vits2/nlp/japanese/pyopenjtalk_worker/__init__.py +++ b/style_bert_vits2/nlp/japanese/pyopenjtalk_worker/__init__.py @@ -88,7 +88,7 @@ def initialize_worker(port: int = WORKER_PORT) -> None: client = None try: client = WorkerClient(port) - except (socket.timeout, socket.error): + except (OSError, socket.timeout): logger.debug("try starting pyopenjtalk worker server") import os import subprocess @@ -120,7 +120,7 @@ def initialize_worker(port: int = WORKER_PORT) -> None: try: client = WorkerClient(port) break - except socket.error: + except OSError: time.sleep(0.5) count += 1 # 20: max number of retries diff --git a/style_bert_vits2/nlp/japanese/user_dict/word_model.py b/style_bert_vits2/nlp/japanese/user_dict/word_model.py index c85a5b9..43420da 100644 --- a/style_bert_vits2/nlp/japanese/user_dict/word_model.py +++ b/style_bert_vits2/nlp/japanese/user_dict/word_model.py @@ -114,7 +114,7 @@ class PartOfSpeechDetail(BaseModel): part_of_speech_detail_2: str = Field(title="品詞細分類2") part_of_speech_detail_3: str = Field(title="品詞細分類3") # context_idは辞書の左・右文脈IDのこと - # https://github.com/VOICEVOX/open_jtalk/blob/427cfd761b78efb6094bea3c5bb8c968f0d711ab/src/mecab-naist-jdic/_left-id.def # noqa + # https://github.com/VOICEVOX/open_jtalk/blob/427cfd761b78efb6094bea3c5bb8c968f0d711ab/src/mecab-naist-jdic/_left-id.def context_id: int = Field(title="文脈ID") cost_candidates: List[int] = Field(title="コストのパーセンタイル") accent_associative_rules: List[str] = Field(title="アクセント結合規則の一覧") diff --git a/style_bert_vits2/tts_model.py b/style_bert_vits2/tts_model.py index 9f66874..6df8394 100644 --- a/style_bert_vits2/tts_model.py +++ b/style_bert_vits2/tts_model.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import Any, Optional, Union import numpy as np import torch diff --git a/style_bert_vits2/utils/subprocess.py b/style_bert_vits2/utils/subprocess.py index f8e8e94..8f159a2 100644 --- a/style_bert_vits2/utils/subprocess.py +++ b/style_bert_vits2/utils/subprocess.py @@ -27,6 +27,7 @@ def run_script_with_log( stderr=subprocess.PIPE, text=True, encoding="utf-8", + check=False, ) if result.returncode != 0: logger.error(f"Error: {' '.join(cmd)}\n{result.stderr}") diff --git a/style_gen.py b/style_gen.py index f8b6452..1ced5f0 100644 --- a/style_gen.py +++ b/style_gen.py @@ -26,7 +26,6 @@ class NaNValueError(ValueError): """カスタム例外クラス。NaN値が見つかった場合に使用されます。""" - # 推論時にインポートするために短いが関数を書く def get_style_vector(wav_path: str) -> NDArray[Any]: return inference(wav_path) # type: ignore diff --git a/train_ms_jp_extra.py b/train_ms_jp_extra.py index cdc46b2..07cc24b 100644 --- a/train_ms_jp_extra.py +++ b/train_ms_jp_extra.py @@ -17,11 +17,7 @@ from tqdm import tqdm # logging.getLogger("numba").setLevel(logging.WARNING) import default_style from config import get_config -from data_utils import ( - DistributedBucketSampler, - TextAudioSpeakerCollate, - TextAudioSpeakerLoader, -) +from data_utils import TextAudioSpeakerCollate, TextAudioSpeakerLoader from losses import WavLMLoss, discriminator_loss, feature_loss, generator_loss, kl_loss from mel_processing import mel_spectrogram_torch, spec_to_mel_torch from style_bert_vits2.logging import logger diff --git a/transcribe.py b/transcribe.py index c7aa493..3fcde25 100644 --- a/transcribe.py +++ b/transcribe.py @@ -1,10 +1,8 @@ import argparse -import os import sys from pathlib import Path from typing import Any, Optional -import yaml from torch.utils.data import Dataset from tqdm import tqdm