AlekseyCalvin commited on
Commit
a6d1a0c
·
verified ·
1 Parent(s): a20e358

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -37
app.py CHANGED
@@ -18,11 +18,12 @@ from huggingface_hub import HfApi, hf_hub_download, list_repo_files, login
18
  from safetensors.torch import load_file, save_file
19
  from tqdm import tqdm
20
 
21
- # --- Essential Imports (No try-except blocks to ensure visibility of errors) ---
 
22
  from gradio_logsview.logsview import Log, LogsView, LogsViewRunner
23
  from mergekit.config import MergeConfiguration
24
 
25
- # --- Constants ---
26
  try:
27
  TempDir = Path("/tmp/temp_tool")
28
  os.makedirs(TempDir, exist_ok=True)
@@ -135,7 +136,7 @@ def get_key_stem(key):
135
  return key
136
 
137
  # =================================================================================
138
- # TABS 1-4 LOGIC (Legacy Python Implementation)
139
  # =================================================================================
140
 
141
  class MemoryEfficientSafeOpen:
@@ -203,8 +204,7 @@ def task_merge_legacy(hf_token, base, sub, lora, scale, prec, shard, out, struct
203
  except Exception as e: return f"Error: {e}"
204
  if struct_s:
205
  try:
206
- files = api.list_repo_files(repo_id=struct_s, token=hf_token)
207
- for f in tqdm(files, desc="Copying Structure"):
208
  if sub and f.startswith(sub): continue
209
  if not sub and any(f.endswith(x) for x in ['.safetensors', '.bin', '.pt', '.pth']): continue
210
  l = hf_hub_download(repo_id=struct_s, filename=f, token=hf_token, local_dir=TempDir)
@@ -418,7 +418,7 @@ def task_resize(hf_token, lora_input, new_rank, dynamic_method, dynamic_param, o
418
  return "Done"
419
 
420
  # =================================================================================
421
- # MERGEKIT & LOGSVIEW (TABS 5-9) - FIXED CLI LOGIC
422
  # =================================================================================
423
 
424
  def parse_weight(w_str):
@@ -432,14 +432,17 @@ def run_mergekit_logic(config_dict, token, out_repo, private, shard_size, output
432
  runner = LogsViewRunner()
433
  cleanup_temp()
434
 
435
- # 1. Validation
 
 
 
436
  try:
437
- MergeConfiguration.model_validate(config_dict)
 
438
  except Exception as e:
439
  yield runner.log(f"Invalid Config: {e}", level="ERROR")
440
  return
441
 
442
- # 2. Auth & Config Save
443
  if token:
444
  login(token.strip())
445
  os.environ["HF_TOKEN"] = token.strip()
@@ -447,10 +450,6 @@ def run_mergekit_logic(config_dict, token, out_repo, private, shard_size, output
447
  if "dtype" not in config_dict: config_dict["dtype"] = output_precision
448
  if "tokenizer_source" not in config_dict and tokenizer_source != "base":
449
  config_dict["tokenizer_source"] = tokenizer_source
450
-
451
- # Add chat_template if not empty
452
- if chat_template and chat_template.strip():
453
- config_dict["chat_template"] = chat_template.strip()
454
 
455
  config_path = TempDir / "config.yaml"
456
  with open(config_path, "w") as f: yaml.dump(config_dict, f, sort_keys=False)
@@ -458,7 +457,6 @@ def run_mergekit_logic(config_dict, token, out_repo, private, shard_size, output
458
  yield runner.log(f"Config saved to {config_path}")
459
  yield runner.log(f"YAML:\n{yaml.dump(config_dict, sort_keys=False)}")
460
 
461
- # 3. Create Repo
462
  try:
463
  api.create_repo(repo_id=out_repo, private=private, exist_ok=True, token=token)
464
  yield runner.log(f"Repo {out_repo} ready.")
@@ -466,9 +464,7 @@ def run_mergekit_logic(config_dict, token, out_repo, private, shard_size, output
466
  yield runner.log(f"Repo Error: {e}", level="ERROR")
467
  return
468
 
469
- # 4. Execution
470
  out_path = TempDir / "merge_output"
471
-
472
  shard_arg = f"{int(float(shard_size) * 1024)}M"
473
 
474
  cmd = [
@@ -494,7 +490,6 @@ def run_mergekit_logic(config_dict, token, out_repo, private, shard_size, output
494
  yield runner.log("Merge failed.", level="ERROR")
495
  return
496
 
497
- # 5. Upload
498
  yield runner.log(f"Uploading to {out_repo}...")
499
  yield from runner.run_python(api.upload_folder, repo_id=out_repo, folder_path=out_path)
500
  yield runner.log("Upload Complete!")
@@ -513,23 +508,27 @@ def wrapper_amphinterpolative(token, method, base, t, norm, i8, flat, row, eps,
513
  if method in ["slerp", "nuslerp"]:
514
  if not base.strip(): yield runner.log("Error: Base model required", level="ERROR"); return
515
  config["base_model"] = base.strip()
516
- sources = []
517
- for m, w in [(m1,w1), (m2,w2)]:
518
- if m.strip(): sources.append({"model": m, "parameters": {"weight": parse_weight(w)}})
519
  config["slices"] = [{"sources": sources, "parameters": params}]
520
  else:
521
  if base.strip() and method == "multislerp": config["base_model"] = base.strip()
522
- models = []
523
- for m, w in [(m1, w1), (m2, w2), (m3, w3), (m4, w4), (m5, w5)]:
524
- if m.strip(): models.append({"model": m, "parameters": {"weight": parse_weight(w)}})
525
  config["models"] = models
526
  config["parameters"] = params
527
 
528
  yield from run_mergekit_logic(config, token, out, priv, shard, prec, tok_src, chat_t, program="mergekit-yaml")
529
 
530
  def wrapper_stirtie(token, method, base, norm, i8, lamb, resc, topk, m1, w1, d1, g1, e1, m2, w2, d2, g2, e2, m3, w3, d3, g3, e3, m4, w4, d4, g4, e4, out, priv, shard, prec, tok_src, chat_t):
 
 
531
  models = []
532
- for m, w, d, g, e in [(m1,w1,d1,g1,e1), (m2,w2,d2,g2,e2), (m3,w3,d3,g3,e3), (m4,w4,d4,g4,e4)]:
 
 
 
 
 
 
533
  if not m.strip(): continue
534
  p = {"weight": parse_weight(w)}
535
  if method in ["ties", "dare_ties", "dare_linear", "breadcrumbs_ties"]: p["density"] = parse_weight(d)
@@ -553,13 +552,11 @@ def wrapper_stirtie(token, method, base, norm, i8, lamb, resc, topk, m1, w1, d1,
553
  def wrapper_specious(token, method, base, norm, i8, t, filt_w, m1, w1, f1, m2, w2, m3, w3, m4, w4, m5, w5, out, priv, shard, prec, tok_src, chat_t):
554
  models = []
555
  if method == "passthrough":
556
- if not m1.strip(): yield runner.log("Error: Model 1 required", level="ERROR"); return
557
  p = {"weight": parse_weight(w1)}
558
  if f1.strip(): p["filter"] = f1.strip()
559
  models.append({"model": m1, "parameters": p})
560
  else:
561
- for m, w in [(m1,w1), (m2,w2), (m3,w3), (m4,w4), (m5,w5)]:
562
- if m.strip(): models.append({"model": m, "parameters": {"weight": parse_weight(w)}})
563
 
564
  config = {"merge_method": method, "parameters": {"normalize": norm, "int8_mask": i8}}
565
  if base.strip(): config["base_model"] = base.strip()
@@ -577,12 +574,13 @@ def wrapper_moer(token, base, experts, gate, dtype, out, priv, shard, prec, tok_
577
  "dtype": dtype,
578
  "experts": formatted
579
  }
 
580
  yield from run_mergekit_logic(config, token, out, priv, shard, prec, tok_src, chat_t, program="mergekit-moe")
581
 
582
  def wrapper_rawer(token, models, method, dtype, out, priv, shard, prec, tok_src, chat_t):
583
- m_list = [m.strip() for m in models.split('\n') if m.strip()]
584
  config = {
585
- "models": [{"model": m, "parameters": {"weight": 1.0}} for m in m_list],
586
  "merge_method": method,
587
  "dtype": dtype
588
  }
@@ -680,7 +678,7 @@ with gr.Blocks() as demo:
680
  t4_out = gr.Textbox(label="Output")
681
  gr.Button("Resize").click(task_resize, [t4_token, t4_in, t4_rank, t4_method, t4_param, t4_out], gr.Textbox(label="Result"))
682
 
683
- # --- TAB 5: Amphinterpolative ---
684
  with gr.Tab("Amphinterpolative"):
685
  gr.Markdown("### Spherical Interpolation Family")
686
  t5_token = gr.Textbox(label="HF Token", type="password")
@@ -703,7 +701,7 @@ with gr.Blocks() as demo:
703
  t5_out = gr.Textbox(label="Output Repo"); t5_priv = gr.Checkbox(label="Private", value=True)
704
  gr.Button("Execute").click(wrapper_amphinterpolative, [t5_token, t5_method, t5_base, t5_t, t5_norm, t5_i8, t5_flat, t5_row, t5_eps, t5_iter, t5_tol, m1, w1, m2, w2, m3, w3, m4, w4, m5, w5, t5_out, t5_priv, t5_shard, t5_prec, t5_tok, t5_chat], LogsView())
705
 
706
- # --- TAB 6: Stir/Tie Bases ---
707
  with gr.Tab("Stir/Tie Bases"):
708
  gr.Markdown("### Task Vector Family")
709
  t6_token = gr.Textbox(label="Token", type="password")
@@ -716,10 +714,14 @@ with gr.Blocks() as demo:
716
  m1_6, w1_6 = gr.Textbox(label="Model 1"), gr.Textbox(label="Weight 1", value="1.0"); d1_6, g1_6, e1_6 = gr.Textbox(label="Density", value="1.0"), gr.Number(label="Gamma", value=0.01), gr.Number(label="Epsilon", value=0.15)
717
  with gr.Accordion("More", open=False):
718
  m2_6, w2_6 = gr.Textbox(label="Model 2"), gr.Textbox(label="Weight 2", value="1.0"); d2_6, g2_6, e2_6 = gr.Textbox(label="Density", value="1.0"), gr.Number(label="Gamma", value=0.01), gr.Number(label="Epsilon", value=0.15)
 
 
 
719
  t6_out = gr.Textbox(label="Output Repo"); t6_priv = gr.Checkbox(label="Private", value=True)
720
- gr.Button("Execute").click(wrapper_stirtie, [t6_token, t6_method, t6_base, t6_norm, t6_i8, t6_lamb, t6_resc, t6_topk, m1_6, w1_6, d1_6, g1_6, e1_6, m2_6, w2_6, d2_6, g2_6, e2_6, t6_out, t6_priv, t6_shard, t6_prec, t6_tok, t6_chat], LogsView())
 
721
 
722
- # --- TAB 7: Specious ---
723
  with gr.Tab("Specious"):
724
  gr.Markdown("### Specialized Methods")
725
  t7_token = gr.Textbox(label="Token", type="password")
@@ -736,7 +738,7 @@ with gr.Blocks() as demo:
736
  t7_out = gr.Textbox(label="Output Repo"); t7_priv = gr.Checkbox(label="Private", value=True)
737
  gr.Button("Execute").click(wrapper_specious, [t7_token, t7_method, t7_base, t7_norm, t7_i8, t7_t, t7_filt_w, m1_7, w1_7, f1_7, m2_7, w2_7, m3_7, w3_7, m4_7, w4_7, m5_7, w5_7, t7_out, t7_priv, t7_shard, t7_prec, t7_tok, t7_chat], LogsView())
738
 
739
- # --- TAB 8: MoEr ---
740
  with gr.Tab("MoEr"):
741
  gr.Markdown("### Mixture of Experts")
742
  t8_token = gr.Textbox(label="Token", type="password")
@@ -746,7 +748,7 @@ with gr.Blocks() as demo:
746
  t8_out = gr.Textbox(label="Output Repo"); t8_priv = gr.Checkbox(label="Private", value=True)
747
  gr.Button("Build MoE").click(wrapper_moer, [t8_token, t8_base, t8_experts, t8_gate, t8_dtype, t8_out, t8_priv, t8_shard, t8_prec, t8_tok, t8_chat], LogsView())
748
 
749
- # --- TAB 9: Rawer ---
750
  with gr.Tab("Rawer"):
751
  gr.Markdown("### Raw PyTorch / Non-Transformer")
752
  t9_token = gr.Textbox(label="Token", type="password"); t9_models = gr.TextArea(label="Models (one per line)")
@@ -756,9 +758,8 @@ with gr.Blocks() as demo:
756
  t9_out = gr.Textbox(label="Output Repo"); t9_priv = gr.Checkbox(label="Private", value=True)
757
  gr.Button("Merge Raw").click(wrapper_rawer, [t9_token, t9_models, t9_method, t9_dtype, t9_out, t9_priv, t9_shard, t9_prec, t9_tok, t9_chat], LogsView())
758
 
759
- # --- TAB 10: Mario,DARE! ---
760
  with gr.Tab("Mario,DARE!"):
761
- gr.Markdown("### From sft-merger by [Martyn Garcia](https://github.com/martyn)")
762
  t10_token = gr.Textbox(label="Token", type="password")
763
  with gr.Row():
764
  t10_base = gr.Textbox(label="Base Model"); t10_ft = gr.Textbox(label="Fine-Tuned Model")
 
18
  from safetensors.torch import load_file, save_file
19
  from tqdm import tqdm
20
 
21
+ # --- Essential Imports ---
22
+ # No try/except block here. If these fail, the app should error out visibly rather than freeze.
23
  from gradio_logsview.logsview import Log, LogsView, LogsViewRunner
24
  from mergekit.config import MergeConfiguration
25
 
26
+ # --- Constants & Setup ---
27
  try:
28
  TempDir = Path("/tmp/temp_tool")
29
  os.makedirs(TempDir, exist_ok=True)
 
136
  return key
137
 
138
  # =================================================================================
139
+ # TABS 1-4 LOGIC (RESTORED)
140
  # =================================================================================
141
 
142
  class MemoryEfficientSafeOpen:
 
204
  except Exception as e: return f"Error: {e}"
205
  if struct_s:
206
  try:
207
+ for f in api.list_repo_files(repo_id=struct_s, token=hf_token):
 
208
  if sub and f.startswith(sub): continue
209
  if not sub and any(f.endswith(x) for x in ['.safetensors', '.bin', '.pt', '.pth']): continue
210
  l = hf_hub_download(repo_id=struct_s, filename=f, token=hf_token, local_dir=TempDir)
 
418
  return "Done"
419
 
420
  # =================================================================================
421
+ # MERGEKIT & LOGSVIEW (TABS 5-9)
422
  # =================================================================================
423
 
424
  def parse_weight(w_str):
 
432
  runner = LogsViewRunner()
433
  cleanup_temp()
434
 
435
+ # Empty field handling: Remove keys with empty values recursively if needed, but primarily handle chat_template
436
+ if chat_template and chat_template.strip():
437
+ config_dict["chat_template"] = chat_template.strip()
438
+
439
  try:
440
+ if program != "mergekit-moe":
441
+ MergeConfiguration.model_validate(config_dict)
442
  except Exception as e:
443
  yield runner.log(f"Invalid Config: {e}", level="ERROR")
444
  return
445
 
 
446
  if token:
447
  login(token.strip())
448
  os.environ["HF_TOKEN"] = token.strip()
 
450
  if "dtype" not in config_dict: config_dict["dtype"] = output_precision
451
  if "tokenizer_source" not in config_dict and tokenizer_source != "base":
452
  config_dict["tokenizer_source"] = tokenizer_source
 
 
 
 
453
 
454
  config_path = TempDir / "config.yaml"
455
  with open(config_path, "w") as f: yaml.dump(config_dict, f, sort_keys=False)
 
457
  yield runner.log(f"Config saved to {config_path}")
458
  yield runner.log(f"YAML:\n{yaml.dump(config_dict, sort_keys=False)}")
459
 
 
460
  try:
461
  api.create_repo(repo_id=out_repo, private=private, exist_ok=True, token=token)
462
  yield runner.log(f"Repo {out_repo} ready.")
 
464
  yield runner.log(f"Repo Error: {e}", level="ERROR")
465
  return
466
 
 
467
  out_path = TempDir / "merge_output"
 
468
  shard_arg = f"{int(float(shard_size) * 1024)}M"
469
 
470
  cmd = [
 
490
  yield runner.log("Merge failed.", level="ERROR")
491
  return
492
 
 
493
  yield runner.log(f"Uploading to {out_repo}...")
494
  yield from runner.run_python(api.upload_folder, repo_id=out_repo, folder_path=out_path)
495
  yield runner.log("Upload Complete!")
 
508
  if method in ["slerp", "nuslerp"]:
509
  if not base.strip(): yield runner.log("Error: Base model required", level="ERROR"); return
510
  config["base_model"] = base.strip()
511
+ sources = [{"model": m, "parameters": {"weight": parse_weight(w)}} for m, w in [(m1,w1), (m2,w2)] if m.strip()]
 
 
512
  config["slices"] = [{"sources": sources, "parameters": params}]
513
  else:
514
  if base.strip() and method == "multislerp": config["base_model"] = base.strip()
515
+ models = [{"model": m, "parameters": {"weight": parse_weight(w)}} for m, w in [(m1,w1), (m2,w2), (m3,w3), (m4,w4), (m5,w5)] if m.strip()]
 
 
516
  config["models"] = models
517
  config["parameters"] = params
518
 
519
  yield from run_mergekit_logic(config, token, out, priv, shard, prec, tok_src, chat_t, program="mergekit-yaml")
520
 
521
  def wrapper_stirtie(token, method, base, norm, i8, lamb, resc, topk, m1, w1, d1, g1, e1, m2, w2, d2, g2, e2, m3, w3, d3, g3, e3, m4, w4, d4, g4, e4, out, priv, shard, prec, tok_src, chat_t):
522
+ # Fix: This wrapper was causing the freeze due to mismatched arguments.
523
+ # It must handle m3 and m4 inputs correctly.
524
  models = []
525
+ # Loop over the 4 models defined in UI
526
+ for m, w, d, g, e in [
527
+ (m1, w1, d1, g1, e1),
528
+ (m2, w2, d2, g2, e2),
529
+ (m3, w3, d3, g3, e3),
530
+ (m4, w4, d4, g4, e4)
531
+ ]:
532
  if not m.strip(): continue
533
  p = {"weight": parse_weight(w)}
534
  if method in ["ties", "dare_ties", "dare_linear", "breadcrumbs_ties"]: p["density"] = parse_weight(d)
 
552
  def wrapper_specious(token, method, base, norm, i8, t, filt_w, m1, w1, f1, m2, w2, m3, w3, m4, w4, m5, w5, out, priv, shard, prec, tok_src, chat_t):
553
  models = []
554
  if method == "passthrough":
 
555
  p = {"weight": parse_weight(w1)}
556
  if f1.strip(): p["filter"] = f1.strip()
557
  models.append({"model": m1, "parameters": p})
558
  else:
559
+ models = [{"model": m, "parameters": {"weight": parse_weight(w)}} for m, w in [(m1,w1), (m2,w2), (m3,w3), (m4,w4), (m5,w5)] if m.strip()]
 
560
 
561
  config = {"merge_method": method, "parameters": {"normalize": norm, "int8_mask": i8}}
562
  if base.strip(): config["base_model"] = base.strip()
 
574
  "dtype": dtype,
575
  "experts": formatted
576
  }
577
+ # Uses mergekit-moe CLI
578
  yield from run_mergekit_logic(config, token, out, priv, shard, prec, tok_src, chat_t, program="mergekit-moe")
579
 
580
  def wrapper_rawer(token, models, method, dtype, out, priv, shard, prec, tok_src, chat_t):
581
+ models_list = [{"model": m.strip(), "parameters": {"weight": 1.0}} for m in models.split('\n') if m.strip()]
582
  config = {
583
+ "models": models_list,
584
  "merge_method": method,
585
  "dtype": dtype
586
  }
 
678
  t4_out = gr.Textbox(label="Output")
679
  gr.Button("Resize").click(task_resize, [t4_token, t4_in, t4_rank, t4_method, t4_param, t4_out], gr.Textbox(label="Result"))
680
 
681
+ # --- TAB 5 ---
682
  with gr.Tab("Amphinterpolative"):
683
  gr.Markdown("### Spherical Interpolation Family")
684
  t5_token = gr.Textbox(label="HF Token", type="password")
 
701
  t5_out = gr.Textbox(label="Output Repo"); t5_priv = gr.Checkbox(label="Private", value=True)
702
  gr.Button("Execute").click(wrapper_amphinterpolative, [t5_token, t5_method, t5_base, t5_t, t5_norm, t5_i8, t5_flat, t5_row, t5_eps, t5_iter, t5_tol, m1, w1, m2, w2, m3, w3, m4, w4, m5, w5, t5_out, t5_priv, t5_shard, t5_prec, t5_tok, t5_chat], LogsView())
703
 
704
+ # --- TAB 6 ---
705
  with gr.Tab("Stir/Tie Bases"):
706
  gr.Markdown("### Task Vector Family")
707
  t6_token = gr.Textbox(label="Token", type="password")
 
714
  m1_6, w1_6 = gr.Textbox(label="Model 1"), gr.Textbox(label="Weight 1", value="1.0"); d1_6, g1_6, e1_6 = gr.Textbox(label="Density", value="1.0"), gr.Number(label="Gamma", value=0.01), gr.Number(label="Epsilon", value=0.15)
715
  with gr.Accordion("More", open=False):
716
  m2_6, w2_6 = gr.Textbox(label="Model 2"), gr.Textbox(label="Weight 2", value="1.0"); d2_6, g2_6, e2_6 = gr.Textbox(label="Density", value="1.0"), gr.Number(label="Gamma", value=0.01), gr.Number(label="Epsilon", value=0.15)
717
+ # FIX: Added Missing UI components for models 3 & 4
718
+ m3_6, w3_6 = gr.Textbox(label="Model 3"), gr.Textbox(label="Weight 3", value="1.0"); d3_6, g3_6, e3_6 = gr.Textbox(label="Density", value="1.0"), gr.Number(label="Gamma", value=0.01), gr.Number(label="Epsilon", value=0.15)
719
+ m4_6, w4_6 = gr.Textbox(label="Model 4"), gr.Textbox(label="Weight 4", value="1.0"); d4_6, g4_6, e4_6 = gr.Textbox(label="Density", value="1.0"), gr.Number(label="Gamma", value=0.01), gr.Number(label="Epsilon", value=0.15)
720
  t6_out = gr.Textbox(label="Output Repo"); t6_priv = gr.Checkbox(label="Private", value=True)
721
+ # FIX: Included all model variables in input list
722
+ gr.Button("Execute").click(wrapper_stirtie, [t6_token, t6_method, t6_base, t6_norm, t6_i8, t6_lamb, t6_resc, t6_topk, m1_6, w1_6, d1_6, g1_6, e1_6, m2_6, w2_6, d2_6, g2_6, e2_6, m3_6, w3_6, d3_6, g3_6, e3_6, m4_6, w4_6, d4_6, g4_6, e4_6, t6_out, t6_priv, t6_shard, t6_prec, t6_tok, t6_chat], LogsView())
723
 
724
+ # --- TAB 7 ---
725
  with gr.Tab("Specious"):
726
  gr.Markdown("### Specialized Methods")
727
  t7_token = gr.Textbox(label="Token", type="password")
 
738
  t7_out = gr.Textbox(label="Output Repo"); t7_priv = gr.Checkbox(label="Private", value=True)
739
  gr.Button("Execute").click(wrapper_specious, [t7_token, t7_method, t7_base, t7_norm, t7_i8, t7_t, t7_filt_w, m1_7, w1_7, f1_7, m2_7, w2_7, m3_7, w3_7, m4_7, w4_7, m5_7, w5_7, t7_out, t7_priv, t7_shard, t7_prec, t7_tok, t7_chat], LogsView())
740
 
741
+ # --- TAB 8 (MoEr) ---
742
  with gr.Tab("MoEr"):
743
  gr.Markdown("### Mixture of Experts")
744
  t8_token = gr.Textbox(label="Token", type="password")
 
748
  t8_out = gr.Textbox(label="Output Repo"); t8_priv = gr.Checkbox(label="Private", value=True)
749
  gr.Button("Build MoE").click(wrapper_moer, [t8_token, t8_base, t8_experts, t8_gate, t8_dtype, t8_out, t8_priv, t8_shard, t8_prec, t8_tok, t8_chat], LogsView())
750
 
751
+ # --- TAB 9 (Rawer) ---
752
  with gr.Tab("Rawer"):
753
  gr.Markdown("### Raw PyTorch / Non-Transformer")
754
  t9_token = gr.Textbox(label="Token", type="password"); t9_models = gr.TextArea(label="Models (one per line)")
 
758
  t9_out = gr.Textbox(label="Output Repo"); t9_priv = gr.Checkbox(label="Private", value=True)
759
  gr.Button("Merge Raw").click(wrapper_rawer, [t9_token, t9_models, t9_method, t9_dtype, t9_out, t9_priv, t9_shard, t9_prec, t9_tok, t9_chat], LogsView())
760
 
761
+ # --- TAB 10 ---
762
  with gr.Tab("Mario,DARE!"):
 
763
  t10_token = gr.Textbox(label="Token", type="password")
764
  with gr.Row():
765
  t10_base = gr.Textbox(label="Base Model"); t10_ft = gr.Textbox(label="Fine-Tuned Model")