Feat: new merge method: triple weighted sum, add zero merge

This commit is contained in:
litagin02
2024-06-14 18:05:37 +09:00
parent b5abe5f058
commit d7b93dbd18

View File

@@ -1,5 +1,6 @@
import json import json
from pathlib import Path from pathlib import Path
from typing import Union
import gradio as gr import gradio as gr
import numpy as np import numpy as np
@@ -23,6 +24,14 @@ path_config = get_path_config()
assets_root = path_config.assets_root assets_root = path_config.assets_root
def load_safetensors(model_path: Union[str, Path]) -> dict[str, torch.Tensor]:
result: dict[str, torch.Tensor] = {}
with safe_open(model_path, framework="pt", device="cpu") as f:
for k in f.keys():
result[k] = f.get_tensor(k)
return result
def merge_style( def merge_style(
model_name_a: str, model_name_a: str,
model_name_b: str, model_name_b: str,
@@ -208,17 +217,11 @@ def merge_models(
output_name: str, output_name: str,
use_slerp_instead_of_lerp: bool, use_slerp_instead_of_lerp: bool,
): ):
"""model Aを起点に、model Bの各要素を重み付けしてマージする。 """
safetensors形式を前提とする。""" new = (1 - weight) * A + weight * B
model_a_weight: dict[str, torch.Tensor] = {} """
with safe_open(model_path_a, framework="pt", device="cpu") as f: model_a_weight = load_safetensors(model_path_a)
for k in f.keys(): model_b_weight = load_safetensors(model_path_b)
model_a_weight[k] = f.get_tensor(k)
model_b_weight: dict[str, torch.Tensor] = {}
with safe_open(model_path_b, framework="pt", device="cpu") as f:
for k in f.keys():
model_b_weight[k] = f.get_tensor(k)
merged_model_weight = model_a_weight.copy() merged_model_weight = model_a_weight.copy()
@@ -242,15 +245,43 @@ def merge_models(
save_file(merged_model_weight, merged_model_path) save_file(merged_model_weight, merged_model_path)
info = { info = {
"method": "usual",
"model_a": model_path_a, "model_a": model_path_a,
"model_b": model_path_b, "model_b": model_path_b,
"voice_weight": voice_weight, "voice_weight": voice_weight,
"voice_pitch_weight": voice_pitch_weight, "voice_pitch_weight": voice_pitch_weight,
"speech_style_weight": speech_style_weight, "speech_style_weight": speech_style_weight,
"tempo_weight": tempo_weight, "tempo_weight": tempo_weight,
"use_slerp_instead_of_lerp": use_slerp_instead_of_lerp,
} }
with open(assets_root / output_name / "recipe.json", "w", encoding="utf-8") as f: with open(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)
# Default style merge only using Neutral style
model_name_a = Path(model_path_a).parent.name
model_name_b = Path(model_path_b).parent.name
style_vectors_a = np.load(
assets_root / model_name_a / "style_vectors.npy"
) # (style_num_a, 256)
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", encoding="utf-8") as f:
new_config = json.load(f)
new_config["model_name"] = output_name
new_config["data"]["num_styles"] = 1
new_config["data"]["style2id"] = {DEFAULT_STYLE: 0}
with open(assets_root / output_name / "config.json", "w", encoding="utf-8") as f:
json.dump(new_config, f, indent=2, ensure_ascii=False)
neutral_vector_a = style_vectors_a[0]
neutral_vector_b = style_vectors_b[0]
weight = speech_style_weight
new_neutral_vector = (1 - weight) * neutral_vector_a + weight * neutral_vector_b
new_style_vectors = np.array([new_neutral_vector])
new_style_path = assets_root / output_name / "style_vectors.npy"
np.save(new_style_path, new_style_vectors)
return merged_model_path return merged_model_path
@@ -267,20 +298,9 @@ def merge_models_add_diff(
""" """
new = A + weight * (B - C) new = A + weight * (B - C)
""" """
model_a_weight: dict[str, torch.Tensor] = {} model_a_weight = load_safetensors(model_path_a)
with safe_open(model_path_a, framework="pt", device="cpu") as f: model_b_weight = load_safetensors(model_path_b)
for k in f.keys(): model_c_weight = load_safetensors(model_path_c)
model_a_weight[k] = f.get_tensor(k)
model_b_weight: dict[str, torch.Tensor] = {}
with safe_open(model_path_b, framework="pt", device="cpu") as f:
for k in f.keys():
model_b_weight[k] = f.get_tensor(k)
model_c_weight: dict[str, torch.Tensor] = {}
with safe_open(model_path_c, framework="pt", device="cpu") as f:
for k in f.keys():
model_c_weight[k] = f.get_tensor(k)
merged_model_weight = model_a_weight.copy() merged_model_weight = model_a_weight.copy()
@@ -304,6 +324,7 @@ def merge_models_add_diff(
save_file(merged_model_weight, merged_model_path) save_file(merged_model_weight, merged_model_path)
info = { info = {
"method": "add_diff",
"model_a": model_path_a, "model_a": model_path_a,
"model_b": model_path_b, "model_b": model_path_b,
"model_c": model_path_c, "model_c": model_path_c,
@@ -314,17 +335,199 @@ def merge_models_add_diff(
} }
with open(assets_root / output_name / "recipe.json", "w", encoding="utf-8") as f: with open(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)
# Default style merge only using Neutral style
model_name_a = Path(model_path_a).parent.name
model_name_b = Path(model_path_b).parent.name
model_name_c = Path(model_path_c).parent.name
style_vectors_a = np.load(
assets_root / model_name_a / "style_vectors.npy"
) # (style_num_a, 256)
style_vectors_b = np.load(
assets_root / model_name_b / "style_vectors.npy"
) # (style_num_b, 256)
style_vectors_c = np.load(
assets_root / model_name_c / "style_vectors.npy"
) # (style_num_c, 256)
with open(assets_root / model_name_a / "config.json", encoding="utf-8") as f:
new_config = json.load(f)
new_config["model_name"] = output_name
new_config["data"]["num_styles"] = 1
new_config["data"]["style2id"] = {DEFAULT_STYLE: 0}
with open(assets_root / output_name / "config.json", "w", encoding="utf-8") as f:
json.dump(new_config, f, indent=2, ensure_ascii=False)
neutral_vector_a = style_vectors_a[0]
neutral_vector_b = style_vectors_b[0]
neutral_vector_c = style_vectors_c[0]
weight = speech_style_weight
new_neutral_vector = neutral_vector_a + weight * (
neutral_vector_b - neutral_vector_c
)
new_style_vectors = np.array([new_neutral_vector])
new_style_path = assets_root / output_name / "style_vectors.npy"
np.save(new_style_path, new_style_vectors)
return merged_model_path
def merge_models_weighted_sum(
model_path_a: str,
model_path_b: str,
model_path_c: str,
model_a_coeff: float,
model_b_coeff: float,
model_c_coeff: float,
output_name: str,
):
model_a_weight = load_safetensors(model_path_a)
model_b_weight = load_safetensors(model_path_b)
model_c_weight = load_safetensors(model_path_c)
merged_model_weight = model_a_weight.copy()
for key in model_a_weight:
merged_model_weight[key] = (
model_a_coeff * model_a_weight[key]
+ model_b_coeff * model_b_weight[key]
+ model_c_coeff * model_c_weight[key]
)
merged_model_path = assets_root / output_name / f"{output_name}.safetensors"
merged_model_path.parent.mkdir(parents=True, exist_ok=True)
save_file(merged_model_weight, merged_model_path)
info = {
"method": "weighted_sum",
"model_a": model_path_a,
"model_b": model_path_b,
"model_c": model_path_c,
"model_a_coeff": model_a_coeff,
"model_b_coeff": model_b_coeff,
"model_c_coeff": model_c_coeff,
}
with open(assets_root / output_name / "recipe.json", "w", encoding="utf-8") as f:
json.dump(info, f, indent=2, ensure_ascii=False)
# Default style merge only using Neutral style
model_name_a = Path(model_path_a).parent.name
model_name_b = Path(model_path_b).parent.name
model_name_c = Path(model_path_c).parent.name
style_vectors_a = np.load(
assets_root / model_name_a / "style_vectors.npy"
) # (style_num_a, 256)
style_vectors_b = np.load(
assets_root / model_name_b / "style_vectors.npy"
) # (style_num_b, 256)
style_vectors_c = np.load(
assets_root / model_name_c / "style_vectors.npy"
) # (style_num_c, 256)
with open(assets_root / model_name_a / "config.json", encoding="utf-8") as f:
new_config = json.load(f)
new_config["model_name"] = output_name
new_config["data"]["num_styles"] = 1
new_config["data"]["style2id"] = {DEFAULT_STYLE: 0}
with open(assets_root / output_name / "config.json", "w", encoding="utf-8") as f:
json.dump(new_config, f, indent=2, ensure_ascii=False)
neutral_vector_a = style_vectors_a[0]
neutral_vector_b = style_vectors_b[0]
neutral_vector_c = style_vectors_c[0]
new_neutral_vector = (
model_a_coeff * neutral_vector_a
+ model_b_coeff * neutral_vector_b
+ model_c_coeff * neutral_vector_c
)
new_style_vectors = np.array([new_neutral_vector])
new_style_path = assets_root / output_name / "style_vectors.npy"
np.save(new_style_path, new_style_vectors)
return merged_model_path
def merge_models_add_zero(
model_path_a: str,
model_path_b: str,
voice_weight: float,
voice_pitch_weight: float,
speech_style_weight: float,
tempo_weight: float,
output_name: str,
):
model_a_weight = load_safetensors(model_path_a)
model_b_weight = load_safetensors(model_path_b)
merged_model_weight = model_a_weight.copy()
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]):
weight = voice_pitch_weight
elif any([key.startswith(prefix) for prefix in speech_style_keys]):
weight = speech_style_weight
elif any([key.startswith(prefix) for prefix in tempo_keys]):
weight = tempo_weight
else:
continue
merged_model_weight[key] = model_a_weight[key] + weight * model_b_weight[key]
merged_model_path = assets_root / output_name / f"{output_name}.safetensors"
merged_model_path.parent.mkdir(parents=True, exist_ok=True)
save_file(merged_model_weight, merged_model_path)
info = {
"method": "add_zero",
"model_a": model_path_a,
"model_b": model_path_b,
"voice_weight": voice_weight,
"voice_pitch_weight": voice_pitch_weight,
"speech_style_weight": speech_style_weight,
"tempo_weight": tempo_weight,
}
with open(assets_root / output_name / "recipe.json", "w", encoding="utf-8") as f:
json.dump(info, f, indent=2, ensure_ascii=False)
# Default style merge only using Neutral style
model_name_a = Path(model_path_a).parent.name
model_name_b = Path(model_path_b).parent.name
style_vectors_a = np.load(
assets_root / model_name_a / "style_vectors.npy"
) # (style_num_a, 256)
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", encoding="utf-8") as f:
new_config = json.load(f)
new_config["model_name"] = output_name
new_config["data"]["num_styles"] = 1
new_config["data"]["style2id"] = {DEFAULT_STYLE: 0}
with open(assets_root / output_name / "config.json", "w", encoding="utf-8") as f:
json.dump(new_config, f, indent=2, ensure_ascii=False)
neutral_vector_a = style_vectors_a[0]
neutral_vector_b = style_vectors_b[0]
weight = speech_style_weight
new_neutral_vector = neutral_vector_a + weight * neutral_vector_b
new_style_vectors = np.array([new_neutral_vector])
new_style_path = assets_root / output_name / "style_vectors.npy"
np.save(new_style_path, new_style_vectors)
return merged_model_path return merged_model_path
def merge_models_gr( def merge_models_gr(
model_name_a: str,
model_path_a: str, model_path_a: str,
model_name_b: str,
model_path_b: str, model_path_b: str,
model_name_c: str,
model_path_c: str, model_path_c: str,
use_add_diff: bool, model_a_coeff: float,
model_b_coeff: float,
model_c_coeff: float,
method: str,
output_name: str, output_name: str,
voice_weight: float, voice_weight: float,
voice_pitch_weight: float, voice_pitch_weight: float,
@@ -334,7 +537,13 @@ def merge_models_gr(
): ):
if output_name == "": if output_name == "":
return "Error: 新しいモデル名を入力してください。" return "Error: 新しいモデル名を入力してください。"
if not use_add_diff: assert method in [
"usual",
"add_diff",
"weighted_sum",
"add_zero",
], f"Invalid method: {method}"
if method == "usual":
merged_model_path = merge_models( merged_model_path = merge_models(
model_path_a, model_path_a,
model_path_b, model_path_b,
@@ -345,7 +554,7 @@ def merge_models_gr(
output_name, output_name,
use_slerp_instead_of_lerp, use_slerp_instead_of_lerp,
) )
else: elif method == "add_diff":
merged_model_path = merge_models_add_diff( merged_model_path = merge_models_add_diff(
model_path_a, model_path_a,
model_path_b, model_path_b,
@@ -356,6 +565,26 @@ def merge_models_gr(
tempo_weight, tempo_weight,
output_name, output_name,
) )
elif method == "weighted_sum":
merged_model_path = merge_models_weighted_sum(
model_path_a,
model_path_b,
model_path_c,
model_a_coeff,
model_b_coeff,
model_c_coeff,
output_name,
)
else: # add_zero
merged_model_path = merge_models_add_zero(
model_path_a,
model_path_b,
voice_weight,
voice_pitch_weight,
speech_style_weight,
tempo_weight,
output_name,
)
return f"Success: モデルを{merged_model_path}に保存しました。" return f"Success: モデルを{merged_model_path}に保存しました。"
@@ -363,7 +592,7 @@ def merge_style_gr(
model_name_a: str, model_name_a: str,
model_name_b: str, model_name_b: str,
model_name_c: str, model_name_c: str,
use_add_diff: bool, method: str,
weight: float, weight: float,
output_name: str, output_name: str,
style_tuple_list_str: str, style_tuple_list_str: str,
@@ -374,38 +603,35 @@ def merge_style_gr(
for line in style_tuple_list_str.split("\n"): for line in style_tuple_list_str.split("\n"):
if not line: if not line:
continue continue
style_triple = line.split(",") style_tuple = line.split(",")
if not use_add_diff: if method == "usual":
if len(style_triple) != 3: if len(style_tuple) != 3:
logger.error(f"Invalid style triple: {line}") logger.error(f"Invalid style triple: {line}")
return ( return (
f"Error: スタイルを3つのカンマ区切りで入力してください:\n{line}", f"Error: スタイルを3つのカンマ区切りで入力してください:\n{line}",
None, None,
) )
style_a, style_b, style_out = style_triple style_a, style_b, style_out = style_tuple
style_a = style_a.strip() style_a = style_a.strip()
style_b = style_b.strip() style_b = style_b.strip()
style_out = style_out.strip() style_out = style_out.strip()
style_tuple_list.append((style_a, style_b, style_out)) style_tuple_list.append((style_a, style_b, style_out))
new_style_path, new_styles = merge_style(
model_name_a, model_name_b, weight, output_name, style_tuple_list
)
else: else:
if len(style_triple) != 4: if len(style_tuple) != 4:
logger.error(f"Invalid style triple: {line}") logger.error(f"Invalid style triple: {line}")
return ( return (
f"Error: スタイルを4つのカンマ区切りで入力してください:\n{line}", f"Error: スタイルを4つのカンマ区切りで入力してください:\n{line}",
None, None,
) )
style_a, style_b, style_c, style_out = style_triple style_a, style_b, style_c, style_out = style_tuple
style_a = style_a.strip() style_a = style_a.strip()
style_b = style_b.strip() style_b = style_b.strip()
style_c = style_c.strip() style_c = style_c.strip()
style_out = style_out.strip() style_out = style_out.strip()
style_tuple_list.append((style_a, style_b, style_c, style_out)) style_tuple_list.append((style_a, style_b, style_c, style_out))
try:
if not use_add_diff:
new_style_path, new_styles = merge_style(
model_name_a, model_name_b, weight, output_name, style_tuple_list
)
else:
new_style_path, new_styles = merge_style_add_diff( new_style_path, new_styles = merge_style_add_diff(
model_name_a, model_name_a,
model_name_b, model_name_b,
@@ -414,8 +640,6 @@ def merge_style_gr(
output_name, output_name,
style_tuple_list, style_tuple_list,
) )
except ValueError as e:
return f"Error: {e}"
return f"Success: スタイルを{new_style_path}に保存しました。", gr.Dropdown( return f"Success: スタイルを{new_style_path}に保存しました。", gr.Dropdown(
choices=new_styles, value=new_styles[0] choices=new_styles, value=new_styles[0]
) )
@@ -501,6 +725,95 @@ Happy, Surprise, HappySurprise
- 構造上の相性の関係で、スタイルベクトルを混ぜる重みは、上の「話し方」と同じ比率で混ぜられます。例えば「話し方」が0のときはモデルAのみしか使われません。 - 構造上の相性の関係で、スタイルベクトルを混ぜる重みは、上の「話し方」と同じ比率で混ぜられます。例えば「話し方」が0のときはモデルAのみしか使われません。
""" """
usual_md = """
`weight` を下の各スライダーで定める数値とすると、各要素ごとに、
```
new_model = (1 - weight) * A + weight * B
```
としてマージされます。
"""
add_diff_md = """
`weight` を下の各スライダーで定める数値とすると、各要素ごとに、
```
new_model = A + weight * (B - C)
```
としてマージされます。
"""
weighted_sum_md = """
モデルの係数をそれぞれ `a`, `b`, `c` とすると、 **全要素に対して**、
```
new_model = a * A + b * B + c * C
```
としてマージされます。
TIPS:
- A, B, C が全て通常モデルの場合は、`a + b + c = 1`となるようにするのがよいと思います。
- `a + b + c = 0` とすると(たとえば `A - B`)、話者性を持たないゼロモデルを作ることができ、「ゼロモデルとの和」で結果を使うことが出来ます(差分マージなど)
"""
add_zero_md = """
「ゼロモデル」を、いくつかのモデルの加重和であってその係数の和が0であるようなものとします例えば `C - D` など)。
そうして作ったゼロモデルBと通常モデルAに対して、`weight` を下の各スライダーで定める数値とすると、各要素ごとに、
```
new_model = A + weight * B
```
としてマージされます。
"""
def method_change(x: str):
assert x in [
"usual",
"add_diff",
"weighted_sum",
"add_zero",
], f"Invalid method: {x}"
# model_desc, c_col, model_a_coeff, model_b_coeff, model_c_coeff, weight_row, use_slerp_instead_of_lerp
if x == "usual":
return (
gr.Markdown(usual_md),
gr.Column(visible=False),
gr.Number(visible=False),
gr.Number(visible=False),
gr.Number(visible=False),
gr.Row(visible=True),
gr.Checkbox(visible=True),
)
elif x == "add_diff":
return (
gr.Markdown(add_diff_md),
gr.Column(visible=True),
gr.Number(visible=False),
gr.Number(visible=False),
gr.Number(visible=False),
gr.Row(visible=True),
gr.Checkbox(visible=False),
)
elif x == "add_zero":
return (
gr.Markdown(add_zero_md),
gr.Column(visible=False),
gr.Number(visible=False),
gr.Number(visible=False),
gr.Number(visible=False),
gr.Row(visible=True),
gr.Checkbox(visible=False),
)
else: # weighted_sum
return (
gr.Markdown(weighted_sum_md),
gr.Column(visible=True),
gr.Number(visible=True),
gr.Number(visible=True),
gr.Number(visible=True),
gr.Row(visible=False),
gr.Checkbox(visible=False),
)
def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks: def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
model_names = model_holder.model_names model_names = model_holder.model_names
@@ -525,7 +838,16 @@ def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
) )
with gr.Accordion(label="使い方", open=False): with gr.Accordion(label="使い方", open=False):
gr.Markdown(initial_md) gr.Markdown(initial_md)
use_add_diff = gr.Checkbox(label="差分マージ", value=False) method = gr.Radio(
label="マージ方法",
choices=[
("通常マージ", "usual"),
("差分マージ", "add_diff"),
("加重和", "weighted_sum"),
("ゼロモデルマージ", "add_zero"),
],
value="usual",
)
with gr.Row(): with gr.Row():
with gr.Column(scale=3): with gr.Column(scale=3):
model_name_a = gr.Dropdown( model_name_a = gr.Dropdown(
@@ -538,6 +860,12 @@ def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
choices=initial_model_files, choices=initial_model_files,
value=initial_model_files[0], value=initial_model_files[0],
) )
model_a_coeff = gr.Number(
label="モデルAの係数",
value=1.0,
step=0.1,
visible=False,
)
with gr.Column(scale=3): with gr.Column(scale=3):
model_name_b = gr.Dropdown( model_name_b = gr.Dropdown(
label="モデルB", label="モデルB",
@@ -549,26 +877,34 @@ def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
choices=initial_model_files, choices=initial_model_files,
value=initial_model_files[0], value=initial_model_files[0],
) )
with gr.Column(scale=3): model_b_coeff = gr.Number(
label="モデルBの係数",
value=-1.0,
step=0.1,
visible=False,
)
with gr.Column(scale=3, visible=False) as c_col:
model_name_c = gr.Dropdown( model_name_c = gr.Dropdown(
label="モデルC", label="モデルC",
choices=model_names, choices=model_names,
value=model_names[initial_id], value=model_names[initial_id],
visible=False,
) )
model_path_c = gr.Dropdown( model_path_c = gr.Dropdown(
label="モデルファイル", label="モデルファイル",
choices=initial_model_files, choices=initial_model_files,
value=initial_model_files[0], value=initial_model_files[0],
)
model_c_coeff = gr.Number(
label="モデルCの係数",
value=0.0,
step=0.1,
visible=False, visible=False,
) )
refresh_button = gr.Button("更新", scale=1, visible=True) refresh_button = gr.Button("更新", scale=1, visible=True)
gr.Markdown( method_desc = gr.Markdown(usual_md)
"通常マージの場合、`new = (1 - weight) * A + weight * B`、差分マージの場合、`new = A + weight * (B - C)`"
)
with gr.Column(variant="panel"): with gr.Column(variant="panel"):
new_name = gr.Textbox(label="新しいモデル名", placeholder="new_model") new_name = gr.Textbox(label="新しいモデル名", placeholder="new_model")
with gr.Row(): with gr.Row() as weight_row:
voice_slider = gr.Slider( voice_slider = gr.Slider(
label="声質", label="声質",
value=0, value=0,
@@ -600,6 +936,7 @@ def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
use_slerp_instead_of_lerp = gr.Checkbox( use_slerp_instead_of_lerp = gr.Checkbox(
label="線形補完のかわりに球面線形補完を使う", label="線形補完のかわりに球面線形補完を使う",
value=False, value=False,
visible=True,
) )
with gr.Column(variant="panel"): with gr.Column(variant="panel"):
gr.Markdown("## モデルファイルsafetensorsのマージ") gr.Markdown("## モデルファイルsafetensorsのマージ")
@@ -626,8 +963,8 @@ def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
) )
style = gr.Dropdown( style = gr.Dropdown(
label="スタイル", label="スタイル",
choices=["スタイルをマージしてください"], choices=[DEFAULT_STYLE],
value="スタイルをマージしてください", value=DEFAULT_STYLE,
) )
emotion_weight = gr.Slider( emotion_weight = gr.Slider(
minimum=0, minimum=0,
@@ -638,10 +975,18 @@ def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
) )
tts_button = gr.Button("音声合成", variant="primary") tts_button = gr.Button("音声合成", variant="primary")
audio_output = gr.Audio(label="結果") audio_output = gr.Audio(label="結果")
use_add_diff.change( method.change(
lambda x: (gr.Dropdown(visible=x), gr.Dropdown(visible=x)), method_change,
inputs=[use_add_diff], inputs=[method],
outputs=[model_name_c, model_path_c], outputs=[
method_desc,
c_col,
model_a_coeff,
model_b_coeff,
model_c_coeff,
weight_row,
use_slerp_instead_of_lerp,
],
) )
model_name_a.change( model_name_a.change(
model_holder.update_model_files_for_gradio, model_holder.update_model_files_for_gradio,
@@ -680,13 +1025,13 @@ def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
model_merge_button.click( model_merge_button.click(
merge_models_gr, merge_models_gr,
inputs=[ inputs=[
model_name_a,
model_path_a, model_path_a,
model_name_b,
model_path_b, model_path_b,
model_name_c,
model_path_c, model_path_c,
use_add_diff, model_a_coeff,
model_b_coeff,
model_c_coeff,
method,
new_name, new_name,
voice_slider, voice_slider,
voice_pitch_slider, voice_pitch_slider,
@@ -703,7 +1048,7 @@ def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
model_name_a, model_name_a,
model_name_b, model_name_b,
model_name_c, model_name_c,
use_add_diff, method,
speech_style_slider, speech_style_slider,
new_name, new_name,
style_triple_list, style_triple_list,