Qwen3.8-27B-MTP-GGUF / bench /selftest_mathe.py
Davidmg0815's picture
Omega-Messung: MATH-500 mit vollem Reasoning, Fehleranalyse, korrigierter Antwortvergleich
52467f4 verified
Raw
History Blame Contribute Delete
5.24 kB
#!/usr/bin/env python3
"""Prueft die Antwortextraktion und den Vergleich.
Bei Mathematik-Benchmarks steckt der Fehler fast nie im Modell, sondern im
Vergleich: dieselbe Antwort kommt als 0.75, \\frac{3}{4}, 3/4 oder
\\dfrac{3}{4}. Wer stur auf Zeichengleichheit prueft, misst Schreibweise
statt Rechnen.
Teil 3 laeuft gegen die echten Musterloesungen des Datensatzes: die muessen
sich mit sich selbst vergleichen lassen, sonst ist die Quote systematisch
zu niedrig.
"""
import json
import sys
sys.path.insert(0, "/mnt/models/qwen38-prep")
import bench_mathe as B
GLEICH = [
("\\frac{3}{4}", "0.75"),
("0.75", "\\frac{3}{4}"),
("3/4", "\\frac{3}{4}"),
("\\dfrac{1}{2}", "\\frac{1}{2}"),
("\\left( 3, \\frac{\\pi}{2} \\right)", "(3,\\frac{\\pi}{2})"),
("1,000", "1000"),
("42", "42."),
("\\text{even}", "even"),
("90^\\circ", "90"),
(" 7 ", "7"),
("50\\%", "50"),
# Aus echten Fehlschlaegen des ersten Durchgangs — jeder dieser Faelle
# wurde damals faelschlich als falsche Antwort gewertet.
("\\frac{4}{3}", "\\frac43"),
("\\frac{3}{4}", "\\frac 34"),
("\\frac{3}{4}", "\\dfrac34"),
("5", "x=5"),
("[-2, 7]", "x \\in [-2,7]"),
("B", "\\text{(B)}"),
("0,35625", ".35625"),
(".5", "0.5"),
("-.25", "-0.25"),
# Gefunden am 17.08. in der OMEGA-Bedarfsmessung: die Musterloesung haengt
# die Einheit an, das Modell nicht. Wurde als falsch gewertet.
("\\frac{270}{7}", "\\frac{270}7\\text{ degrees}"),
("5", "5\\text{ inches}"),
("5\\text{ cm}", "5"),
# Gemischte frac-Schreibweise: nur ein Argument geklammert.
("\\frac{270}{7}", "\\frac{270}7"),
("\\frac2{15}", "\\frac{2}{15}"),
# Gefunden am 17.08. bei der Fehleranalyse des OMEGA-Hauptlaufs: von drei
# abgeschlossenen Fehlschlaegen waren zwei reine Schreibweise.
("1-\\sqrt{19}, 1+\\sqrt{19}", "1 \\pm \\sqrt{19}"),
("1 \\pm \\sqrt{19}", "1+\\sqrt{19}, 1-\\sqrt{19}"),
("\\begin{pmatrix} \\frac{16}{49} \\\\[2mm] \\frac{48}{49} \\end{pmatrix}",
"\\begin{pmatrix} 16/49 \\\\ 48/49 \\end{pmatrix}"),
]
UNGLEICH = [
("\\frac{3}{4}", "\\frac{4}{3}"),
("42", "43"),
("0.75", "0.76"),
("even", "odd"),
("(3,2)", "(2,3)"),
# Die Einheitenregel darf nicht so weit gehen, dass Zahlen egal werden.
("\\frac{270}{7}", "\\frac{271}7\\text{ degrees}"),
("5", "6\\text{ inches}"),
# Die \pm-Regel darf nur die Schreibweise aufloesen, nicht die Werte.
("1-\\sqrt{19}, 1+\\sqrt{19}", "1 \\pm \\sqrt{17}"),
("2 \\pm \\sqrt{19}", "1 \\pm \\sqrt{19}"),
# Matrizen: gleiche Schreibweise, anderer Eintrag.
("\\begin{pmatrix} \\frac{16}{49} \\\\[2mm] \\frac{48}{49} \\end{pmatrix}",
"\\begin{pmatrix} 16/49 \\\\ 47/49 \\end{pmatrix}"),
]
BOXED = [
("Also ist die Antwort \\boxed{42}.", "42"),
("\\boxed{\\frac{1}{2}}", "\\frac{1}{2}"),
("erst \\boxed{1}, dann \\boxed{2}", "2"), # das LETZTE zaehlt
("\\boxed{\\left( 3, \\frac{\\pi}{2} \\right)}",
"\\left( 3, \\frac{\\pi}{2} \\right)"),
("kein Kasten hier", None),
]
GSM = [
("Rechnung ... #### 18", "18"),
("#### 1,000", "1,000"),
("erst #### 5 dann #### 7", "7"),
("nur Text mit Zahl 33 am Ende", "33"),
]
def main():
fehler = 0
print("=== Teil 1: gleiche Antworten müssen als gleich gelten ===")
for a, b in GLEICH:
ok = B.stimmt(a, b)
print(f" {'ok ' if ok else 'FEHL'} {a!r} == {b!r}")
if not ok:
fehler += 1
print("\n=== Teil 2: verschiedene Antworten müssen verschieden bleiben ===")
for a, b in UNGLEICH:
ok = not B.stimmt(a, b)
print(f" {'ok ' if ok else 'ZU LASCH'} {a!r} != {b!r}")
if not ok:
fehler += 1
print("\n=== Teil 3: \\boxed{} korrekt herausschälen ===")
for text, erwartet in BOXED:
got = B.hole_boxed(text)
ok = got == erwartet
print(f" {'ok ' if ok else 'FEHL'} {text[:44]!r} -> {got!r}")
if not ok:
fehler += 1
print("\n=== Teil 4: GSM8K-Format ===")
for text, erwartet in GSM:
got = B.hole_gsm(text)
ok = got == erwartet
print(f" {'ok ' if ok else 'FEHL'} {text[:44]!r} -> {got!r}")
if not ok:
fehler += 1
print("\n=== Teil 5: Musterlösungen gegen sich selbst ===")
for satz, feld in (("math500", "answer"), ("gsm8k-platinum", None)):
try:
aufgaben = B.lade(satz, 120)
except FileNotFoundError:
print(f" {satz}: nicht vorhanden, übersprungen")
continue
treffer = 0
misslungen = []
for a in aufgaben:
erw = a["answer"] if feld else B.hole_gsm(a["answer"])
if B.stimmt(erw, erw):
treffer += 1
else:
misslungen.append(erw)
print(f" {satz}: {treffer}/{len(aufgaben)} vergleichen sich mit sich selbst")
for m in misslungen[:5]:
print(f" problematisch: {m!r}")
if treffer < len(aufgaben):
fehler += 1
print(f"\n{'ALLES SAUBER' if not fehler else str(fehler) + ' PROBLEME'}")
return 1 if fehler else 0
if __name__ == "__main__":
sys.exit(main())