holoaeon / scripts /eval_diff.py
weideyouni's picture
sync: five-site DNA + B0 baseline freeze (92fd8b5)
9f075f3 verified
Raw History Blame Contribute Delete
3.04 kB
# -*- coding: utf-8 -*-
"""
eval_diff.py —— 双轨对比(W15,旁挂脚本)
================================================================================
确定性轨:逐条比 ok(routes 是否仍回到原技能)。
质量轨:逐条比 score(judge/规则分只**披露**,不裁决)。
任何一侧的差异都列出明细,不污染黄金值。
用法:
python scripts\\eval_diff.py --left a.json --right b.json
python scripts\\eval_diff.py --variant trunc12 # 内部跑 raw vs 变体
"""
from __future__ import annotations
import argparse
import json
import os
import sys
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if ROOT not in sys.path:
sys.path.insert(0, ROOT)
SCRIPTS = os.path.dirname(os.path.abspath(__file__))
if SCRIPTS not in sys.path:
sys.path.insert(0, SCRIPTS)
import eval_set # noqa: E402
def diff(left: dict, right: dict) -> dict:
li = {r["skill"]: r for r in left.get("rows", [])}
ri = {r["skill"]: r for r in right.get("rows", [])}
common = sorted(set(li) & set(ri))
improved, regressed, unchanged = [], [], 0
score_moved = []
for name in common:
a, b = li[name], ri[name]
if a["ok"] != b["ok"]:
(improved if b["ok"] else regressed).append(name)
else:
unchanged += 1
if abs(float(a.get("score", 0.0)) - float(b.get("score", 0.0))) > 1e-9:
score_moved.append({"skill": name,
"left": a.get("score"), "right": b.get("score")})
return {
"left": {"variant": left.get("variant"), "accuracy": left.get("accuracy"),
"cases": left.get("cases")},
"right": {"variant": right.get("variant"), "accuracy": right.get("accuracy"),
"cases": right.get("cases")},
"common": len(common),
"improved": improved,
"regressed": regressed,
"unchanged": unchanged,
"score_moved": score_moved[:10],
"score_moved_count": len(score_moved),
"verdict": "REGRESSED" if regressed else "OK",
"note": "质量轨只披露;裁决走确定性轨",
}
def _load(path: str) -> dict:
with open(path, "r", encoding="utf-8") as fh:
return json.load(fh)
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--left", default="")
ap.add_argument("--right", default="")
ap.add_argument("--variant", default="cross")
ap.add_argument("--json", default="")
a = ap.parse_args()
if a.left and a.right:
left, right = _load(a.left), _load(a.right)
else:
left, right = eval_set.run("raw"), eval_set.run(a.variant)
rep = diff(left, right)
if a.json:
with open(a.json, "w", encoding="utf-8", newline="\n") as fh:
json.dump(rep, fh, ensure_ascii=False, indent=2, sort_keys=True)
fh.write("\n")
print(json.dumps(rep, ensure_ascii=False))
return 0 if rep["common"] else 1
if __name__ == "__main__":
raise SystemExit(main())