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)
|
|
|