pliny-the-prompter commited on
Commit
f70828b
Β·
verified Β·
1 Parent(s): 4837177

Upload 129 files

Browse files
Files changed (4) hide show
  1. README.md +1 -0
  2. app.py +47 -6
  3. hf-spaces/README.md +1 -0
  4. obliteratus/cli.py +25 -1
README.md CHANGED
@@ -6,6 +6,7 @@ colorTo: gray
6
  sdk: gradio
7
  sdk_version: "5.29.0"
8
  app_file: app.py
 
9
  pinned: true
10
  license: agpl-3.0
11
  tags:
 
6
  sdk: gradio
7
  sdk_version: "5.29.0"
8
  app_file: app.py
9
+ persistent_storage: true
10
  pinned: true
11
  license: agpl-3.0
12
  tags:
app.py CHANGED
@@ -106,6 +106,9 @@ _session_models: dict[str, dict] = {}
106
  # Legacy alias β€” some internal code may still reference _bench_configs
107
  _bench_configs = _session_models
108
 
 
 
 
109
  # Counter for unique obliteration save directories
110
  _obliterate_counter: int = 0
111
 
@@ -1564,9 +1567,11 @@ def obliterate(model_choice: str, method_choice: str, hub_repo: str,
1564
  pass # Telemetry is best-effort
1565
 
1566
  # ── Session cache: register this obliteration for Chat tab switching ──
 
1567
  _ts = datetime.now().strftime("%H:%M")
1568
  _short_model = model_id.split("/")[-1] if "/" in model_id else model_id
1569
  _cache_label = f"{method} on {_short_model} ({_ts})"
 
1570
  _session_models[_cache_label] = {
1571
  "model_id": model_id,
1572
  "model_choice": model_choice,
@@ -1792,6 +1797,16 @@ def chat_respond(message: str, history: list[dict], system_prompt: str,
1792
  yield "No model loaded yet. Go to the **Obliterate** tab first and liberate a model."
1793
  return
1794
 
 
 
 
 
 
 
 
 
 
 
1795
  # Sanitize inputs to prevent resource exhaustion
1796
  system_prompt = (system_prompt or "")[:4096]
1797
  message = (message or "")[:8192]
@@ -1916,8 +1931,8 @@ def load_bench_into_chat(choice: str, progress=gr.Progress()):
1916
 
1917
  On ZeroGPU, uses the visitor's GPU quota.
1918
  """
1919
- if choice not in _bench_configs:
1920
- yield "**Error:** No benchmark result selected.", ""
1921
  return
1922
 
1923
  cfg = _bench_configs[choice]
@@ -1925,6 +1940,18 @@ def load_bench_into_chat(choice: str, progress=gr.Progress()):
1925
  method_key = cfg["method"]
1926
  checkpoint_dir = cfg.get("output_dir")
1927
 
 
 
 
 
 
 
 
 
 
 
 
 
1928
  with _lock:
1929
  if _state["status"] == "obliterating":
1930
  yield "**Error:** An obliteration is already in progress.", ""
@@ -2105,6 +2132,14 @@ def ab_chat_respond(message: str, history_left: list[dict], history_right: list[
2105
  "#### Abliterated")
2106
  return
2107
 
 
 
 
 
 
 
 
 
2108
  # Build header strings showing model name on each side
2109
  header_left = f"#### Original (Pre-Abliteration)\n`{model_name}`"
2110
  header_right = f"#### Abliterated\n`{model_name}`"
@@ -2254,9 +2289,12 @@ def ab_chat_respond(message: str, history_left: list[dict], history_right: list[
2254
  except Exception as e:
2255
  original_response = f"*Could not load original model for comparison: {e}*"
2256
 
2257
- # Restore abliterated model to GPU for subsequent chat/operations
 
 
2258
  try:
2259
- abliterated_model.to(abl_device)
 
2260
  except Exception:
2261
  pass # If GPU restore fails, model stays on CPU (still usable)
2262
 
@@ -2747,7 +2785,7 @@ button.tab-nav.selected {
2747
 
2748
  /* ---- CARD-STYLE BLOCKS ---- */
2749
  .gr-panel, .gr-box, .gr-form, .gr-group,
2750
- div.block { position: relative; }
2751
  div.block::before {
2752
  content: '';
2753
  position: absolute;
@@ -3903,7 +3941,10 @@ Built on the shoulders of:
3903
  custom_harmful_tb, custom_harmless_tb] + _adv_controls,
3904
  outputs=[status_md, log_box, chat_status],
3905
  ).then(
3906
- fn=lambda: (gr.update(choices=_get_session_model_choices()), _get_vram_html()),
 
 
 
3907
  outputs=[session_model_dd, vram_display],
3908
  )
3909
 
 
106
  # Legacy alias β€” some internal code may still reference _bench_configs
107
  _bench_configs = _session_models
108
 
109
+ # Label of the most recently obliterated model (for auto-selecting in Chat tab dropdown)
110
+ _last_obliterated_label: str = ""
111
+
112
  # Counter for unique obliteration save directories
113
  _obliterate_counter: int = 0
114
 
 
1567
  pass # Telemetry is best-effort
1568
 
1569
  # ── Session cache: register this obliteration for Chat tab switching ──
1570
+ global _last_obliterated_label
1571
  _ts = datetime.now().strftime("%H:%M")
1572
  _short_model = model_id.split("/")[-1] if "/" in model_id else model_id
1573
  _cache_label = f"{method} on {_short_model} ({_ts})"
1574
+ _last_obliterated_label = _cache_label
1575
  _session_models[_cache_label] = {
1576
  "model_id": model_id,
1577
  "model_choice": model_choice,
 
1797
  yield "No model loaded yet. Go to the **Obliterate** tab first and liberate a model."
1798
  return
1799
 
1800
+ # ZeroGPU safety: ensure model is on GPU if available.
1801
+ # Between GPU allocations, ZeroGPU may have moved the model to CPU/meta.
1802
+ # The @spaces.GPU decorator guarantees a GPU is available here, so move if needed.
1803
+ try:
1804
+ dev = next(model.parameters()).device
1805
+ if torch.cuda.is_available() and dev.type != "cuda":
1806
+ model.to("cuda")
1807
+ except (StopIteration, RuntimeError):
1808
+ pass
1809
+
1810
  # Sanitize inputs to prevent resource exhaustion
1811
  system_prompt = (system_prompt or "")[:4096]
1812
  message = (message or "")[:8192]
 
1931
 
1932
  On ZeroGPU, uses the visitor's GPU quota.
1933
  """
1934
+ if not choice or choice not in _bench_configs:
1935
+ yield "**Error:** No benchmark result selected. Pick a model from the dropdown first.", ""
1936
  return
1937
 
1938
  cfg = _bench_configs[choice]
 
1940
  method_key = cfg["method"]
1941
  checkpoint_dir = cfg.get("output_dir")
1942
 
1943
+ # If this model is already the active one, skip the destructive reload
1944
+ with _lock:
1945
+ if (_state["status"] == "ready"
1946
+ and _state["model"] is not None
1947
+ and _state["model_name"] == cfg.get("model_choice", "")
1948
+ and _state["method"] == method_key):
1949
+ yield (
1950
+ f"**Already loaded!** `{choice}` is ready β€” just type in the chat below.",
1951
+ get_chat_header(),
1952
+ )
1953
+ return
1954
+
1955
  with _lock:
1956
  if _state["status"] == "obliterating":
1957
  yield "**Error:** An obliteration is already in progress.", ""
 
2132
  "#### Abliterated")
2133
  return
2134
 
2135
+ # ZeroGPU safety: ensure model is on GPU if available
2136
+ try:
2137
+ dev = next(abliterated_model.parameters()).device
2138
+ if torch.cuda.is_available() and dev.type != "cuda":
2139
+ abliterated_model.to("cuda")
2140
+ except (StopIteration, RuntimeError):
2141
+ pass
2142
+
2143
  # Build header strings showing model name on each side
2144
  header_left = f"#### Original (Pre-Abliteration)\n`{model_name}`"
2145
  header_right = f"#### Abliterated\n`{model_name}`"
 
2289
  except Exception as e:
2290
  original_response = f"*Could not load original model for comparison: {e}*"
2291
 
2292
+ # Restore abliterated model to GPU for subsequent chat/operations.
2293
+ # Use torch.device("cuda") rather than the captured abl_device, since
2294
+ # on ZeroGPU the original device reference may point to a stale context.
2295
  try:
2296
+ restore_device = torch.device("cuda") if torch.cuda.is_available() else abl_device
2297
+ abliterated_model.to(restore_device)
2298
  except Exception:
2299
  pass # If GPU restore fails, model stays on CPU (still usable)
2300
 
 
2785
 
2786
  /* ---- CARD-STYLE BLOCKS ---- */
2787
  .gr-panel, .gr-box, .gr-form, .gr-group,
2788
+ div.block { position: relative; padding-left: 10px !important; }
2789
  div.block::before {
2790
  content: '';
2791
  position: absolute;
 
3941
  custom_harmful_tb, custom_harmless_tb] + _adv_controls,
3942
  outputs=[status_md, log_box, chat_status],
3943
  ).then(
3944
+ fn=lambda: (
3945
+ gr.update(choices=_get_session_model_choices(), value=_last_obliterated_label or None),
3946
+ _get_vram_html(),
3947
+ ),
3948
  outputs=[session_model_dd, vram_display],
3949
  )
3950
 
hf-spaces/README.md CHANGED
@@ -7,6 +7,7 @@ sdk: gradio
7
  sdk_version: "5.29.0"
8
  app_file: app.py
9
  hardware: zero-a10g
 
10
  pinned: true
11
  license: agpl-3.0
12
  tags:
 
7
  sdk_version: "5.29.0"
8
  app_file: app.py
9
  hardware: zero-a10g
10
+ persistent_storage: true
11
  pinned: true
12
  license: agpl-3.0
13
  tags:
obliteratus/cli.py CHANGED
@@ -448,12 +448,36 @@ def _cmd_abliterate(args):
448
  live.update(make_display())
449
  raise
450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  console.print()
 
 
 
452
  console.print(
453
  Panel(
454
  f"[bold green]Abliteration complete![/]\n\n"
455
  f" Model saved to: [cyan]{result_path}[/]\n"
456
- f" Metadata: [cyan]{result_path}/abliteration_metadata.json[/]\n\n"
 
457
  f" [dim]Load with:[/] AutoModelForCausalLM.from_pretrained('{result_path}')",
458
  border_style="green",
459
  title="[bold green]βœ“ REBIRTH COMPLETE[/]",
 
448
  live.update(make_display())
449
  raise
450
 
451
+ # ── Telemetry: send pipeline report to community leaderboard ──
452
+ try:
453
+ from obliteratus.telemetry import maybe_send_pipeline_report
454
+ maybe_send_pipeline_report(pipeline)
455
+ except Exception:
456
+ pass # Telemetry is best-effort
457
+
458
+ # ── Community contribution (--contribute flag) ──
459
+ contrib_path = None
460
+ if getattr(args, "contribute", False):
461
+ try:
462
+ from obliteratus.community import save_contribution
463
+ contrib_path = save_contribution(
464
+ pipeline,
465
+ model_name=model_name,
466
+ notes=getattr(args, "contribute_notes", ""),
467
+ )
468
+ except Exception as e:
469
+ console.print(f"[yellow]Could not save contribution: {e}[/yellow]")
470
+
471
  console.print()
472
+ contrib_line = ""
473
+ if contrib_path:
474
+ contrib_line = f"\n Contribution: [cyan]{contrib_path}[/]"
475
  console.print(
476
  Panel(
477
  f"[bold green]Abliteration complete![/]\n\n"
478
  f" Model saved to: [cyan]{result_path}[/]\n"
479
+ f" Metadata: [cyan]{result_path}/abliteration_metadata.json[/]"
480
+ f"{contrib_line}\n\n"
481
  f" [dim]Load with:[/] AutoModelForCausalLM.from_pretrained('{result_path}')",
482
  border_style="green",
483
  title="[bold green]βœ“ REBIRTH COMPLETE[/]",