"""Seed 17·31·47 P boundary joint 결과를 동일 gate로 집계한다.""" from __future__ import annotations import argparse from datetime import datetime, timezone import json from pathlib import Path import numpy as np PROJECT_ROOT = Path(__file__).parents[1] def _parse_args() -> argparse.Namespace: """필요 변수: seed별 report·출력 경로. 작동 원리: 고정 3-seed 집계 CLI를 만든다.""" parser = argparse.ArgumentParser(description="Summarize Math Ink 0.6 P boundary joint seeds") parser.add_argument( "--report", type=Path, action="append", default=None, help="반복 지정한다. 생략하면 최초 legacy 3-seed report를 사용한다.", ) parser.add_argument("--output", type=Path, required=True) return parser.parse_args() def _summary06(values: list[float]) -> dict[str, float | list[float]]: """필요 변수: seed별 실수 지표. 작동 원리: 원값·평균·표준편차·최저값을 함께 반환한다.""" array = np.asarray(values, dtype=np.float64) return { "values": values, "mean": float(array.mean()), "std": float(array.std()), "minimum": float(array.min()), } def main() -> None: """필요 변수: seed 17·31·47 report. 작동 원리: 전 seed gate와 exact/family/boundary 개선을 요약한다.""" args = _parse_args() report_paths = args.report or [ PROJECT_ROOT / "research/runs/math_ink_06_p_boundary_joint_seed17_20260724/report.json", PROJECT_ROOT / "research/runs/math_ink_06_p_boundary_joint_seed31_20260724/report.json", PROJECT_ROOT / "research/runs/math_ink_06_p_boundary_joint_seed47_20260724/report.json", ] reports = [json.loads(path.read_text(encoding="utf-8")) for path in report_paths] seeds = [int(report["seed"]) for report in reports] if sorted(seeds) != [17, 31, 47] or len(set(seeds)) != 3: raise ValueError(f"필수 seed 17·31·47 report가 아닙니다: {seeds}") metrics = { "baseline_exact_top1": _summary06([ float(report["baseline_test"]["exact_top1"]) for report in reports ]), "baseline_family_top1": _summary06([ float(report["baseline_test"]["family_top1"]) for report in reports ]), "exact_top1": _summary06([ float(report["official_test"]["authentic"]["exact_top1"]) for report in reports ]), "family_top1": _summary06([ float(report["official_test"]["authentic"]["family_top1"]) for report in reports ]), "exact_gain_pp": _summary06([ float(report["official_test"]["deltas"]["exact_top1_pp"]) for report in reports ]), "family_gain_pp": _summary06([ float(report["official_test"]["deltas"]["family_top1_pp"]) for report in reports ]), "single_symbol_recall": _summary06([ float(report["official_test"]["boundary"]["single_symbol_recall"]) for report in reports ]), "cross_boundary_recall": _summary06([ float(report["official_test"]["boundary"]["cross_boundary_recall"]) for report in reports ]), "boundary_f1": _summary06([ float(report["official_test"]["boundary"]["f1"]) for report in reports ]), } all_seed_gate = all(bool(report["decision"]["release_adopted"]) for report in reports) release_adopted = bool( all_seed_gate and metrics["exact_gain_pp"]["minimum"] > 0.0 and metrics["family_gain_pp"]["minimum"] > 0.0 and metrics["single_symbol_recall"]["minimum"] >= 0.95 and metrics["cross_boundary_recall"]["minimum"] >= 0.95 ) summary = { "experiment": "P-MATH-INK-06-BOUNDARY-JOINT-3SEED-001", "generated_at": datetime.now(timezone.utc).isoformat(), "seeds": seeds, "reports": [str(path) for path in report_paths], "metrics": metrics, "decision": { "all_seed_gate_passed": all_seed_gate, "p_proxy_release_adopted": release_adopted, "product_validation": False, "next_gate": "실제 P 연속 수식 writer/device-disjoint boundary 평가", }, "track": "P_with_obligations", "product_validation": False, } args.output.parent.mkdir(parents=True, exist_ok=True) args.output.write_text( json.dumps(summary, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", ) print(json.dumps(summary, ensure_ascii=False, indent=2)) if __name__ == "__main__": main()