Series A: local Qwen on the MacBook (remote server), 12 h window with hard stop, clean pause on server loss, dashboard card, docs/remote-model.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -243,6 +243,65 @@ def agg_table(title, evs, rows, key, note=""):
|
||||
% (E(title), E(key.replace("_", " ")), trs, "<div class=note>%s</div>" % E(note) if note else ""))
|
||||
|
||||
|
||||
def local_card():
|
||||
"""Card for series A (local Qwen on the MacBook): state.json of harness.localqwen. Empty string without a series."""
|
||||
path = os.path.join(ROOT, "runs", "local_qwen", "state.json")
|
||||
if not os.path.exists(path):
|
||||
return ""
|
||||
try:
|
||||
st = json.load(open(path))
|
||||
except ValueError:
|
||||
return ""
|
||||
now = time.time()
|
||||
url = st.get("base_url") or ""
|
||||
up = ping(url + "/models", timeout=4) if url else False # the dashboard asks the MacBook itself
|
||||
status = st.get("status", "?")
|
||||
left = st.get("window_start", now) + st.get("window_hours", 12) * 3600 - now
|
||||
cur = st.get("current")
|
||||
plan, res = st.get("plan", []), st.get("results", [])
|
||||
chips = "<span class='chip %s'>server %s</span> <span class='chip %s'>%s</span>" % (
|
||||
"ok" if up else "er", "answers" if up else "does not answer",
|
||||
{"running": "ok", "paused": "wa", "finished": "gr", "window_over": "gr"}.get(status, "gr"), E(status))
|
||||
rows = ""
|
||||
per = {}
|
||||
for r in res:
|
||||
k = per.setdefault(r["kind"], {"runs": 0, "ok": 0, "scores": [], "fail": {}})
|
||||
k["runs"] += 1
|
||||
k["ok"] += r["accepted"]
|
||||
if r.get("score") is not None:
|
||||
k["scores"].append(r["score"])
|
||||
for f in r.get("failure_types", []):
|
||||
k["fail"][f] = k["fail"].get(f, 0) + 1
|
||||
planned = {}
|
||||
for p_ in plan:
|
||||
planned[p_["kind"]] = planned.get(p_["kind"], 0) + 1
|
||||
for kind in [x for x in ("INTF", "TABL", "STRU", "MSAG", "EXC", "DDLS") if x in planned or x in per]:
|
||||
k = per.get(kind, {"runs": 0, "ok": 0, "scores": [], "fail": {}})
|
||||
mean = "%.0f" % (sum(k["scores"]) / len(k["scores"])) if k["scores"] else "-"
|
||||
rate = "%.0f%%" % (100.0 * k["ok"] / k["runs"]) if k["runs"] else "-"
|
||||
fails = ", ".join("%s %d" % (f, n) for f, n in sorted(k["fail"].items(), key=lambda x: -x[1])) or "-"
|
||||
rows += ("<tr><td>%s</td><td class=n>%d/%d</td><td class=n>%d</td><td class=n>%s</td><td class=n>%s</td><td>%s</td></tr>"
|
||||
% (kind, k["runs"], planned.get(kind, 0), k["ok"], rate, mean, E(fails)))
|
||||
if cur:
|
||||
elapsed = (now - cur["start"]) / 60
|
||||
curtxt = "%s (%s, %s), run %d min%s" % (cur["task"], cur["kind"], cur["category"], elapsed,
|
||||
", restart %d" % cur["restarts"] if cur.get("restarts") else "")
|
||||
else:
|
||||
curtxt = "none (%s)" % status
|
||||
evs = "".join("<div class=note>%s %s %s: %s</div>" % (time.strftime("%H:%M", time.localtime(e["t"])), E(e["kind"]),
|
||||
E(e["task"]), E(e["text"])) for e in st.get("events", [])[-3:])
|
||||
hdr = ("<div class=card style='grid-column:1/-1'><h2>Series A: local Qwen 3.8 27B on the MacBook (thinking off, 16384 tokens, loop guard 3, budget 60)</h2>"
|
||||
"<div class=b>%s model <span class=mono>%s</span></div>"
|
||||
"<div class=b><table><tr><td>Current task</td><td>%s</td><td>Done / planned</td><td class=n>%d / %d</td>"
|
||||
"<td>Time left in the window</td><td class=n>%s</td><td>Paused</td><td class=n>%.0f min</td></tr></table></div>"
|
||||
% (chips, E(os.path.basename(str(st.get("model_id", "")))), E(curtxt), len(res), len(plan),
|
||||
("%dh %02dm" % (left // 3600, (left % 3600) // 60)) if left > 0 else "over", st.get("paused_seconds", 0) / 60))
|
||||
tbl = ("<div class=b><table><tr><th>kind</th><th class=n>runs/planned</th><th class=n>accepted</th><th class=n>pass rate</th>"
|
||||
"<th class=n>mean score</th><th>failure types</th></tr>%s</table></div>%s"
|
||||
"<div class=note>Accepted trajectories of this series are kept apart (runs/local_qwen/accepted.jsonl), not for the first SFT.</div></div>" % (rows, evs))
|
||||
return hdr + tbl
|
||||
|
||||
|
||||
def mix_table(rows, evs):
|
||||
kt = mix.accepted_task_counts()
|
||||
kr = {}
|
||||
@@ -376,7 +435,7 @@ def render(d):
|
||||
% ("ok" if d["a4h"] else "er", "up" if d["a4h"] else "down", "ok" if d["mcp"] else "er", "up" if d["mcp"] else "down", scls, status,
|
||||
E("\n".join(d["procs"]))))
|
||||
logc = "<div class=card><h2>Pipeline log</h2><div class=b><div class='log mono'>%s</div></div></div>" % E("\n".join(d["log_tail"]))
|
||||
body = (banner + "<div class=tiles>" + tiles + "</div><div class=grid>" + budget + prog + stops + sysc
|
||||
body = (banner + "<div class=tiles>" + tiles + "</div><div class=grid>" + local_card() + budget + prog + stops + sysc
|
||||
+ mix_table(rows, evs) + agg_table("Trajectories by category", evs, rows, "category") + agg_table("Trajectories by object type", evs, rows, "object_type")
|
||||
+ gen_table(logs, "category", "Task generation by category") + gen_table(logs, "object_type", "Task generation by object type")
|
||||
+ tok + recent + logc + "</div>")
|
||||
|
||||
Reference in New Issue
Block a user