Ver 2.7.0 maybe
This commit is contained in:
@@ -15,6 +15,7 @@ You can install via `pip install style-bert-vits2` (inference only), see [librar
|
|||||||
- [Zennの解説記事](https://zenn.dev/litagin/articles/034819a5256ff4)
|
- [Zennの解説記事](https://zenn.dev/litagin/articles/034819a5256ff4)
|
||||||
|
|
||||||
- [**リリースページ**](https://github.com/litagin02/Style-Bert-VITS2/releases/)、[更新履歴](/docs/CHANGELOG.md)
|
- [**リリースページ**](https://github.com/litagin02/Style-Bert-VITS2/releases/)、[更新履歴](/docs/CHANGELOG.md)
|
||||||
|
- 2025-08-24: Ver 2.7.0: 外部ライブラリ [Aivis Project](https://aivis-project.com/) 等との連携のため、ONNX変換のGUI追加、また音声認識モデルとして `litagin/anime-whisper` の追加等
|
||||||
- 2024-09-09: Ver 2.6.1: Google colabでうまく学習できない等のバグ修正のみ
|
- 2024-09-09: Ver 2.6.1: Google colabでうまく学習できない等のバグ修正のみ
|
||||||
- 2024-06-16: Ver 2.6.0 (モデルの差分マージ・加重マージ・ヌルモデルマージの追加、使い道については[この記事](https://zenn.dev/litagin/articles/1297b1dc7bdc79)参照)
|
- 2024-06-16: Ver 2.6.0 (モデルの差分マージ・加重マージ・ヌルモデルマージの追加、使い道については[この記事](https://zenn.dev/litagin/articles/1297b1dc7bdc79)参照)
|
||||||
- 2024-06-14: Ver 2.5.1 (利用規約をお願いへ変更したのみ)
|
- 2024-06-14: Ver 2.5.1 (利用規約をお願いへ変更したのみ)
|
||||||
@@ -155,6 +156,10 @@ API仕様は起動後に`/docs`にて確認ください。
|
|||||||
2つのモデルを、「声質」「声の高さ」「感情表現」「テンポ」の4点で混ぜ合わせて、新しいモデルを作ったり、また「あるモデルに、別の2つのモデルの差分を足す」等の操作ができます。
|
2つのモデルを、「声質」「声の高さ」「感情表現」「テンポ」の4点で混ぜ合わせて、新しいモデルを作ったり、また「あるモデルに、別の2つのモデルの差分を足す」等の操作ができます。
|
||||||
`App.bat`をダブルクリックか`python app.py`して開くWebUIの「マージ」タブから、2つのモデルを選択してマージすることができます。または`Merge.bat`をダブルクリックでもその単独タブが開きます。
|
`App.bat`をダブルクリックか`python app.py`して開くWebUIの「マージ」タブから、2つのモデルを選択してマージすることができます。または`Merge.bat`をダブルクリックでもその単独タブが開きます。
|
||||||
|
|
||||||
|
### ONNX変換
|
||||||
|
|
||||||
|
タブの「ONNX変換」から、学習済みsafetensorsファイルをONNX形式に変換することができます。これは外部ライブラリ等でONNX形式ファイルが必要な場合に使えます。例えば [Aivis Project](https://aivis-project.com/) では [AIVM Generator](https://aivm-generator.aivis-project.com/) を使って、safetensorsファイルとONNXファイルからAivis Speech用のモデルを作成できます。
|
||||||
|
|
||||||
### 自然性評価
|
### 自然性評価
|
||||||
|
|
||||||
学習結果のうちどのステップ数がいいかの「一つの」指標として、[SpeechMOS](https://github.com/tarepan/SpeechMOS) を使うスクリプトを用意しています:
|
学習結果のうちどのステップ数がいいかの「一つの」指標として、[SpeechMOS](https://github.com/tarepan/SpeechMOS) を使うスクリプトを用意しています:
|
||||||
|
|||||||
8
app.py
8
app.py
@@ -5,6 +5,7 @@ import gradio as gr
|
|||||||
import torch
|
import torch
|
||||||
|
|
||||||
from config import get_path_config
|
from config import get_path_config
|
||||||
|
from gradio_tabs.convert_onnx import create_onnx_app
|
||||||
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
|
||||||
from gradio_tabs.merge import create_merge_app
|
from gradio_tabs.merge import create_merge_app
|
||||||
@@ -42,7 +43,10 @@ if device == "cuda" and not torch.cuda.is_available():
|
|||||||
|
|
||||||
path_config = get_path_config()
|
path_config = get_path_config()
|
||||||
model_holder = TTSModelHolder(
|
model_holder = TTSModelHolder(
|
||||||
Path(path_config.assets_root), device, torch_device_to_onnx_providers(device)
|
Path(path_config.assets_root),
|
||||||
|
device,
|
||||||
|
torch_device_to_onnx_providers(device),
|
||||||
|
ignore_onnx=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
with gr.Blocks(theme=GRADIO_THEME) as app:
|
with gr.Blocks(theme=GRADIO_THEME) as app:
|
||||||
@@ -58,6 +62,8 @@ with gr.Blocks(theme=GRADIO_THEME) as app:
|
|||||||
create_style_vectors_app()
|
create_style_vectors_app()
|
||||||
with gr.Tab("マージ"):
|
with gr.Tab("マージ"):
|
||||||
create_merge_app(model_holder=model_holder)
|
create_merge_app(model_holder=model_holder)
|
||||||
|
with gr.Tab("ONNX変換"):
|
||||||
|
create_onnx_app(model_holder=model_holder)
|
||||||
|
|
||||||
app.launch(
|
app.launch(
|
||||||
server_name=args.host,
|
server_name=args.host,
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ if __name__ == "__main__":
|
|||||||
executor.map(process_line, zip(lines, add_blank)),
|
executor.map(process_line, zip(lines, add_blank)),
|
||||||
total=len(lines),
|
total=len(lines),
|
||||||
file=SAFE_STDOUT,
|
file=SAFE_STDOUT,
|
||||||
|
dynamic_ncols=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
10
colab.ipynb
10
colab.ipynb
@@ -425,6 +425,16 @@
|
|||||||
"# 学習結果を試す・マージ・スタイル分けはこちらから\n",
|
"# 学習結果を試す・マージ・スタイル分けはこちらから\n",
|
||||||
"!python app.py --share"
|
"!python app.py --share"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# ONNX変換は、変換したいsafetensorsファイルを指定してこのセルを実行してください。\n",
|
||||||
|
"!python convert_onnx.py --model \"Data/your_model/your_model_e100_s10000.safetensors\""
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class TextAudioSpeakerLoader(torch.utils.data.Dataset):
|
|||||||
skipped = 0
|
skipped = 0
|
||||||
logger.info("Init dataset...")
|
logger.info("Init dataset...")
|
||||||
for _id, spk, language, text, phones, tone, word2ph in tqdm(
|
for _id, spk, language, text, phones, tone, word2ph in tqdm(
|
||||||
self.audiopaths_sid_text, file=sys.stdout
|
self.audiopaths_sid_text, file=sys.stdout, dynamic_ncols=True
|
||||||
):
|
):
|
||||||
audiopath = f"{_id}"
|
audiopath = f"{_id}"
|
||||||
# if self.min_text_len <= len(phones) and len(phones) <= self.max_text_len:
|
# if self.min_text_len <= len(phones) and len(phones) <= self.max_text_len:
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v2.7.0 (2025-08-24)
|
||||||
|
|
||||||
|
- [AivisProject](https://aivis-project.com/) 等との連携のため、ONNX変換のGUI追加 (Gradioタブの一つとして)
|
||||||
|
- また音声認識モデルとして `litagin/anime-whisper` の追加
|
||||||
|
- その他軽微な修正等
|
||||||
|
|
||||||
## v2.6.1 (2024-09-09)
|
## v2.6.1 (2024-09-09)
|
||||||
|
|
||||||
- Google colabで、torchのバージョン由来でエラーが発生する不具合の修正(たぶん)
|
- Google colabで、torchのバージョン由来でエラーが発生する不具合の修正(たぶん)
|
||||||
|
|||||||
101
gradio_tabs/convert_onnx.py
Normal file
101
gradio_tabs/convert_onnx.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import gradio as gr
|
||||||
|
|
||||||
|
from style_bert_vits2.constants import GRADIO_THEME
|
||||||
|
from style_bert_vits2.logging import logger
|
||||||
|
from style_bert_vits2.tts_model import NullModelParam, TTSModelHolder
|
||||||
|
from style_bert_vits2.utils.subprocess import run_script_with_log
|
||||||
|
|
||||||
|
|
||||||
|
def call_convert_onnx(
|
||||||
|
model: str,
|
||||||
|
):
|
||||||
|
if model == "":
|
||||||
|
return "Error: モデル名を入力してください。"
|
||||||
|
logger.info("Start converting model to onnx...")
|
||||||
|
cmd = [
|
||||||
|
"convert_onnx.py",
|
||||||
|
"--model",
|
||||||
|
model,
|
||||||
|
]
|
||||||
|
success, message = run_script_with_log(cmd, ignore_warning=True)
|
||||||
|
if not success:
|
||||||
|
return f"Error: {message}"
|
||||||
|
return "ONNX変換が完了しました。"
|
||||||
|
|
||||||
|
|
||||||
|
initial_md = """
|
||||||
|
safetensors形式のモデルをONNX形式に変換します。
|
||||||
|
このONNXモデルは、[AIVM Generator](https://aivm-generator.aivis-project.com/) 等でさらにAIVM形式・AIVMX形式に変換して[AivisSpeech](https://aivis-project.com/)で利用できます。
|
||||||
|
|
||||||
|
変換には5分以上ほどの時間がかかります。進捗状況はターミナルのログを参照してください。
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def create_onnx_app(model_holder: TTSModelHolder) -> gr.Blocks:
|
||||||
|
def get_model_files(model_name: str):
|
||||||
|
return [str(f) for f in model_holder.model_files_dict[model_name]]
|
||||||
|
|
||||||
|
model_names = model_holder.model_names
|
||||||
|
if len(model_names) == 0:
|
||||||
|
logger.error(
|
||||||
|
f"モデルが見つかりませんでした。{model_holder.root_dir}にモデルを置いてください。"
|
||||||
|
)
|
||||||
|
with gr.Blocks() as app:
|
||||||
|
gr.Markdown(
|
||||||
|
f"Error: モデルが見つかりませんでした。{model_holder.root_dir}にモデルを置いてください。"
|
||||||
|
)
|
||||||
|
return app
|
||||||
|
initial_id = 0
|
||||||
|
initial_pth_files = get_model_files(model_names[initial_id])
|
||||||
|
|
||||||
|
with gr.Blocks(theme=GRADIO_THEME) as app:
|
||||||
|
gr.Markdown(initial_md)
|
||||||
|
with gr.Row():
|
||||||
|
with gr.Column():
|
||||||
|
model_name = gr.Dropdown(
|
||||||
|
label="モデル一覧",
|
||||||
|
choices=model_names,
|
||||||
|
value=model_names[initial_id],
|
||||||
|
)
|
||||||
|
model_path = gr.Dropdown(
|
||||||
|
label="モデルファイル",
|
||||||
|
choices=initial_pth_files,
|
||||||
|
value=initial_pth_files[0],
|
||||||
|
)
|
||||||
|
refresh_button = gr.Button("更新")
|
||||||
|
convert_button = gr.Button("ONNX形式に変換", variant="primary")
|
||||||
|
info = gr.Textbox(label="情報")
|
||||||
|
|
||||||
|
model_name.change(
|
||||||
|
model_holder.update_model_files_for_gradio,
|
||||||
|
inputs=[model_name],
|
||||||
|
outputs=[model_path],
|
||||||
|
)
|
||||||
|
|
||||||
|
def refresh_fn() -> tuple[gr.Dropdown, gr.Dropdown]:
|
||||||
|
names, files, _ = model_holder.update_model_names_for_gradio()
|
||||||
|
return names, files
|
||||||
|
|
||||||
|
refresh_button.click(
|
||||||
|
refresh_fn,
|
||||||
|
outputs=[model_name, model_path],
|
||||||
|
)
|
||||||
|
convert_button.click(
|
||||||
|
call_convert_onnx,
|
||||||
|
inputs=[model_path],
|
||||||
|
outputs=[info],
|
||||||
|
)
|
||||||
|
|
||||||
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from config import get_path_config
|
||||||
|
|
||||||
|
path_config = get_path_config()
|
||||||
|
assets_root = path_config.assets_root
|
||||||
|
model_holder = TTSModelHolder(assets_root, "cpu", "", ignore_onnx=True)
|
||||||
|
app = create_onnx_app(model_holder)
|
||||||
|
app.launch(inbrowser=True)
|
||||||
@@ -51,6 +51,11 @@ def do_transcribe(
|
|||||||
):
|
):
|
||||||
if model_name == "":
|
if model_name == "":
|
||||||
return "Error: モデル名を入力してください。"
|
return "Error: モデル名を入力してください。"
|
||||||
|
if hf_repo_id == "litagin/anime-whisper":
|
||||||
|
logger.info(
|
||||||
|
"Since litagin/anime-whisper does not support initial prompt, it will be ignored."
|
||||||
|
)
|
||||||
|
initial_prompt = ""
|
||||||
|
|
||||||
cmd = [
|
cmd = [
|
||||||
"transcribe.py",
|
"transcribe.py",
|
||||||
@@ -159,34 +164,30 @@ def create_dataset_app() -> gr.Blocks:
|
|||||||
result1 = gr.Textbox(label="結果")
|
result1 = gr.Textbox(label="結果")
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
with gr.Column():
|
with gr.Column():
|
||||||
|
use_hf_whisper = gr.Checkbox(
|
||||||
|
label="HuggingFaceのWhisperを使う(速度が速いがVRAMを多く使う)",
|
||||||
|
value=False,
|
||||||
|
)
|
||||||
whisper_model = gr.Dropdown(
|
whisper_model = gr.Dropdown(
|
||||||
[
|
[
|
||||||
"tiny",
|
|
||||||
"base",
|
|
||||||
"small",
|
|
||||||
"medium",
|
|
||||||
"large",
|
"large",
|
||||||
"large-v2",
|
"large-v2",
|
||||||
"large-v3",
|
"large-v3",
|
||||||
],
|
],
|
||||||
label="Whisperモデル",
|
label="Whisperモデル",
|
||||||
value="large-v3",
|
value="large-v3",
|
||||||
)
|
visible=True,
|
||||||
use_hf_whisper = gr.Checkbox(
|
|
||||||
label="HuggingFaceのWhisperを使う(速度が速いがVRAMを多く使う)",
|
|
||||||
value=False,
|
|
||||||
)
|
)
|
||||||
hf_repo_id = gr.Dropdown(
|
hf_repo_id = gr.Dropdown(
|
||||||
[
|
[
|
||||||
"openai/whisper-large-v3-turbo",
|
"openai/whisper-large-v3-turbo",
|
||||||
"openai/whisper-large-v3",
|
"openai/whisper-large-v3",
|
||||||
"openai/whisper-large-v2",
|
"openai/whisper-large-v2",
|
||||||
"kotoba-tech/kotoba-whisper-v1.1",
|
|
||||||
"kotoba-tech/kotoba-whisper-v2.1",
|
"kotoba-tech/kotoba-whisper-v2.1",
|
||||||
"litagin/anime-whisper",
|
"litagin/anime-whisper",
|
||||||
],
|
],
|
||||||
label="HuggingFaceのWhisper repo_id",
|
label="HuggingFaceのWhisper repo_id",
|
||||||
value="openai/whisper-large-v3",
|
value="openai/whisper-large-v3-turbo",
|
||||||
visible=False,
|
visible=False,
|
||||||
)
|
)
|
||||||
compute_type = gr.Dropdown(
|
compute_type = gr.Dropdown(
|
||||||
@@ -258,12 +259,13 @@ def create_dataset_app() -> gr.Blocks:
|
|||||||
)
|
)
|
||||||
use_hf_whisper.change(
|
use_hf_whisper.change(
|
||||||
lambda x: (
|
lambda x: (
|
||||||
|
gr.update(visible=not x),
|
||||||
gr.update(visible=x),
|
gr.update(visible=x),
|
||||||
gr.update(visible=x),
|
gr.update(visible=x),
|
||||||
gr.update(visible=not x),
|
gr.update(visible=not x),
|
||||||
),
|
),
|
||||||
inputs=[use_hf_whisper],
|
inputs=[use_hf_whisper],
|
||||||
outputs=[hf_repo_id, batch_size, compute_type],
|
outputs=[whisper_model, hf_repo_id, batch_size, compute_type],
|
||||||
)
|
)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ def save_style_vectors_by_dirs(model_name: str, audio_dir_str: str):
|
|||||||
total=len(audio_files),
|
total=len(audio_files),
|
||||||
file=SAFE_STDOUT,
|
file=SAFE_STDOUT,
|
||||||
desc="Generating style vectors",
|
desc="Generating style vectors",
|
||||||
|
dynamic_ncols=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ def preprocess(
|
|||||||
transcription_path.open("r", encoding="utf-8") as trans_file,
|
transcription_path.open("r", encoding="utf-8") as trans_file,
|
||||||
cleaned_path.open("w", encoding="utf-8") as out_file,
|
cleaned_path.open("w", encoding="utf-8") as out_file,
|
||||||
):
|
):
|
||||||
for line in tqdm(trans_file, file=SAFE_STDOUT, total=total_lines):
|
for line in tqdm(trans_file, file=SAFE_STDOUT, total=total_lines, dynamic_ncols=True):
|
||||||
try:
|
try:
|
||||||
processed_line = process_line(
|
processed_line = process_line(
|
||||||
line,
|
line,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ pypinyin
|
|||||||
pyworld-prebuilt
|
pyworld-prebuilt
|
||||||
# stable_ts
|
# stable_ts
|
||||||
# tensorboard
|
# tensorboard
|
||||||
torch
|
torch<2.4
|
||||||
torchaudio
|
torchaudio<2.4
|
||||||
transformers
|
transformers
|
||||||
umap-learn
|
umap-learn
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ pypinyin
|
|||||||
pyworld-prebuilt
|
pyworld-prebuilt
|
||||||
stable_ts
|
stable_ts
|
||||||
tensorboard
|
tensorboard
|
||||||
torch
|
torch<2.4
|
||||||
torchaudio
|
torchaudio<2.4
|
||||||
transformers
|
transformers
|
||||||
umap-learn
|
umap-learn
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ if __name__ == "__main__":
|
|||||||
for file in original_files
|
for file in original_files
|
||||||
]
|
]
|
||||||
for future in tqdm(
|
for future in tqdm(
|
||||||
as_completed(futures), total=len(original_files), file=SAFE_STDOUT
|
as_completed(futures), total=len(original_files), file=SAFE_STDOUT, dynamic_ncols=True
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -202,7 +202,9 @@ if args.preload_onnx_bert:
|
|||||||
)
|
)
|
||||||
onnx_bert_models.load_tokenizer(Languages.JP)
|
onnx_bert_models.load_tokenizer(Languages.JP)
|
||||||
|
|
||||||
model_holder = TTSModelHolder(model_dir, device, torch_device_to_onnx_providers(device))
|
model_holder = TTSModelHolder(
|
||||||
|
model_dir, device, torch_device_to_onnx_providers(device), ignore_onnx=True
|
||||||
|
)
|
||||||
if len(model_holder.model_names) == 0:
|
if len(model_holder.model_names) == 0:
|
||||||
logger.error(f"Models not found in {model_dir}.")
|
logger.error(f"Models not found in {model_dir}.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
2
slice.py
2
slice.py
@@ -230,7 +230,7 @@ if __name__ == "__main__":
|
|||||||
for t in threads:
|
for t in threads:
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
pbar = tqdm(total=len(audio_files), file=SAFE_STDOUT)
|
pbar = tqdm(total=len(audio_files), file=SAFE_STDOUT, dynamic_ncols=True)
|
||||||
for file in audio_files:
|
for file in audio_files:
|
||||||
q.put(file)
|
q.put(file)
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ safetensors_files = list(safetensors_files)
|
|||||||
|
|
||||||
logger.info(f"There are {len(safetensors_files)} models.")
|
logger.info(f"There are {len(safetensors_files)} models.")
|
||||||
|
|
||||||
for model_file in tqdm(safetensors_files):
|
for model_file in tqdm(safetensors_files, dynamic_ncols=True):
|
||||||
# `test_e10_s1000.safetensors`` -> 1000を取り出す
|
# `test_e10_s1000.safetensors`` -> 1000を取り出す
|
||||||
match = re.search(r"_s(\d+)\.safetensors$", model_file.name)
|
match = re.search(r"_s(\d+)\.safetensors$", model_file.name)
|
||||||
if match:
|
if match:
|
||||||
|
|||||||
@@ -11,10 +11,8 @@ import torch
|
|||||||
from numpy.typing import NDArray
|
from numpy.typing import NDArray
|
||||||
|
|
||||||
from style_bert_vits2.logging import logger
|
from style_bert_vits2.logging import logger
|
||||||
from style_bert_vits2.models.utils import (
|
from style_bert_vits2.models.utils import checkpoints # type: ignore # noqa: F401
|
||||||
checkpoints, # type: ignore # noqa: F401
|
from style_bert_vits2.models.utils import safetensors # type: ignore # noqa: F401
|
||||||
safetensors, # type: ignore # noqa: F401
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ def normalize_text(text: str) -> str:
|
|||||||
# 結合文字の濁点・半濁点を削除
|
# 結合文字の濁点・半濁点を削除
|
||||||
# 通常の「ば」等はそのままのこされる、「あ゛」は上で「あ゙」になりここで「あ」になる
|
# 通常の「ば」等はそのままのこされる、「あ゛」は上で「あ゙」になりここで「あ」になる
|
||||||
res = res.replace("\u3099", "") # 結合文字の濁点を削除、る゙ → る
|
res = res.replace("\u3099", "") # 結合文字の濁点を削除、る゙ → る
|
||||||
res = res.replace("\u309A", "") # 結合文字の半濁点を削除、な゚ → な
|
res = res.replace("\u309a", "") # 結合文字の半濁点を削除、な゚ → な
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ def run_script_with_log(
|
|||||||
|
|
||||||
|
|
||||||
def second_elem_of(
|
def second_elem_of(
|
||||||
original_function: Callable[..., tuple[Any, Any]]
|
original_function: Callable[..., tuple[Any, Any]],
|
||||||
) -> Callable[..., Any]:
|
) -> Callable[..., Any]:
|
||||||
"""
|
"""
|
||||||
与えられた関数をラップし、その戻り値の 2 番目の要素のみを返す関数を生成する。
|
与えられた関数をラップし、その戻り値の 2 番目の要素のみを返す関数を生成する。
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ if __name__ == "__main__":
|
|||||||
executor.map(process_line, training_lines),
|
executor.map(process_line, training_lines),
|
||||||
total=len(training_lines),
|
total=len(training_lines),
|
||||||
file=SAFE_STDOUT,
|
file=SAFE_STDOUT,
|
||||||
|
dynamic_ncols=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ok_training_lines = [line for line, error in training_results if error is None]
|
ok_training_lines = [line for line, error in training_results if error is None]
|
||||||
@@ -102,6 +103,7 @@ if __name__ == "__main__":
|
|||||||
executor.map(process_line, val_lines),
|
executor.map(process_line, val_lines),
|
||||||
total=len(val_lines),
|
total=len(val_lines),
|
||||||
file=SAFE_STDOUT,
|
file=SAFE_STDOUT,
|
||||||
|
dynamic_ncols=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ok_val_lines = [line for line, error in val_results if error is None]
|
ok_val_lines = [line for line, error in val_results if error is None]
|
||||||
|
|||||||
@@ -485,6 +485,7 @@ def run():
|
|||||||
initial=global_step,
|
initial=global_step,
|
||||||
smoothing=0.05,
|
smoothing=0.05,
|
||||||
file=SAFE_STDOUT,
|
file=SAFE_STDOUT,
|
||||||
|
dynamic_ncols=True,
|
||||||
)
|
)
|
||||||
initial_step = global_step
|
initial_step = global_step
|
||||||
|
|
||||||
|
|||||||
@@ -562,6 +562,7 @@ def run():
|
|||||||
initial=global_step,
|
initial=global_step,
|
||||||
smoothing=0.05,
|
smoothing=0.05,
|
||||||
file=SAFE_STDOUT,
|
file=SAFE_STDOUT,
|
||||||
|
dynamic_ncols=True,
|
||||||
)
|
)
|
||||||
initial_step = global_step
|
initial_step = global_step
|
||||||
|
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ def transcribe_files_with_hf_whisper(
|
|||||||
max_new_tokens=128,
|
max_new_tokens=128,
|
||||||
chunk_length_s=30,
|
chunk_length_s=30,
|
||||||
batch_size=batch_size,
|
batch_size=batch_size,
|
||||||
torch_dtype=torch.float16,
|
torch_dtype=torch.float16 if device == "cuda" else torch.float32,
|
||||||
device="cuda",
|
device=device,
|
||||||
trust_remote_code=True,
|
trust_remote_code=True,
|
||||||
# generate_kwargs=generate_kwargs,
|
# generate_kwargs=generate_kwargs,
|
||||||
)
|
)
|
||||||
@@ -154,6 +154,10 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
wav_files = [f for f in input_dir.rglob("*.wav") if f.is_file()]
|
wav_files = [f for f in input_dir.rglob("*.wav") if f.is_file()]
|
||||||
wav_files = sorted(wav_files, key=lambda x: str(x))
|
wav_files = sorted(wav_files, key=lambda x: str(x))
|
||||||
|
logger.info(f"Found {len(wav_files)} WAV files")
|
||||||
|
if len(wav_files) == 0:
|
||||||
|
logger.warning(f"No WAV files found in {input_dir}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if output_file.exists():
|
if output_file.exists():
|
||||||
logger.warning(f"{output_file} exists, backing up to {output_file}.bak")
|
logger.warning(f"{output_file} exists, backing up to {output_file}.bak")
|
||||||
@@ -183,7 +187,7 @@ if __name__ == "__main__":
|
|||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
logger.warning(f"Failed to load model, so use `auto` compute_type: {e}")
|
logger.warning(f"Failed to load model, so use `auto` compute_type: {e}")
|
||||||
model = WhisperModel(args.model, device=device)
|
model = WhisperModel(args.model, device=device)
|
||||||
for wav_file in tqdm(wav_files, file=SAFE_STDOUT):
|
for wav_file in tqdm(wav_files, file=SAFE_STDOUT, dynamic_ncols=True):
|
||||||
text = transcribe_with_faster_whisper(
|
text = transcribe_with_faster_whisper(
|
||||||
model=model,
|
model=model,
|
||||||
audio_file=wav_file,
|
audio_file=wav_file,
|
||||||
@@ -198,7 +202,7 @@ if __name__ == "__main__":
|
|||||||
else:
|
else:
|
||||||
model_id = args.hf_repo_id
|
model_id = args.hf_repo_id
|
||||||
logger.info(f"Loading HF Whisper model ({model_id})")
|
logger.info(f"Loading HF Whisper model ({model_id})")
|
||||||
pbar = tqdm(total=len(wav_files), file=SAFE_STDOUT)
|
pbar = tqdm(total=len(wav_files), file=SAFE_STDOUT, dynamic_ncols=True)
|
||||||
results = transcribe_files_with_hf_whisper(
|
results = transcribe_files_with_hf_whisper(
|
||||||
audio_files=wav_files,
|
audio_files=wav_files,
|
||||||
model_id=model_id,
|
model_id=model_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user