add api server

This commit is contained in:
Daiki Arai
2023-12-28 23:58:06 +09:00
parent a3d0380523
commit e27e1de450
6 changed files with 292 additions and 699 deletions

View File

@@ -9,6 +9,7 @@ from sklearn.manifold import TSNE
from config import config
MAX_CLUSTER_NUM = 10
DEFAULT_EMOTION: str = 'Neutral'
tsne = TSNE(n_components=2, random_state=42, metric="cosine")
@@ -132,7 +133,7 @@ def save_only_mean(model_name):
with open(config_path, "r") as f:
json_dict = json.load(f)
json_dict["data"]["num_styles"] = 1
json_dict["data"]["style2id"] = {"Neutral": 0}
json_dict["data"]["style2id"] = {DEFAULT_EMOTION: 0}
with open(config_path, "w") as f:
json.dump(json_dict, f, indent=2)
return f"成功!\n{style_vector_path}に保存し{config_path}を更新しました。"
@@ -152,7 +153,7 @@ def save_style_vectors(model_name, style_names: str):
config_path = os.path.join(result_dir, "config.json")
if not os.path.exists(config_path):
return f"{config_path}が存在しません。"
style_name_list = ["Neutral"]
style_name_list = [DEFAULT_EMOTION]
style_name_list = style_name_list + style_names.split(",")
if len(style_name_list) != len(centroids) + 1:
return f"スタイルの数が合いません。`,`で正しく{len(centroids)}個に区切られているか確認してください: {style_names}"
@@ -201,7 +202,7 @@ def save_style_vectors_from_files(model_name, audio_files_text, style_names_text
config_path = os.path.join(result_dir, "config.json")
if not os.path.exists(config_path):
return f"{config_path}が存在しません。"
style_name_list = ["Neutral"]
style_name_list = [DEFAULT_EMOTION]
style_name_list = style_name_list + style_names
assert len(style_name_list) == len(style_vectors)
@@ -216,7 +217,7 @@ def save_style_vectors_from_files(model_name, audio_files_text, style_names_text
return f"成功!\n{style_vector_path}に保存し{config_path}を更新しました。"
initial_md = """
initial_md = f"""
# Style Bert-VITS2 スタイルベクトルの作成
Style-Bert-VITS2で音声合成するには、スタイルベクトルのファイル`style_vectors.npy`が必要です。これをモデルごとに作成する必要があります。
@@ -225,7 +226,7 @@ Style-Bert-VITS2で音声合成するには、スタイルベクトルのファ
## 方法
どうやってスタイルベクトルファイルを作るかはいくつか方法があります。
- 方法1: めんどくさいから平均スタイルのみを使う(使えるスタイルは標準のNeutralのみ)
- 方法1: めんどくさいから平均スタイルのみを使う(使えるスタイルは標準の{DEFAULT_EMOTION}のみ)
- 方法2: 音声ファイルを自動でスタイル別に分け、その各スタイルの平均を取って保存
- 方法3: スタイルを代表する音声ファイルを手動で選んで、その音声のスタイルベクトルを保存
- 方法4: 自分でもっと頑張ってこだわって作るJVNVコーパスなど、もともとスタイルラベル等が利用可能な場合はこれがよいかも
@@ -233,7 +234,7 @@ Style-Bert-VITS2で音声合成するには、スタイルベクトルのファ
基本的には方法2を使うことを、めんどくさかったりあまり感情に幅がないデータセットなら方法1をおすすめします。
"""
method2 = """
method2 = f"""
学習の時に取り出したスタイルベクトルを読み込んで、可視化を見ながらスタイルを分けていきます。
手順:
@@ -245,102 +246,103 @@ method2 = """
詳細: スタイルベクトル(256次元)たちを適当なアルゴリズムでクラスタリングして、各クラスタの中心のベクトル(と全体の平均ベクトル)を保存します。
平均スタイル(Neutral)は自動的に保存されます。
平均スタイル({DEFAULT_EMOTION})は自動的に保存されます。
"""
with gr.Blocks(theme="NoCrypt/miku") as app:
gr.Markdown(initial_md)
with gr.Row():
model_name = gr.Textbox("your_model_name", label="モデル名")
load_button = gr.Button("スタイルベクトルを読み込む", variant="primary")
output = gr.Plot(label="音声スタイルの可視化")
load_button.click(load, inputs=[model_name], outputs=[output])
with gr.Tab("方法1: 平均スタイルのみを保存"):
gr.Markdown("平均Neutralスタイルのみを保存する場合は、以下のボタンを押してください。")
if __name__ == "__main__":
with gr.Blocks(theme="NoCrypt/miku") as app:
gr.Markdown(initial_md)
with gr.Row():
save_button1 = gr.Button("スタイルベクトルを保存", variant="primary")
info1 = gr.Textbox(label="保存結果")
save_button1.click(save_only_mean, inputs=[model_name], outputs=[info1])
with gr.Tab("方法2: スタイル分けを自動で行う"):
n_clusters = gr.Slider(
minimum=2,
maximum=10,
step=1,
value=4,
label="作るスタイルの数(平均スタイルを除く)",
info="上の図を見ながらスタイルの数を試行錯誤してください。",
)
c_method = gr.Radio(
choices=[
"Agglomerative after t-SNE",
"KMeans after t-SNE",
"Agglomerative",
"KMeans",
],
label="アルゴリズム",
info="分類する(クラスタリング)アルゴリズムを選択します。いろいろ試してみてください。",
value="Agglomerative after t-SNE",
)
c_button = gr.Button("スタイル分けを実行")
audio_list = []
md_list = []
gr.Markdown("スタイル分けの結果と、各スタイルの特徴的な代表音声(図の黒い x 印)")
gr.Markdown("注意: もともと256次元なものをを2次元に落としているので、正確なベクトルの位置関係ではありません。")
with gr.Row():
gr_plot = gr.Plot()
model_name = gr.Textbox("your_model_name", label="モデル名")
load_button = gr.Button("スタイルベクトルを読み込む", variant="primary")
output = gr.Plot(label="音声スタイルの可視化")
load_button.click(load, inputs=[model_name], outputs=[output])
with gr.Tab("方法1: 平均スタイルのみを保存"):
gr.Markdown(f"平均({DEFAULT_EMOTION})スタイルのみを保存する場合は、以下のボタンを押してください。")
with gr.Row():
for i in range(MAX_CLUSTER_NUM):
with gr.Column():
md_list.append(gr.Markdown(visible=False))
audio_list.append(
gr.Audio(
visible=False,
scale=1,
show_label=True,
label=f"スタイル{i+1}",
save_button1 = gr.Button("スタイルベクトルを保存", variant="primary")
info1 = gr.Textbox(label="保存結果")
save_button1.click(save_only_mean, inputs=[model_name], outputs=[info1])
with gr.Tab("方法2: スタイル分けを自動で行う"):
n_clusters = gr.Slider(
minimum=2,
maximum=10,
step=1,
value=4,
label="作るスタイルの数(平均スタイルを除く)",
info="上の図を見ながらスタイルの数を試行錯誤してください。",
)
c_method = gr.Radio(
choices=[
"Agglomerative after t-SNE",
"KMeans after t-SNE",
"Agglomerative",
"KMeans",
],
label="アルゴリズム",
info="分類する(クラスタリング)アルゴリズムを選択します。いろいろ試してみてください。",
value="Agglomerative after t-SNE",
)
c_button = gr.Button("スタイル分けを実行")
audio_list = []
md_list = []
gr.Markdown("スタイル分けの結果と、各スタイルの特徴的な代表音声(図の黒い x 印)")
gr.Markdown("注意: もともと256次元なものをを2次元に落としているので、正確なベクトルの位置関係ではありません。")
with gr.Row():
gr_plot = gr.Plot()
with gr.Row():
for i in range(MAX_CLUSTER_NUM):
with gr.Column():
md_list.append(gr.Markdown(visible=False))
audio_list.append(
gr.Audio(
visible=False,
scale=1,
show_label=True,
label=f"スタイル{i+1}",
)
)
)
c_button.click(
do_clustering_gradio,
inputs=[n_clusters, c_method],
outputs=[gr_plot] + audio_list + md_list,
)
gr.Markdown("結果が良さそうなら、これを保存します。")
style_names = gr.Textbox(
"Angry, Sad, Happy",
label="スタイルの名前",
info="スタイルの名前を`,`で区切って入力してください(日本語可)。例: `Angry, Sad, Happy`や`怒り, 悲しみ, 喜び`など。平均音声はNeutralとして自動的に保存されます。",
)
with gr.Row():
save_button = gr.Button("スタイルベクトルを保存", variant="primary")
info2 = gr.Textbox(label="保存結果")
c_button.click(
do_clustering_gradio,
inputs=[n_clusters, c_method],
outputs=[gr_plot] + audio_list + md_list,
)
gr.Markdown("結果が良さそうなら、これを保存します。")
style_names = gr.Textbox(
"Angry, Sad, Happy",
label="スタイルの名前",
info=f"スタイルの名前を`,`で区切って入力してください(日本語可)。例: `Angry, Sad, Happy`や`怒り, 悲しみ, 喜び`など。平均音声は{DEFAULT_EMOTION}として自動的に保存されます。",
)
with gr.Row():
save_button = gr.Button("スタイルベクトルを保存", variant="primary")
info2 = gr.Textbox(label="保存結果")
save_button.click(
save_style_vectors, inputs=[model_name, style_names], outputs=[info2]
)
with gr.Tab("方法3: 手動でスタイルを選ぶ"):
gr.Markdown("下のテキスト欄に、各スタイルの代表音声のファイル名を`,`区切りで、その横に対応するスタイル名を`,`区切りで入力してください。")
gr.Markdown("例: `angry.wav, sad.wav, happy.wav`と`Angry, Sad, Happy`")
gr.Markdown("注意: Neutralスタイルは自動的に保存されます、手動ではNeutralという名前のスタイルは指定しないでください。")
with gr.Row():
audio_files_text = gr.Textbox(
label="音声ファイル名", placeholder="angry.wav, sad.wav, happy.wav"
save_button.click(
save_style_vectors, inputs=[model_name, style_names], outputs=[info2]
)
style_names_text = gr.Textbox(
label="スタイル名", placeholder="Angry, Sad, Happy"
with gr.Tab("方法3: 手動でスタイルを選ぶ"):
gr.Markdown("下のテキスト欄に、各スタイルの代表音声のファイル名を`,`区切りで、その横に対応するスタイル名を`,`区切りで入力してください。")
gr.Markdown("例: `angry.wav, sad.wav, happy.wav`と`Angry, Sad, Happy`")
gr.Markdown(f"注意: {DEFAULT_EMOTION}スタイルは自動的に保存されます、手動では{DEFAULT_EMOTION}という名前のスタイルは指定しないでください。")
with gr.Row():
audio_files_text = gr.Textbox(
label="音声ファイル名", placeholder="angry.wav, sad.wav, happy.wav"
)
style_names_text = gr.Textbox(
label="スタイル名", placeholder="Angry, Sad, Happy"
)
with gr.Row():
save_button3 = gr.Button("スタイルベクトルを保存", variant="primary")
info3 = gr.Textbox(label="保存結果")
save_button3.click(
save_style_vectors_from_files,
inputs=[model_name, audio_files_text, style_names_text],
outputs=[info3],
)
with gr.Tab("方法4: がんばる"):
gr.Markdown(
"`clustering.ipynb`にjvnvコーパスの場合の作り方とかクラスタ分けのいろいろを書いています。これを参考に自分で頑張って作ってください。"
)
with gr.Row():
save_button3 = gr.Button("スタイルベクトルを保存", variant="primary")
info3 = gr.Textbox(label="保存結果")
save_button3.click(
save_style_vectors_from_files,
inputs=[model_name, audio_files_text, style_names_text],
outputs=[info3],
)
with gr.Tab("方法4: がんばる"):
gr.Markdown(
"`clustering.ipynb`にjvnvコーパスの場合の作り方とかクラスタ分けのいろいろを書いています。これを参考に自分で頑張って作ってください。"
)
app.launch(inbrowser=True)
app.launch(inbrowser=True)