Spaces:
Running
Running
cockolo terada
commited on
Update gradio_tabs/single.py
Browse files- gradio_tabs/single.py +6 -24
gradio_tabs/single.py
CHANGED
@@ -27,9 +27,8 @@ from typing import Dict, Any, List, Tuple, Optional, Set
|
|
27 |
# --- タイムゾーン定義 ---
|
28 |
# グローバルな定数としてJSTを定義
|
29 |
JST = timezone(timedelta(hours=9), 'JST')
|
30 |
-
#
|
31 |
FN_MODEL_CACHE_PATH = Path("/tmp/sbv2_merger_cache")
|
32 |
-
# ▲▲▲ 変更点 ▲▲▲
|
33 |
|
34 |
|
35 |
# --- モック(本来はライブラリからインポート) ---
|
@@ -182,14 +181,12 @@ def format_and_sort_model_names(dir_list: List[str]) -> List[Tuple[str, str]]:
|
|
182 |
result_list.extend(sorted(unparsed_models))
|
183 |
return result_list
|
184 |
|
185 |
-
# ▼▼▼ 変更点: FNモデルソート用のヘルパー関数を追加 ▼▼▼
|
186 |
def get_fn_model_sort_key(name: str) -> int:
|
187 |
"""FNモデル名からソート用の数値を抽出する。例: 'FN10' -> 10"""
|
188 |
match = re.search(r'FN(\d+)', name, re.IGNORECASE)
|
189 |
if match:
|
190 |
return int(match.group(1))
|
191 |
return float('inf') # マッチしないものは後ろに配置
|
192 |
-
# ▲▲▲ 変更点 ▲▲▲
|
193 |
|
194 |
|
195 |
def set_random_seed(seed: int):
|
@@ -209,15 +206,13 @@ def get_directory_size(directory_path: Path) -> int:
|
|
209 |
for dirpath, _, filenames in os.walk(directory_path):
|
210 |
for f in filenames:
|
211 |
fp = os.path.join(dirpath, f)
|
212 |
-
# シンボリックリンクが壊れている場合などを考慮
|
213 |
if not os.path.islink(fp):
|
214 |
try:
|
215 |
total_size += os.path.getsize(fp)
|
216 |
except OSError:
|
217 |
-
# ファイルがスキャン中に削除された場合など
|
218 |
pass
|
219 |
except FileNotFoundError:
|
220 |
-
return 0
|
221 |
return total_size
|
222 |
|
223 |
def format_bytes(size_bytes: int) -> str:
|
@@ -518,9 +513,7 @@ def create_synthesis_app(model_holder: TTSModelHolder) -> gr.Blocks:
|
|
518 |
|
519 |
with gr.Column(scale=1):
|
520 |
with gr.Row():
|
521 |
-
# ▼▼▼ 変更点: 「融☆合モデルを使う」を「FNモデルモード」に変更し、最初は非表示に ▼▼▼
|
522 |
use_fn_model_mode_checkbox = gr.Checkbox(label="FNモデルモード", value=False, interactive=True, scale=3, visible=False)
|
523 |
-
# ▲▲▲ 変更点 ▲▲▲
|
524 |
refresh_model_list_button = gr.Button("再読込", scale=1)
|
525 |
selected_model_dropdown = gr.Dropdown(label="話者", choices=[], value=None, interactive=True)
|
526 |
current_styles_dropdown = gr.Dropdown(label="スタイル", choices=[], type="value", interactive=True)
|
@@ -619,10 +612,8 @@ def create_synthesis_app(model_holder: TTSModelHolder) -> gr.Blocks:
|
|
619 |
default_weight = styles_map[first_key].get("weight", DEFAULT_STYLE_WEIGHT)
|
620 |
return gr.update(choices=display_names, value=default_display_name), gr.update(value=default_weight), styles_map
|
621 |
|
622 |
-
# ▼▼▼ 変更点: FNモデルモードに対応したモデルリスト更新関数 ▼▼▼
|
623 |
def action_refresh_model_list(use_fn_model_mode: bool):
|
624 |
"""モデルリストを再読み込みし、UIとバックエンドの状態を同期させる。"""
|
625 |
-
# 既存のシンボリックリンクをクリア
|
626 |
if assets_root_path.exists():
|
627 |
for item in assets_root_path.iterdir():
|
628 |
if item.is_symlink():
|
@@ -631,7 +622,6 @@ def create_synthesis_app(model_holder: TTSModelHolder) -> gr.Blocks:
|
|
631 |
except OSError as e:
|
632 |
print(f"Failed to remove symlink {item}: {e}")
|
633 |
|
634 |
-
# FNモデルキャッシュパスからFNモデルを探し、シンボリックリンクを作成
|
635 |
fn_models_found = []
|
636 |
if FN_MODEL_CACHE_PATH.exists() and FN_MODEL_CACHE_PATH.is_dir():
|
637 |
for item in FN_MODEL_CACHE_PATH.iterdir():
|
@@ -646,28 +636,25 @@ def create_synthesis_app(model_holder: TTSModelHolder) -> gr.Blocks:
|
|
646 |
|
647 |
fn_mode_checkbox_update = gr.update(visible=bool(fn_models_found))
|
648 |
|
649 |
-
# バックエンドのモデルリストを更新
|
650 |
model_holder.refresh()
|
651 |
|
652 |
model_dropdown_update = gr.update(choices=[], value=None)
|
653 |
if use_fn_model_mode and fn_models_found:
|
654 |
-
# FNモデルモードの場合: FNモデルを数値でソートして表示
|
655 |
sorted_fn_models = sorted(fn_models_found, key=get_fn_model_sort_key)
|
656 |
value = sorted_fn_models[0] if sorted_fn_models else None
|
657 |
model_dropdown_update = gr.update(choices=sorted_fn_models, value=value)
|
658 |
else:
|
659 |
-
# 通常モードの場合: 通常モデルとマージモデルを表示
|
660 |
ui_model_list = [p.name for p in assets_root_path.iterdir() if p.is_dir() and not p.is_symlink()]
|
661 |
formatted_choices = format_and_sort_model_names(ui_model_list)
|
662 |
value = formatted_choices[0][1] if formatted_choices else None
|
663 |
model_dropdown_update = gr.update(choices=formatted_choices, value=value)
|
664 |
|
665 |
-
#
|
666 |
-
selected_model_for_style = model_dropdown_update
|
|
|
667 |
style_dropdown_update, style_weight_update, styles_data_state_update = load_styles_for_ui(selected_model_for_style)
|
668 |
|
669 |
return fn_mode_checkbox_update, model_dropdown_update, style_dropdown_update, style_weight_update, styles_data_state_update
|
670 |
-
# ▲▲▲ 変更点 ▲▲▲
|
671 |
|
672 |
|
673 |
def on_model_select_change(selected_model_name: Optional[str]):
|
@@ -1080,7 +1067,6 @@ def create_synthesis_app(model_holder: TTSModelHolder) -> gr.Blocks:
|
|
1080 |
|
1081 |
|
1082 |
# --- イベントリスナー接続 ---
|
1083 |
-
# ▼▼▼ 変更点: FNモデルモードに対応したイベントリスナーの定義 ▼▼▼
|
1084 |
refresh_triggers = [refresh_model_list_button.click, use_fn_model_mode_checkbox.change]
|
1085 |
outputs_for_refresh = [use_fn_model_mode_checkbox, selected_model_dropdown, current_styles_dropdown, style_weight_for_synth_slider, all_styles_data_state]
|
1086 |
|
@@ -1166,14 +1152,12 @@ def create_synthesis_app(model_holder: TTSModelHolder) -> gr.Blocks:
|
|
1166 |
app.load(action_refresh_model_list,
|
1167 |
inputs=[use_fn_model_mode_checkbox],
|
1168 |
outputs=outputs_for_refresh)
|
1169 |
-
# ▲▲▲ 変更点 ▲▲▲
|
1170 |
return app
|
1171 |
|
1172 |
# --- アプリケーションの起動 ---
|
1173 |
if __name__ == "__main__":
|
1174 |
if Path("model_assets").exists(): shutil.rmtree("model_assets")
|
1175 |
|
1176 |
-
# ▼▼▼ 変更点: FNモデルキャッシュパスの作成とGradioへの許可 ▼▼▲
|
1177 |
# モックFNモデルを作成してテスト
|
1178 |
FN_MODEL_CACHE_PATH.mkdir(exist_ok=True, parents=True)
|
1179 |
(FN_MODEL_CACHE_PATH / "FN1").mkdir(exist_ok=True)
|
@@ -1188,7 +1172,6 @@ if __name__ == "__main__":
|
|
1188 |
assets_dir_path.mkdir(exist_ok=True)
|
1189 |
allowed_paths = [str(assets_dir_path)]
|
1190 |
|
1191 |
-
# FNモデルのキャッシュパスへのアクセスを許可
|
1192 |
if FN_MODEL_CACHE_PATH.exists() and FN_MODEL_CACHE_PATH.is_dir():
|
1193 |
allowed_paths.append(str(FN_MODEL_CACHE_PATH.resolve()))
|
1194 |
else:
|
@@ -1209,5 +1192,4 @@ if __name__ == "__main__":
|
|
1209 |
|
1210 |
print(f"Gradioに次のパスへのアクセスを許可します: {', '.join(allowed_paths)}")
|
1211 |
|
1212 |
-
app.launch(allowed_paths=allowed_paths)
|
1213 |
-
# ▲▲▲ 変更点 ▲▲▲
|
|
|
27 |
# --- タイムゾーン定義 ---
|
28 |
# グローバルな定数としてJSTを定義
|
29 |
JST = timezone(timedelta(hours=9), 'JST')
|
30 |
+
# FNモデル用のキャッシュパスを定義
|
31 |
FN_MODEL_CACHE_PATH = Path("/tmp/sbv2_merger_cache")
|
|
|
32 |
|
33 |
|
34 |
# --- モック(本来はライブラリからインポート) ---
|
|
|
181 |
result_list.extend(sorted(unparsed_models))
|
182 |
return result_list
|
183 |
|
|
|
184 |
def get_fn_model_sort_key(name: str) -> int:
|
185 |
"""FNモデル名からソート用の数値を抽出する。例: 'FN10' -> 10"""
|
186 |
match = re.search(r'FN(\d+)', name, re.IGNORECASE)
|
187 |
if match:
|
188 |
return int(match.group(1))
|
189 |
return float('inf') # マッチしないものは後ろに配置
|
|
|
190 |
|
191 |
|
192 |
def set_random_seed(seed: int):
|
|
|
206 |
for dirpath, _, filenames in os.walk(directory_path):
|
207 |
for f in filenames:
|
208 |
fp = os.path.join(dirpath, f)
|
|
|
209 |
if not os.path.islink(fp):
|
210 |
try:
|
211 |
total_size += os.path.getsize(fp)
|
212 |
except OSError:
|
|
|
213 |
pass
|
214 |
except FileNotFoundError:
|
215 |
+
return 0
|
216 |
return total_size
|
217 |
|
218 |
def format_bytes(size_bytes: int) -> str:
|
|
|
513 |
|
514 |
with gr.Column(scale=1):
|
515 |
with gr.Row():
|
|
|
516 |
use_fn_model_mode_checkbox = gr.Checkbox(label="FNモデルモード", value=False, interactive=True, scale=3, visible=False)
|
|
|
517 |
refresh_model_list_button = gr.Button("再読込", scale=1)
|
518 |
selected_model_dropdown = gr.Dropdown(label="話者", choices=[], value=None, interactive=True)
|
519 |
current_styles_dropdown = gr.Dropdown(label="スタイル", choices=[], type="value", interactive=True)
|
|
|
612 |
default_weight = styles_map[first_key].get("weight", DEFAULT_STYLE_WEIGHT)
|
613 |
return gr.update(choices=display_names, value=default_display_name), gr.update(value=default_weight), styles_map
|
614 |
|
|
|
615 |
def action_refresh_model_list(use_fn_model_mode: bool):
|
616 |
"""モデルリストを再読み込みし、UIとバックエンドの状態を同期させる。"""
|
|
|
617 |
if assets_root_path.exists():
|
618 |
for item in assets_root_path.iterdir():
|
619 |
if item.is_symlink():
|
|
|
622 |
except OSError as e:
|
623 |
print(f"Failed to remove symlink {item}: {e}")
|
624 |
|
|
|
625 |
fn_models_found = []
|
626 |
if FN_MODEL_CACHE_PATH.exists() and FN_MODEL_CACHE_PATH.is_dir():
|
627 |
for item in FN_MODEL_CACHE_PATH.iterdir():
|
|
|
636 |
|
637 |
fn_mode_checkbox_update = gr.update(visible=bool(fn_models_found))
|
638 |
|
|
|
639 |
model_holder.refresh()
|
640 |
|
641 |
model_dropdown_update = gr.update(choices=[], value=None)
|
642 |
if use_fn_model_mode and fn_models_found:
|
|
|
643 |
sorted_fn_models = sorted(fn_models_found, key=get_fn_model_sort_key)
|
644 |
value = sorted_fn_models[0] if sorted_fn_models else None
|
645 |
model_dropdown_update = gr.update(choices=sorted_fn_models, value=value)
|
646 |
else:
|
|
|
647 |
ui_model_list = [p.name for p in assets_root_path.iterdir() if p.is_dir() and not p.is_symlink()]
|
648 |
formatted_choices = format_and_sort_model_names(ui_model_list)
|
649 |
value = formatted_choices[0][1] if formatted_choices else None
|
650 |
model_dropdown_update = gr.update(choices=formatted_choices, value=value)
|
651 |
|
652 |
+
# ▼▼▼ 変更点: .value を ['value'] に修正 ▼▼▼
|
653 |
+
selected_model_for_style = model_dropdown_update['value']
|
654 |
+
# ▲▲▲ 変更点 ▲▲▲
|
655 |
style_dropdown_update, style_weight_update, styles_data_state_update = load_styles_for_ui(selected_model_for_style)
|
656 |
|
657 |
return fn_mode_checkbox_update, model_dropdown_update, style_dropdown_update, style_weight_update, styles_data_state_update
|
|
|
658 |
|
659 |
|
660 |
def on_model_select_change(selected_model_name: Optional[str]):
|
|
|
1067 |
|
1068 |
|
1069 |
# --- イベントリスナー接続 ---
|
|
|
1070 |
refresh_triggers = [refresh_model_list_button.click, use_fn_model_mode_checkbox.change]
|
1071 |
outputs_for_refresh = [use_fn_model_mode_checkbox, selected_model_dropdown, current_styles_dropdown, style_weight_for_synth_slider, all_styles_data_state]
|
1072 |
|
|
|
1152 |
app.load(action_refresh_model_list,
|
1153 |
inputs=[use_fn_model_mode_checkbox],
|
1154 |
outputs=outputs_for_refresh)
|
|
|
1155 |
return app
|
1156 |
|
1157 |
# --- アプリケーションの起動 ---
|
1158 |
if __name__ == "__main__":
|
1159 |
if Path("model_assets").exists(): shutil.rmtree("model_assets")
|
1160 |
|
|
|
1161 |
# モックFNモデルを作成してテスト
|
1162 |
FN_MODEL_CACHE_PATH.mkdir(exist_ok=True, parents=True)
|
1163 |
(FN_MODEL_CACHE_PATH / "FN1").mkdir(exist_ok=True)
|
|
|
1172 |
assets_dir_path.mkdir(exist_ok=True)
|
1173 |
allowed_paths = [str(assets_dir_path)]
|
1174 |
|
|
|
1175 |
if FN_MODEL_CACHE_PATH.exists() and FN_MODEL_CACHE_PATH.is_dir():
|
1176 |
allowed_paths.append(str(FN_MODEL_CACHE_PATH.resolve()))
|
1177 |
else:
|
|
|
1192 |
|
1193 |
print(f"Gradioに次のパスへのアクセスを許可します: {', '.join(allowed_paths)}")
|
1194 |
|
1195 |
+
app.launch(allowed_paths=allowed_paths)
|
|