aiflow-math-ink-06-intermediate / scripts /summarize_math_ink_06_p_formula_seeds.py
cwLeeDev's picture
Add fail-closed P formula student distillation path
bb698e6 verified
Raw
History Blame Contribute Delete
4.63 kB
"""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()