radar: Kandidaten messen mit der schnellsten Draft-Variante, Bild-Probe und Betrieb wie heute mit Zwilling
Ampel / ampel (push) Failing after 22s
Ampel / ampel (push) Failing after 22s
Das heutige Modell misst mit seinem Draft (Hirn 106 t/s, ohne 68), Kandidaten liefen ohne - Ornith fiel am 24.09. deshalb durch, obwohl es dieselbe Architektur hat. Jetzt probiert das Radar kurz: ohne Draft, eingebauten MTP-Kopf und den Draft des heutigen Modells (gleiche Architektur, Speicher reicht) und testet mit der schnellsten. Spekulatives Dekodieren aendert die Antworten nicht, nur das Tempo. Mit Draft laeuft die Bild-Probe auf einem Zwilling ohne Draft (llama.cpp: Draft und Bild = HTTP 500). Uebernehmen baut wie der Betrieb seit 24.09.: Hauptmodell mit dem gewaehlten Draft ohne Projektor, dazu ein Bild-Zwilling; der alte Zwilling fliegt raus. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
42363229d4
commit
4a05bc2a05
+83
-19
@@ -763,20 +763,23 @@ def pruefe(rolle: str, basis: str, modell: str, *, bild: bool = False, frist: fl
|
||||
else:
|
||||
werte["code"] = messe_code(basis, modell, frist)
|
||||
protokoll(f" code : {werte['code']['ok']}/{werte['code']['von']} in {werte['code']['sekunden']} s")
|
||||
werte["bild"] = None
|
||||
if bild:
|
||||
try:
|
||||
werte["bild"] = messe_bild(basis, bild_modell or modell, rolle, frist)
|
||||
except Zeitende:
|
||||
raise
|
||||
except Exception as e:
|
||||
werte["bild"] = {"direkt": 0.0, "gefunden": [], "agentisch": False, "fehler": str(e)[:160]}
|
||||
protokoll(f" bild : {werte['bild'].get('direkt')} direkt, im Ablauf "
|
||||
f"{'ja' if werte['bild'].get('agentisch') else 'nein'}")
|
||||
werte["bild"] = bild_probe(basis, bild_modell or modell, rolle, frist, protokoll) if bild else None
|
||||
werte["dauer_s"] = round(time.time() - t0)
|
||||
return werte
|
||||
|
||||
|
||||
def bild_probe(basis: str, modell: str, rolle: str, frist: float | None = None, protokoll=log) -> dict:
|
||||
"""Bild-Probe mit Fehlerfang: ein Absturz der Probe ist ein Messwert, kein Programmfehler."""
|
||||
try:
|
||||
ergebnis = messe_bild(basis, modell, rolle, frist)
|
||||
except Zeitende:
|
||||
raise
|
||||
except Exception as e:
|
||||
ergebnis = {"direkt": 0.0, "gefunden": [], "agentisch": False, "fehler": str(e)[:160]}
|
||||
protokoll(f" bild : {ergebnis.get('direkt')} direkt, im Ablauf {'ja' if ergebnis.get('agentisch') else 'nein'}")
|
||||
return ergebnis
|
||||
|
||||
|
||||
# --- Kandidaten-Server -------------------------------------------------------------------
|
||||
|
||||
class Server:
|
||||
@@ -908,30 +911,91 @@ def starte_server(gguf: str, *, mmproj: str | None = None, ctx: int = CTX_STANDA
|
||||
raise
|
||||
|
||||
|
||||
def pruefe_kandidat(rolle: str, gguf: str, *, mmproj: str | None = None, flags=(), ctx: int = CTX_STANDARD,
|
||||
basis: dict | None = None, frist: float | None = None, protokoll=log) -> dict:
|
||||
"""Ganzer Durchlauf eines Kandidaten: Server starten → messen → stoppen → urteilen.
|
||||
basis = Werte der Baseline (ohne sie gibt es kein Urteil, ergebnis None).
|
||||
Rückgabe: {"werte", "ergebnis", "vergleich", "zusammenfassung"}."""
|
||||
def mit_server(gguf: str, arbeit, *, mmproj: str | None = None, ctx: int = CTX_STANDARD, flags=(),
|
||||
frist: float | None = None, protokoll=log):
|
||||
"""Kandidat starten, arbeit() laufen lassen, stoppen. Gibt (Ergebnis, Server) zurück; ein Absturz
|
||||
während der Arbeit wird zu ServerFehler — ein toter Server darf nicht wie ein schlechtes Modell aussehen."""
|
||||
server = starte_server(gguf, mmproj=mmproj, ctx=ctx, flags=flags, frist=frist, protokoll=protokoll)
|
||||
|
||||
def absturz() -> str:
|
||||
return f"Während des Tests abgestürzt (Code {server.prozess.returncode}): {log_ende(SERVER_LOG, 300)}"
|
||||
|
||||
try:
|
||||
werte = pruefe(rolle, KANDIDAT_URL, "kandidat", bild=bool(mmproj), frist=frist, protokoll=protokoll)
|
||||
ergebnis = arbeit()
|
||||
except Exception as e:
|
||||
if not isinstance(e, Zeitende) and server.prozess.poll() is not None:
|
||||
raise ServerFehler(absturz()) from e
|
||||
raise
|
||||
else:
|
||||
# Einzelproben fangen Fehler ab — ein toter Server darf nicht wie ein schlechtes Modell aussehen.
|
||||
if server.prozess.poll() is not None:
|
||||
if server.prozess.poll() is not None: # Einzelproben fangen Fehler ab — darum hier nachsehen
|
||||
raise ServerFehler(absturz())
|
||||
finally:
|
||||
stoppe_server(server)
|
||||
time.sleep(3) # Speicher freigeben lassen, bevor jemand anderes lädt
|
||||
werte.update(ladezeit_s=server.ladezeit, ctx=ctx, befehl=" ".join(server.befehl))
|
||||
return ergebnis, server
|
||||
|
||||
|
||||
_SPEC_FLAGS = ("--spec-type", "--spec-draft-model", "--spec-draft-n-max")
|
||||
|
||||
|
||||
def ohne_draft(flags) -> list[str]:
|
||||
"""Flags ohne spekulatives Dekodieren (jeweils Schalter plus Wert)."""
|
||||
rest, flags, i = [], list(flags), 0
|
||||
while i < len(flags):
|
||||
if flags[i] in _SPEC_FLAGS:
|
||||
i += 2
|
||||
continue
|
||||
rest.append(flags[i])
|
||||
i += 1
|
||||
return rest
|
||||
|
||||
|
||||
def waehle_draft(gguf: str, varianten: list[dict], *, frist: float | None = None, protokoll=log) -> dict:
|
||||
"""Schnellste Art des spekulativen Dekodierens für einen Kandidaten. Jede Variante {"name", "flags", …}
|
||||
wird gestartet und bei 13k Tiefe gemessen; startet eine nicht (z. B. passt das Vokabular des Drafts
|
||||
nicht), fällt sie raus. Spekulatives Dekodieren ändert die Antworten nicht, nur das Tempo — darum
|
||||
entscheidet allein das Tempo. Rückgabe: die gewählte Variante plus "messungen" (Name → t/s bzw. Grund)."""
|
||||
messungen: dict[str, object] = {}
|
||||
beste: tuple[dict, float] | None = None
|
||||
for v in varianten:
|
||||
try:
|
||||
tempo, _ = mit_server(gguf, lambda: messe_tempo(KANDIDAT_URL, "kandidat", frist), ctx=32768,
|
||||
flags=v["flags"], frist=frist, protokoll=protokoll)
|
||||
except Zeitende:
|
||||
raise
|
||||
except Exception as e:
|
||||
messungen[v["name"]] = f"geht nicht: {str(e)[:120]}"
|
||||
protokoll(f" Draft-Variante {v['name']}: geht nicht ({str(e)[:120]})")
|
||||
continue
|
||||
tiefe = tempo.get("tiefe") or {}
|
||||
tps = float(tiefe.get("tg_tps") or 0)
|
||||
messungen[v["name"]] = tps
|
||||
protokoll(f" Draft-Variante {v['name']}: {tps} t/s bei 13k (Akzeptanz {tiefe.get('acc')})")
|
||||
if beste is None or tps > beste[1]:
|
||||
beste = (v, tps)
|
||||
gewaehlt = beste[0] if beste else next((v for v in varianten if not v["flags"]), varianten[0])
|
||||
return {**gewaehlt, "messungen": messungen}
|
||||
|
||||
|
||||
def pruefe_kandidat(rolle: str, gguf: str, *, mmproj: str | None = None, flags=(), ctx: int = CTX_STANDARD,
|
||||
basis: dict | None = None, frist: float | None = None, protokoll=log) -> dict:
|
||||
"""Ganzer Durchlauf eines Kandidaten: Server starten → messen → stoppen → urteilen.
|
||||
basis = Werte der Baseline (ohne sie gibt es kein Urteil, ergebnis None).
|
||||
Mit Draft wie im Betrieb seit 24.09.: Text auf einem Server ohne Projektor, die Bild-Probe auf einem
|
||||
Zwilling ohne Draft — llama.cpp kann Draft und Bild nicht zusammen (HTTP 500).
|
||||
Rückgabe: {"werte", "ergebnis", "vergleich", "zusammenfassung"}."""
|
||||
mit_draft = "--spec-type" in list(flags)
|
||||
text_mmproj = None if mit_draft else mmproj
|
||||
werte, server = mit_server(
|
||||
gguf, lambda: pruefe(rolle, KANDIDAT_URL, "kandidat", bild=bool(text_mmproj), frist=frist, protokoll=protokoll),
|
||||
mmproj=text_mmproj, ctx=ctx, flags=flags, frist=frist, protokoll=protokoll)
|
||||
befehle = [" ".join(server.befehl)]
|
||||
if mit_draft and mmproj:
|
||||
werte["bild"], zwilling = mit_server(
|
||||
gguf, lambda: bild_probe(KANDIDAT_URL, "kandidat", rolle, frist, protokoll),
|
||||
mmproj=mmproj, ctx=min(ctx, 32768), flags=ohne_draft(flags), frist=frist, protokoll=protokoll)
|
||||
befehle.append(" ".join(zwilling.befehl))
|
||||
werte.update(ladezeit_s=server.ladezeit, ctx=ctx, befehl=" | ".join(befehle))
|
||||
if not basis:
|
||||
return {"werte": werte, "ergebnis": None, "vergleich": {},
|
||||
"zusammenfassung": "Gemessen, aber ohne Vergleichswerte des heutigen Modells."}
|
||||
|
||||
Reference in New Issue
Block a user