| """P Formula adapter seed 17ยท31ยท47์ ๊ฐ๋ณ gate์ distillation ํ์ฉ ์ฌ๋ถ๋ฅผ ์์ฝํ๋ค.""" |
|
|
| from __future__ import annotations |
|
|
| import argparse |
| from datetime import datetime, timezone |
| import json |
| from pathlib import Path |
| import statistics |
| from typing import Any |
|
|
|
|
| REQUIRED_SEEDS06 = frozenset({17, 31, 47}) |
|
|
|
|
| def summarize_p_formula_seeds06(reports: list[dict[str, Any]]) -> dict[str, Any]: |
| """ํ์ ๋ณ์: ์ธ seed report. ์๋ ์๋ฆฌ: seed ๋๋ฝยทR ํผ์
ยทtest ์๋ต์ ๊ฑฐ๋ถํ๊ณ metric ๋ถ์ฐ๊ณผ AND gate๋ฅผ ๊ณ์ฐํ๋ค.""" |
|
|
| seeds = [int(report["seed"]) for report in reports] |
| if len(reports) != 3 or set(seeds) != REQUIRED_SEEDS06 or len(set(seeds)) != 3: |
| raise ValueError("P Formula ์์ฝ์๋ seed 17ยท31ยท47 report๊ฐ ์ ํํ ํ๋์ฉ ํ์ํฉ๋๋ค.") |
| if any(report.get("track") != "P_approved_formula_only" for report in reports): |
| raise ValueError("R-track ๋๋ ์ ์ ์๋ formula adapter report๋ฅผ distillation ์์ฝ์ ์์ ์ ์์ต๋๋ค.") |
| if any(report.get("official_test") is None for report in reports): |
| raise ValueError("official test๋ฅผ ์๋ตํ seed๋ 3-seed gate์ ์ฌ์ฉํ ์ ์์ต๋๋ค.") |
| fingerprints = {str(report.get("data_sha256") or "") for report in reports} |
| if len(fingerprints) != 1 or "" in fingerprints: |
| raise ValueError("์ธ seed๋ ๋์ผํ ๋น์ด ์์ง ์์ P Formula data_sha256์ ๊ฐ์ ธ์ผ ํฉ๋๋ค.") |
| ordered = sorted(reports, key=lambda report: int(report["seed"])) |
|
|
| def aggregate(path: tuple[str, ...]) -> dict[str, Any]: |
| """ํ์ ๋ณ์: nested metric ๊ฒฝ๋ก. ์๋ ์๋ฆฌ: ์ธ seed ๊ฐยทํ๊ท ยทํ์คํธ์ฐจยท์ต์๊ฐ์ ๋ฐํํ๋ค.""" |
|
|
| values = [] |
| for report in ordered: |
| value: Any = report |
| for key in path: |
| value = value[key] |
| values.append(float(value)) |
| return { |
| "values": values, |
| "mean": statistics.fmean(values), |
| "std": statistics.pstdev(values), |
| "minimum": min(values), |
| } |
|
|
| metrics = { |
| "validation_exact_top1": aggregate(("selected_validation", "exact_top1")), |
| "test_exact_top1": aggregate(("official_test", "exact_top1")), |
| "test_exact_top5": aggregate(("official_test", "exact_top5")), |
| "test_visual_family_top1": aggregate(("official_test", "visual_family_top1")), |
| "test_macro_f1": aggregate(("official_test", "macro_f1")), |
| "test_writer_floor": aggregate(("official_test", "writer", "floor")), |
| } |
| individual = { |
| str(report["seed"]): { |
| "passed": bool(report.get("seed_gate", {}).get("passed")), |
| "checks": report.get("seed_gate", {}).get("checks"), |
| "checkpoint": report.get("checkpoint"), |
| } |
| for report in ordered |
| } |
| all_passed = all(row["passed"] for row in individual.values()) |
| return { |
| "experiment": "P-MATH-INK-06-FORMULA-ADAPTER-3SEED-001", |
| "generated_at": datetime.now(timezone.utc).isoformat(), |
| "seeds": [17, 31, 47], |
| "data_sha256": next(iter(fingerprints)), |
| "metrics": metrics, |
| "individual_seed_gates": individual, |
| "decision": { |
| "all_individual_seed_gates_passed": all_passed, |
| "student_distillation_allowed": all_passed, |
| "teacher_ensemble_mobile_deployment_allowed": False, |
| "product_validation": False, |
| "next_gate": ( |
| "single mobile student distillation, LiteRT parity, Android 3-tier benchmark" |
| if all_passed |
| else "P formula data/recipe ๊ฐ์ ํ ์ธ seed ์ ๋ถ ์ฌ๊ฒ์ฆ" |
| ), |
| }, |
| "track": "P_approved_formula_only", |
| "product_validation": False, |
| } |
|
|
|
|
| def main() -> None: |
| """ํ์ ๋ณ์: seed๋ณ report ๊ฒฝ๋กยท์ถ๋ ฅ. ์๋ ์๋ฆฌ: UTF-8 JSON summary๋ฅผ ์์ฑํ๋ค.""" |
|
|
| parser = argparse.ArgumentParser(description="Summarize 3-seed P formula adapters") |
| parser.add_argument("--report", type=Path, action="append", required=True) |
| parser.add_argument("--output", type=Path, required=True) |
| args = parser.parse_args() |
| reports = [ |
| json.loads(path.read_text(encoding="utf-8")) |
| for path in args.report |
| ] |
| summary = summarize_p_formula_seeds06(reports) |
| 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() |
|
|