Spaces:
Running on Zero
Running on Zero
Upload 133 files
Browse files
app.py
CHANGED
|
@@ -19,6 +19,7 @@ from __future__ import annotations
|
|
| 19 |
|
| 20 |
import gc
|
| 21 |
import json as _json
|
|
|
|
| 22 |
import os
|
| 23 |
import re
|
| 24 |
import time
|
|
@@ -26,6 +27,8 @@ import threading
|
|
| 26 |
from datetime import datetime
|
| 27 |
from pathlib import Path
|
| 28 |
|
|
|
|
|
|
|
| 29 |
# ββ Container environment fixes ββββββββββββββββββββββββββββββββββββββ
|
| 30 |
# PyTorch 2.6+ calls getpass.getuser() to build a cache dir, which fails
|
| 31 |
# in containers running as a UID with no /etc/passwd entry (e.g. UID 1000
|
|
@@ -1334,8 +1337,8 @@ def benchmark(
|
|
| 1334 |
n_prompts=actual_n,
|
| 1335 |
quantization=quantization,
|
| 1336 |
)
|
| 1337 |
-
except Exception:
|
| 1338 |
-
|
| 1339 |
|
| 1340 |
# Store config so user can load this result into the Chat tab.
|
| 1341 |
# Keep the checkpoint on disk so loading doesn't require re-training.
|
|
@@ -1686,8 +1689,8 @@ def benchmark_multi_model(
|
|
| 1686 |
n_prompts=actual_n,
|
| 1687 |
quantization=quantization,
|
| 1688 |
)
|
| 1689 |
-
except Exception:
|
| 1690 |
-
|
| 1691 |
|
| 1692 |
# Store config so user can load this result into the Chat tab.
|
| 1693 |
# Keep the checkpoint on disk so loading doesn't require re-training.
|
|
@@ -2087,11 +2090,11 @@ def obliterate(model_choice: str, method_choice: str,
|
|
| 2087 |
|
| 2088 |
# Handle error
|
| 2089 |
if error_ref[0] is not None:
|
| 2090 |
-
with _lock:
|
| 2091 |
-
_state["status"] = "idle"
|
| 2092 |
err_msg = str(error_ref[0]) or repr(error_ref[0])
|
| 2093 |
log_lines.append(f"\nERROR: {err_msg}")
|
| 2094 |
-
|
|
|
|
|
|
|
| 2095 |
yield f"**Error:** {err_msg}", "\n".join(log_lines), get_chat_header(), gr.update(), gr.update(), gr.update()
|
| 2096 |
return
|
| 2097 |
|
|
@@ -2099,6 +2102,20 @@ def obliterate(model_choice: str, method_choice: str,
|
|
| 2099 |
# Wrapped in try/except to ensure status is never stuck on "obliterating".
|
| 2100 |
try:
|
| 2101 |
pipeline = pipeline_ref[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2102 |
can_generate = pipeline._quality_metrics.get("coherence") is not None
|
| 2103 |
|
| 2104 |
# ββ Telemetry: log single obliteration to community leaderboard ββ
|
|
@@ -2132,8 +2149,8 @@ def obliterate(model_choice: str, method_choice: str,
|
|
| 2132 |
quantization=quantization,
|
| 2133 |
)
|
| 2134 |
maybe_send_pipeline_report(pipeline)
|
| 2135 |
-
except Exception:
|
| 2136 |
-
|
| 2137 |
|
| 2138 |
# ββ Session cache: register this obliteration for Chat tab switching ββ
|
| 2139 |
global _last_obliterated_label
|
|
@@ -2298,7 +2315,8 @@ def obliterate(model_choice: str, method_choice: str,
|
|
| 2298 |
log_lines.append(f"LIBERATION COMPLETE in {_elapsed()} \u2014 model saved!")
|
| 2299 |
log_lines.append("=" * 50)
|
| 2300 |
|
| 2301 |
-
|
|
|
|
| 2302 |
if can_generate:
|
| 2303 |
status_msg = f"**{model_choice}** liberated with `{method}` in {_elapsed()}. Head to the **Chat** tab."
|
| 2304 |
else:
|
|
@@ -2324,11 +2342,11 @@ def obliterate(model_choice: str, method_choice: str,
|
|
| 2324 |
|
| 2325 |
except Exception as e:
|
| 2326 |
# Ensure status never gets stuck on "obliterating"
|
| 2327 |
-
with _lock:
|
| 2328 |
-
_state["status"] = "idle"
|
| 2329 |
err_msg = str(e) or repr(e)
|
| 2330 |
log_lines.append(f"\nERROR (post-pipeline): {err_msg}")
|
| 2331 |
-
|
|
|
|
|
|
|
| 2332 |
yield f"**Error:** {err_msg}", "\n".join(log_lines), get_chat_header(), gr.update(), gr.update(), gr.update()
|
| 2333 |
|
| 2334 |
|
|
@@ -3473,8 +3491,8 @@ def run_tourney(model_choice, selected_methods, dataset, quantization):
|
|
| 3473 |
dataset=dataset_key,
|
| 3474 |
quantization=quant,
|
| 3475 |
)
|
| 3476 |
-
except Exception:
|
| 3477 |
-
|
| 3478 |
|
| 3479 |
if winner:
|
| 3480 |
bracket_md = render_bracket_html(result)
|
|
@@ -3988,8 +4006,38 @@ input[type="range"] { accent-color: #00ff41 !important; }
|
|
| 3988 |
|
| 3989 |
_JS = """
|
| 3990 |
() => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3991 |
// Auto-scroll log box to bottom when content changes,
|
| 3992 |
-
//
|
|
|
|
| 3993 |
const observer = new MutationObserver(() => {
|
| 3994 |
document.querySelectorAll('.log-box textarea').forEach(el => {
|
| 3995 |
el.scrollTop = el.scrollHeight;
|
|
@@ -4000,6 +4048,16 @@ _JS = """
|
|
| 4000 |
el.style.borderColor = '#00ff41';
|
| 4001 |
el.style.boxShadow = 'none';
|
| 4002 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4003 |
});
|
| 4004 |
});
|
| 4005 |
setTimeout(() => {
|
|
|
|
| 19 |
|
| 20 |
import gc
|
| 21 |
import json as _json
|
| 22 |
+
import logging
|
| 23 |
import os
|
| 24 |
import re
|
| 25 |
import time
|
|
|
|
| 27 |
from datetime import datetime
|
| 28 |
from pathlib import Path
|
| 29 |
|
| 30 |
+
logger = logging.getLogger(__name__)
|
| 31 |
+
|
| 32 |
# ββ Container environment fixes ββββββββββββββββββββββββββββββββββββββ
|
| 33 |
# PyTorch 2.6+ calls getpass.getuser() to build a cache dir, which fails
|
| 34 |
# in containers running as a UID with no /etc/passwd entry (e.g. UID 1000
|
|
|
|
| 1337 |
n_prompts=actual_n,
|
| 1338 |
quantization=quantization,
|
| 1339 |
)
|
| 1340 |
+
except Exception as _tel_err:
|
| 1341 |
+
logger.debug("Telemetry logging failed (best-effort): %s", _tel_err)
|
| 1342 |
|
| 1343 |
# Store config so user can load this result into the Chat tab.
|
| 1344 |
# Keep the checkpoint on disk so loading doesn't require re-training.
|
|
|
|
| 1689 |
n_prompts=actual_n,
|
| 1690 |
quantization=quantization,
|
| 1691 |
)
|
| 1692 |
+
except Exception as _tel_err:
|
| 1693 |
+
logger.debug("Telemetry logging failed (best-effort): %s", _tel_err)
|
| 1694 |
|
| 1695 |
# Store config so user can load this result into the Chat tab.
|
| 1696 |
# Keep the checkpoint on disk so loading doesn't require re-training.
|
|
|
|
| 2090 |
|
| 2091 |
# Handle error
|
| 2092 |
if error_ref[0] is not None:
|
|
|
|
|
|
|
| 2093 |
err_msg = str(error_ref[0]) or repr(error_ref[0])
|
| 2094 |
log_lines.append(f"\nERROR: {err_msg}")
|
| 2095 |
+
with _lock:
|
| 2096 |
+
_state["status"] = "idle"
|
| 2097 |
+
_state["log"] = log_lines
|
| 2098 |
yield f"**Error:** {err_msg}", "\n".join(log_lines), get_chat_header(), gr.update(), gr.update(), gr.update()
|
| 2099 |
return
|
| 2100 |
|
|
|
|
| 2102 |
# Wrapped in try/except to ensure status is never stuck on "obliterating".
|
| 2103 |
try:
|
| 2104 |
pipeline = pipeline_ref[0]
|
| 2105 |
+
if pipeline is None:
|
| 2106 |
+
# Worker thread completed without error but pipeline was never assigned
|
| 2107 |
+
# (e.g. import failure caught internally, or early return in worker).
|
| 2108 |
+
with _lock:
|
| 2109 |
+
_state["status"] = "idle"
|
| 2110 |
+
log_lines.append("\nERROR: Pipeline completed but produced no result.")
|
| 2111 |
+
with _lock:
|
| 2112 |
+
_state["log"] = log_lines
|
| 2113 |
+
yield (
|
| 2114 |
+
"**Error:** Obliteration finished but no pipeline was produced. "
|
| 2115 |
+
"Check the log for details β this may indicate an import or configuration issue.",
|
| 2116 |
+
"\n".join(log_lines), get_chat_header(), gr.update(), gr.update(), gr.update(),
|
| 2117 |
+
)
|
| 2118 |
+
return
|
| 2119 |
can_generate = pipeline._quality_metrics.get("coherence") is not None
|
| 2120 |
|
| 2121 |
# ββ Telemetry: log single obliteration to community leaderboard ββ
|
|
|
|
| 2149 |
quantization=quantization,
|
| 2150 |
)
|
| 2151 |
maybe_send_pipeline_report(pipeline)
|
| 2152 |
+
except Exception as _tel_err:
|
| 2153 |
+
logger.debug("Telemetry logging failed (best-effort): %s", _tel_err)
|
| 2154 |
|
| 2155 |
# ββ Session cache: register this obliteration for Chat tab switching ββ
|
| 2156 |
global _last_obliterated_label
|
|
|
|
| 2315 |
log_lines.append(f"LIBERATION COMPLETE in {_elapsed()} \u2014 model saved!")
|
| 2316 |
log_lines.append("=" * 50)
|
| 2317 |
|
| 2318 |
+
with _lock:
|
| 2319 |
+
_state["log"] = log_lines
|
| 2320 |
if can_generate:
|
| 2321 |
status_msg = f"**{model_choice}** liberated with `{method}` in {_elapsed()}. Head to the **Chat** tab."
|
| 2322 |
else:
|
|
|
|
| 2342 |
|
| 2343 |
except Exception as e:
|
| 2344 |
# Ensure status never gets stuck on "obliterating"
|
|
|
|
|
|
|
| 2345 |
err_msg = str(e) or repr(e)
|
| 2346 |
log_lines.append(f"\nERROR (post-pipeline): {err_msg}")
|
| 2347 |
+
with _lock:
|
| 2348 |
+
_state["status"] = "idle"
|
| 2349 |
+
_state["log"] = log_lines
|
| 2350 |
yield f"**Error:** {err_msg}", "\n".join(log_lines), get_chat_header(), gr.update(), gr.update(), gr.update()
|
| 2351 |
|
| 2352 |
|
|
|
|
| 3491 |
dataset=dataset_key,
|
| 3492 |
quantization=quant,
|
| 3493 |
)
|
| 3494 |
+
except Exception as _tel_err:
|
| 3495 |
+
logger.debug("Telemetry logging failed (best-effort): %s", _tel_err)
|
| 3496 |
|
| 3497 |
if winner:
|
| 3498 |
bracket_md = render_bracket_html(result)
|
|
|
|
| 4006 |
|
| 4007 |
_JS = """
|
| 4008 |
() => {
|
| 4009 |
+
// ββ Audible ping on completion ββββββββββββββββββββββββββββββββββ
|
| 4010 |
+
// Synthesize a short "ping" using Web Audio API β no audio files needed.
|
| 4011 |
+
let _audioCtx = null;
|
| 4012 |
+
function _playPing() {
|
| 4013 |
+
try {
|
| 4014 |
+
if (!_audioCtx) _audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
| 4015 |
+
const osc = _audioCtx.createOscillator();
|
| 4016 |
+
const gain = _audioCtx.createGain();
|
| 4017 |
+
osc.connect(gain);
|
| 4018 |
+
gain.connect(_audioCtx.destination);
|
| 4019 |
+
osc.type = 'sine';
|
| 4020 |
+
osc.frequency.setValueAtTime(880, _audioCtx.currentTime); // A5
|
| 4021 |
+
osc.frequency.setValueAtTime(1320, _audioCtx.currentTime + 0.08); // E6
|
| 4022 |
+
gain.gain.setValueAtTime(0.3, _audioCtx.currentTime);
|
| 4023 |
+
gain.gain.exponentialRampToValueAtTime(0.001, _audioCtx.currentTime + 0.4);
|
| 4024 |
+
osc.start(_audioCtx.currentTime);
|
| 4025 |
+
osc.stop(_audioCtx.currentTime + 0.4);
|
| 4026 |
+
} catch(e) { /* Audio not available */ }
|
| 4027 |
+
}
|
| 4028 |
+
|
| 4029 |
+
// Track which completion messages we've already pinged for
|
| 4030 |
+
const _pingedMessages = new Set();
|
| 4031 |
+
const _completionPatterns = [
|
| 4032 |
+
'LIBERATION COMPLETE',
|
| 4033 |
+
'BENCHMARK COMPLETE',
|
| 4034 |
+
'Champion:',
|
| 4035 |
+
'Tournament complete',
|
| 4036 |
+
];
|
| 4037 |
+
|
| 4038 |
// Auto-scroll log box to bottom when content changes,
|
| 4039 |
+
// flash the log border red if an ERROR appears,
|
| 4040 |
+
// and play a ping on completion events
|
| 4041 |
const observer = new MutationObserver(() => {
|
| 4042 |
document.querySelectorAll('.log-box textarea').forEach(el => {
|
| 4043 |
el.scrollTop = el.scrollHeight;
|
|
|
|
| 4048 |
el.style.borderColor = '#00ff41';
|
| 4049 |
el.style.boxShadow = 'none';
|
| 4050 |
}
|
| 4051 |
+
// Check for completion patterns and ping once per unique message
|
| 4052 |
+
if (el.value) {
|
| 4053 |
+
for (const pattern of _completionPatterns) {
|
| 4054 |
+
if (el.value.includes(pattern) && !_pingedMessages.has(pattern + el.value.length)) {
|
| 4055 |
+
_pingedMessages.add(pattern + el.value.length);
|
| 4056 |
+
_playPing();
|
| 4057 |
+
break;
|
| 4058 |
+
}
|
| 4059 |
+
}
|
| 4060 |
+
}
|
| 4061 |
});
|
| 4062 |
});
|
| 4063 |
setTimeout(() => {
|