@@ -102,6 +102,25 @@ def merge_style(model_name_a, model_name_b, weight, output_name, style_triple_li
|
|||||||
return output_style_path, list(new_style2id.keys())
|
return output_style_path, list(new_style2id.keys())
|
||||||
|
|
||||||
|
|
||||||
|
def lerp_tensors(t, v0, v1):
|
||||||
|
return v0 * (1 - t) + v1 * t
|
||||||
|
|
||||||
|
def slerp_tensors(t, v0, v1, dot_thres = 0.998):
|
||||||
|
device = v0.device
|
||||||
|
v0c = v0.cpu().numpy()
|
||||||
|
v1c = v1.cpu().numpy()
|
||||||
|
|
||||||
|
dot = np.sum(v0c * v1c / (np.linalg.norm(v0c) * np.linalg.norm(v1c)))
|
||||||
|
|
||||||
|
if abs(dot) > dot_thres:
|
||||||
|
return lerp_tensors(t, v0, v1)
|
||||||
|
|
||||||
|
th0 = np.arccos(dot)
|
||||||
|
sin_th0 = np.sin(th0)
|
||||||
|
th_t = th0 * t
|
||||||
|
|
||||||
|
return torch.from_numpy(v0c * np.sin(th0 - th_t) / sin_th0 + v1c * np.sin(th_t) / sin_th0).to(device)
|
||||||
|
|
||||||
def merge_models(
|
def merge_models(
|
||||||
model_path_a,
|
model_path_a,
|
||||||
model_path_b,
|
model_path_b,
|
||||||
@@ -110,6 +129,7 @@ def merge_models(
|
|||||||
speech_style_weight,
|
speech_style_weight,
|
||||||
tempo_weight,
|
tempo_weight,
|
||||||
output_name,
|
output_name,
|
||||||
|
use_slerp_instead_of_lerp,
|
||||||
):
|
):
|
||||||
"""model Aを起点に、model Bの各要素を重み付けしてマージする。
|
"""model Aを起点に、model Bの各要素を重み付けしてマージする。
|
||||||
safetensors形式を前提とする。"""
|
safetensors形式を前提とする。"""
|
||||||
@@ -137,8 +157,8 @@ def merge_models(
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
merged_model_weight[key] = (
|
merged_model_weight[key] = (
|
||||||
model_a_weight[key] * (1 - weight) + model_b_weight[key] * weight
|
slerp_tensors if use_slerp_instead_of_lerp else lerp_tensors
|
||||||
)
|
)(weight, model_a_weight[key], model_b_weight[key])
|
||||||
|
|
||||||
merged_model_path = os.path.join(
|
merged_model_path = os.path.join(
|
||||||
assets_root, output_name, f"{output_name}.safetensors"
|
assets_root, output_name, f"{output_name}.safetensors"
|
||||||
@@ -171,6 +191,7 @@ def merge_models_gr(
|
|||||||
voice_pitch_weight,
|
voice_pitch_weight,
|
||||||
speech_style_weight,
|
speech_style_weight,
|
||||||
tempo_weight,
|
tempo_weight,
|
||||||
|
use_slerp_instead_of_lerp,
|
||||||
):
|
):
|
||||||
if output_name == "":
|
if output_name == "":
|
||||||
return "Error: 新しいモデル名を入力してください。"
|
return "Error: 新しいモデル名を入力してください。"
|
||||||
@@ -182,6 +203,7 @@ def merge_models_gr(
|
|||||||
speech_style_weight,
|
speech_style_weight,
|
||||||
tempo_weight,
|
tempo_weight,
|
||||||
output_name,
|
output_name,
|
||||||
|
use_slerp_instead_of_lerp,
|
||||||
)
|
)
|
||||||
return f"Success: モデルを{merged_model_path}に保存しました。"
|
return f"Success: モデルを{merged_model_path}に保存しました。"
|
||||||
|
|
||||||
@@ -246,7 +268,12 @@ def load_styles_gr(model_name_a, model_name_b):
|
|||||||
with open(config_path_b, encoding="utf-8") as f:
|
with open(config_path_b, encoding="utf-8") as f:
|
||||||
config_b = json.load(f)
|
config_b = json.load(f)
|
||||||
styles_b = list(config_b["data"]["style2id"].keys())
|
styles_b = list(config_b["data"]["style2id"].keys())
|
||||||
return gr.Textbox(value=", ".join(styles_a)), gr.Textbox(value=", ".join(styles_b))
|
|
||||||
|
return gr.Textbox(value=", ".join(styles_a)), gr.Textbox(value=", ".join(styles_b)), gr.TextArea(
|
||||||
|
label="スタイルのマージリスト",
|
||||||
|
placeholder=f"{DEFAULT_STYLE}, {DEFAULT_STYLE},{DEFAULT_STYLE}\nAngry, Angry, Angry",
|
||||||
|
value='\n'.join(f"{sty_a}, {sty_b}, {sty_a if sty_a != sty_b else ''}{sty_b}" for sty_a in styles_a for sty_b in styles_b),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
initial_md = """
|
initial_md = """
|
||||||
@@ -359,6 +386,10 @@ with gr.Blocks(theme=GRADIO_THEME) as app:
|
|||||||
maximum=1,
|
maximum=1,
|
||||||
step=0.1,
|
step=0.1,
|
||||||
)
|
)
|
||||||
|
use_slerp_instead_of_lerp = gr.Checkbox(
|
||||||
|
label="lerpのかわりにslerpを使う",
|
||||||
|
value=False,
|
||||||
|
)
|
||||||
with gr.Column(variant="panel"):
|
with gr.Column(variant="panel"):
|
||||||
gr.Markdown("## モデルファイル(safetensors)のマージ")
|
gr.Markdown("## モデルファイル(safetensors)のマージ")
|
||||||
model_merge_button = gr.Button("モデルファイルのマージ", variant="primary")
|
model_merge_button = gr.Button("モデルファイルのマージ", variant="primary")
|
||||||
@@ -414,7 +445,7 @@ with gr.Blocks(theme=GRADIO_THEME) as app:
|
|||||||
load_style_button.click(
|
load_style_button.click(
|
||||||
load_styles_gr,
|
load_styles_gr,
|
||||||
inputs=[model_name_a, model_name_b],
|
inputs=[model_name_a, model_name_b],
|
||||||
outputs=[styles_a, styles_b],
|
outputs=[styles_a, styles_b, style_triple_list],
|
||||||
)
|
)
|
||||||
|
|
||||||
model_merge_button.click(
|
model_merge_button.click(
|
||||||
@@ -429,6 +460,7 @@ with gr.Blocks(theme=GRADIO_THEME) as app:
|
|||||||
voice_pitch_slider,
|
voice_pitch_slider,
|
||||||
speech_style_slider,
|
speech_style_slider,
|
||||||
tempo_slider,
|
tempo_slider,
|
||||||
|
use_slerp_instead_of_lerp,
|
||||||
],
|
],
|
||||||
outputs=[info_model_merge],
|
outputs=[info_model_merge],
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user