Qwen3.8-27B-MTP-GGUF / bench /bench_nachmessen.py
Davidmg0815's picture
Upload bench/bench_nachmessen.py with huggingface_hub
b6b0652 verified
Raw
History Blame Contribute Delete
5.02 kB
#!/usr/bin/env python3
"""Misst nur die Aufgaben nach, die im Hauptlauf ins Token-Limit gelaufen sind.
Hintergrund: der Mathe-Durchgang lief mit 1600 Token Budget. Bei den leichten
Aufgaben reicht das dreifach (Median 681), bei Stufe 5 wurde fast die Haelfte
mitten im Rechenweg abgeschnitten und als falsch gezaehlt. Damit misst die
Quote zu einem Drittel das Budget statt das Modell.
Statt alles neu zu rechnen werden nur die abgeschnittenen Aufgaben wiederholt,
mit grosszuegigem Budget. Das kostet rund 25 Minuten je Modell statt drei
Stunden. Das Ergebnis wird als eigene Datei abgelegt und die urspruengliche
NICHT ueberschrieben — beide Zahlen sollen nachvollziehbar bleiben.
"""
import argparse
import json
import os
import sys
import time
sys.path.insert(0, "/mnt/models/qwen38-prep")
import bench_mathe as M
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--port", type=int, default=8291)
ap.add_argument("--quelle", required=True,
help="JSON des Hauptlaufs, z.B. mathe-math500/q38-q8.json")
ap.add_argument("--out", required=True)
ap.add_argument("--satz", default="math500")
ap.add_argument("--max-tokens", type=int, default=8000)
ap.add_argument("--timeout", type=int, default=1800)
ap.add_argument("--reasoning", action="store_true")
args = ap.parse_args()
M.REASONING = args.reasoning
alt = json.load(open(args.quelle))
offen = [x for x in alt["aufgaben"] if x.get("abbruch") == "length"]
if not offen:
print(f"{alt['modell']}: nichts abgeschnitten, nichts nachzumessen",
file=sys.stderr)
json.dump(alt, open(args.out, "w"), ensure_ascii=False, indent=1)
return 0
# Die Aufgabentexte stehen nicht im Bericht, nur die IDs — also den
# Datensatz erneut laden und ueber die ID zuordnen.
alle = M.lade(args.satz, 0)
nach_id = {}
for a in alle:
nach_id[str(a.get("unique_id", ""))] = a
# Der Hauptlauf hat nur eine Teilmenge gezogen; ueber dieselbe Regel
# rekonstruieren, damit die Zuordnung stimmt.
teil = M.lade(args.satz, alt["n"])
for i, a in enumerate(teil, 1):
nach_id.setdefault(str(i), a)
print(f"{alt['modell']}: {len(offen)} abgeschnittene Aufgaben, "
f"neues Budget {args.max_tokens} Token", file=sys.stderr)
neu = {}
t0 = time.time()
for i, x in enumerate(offen, 1):
a = nach_id.get(x["id"])
if a is None:
print(f" [{i}/{len(offen)}] {x['id']}: nicht zuzuordnen",
file=sys.stderr)
continue
erwartet = a.get("answer") if args.satz.startswith("math") \
else M.hole_gsm(a.get("answer", ""))
txt, m, fehler = M.frage(args.port, M.bau_prompt(args.satz, a),
args.max_tokens, args.timeout)
if fehler:
print(f" [{i}/{len(offen)}] {x['id']}: FEHLER {fehler[:40]}",
file=sys.stderr)
continue
gegeben = M.hole_boxed(txt) if args.satz.startswith("math") \
else M.hole_gsm(txt)
ok = M.stimmt(gegeben, erwartet)
neu[x["id"]] = dict(ok=ok, gegeben=(gegeben or "")[:60],
erwartet=str(erwartet)[:60], **m)
print(f" [{i}/{len(offen)}] {x['id']}: "
f"{'OK' if ok else 'falsch'} {m['tokens']} Token"
f"{' ERNEUT AM LIMIT' if m.get('abbruch') == 'length' else ''}",
file=sys.stderr)
# Bericht zusammensetzen: alte Aufgaben, die nachgemessenen ersetzt.
zusammen = []
for x in alt["aufgaben"]:
if x["id"] in neu:
y = dict(x)
y.update(neu[x["id"]])
y["nachgemessen"] = True
zusammen.append(y)
else:
zusammen.append(x)
ok_n = sum(1 for x in zusammen if x["ok"])
nach_level = {}
for x in zusammen:
lv = x.get("level")
if lv is not None:
d = nach_level.setdefault(str(lv), [0, 0])
d[1] += 1
d[0] += 1 if x["ok"] else 0
bericht = dict(alt)
bericht.update(
bestanden=ok_n,
quote=round(ok_n / len(zusammen) * 100, 1),
nach_level={k: v for k, v in sorted(nach_level.items())},
am_limit=sum(1 for x in zusammen if x.get("abbruch") == "length"),
nachgemessen=len(neu),
nachmess_budget=args.max_tokens,
quote_vorher=alt["quote"],
dauer_nachmessung_s=round(time.time() - t0, 1),
aufgaben=zusammen)
json.dump(bericht, open(args.out, "w"), ensure_ascii=False, indent=1)
print(f"\n{alt['modell']}: {alt['quote']}% -> {bericht['quote']}% "
f"({len(neu)} nachgemessen, {bericht['am_limit']} weiterhin am Limit)"
f" | {(time.time()-t0)/60:.1f} min", file=sys.stderr)
lv = " ".join(f"L{k}: {v[0]}/{v[1]}" for k, v in bericht["nach_level"].items())
print(f" nach Schwierigkeit: {lv}", file=sys.stderr)
return 0
if __name__ == "__main__":
sys.exit(main())