diff --git a/README.md b/README.md index c2d0221..0bec04a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # 2024-02-03: JP-Extra対応版 ver 2.0をリリースしました! -[**ver 2.0 リリースページ**](https://github.com/litagin02/Style-Bert-VITS2/releases/tag/2.0) +[**リリースページ**](https://github.com/litagin02/Style-Bert-VITS2/releases/tag/2.0) モデルとして [Bert-VITS2 JP-Extra](https://github.com/fishaudio/Bert-VITS2/releases/tag/JP-Exta) を元としたものが使えるようになりました。日本語の発音やアクセントや自然性が大幅に向上する傾向があります。 [**Changelog**](docs/CHANGELOG.md) +- 2024-02-05: ver 2.0.1 - 2024-02-03: ver 2.0 - 2024-01-09: ver 1.3 - 2023-12-31: ver 1.2 diff --git a/configs/config.json b/configs/config.json index e4dd39a..1b00c64 100644 --- a/configs/config.json +++ b/configs/config.json @@ -67,5 +67,5 @@ "use_spectral_norm": false, "gin_channels": 256 }, - "version": "2.0" + "version": "2.0.1" } diff --git a/configs/configs_jp_extra.json b/configs/configs_jp_extra.json index a11f68d..f60b39e 100644 --- a/configs/configs_jp_extra.json +++ b/configs/configs_jp_extra.json @@ -74,5 +74,5 @@ "initial_channel": 64 } }, - "version": "2.0-JP-Extra" + "version": "2.0.1-JP-Extra" } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 4242acb..24089ea 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v2.0.1 (2024-02-05) + +軽微なバグ修正や改善 +- スタイルベクトルに`nan`が含まれていた場合(主に音声ファイルが極端に短い場合に発生)、それを学習リストから除外するように修正 +- colabにマージの追加 +- 学習時のプログレスバーの表示がおかしかったのを修正 +- デフォルトのjvnvモデルをJP-Extra版にアップデート。 + ## v2.0 (2024-02-03) ### 大きい変更 diff --git a/docs/README_en.md b/docs/README_en.md index c9c2a05..7dd53ae 100644 --- a/docs/README_en.md +++ b/docs/README_en.md @@ -1,3 +1,5 @@ +# This English README is for 1.x versions. WIP for 2.x versions. + # Style-Bert-VITS2 Bert-VITS2 with more controllable voice styles. diff --git a/initialize.py b/initialize.py index f30846b..4e37dbe 100644 --- a/initialize.py +++ b/initialize.py @@ -66,18 +66,18 @@ def download_jp_extra_pretrained_models(): def download_jvnv_models(): files = [ - "jvnv-F1/config.json", - "jvnv-F1/jvnv-F1.safetensors", - "jvnv-F1/style_vectors.npy", - "jvnv-F2/config.json", - "jvnv-F2/jvnv-F2.safetensors", - "jvnv-F2/style_vectors.npy", - "jvnv-M1/config.json", - "jvnv-M1/jvnv-M1.safetensors", - "jvnv-M1/style_vectors.npy", - "jvnv-M2/config.json", - "jvnv-M2/jvnv-M2.safetensors", - "jvnv-M2/style_vectors.npy", + "jvnv--jp/config.json", + "jvnv-F1-jp/jvnv-F1-jp_e160_s14000.safetensors", + "jvnv-F1-jp/style_vectors.npy", + "jvnv-F2-jp/config.json", + "jvnv-F2-jp/jvnv-F2_e166_s20000.safetensors", + "jvnv-F2-jp/style_vectors.npy", + "jvnv-M1-jp/config.json", + "jvnv-M1-jp/jvnv-M1-jp_e158_s14000.safetensors", + "jvnv-M1-jp/style_vectors.npy", + "jvnv-M2-jp/config.json", + "jvnv-M2-jp/jvnv-M2-jp_e159_s17000.safetensors", + "jvnv-M2-jp/style_vectors.npy", ] for file in files: if not Path(f"model_assets/{file}").exists(): diff --git a/scripts/Update-to-JP-Extra.bat b/scripts/Update-to-JP-Extra.bat index 7b71c83..7033e63 100644 --- a/scripts/Update-to-JP-Extra.bat +++ b/scripts/Update-to-JP-Extra.bat @@ -42,7 +42,7 @@ pushd Style-Bert-VITS2 @REM 初期化(必要なモデルのダウンロード) python initialize.py -echo Style-Bert-VITS2の2.0へのアップデートが完了しました。 +echo Style-Bert-VITS2の2.0.1へのアップデートが完了しました。 pause diff --git a/style_gen.py b/style_gen.py index 12dab20..9614c9b 100644 --- a/style_gen.py +++ b/style_gen.py @@ -1,5 +1,5 @@ import argparse -import concurrent.futures +from concurrent.futures import ThreadPoolExecutor import warnings import numpy as np @@ -20,6 +20,12 @@ device = torch.device(config.style_gen_config.device) inference.to(device) +class NaNValueError(ValueError): + """カスタム例外クラス。NaN値が見つかった場合に使用されます。""" + + pass + + # 推論時にインポートするために短いが関数を書く def get_style_vector(wav_path): return inference(wav_path) @@ -29,10 +35,22 @@ def save_style_vector(wav_path): try: style_vec = get_style_vector(wav_path) except Exception as e: - logger.error(f"\nError occurred with file: {wav_path}, Details:\n{e}\n") + logger.error(f"Error occurred with file: {wav_path}, Details:\n{e}\n") raise + # 値にNaNが含まれていると悪影響なのでチェックする + if np.isnan(style_vec).any(): + logger.warning(f"NaN value found in style vector: {wav_path}") + raise NaNValueError(f"NaN value found in style vector: {wav_path}") np.save(f"{wav_path}.npy", style_vec) # `test.wav` -> `test.wav.npy` - return style_vec + + +def process_line(line): + wavname = line.split("|")[0] + try: + save_style_vector(wavname) + return line, None + except NaNValueError: + return line, "nan_error" def save_average_style_vector(style_vectors, filename="style_vectors.npy"): @@ -56,22 +74,53 @@ if __name__ == "__main__": device = config.style_gen_config.device - lines = [] + training_lines = [] with open(hps.data.training_files, encoding="utf-8") as f: - lines.extend(f.readlines()) - - with open(hps.data.validation_files, encoding="utf-8") as f: - lines.extend(f.readlines()) - - wavnames = [line.split("|")[0] for line in lines] - - with concurrent.futures.ThreadPoolExecutor(max_workers=num_processes) as executor: - list( + training_lines.extend(f.readlines()) + with ThreadPoolExecutor(max_workers=num_processes) as executor: + training_results = list( tqdm( - executor.map(save_style_vector, wavnames), - total=len(wavnames), + executor.map(process_line, training_lines), + total=len(training_lines), file=SAFE_STDOUT, ) ) + ok_training_lines = [line for line, error in training_results if error is None] + nan_training_lines = [ + line for line, error in training_results if error == "nan_error" + ] + if nan_training_lines: + nan_files = [line.split("|")[0] for line in nan_training_lines] + logger.warning( + f"Found NaN value in {len(nan_training_lines)} files: {nan_files}, so they will be deleted from training data." + ) - logger.info(f"Finished generating style vectors! total: {len(wavnames)} npy files.") + val_lines = [] + with open(hps.data.validation_files, encoding="utf-8") as f: + val_lines.extend(f.readlines()) + + with ThreadPoolExecutor(max_workers=num_processes) as executor: + val_results = list( + tqdm( + executor.map(process_line, val_lines), + total=len(val_lines), + file=SAFE_STDOUT, + ) + ) + ok_val_lines = [line for line, error in val_results if error is None] + nan_val_lines = [line for line, error in val_results if error == "nan_error"] + if nan_val_lines: + nan_files = [line.split("|")[0] for line in nan_val_lines] + logger.warning( + f"Found NaN value in {len(nan_val_lines)} files: {nan_files}, so they will be deleted from validation data." + ) + + with open(hps.data.training_files, "w", encoding="utf-8") as f: + f.writelines(ok_training_lines) + + with open(hps.data.validation_files, "w", encoding="utf-8") as f: + f.writelines(ok_val_lines) + + ok_num = len(ok_training_lines) + len(ok_val_lines) + + logger.info(f"Finished generating style vectors! total: {ok_num} npy files.")