ONNX
onnxruntime
onnx-mlir
quantization
fp32
ONNX_Models / scripts /validate_model_accuracy_summary.py
purejomo's picture
Finalize public ONNX/ONNX-MLIR validation release
ed3aeeb
Raw
History Blame Contribute Delete
7.05 kB
#!/usr/bin/env python3
"""Independently validate the compact 21-model accuracy CSV."""
from __future__ import annotations
import argparse
import csv
import hashlib
import json
import os
import tempfile
from collections import Counter
from pathlib import Path
from typing import Any
FIELDS = ["model_id", "model_name", "metric", "fp32", "quantized", "delta", "published_comparison"]
EXPECTED: dict[str, tuple[str, str, str, str, str]] = {
"AD01": ("AUC / pAUC (max_fpr=0.1)", "0.876001 / 0.764121", "0.840250 / 0.720049", "-0.035750 / -0.044071", "공개 FP32 AUC/pAUC 0.876001/0.764121; 측정값 동일"),
"LM04": ("AUROC / TPR@FPR 5% / 1% (RAID-extra OOD)", "0.667078 / 0.318983 / 0.233873", "0.668862 / 0.322615 / 0.235853", "+0.001785 / +0.003632 / +0.001981", ""),
"OD06": ("COCO bbox mAP (AP@[0.50:0.95])", "24.8751%", "24.2822%", "-0.5929 pp", ""),
"OD07": ("COCO bbox mAP (AP@[0.50:0.95])", "31.8594%", "31.4191%", "-0.4403 pp", ""),
"SG06": ("mIoU", "75.6398%", "74.1290%", "-1.5108 pp", "공개 FP32 mIoU 75.32%; 측정 75.6398% (+0.3198 pp)"),
"SG07": ("mIoU", "70.6473%", "69.6191%", "-1.0282 pp", "공개 FP32 mIoU 70.19%; 측정 70.6473% (+0.4573 pp)"),
"SG08": ("mIoU (CamVid cross-dataset)", "50.6498%", "51.1600%", "+0.5102 pp", ""),
"SP01": ("Top-1 accuracy", "91.86%", "91.66%", "-0.2045 pp", "공개 시험 정확도 약 92%; 측정 FP32 91.86%, 양자화 91.66% (근접)"),
"SP02": ("FP / FN (1 s)", "5 / 6", "4 / 6", "-1 / +0", ""),
"SP08": ("Top-1 accuracy (yes/no subset)", "94.05%", "94.05%", "+0.0000 pp", ""),
"SP09": ("Top-1 accuracy", "95.06%", "94.70%", "-0.3590 pp", ""),
"VC01": ("Top-1 accuracy", "85.10%", "85.60%", "+0.5000 pp", ""),
"VC02": ("Top-1 accuracy", "87.00%", "87.00%", "+0.0000 pp", ""),
"VC03": ("Top-1 / Top-5 accuracy", "49.80% / 74.20%", "48.00% / 72.80%", "-1.8000 pp / -1.4000 pp", ""),
"VC04": ("Top-1 / Top-5 accuracy", "63.30% / 84.90%", "60.70% / 83.20%", "-2.6000 pp / -1.7000 pp", ""),
"VC05": ("Top-1 accuracy", "58.13%", "56.77%", "-1.3600 pp", ""),
"VC06": ("Top-1 accuracy", "66.20%", "65.31%", "-0.8900 pp", ""),
"VC09": ("Top-1 / Top-5 accuracy", "56.85% / 79.87%", "56.48% / 79.76%", "-0.3700 pp / -0.1100 pp", ""),
"VC11": ("Top-1 accuracy", "75.10%", "74.40%", "-0.7000 pp", ""),
"VC12": ("Top-1 / Top-5 accuracy", "69.48% / 89.26%", "68.30% / 88.44%", "-1.1800 pp / -0.8200 pp", ""),
"VC13": ("Top-1 / Top-5 error", "33.65% / 13.43%", "33.85% / 13.66%", "+0.2000 pp / +0.2300 pp", ""),
}
NO_PUBLISHED_VALUE = "공개 수치 없음."
EXPECTED = {
model_id: (*values[:4], values[4] or NO_PUBLISHED_VALUE)
for model_id, values in EXPECTED.items()
}
class Checks:
def __init__(self) -> None:
self.total = 0
self.failures: list[dict[str, str]] = []
self.categories: Counter[str] = Counter()
def check(self, condition: bool, category: str, detail: str) -> None:
self.total += 1
self.categories[category] += 1
if not condition:
self.failures.append({"category": category, "detail": detail})
def sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def atomic_json(path: Path, value: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
fd, temporary = tempfile.mkstemp(prefix=path.name + ".", suffix=".tmp", dir=path.parent)
try:
with os.fdopen(fd, "w", encoding="utf-8") as handle:
json.dump(value, handle, indent=2, sort_keys=True, ensure_ascii=False)
handle.write("\n")
os.replace(temporary, path)
except BaseException:
Path(temporary).unlink(missing_ok=True)
raise
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--repo-root", type=Path, required=True)
parser.add_argument("--csv", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
root = args.repo_root.resolve()
csv_path = args.csv if args.csv.is_absolute() else root / args.csv
output = args.output if args.output.is_absolute() else root / args.output
checks = Checks()
with csv_path.open(newline="", encoding="utf-8") as handle:
reader = csv.DictReader(handle)
checks.check(reader.fieldnames == FIELDS, "schema", str(reader.fieldnames))
rows = list(reader)
checks.check(len(rows) == 21, "coverage", f"rows={len(rows)}")
by_id = {row["model_id"]: row for row in rows}
checks.check(len(by_id) == len(rows), "coverage", "duplicate model ID")
checks.check(set(by_id) == set(EXPECTED), "coverage", "model ID set differs")
registry = {
row["model_id"]: row for row in csv.DictReader(
(root / "model_registry.csv").open(newline="", encoding="utf-8")
) if row["eligibility"] == "ELIGIBLE"
}
checks.check(set(registry) == set(EXPECTED), "registry", "active registry set differs")
for model_id, expected in EXPECTED.items():
row = by_id.get(model_id, {})
checks.check(row.get("model_name") == registry[model_id]["model_name"], "model_name", model_id)
for field, value in zip(FIELDS[2:], expected):
checks.check(row.get(field) == value, "metric_value", f"{model_id} {field}")
checks.check(by_id.get("VC09", {}).get("fp32") == "56.85% / 79.87%", "known_correction", "VC09")
checks.check(by_id.get("VC12", {}).get("quantized") == "68.30% / 88.44%", "known_correction", "VC12")
checks.check("error" in by_id.get("VC13", {}).get("metric", "").lower(), "known_correction", "VC13")
checks.check(
{
model_id for model_id, row in by_id.items()
if row.get("published_comparison") != NO_PUBLISHED_VALUE
} == {"AD01", "SG06", "SG07", "SP01"},
"published_scope", "comparison column scope",
)
vc11 = json.loads((root / "research/evidence/vision/vc11_compute_graph_equivalence.json").read_text(encoding="utf-8"))
checks.check(vc11.get("status") == "PASS", "vc11_equivalence", "status")
for variant, facts in vc11.get("variants", {}).items():
checks.check(facts.get("official_compute_graph_sha256") == facts.get("acquired_compute_graph_sha256"), "vc11_equivalence", variant)
status = "PASS" if not checks.failures else "FAIL"
atomic_json(output, {
"schema_version": "1.0", "status": status,
"validated_csv": str(csv_path), "validated_csv_sha256": sha256(csv_path),
"row_count": len(rows), "check_count": checks.total,
"failure_count": len(checks.failures), "failures": checks.failures,
"categories": dict(sorted(checks.categories.items())),
"policy": {"model_runtime_executed": False, "dataset_evaluation_executed": False},
})
print(json.dumps({"status": status, "checks": checks.total, "failures": len(checks.failures)}, sort_keys=True))
return 0 if status == "PASS" else 1
if __name__ == "__main__":
raise SystemExit(main())