AI 다이어트 실패 사건 · 정확도 손실을 재는 법 · 실습
이 차이가 재현되는 차이인가 — 정확도 손실을 재는 법
목표
같은 시험 표본에서 FP32 원본·이전 배포본·정수 후보 셋을 돌려 예측과 출력값을 남기고, 정확도 차이가 재현되는 차이인지 따지는 도구 acccmp.py 를 만든다. 구간·쌍 비교·뒤집힌 표본·출력 차이를 각각 재고, 기준선을 둘로 두어 판정을 내린다.
왜 중요한가
"정확도가 0.3% 떨어졌다" 는 그 자체로는 판단 근거가 아니다. 표본 400개에서 정확도 하나의 95% 구간은 폭이 8퍼센트포인트에 가깝다. 두 모델을 따로 재어 뺀 값으로는 이보다 작은 차이를 말할 수 없다.
말할 수 있게 하는 것은 같은 표본이다. 두 모델이 같은 입력을 보았다면, 둘 다 맞힌 표본과 둘 다 틀린 표본은 판정에 쓸 수 없고 한쪽만 맞힌 표본만 정보가 된다. 그 갈린 건수가 실제 분모다.
기준선도 하나가 아니다. FP32 원본은 양자화가 얼마나 깎았는지를 답하고, 이전 배포본은 지금 돌고 있는 것보다 나빠지는지를 답한다. 두 답이 다른 방향일 수 있으므로 둘 다 적는다.
그리고 출력 차이와 과제 지표는 다르다. 최대 절대 오차가 크게 나와도 정확도는 그대로일 수 있고 그 반대도 있다. 결정 경계에서 먼 표본은 출력이 흔들려도 답이 안 바뀌기 때문이다.
채점기는 여러분이 적은 숫자를 믿지 않는다. 매번 다른 씨앗과 표본 수로 자기 예측표를 차려 여러분의 도구를 실제로 실행하고 같은 계산을 다시 해 대조한다. 1단계는 여러분이 남긴 씨앗으로 시험 입력을 다시 만들어 여러분의 모델을 직접 돌려 본다.
단계
1. /root/acc/gen_eval.py 를 만들어 실행해 모델 셋과 /root/acc/preds.json, /root/acc/eval_seed.json 을 만드세요.
2. /root/acc/acccmp.py 에 summary 를 만들어 표본 수와 실행별 정확도를 내게 하세요.
3. interval 을 더해 정확도 하나의 95% 구간을 Wilson 점수 구간으로 내게 하세요.
4. paired 를 더해 같은 표본에서 2x2 로 갈린 건수와 쌍 비교 통계량을 내게 하세요.
5. flips 를 더해 뒤집힌 예측만 방향별로 세게 하세요.
6. outputs 를 더해 출력값 차이(최대 절대 오차·평균 절대 오차·코사인)를 내게 하세요.
7. baseline 을 더해 기준선 둘을 각각 견주게 하고, 여러분 자료의 판정을 /root/acc/verdict.json 에 적으세요.
8. /root/acc/accuracy_report.md 를 네 절로 쓰세요.
참고
- 파이썬은
/opt/onnx-lab/bin/python입니다. 시스템python3에는 numpy 도 onnx 도 없습니다. - 실행 계약:
/opt/onnx-lab/bin/python /root/acc/acccmp.py <명령> <preds.json> [인자...]. 성공하면 종료 코드 0, 파일이 없으면 3, 사용법이 틀리면 2 입니다. 답은 JSON 한 덩어리로 표준출력에 냅니다. preds.json모양:{"labels": [정수...], "runs": {"fp32": {"pred": [정수...], "logits": [[실수...], ...]}, "prev": {...}, "int8": {...}}}. logits 는 반올림하지 말고 그대로 적습니다.eval_seed.json모양:{"seed": 정수, "n": 400, "features": 16, "classes": 10, "label_sigma": 1.0}.- 시험 입력은
numpy.random.default_rng(seed).standard_normal((n, features)).astype(numpy.float32)입니다. 정답표는 FP32 출력(float64 로 올린 값)에numpy.random.default_rng(seed + 1).standard_normal(모양) * label_sigma를 더해 argmax 한 것입니다. 채점기가 이 규칙으로 다시 만들어 여러분의 모델을 직접 돌립니다. - 모델은 입력 이름
x, 입력 모양[None, 16], 출력 클래스 10개입니다.prev.onnx는quantize_dynamic,int8.onnx는quantize_static(quant_format=QDQ)로 만듭니다. 세 파일 이름은/root/acc/fp32.onnx,/root/acc/prev.onnx,/root/acc/int8.onnx입니다. summary응답:{"n": 정수, "runs": {이름: {"correct": 정수, "accuracy": 실수}}}.interval응답:{"run", "n", "correct", "accuracy", "center", "low", "high", "half_width"}. Wilson 점수 구간을 z = 1.96 으로 계산합니다. 중심은 p 가 아니라(p + z^2/(2n)) / (1 + z^2/n)이고, 반폭은z/(1 + z^2/n) * sqrt(p(1-p)/n + z^2/(4n^2))입니다.paired <a> <b>응답:{"a","b","n","both_correct","only_a","only_b","both_wrong","accuracy_a","accuracy_b","delta","discordant","statistic","significant"}. delta 는 b 에서 a 를 뺀 값입니다. discordant 는 only_a 와 only_b 의 합입니다. statistic 은 이 실습이 고정한 잣대로(|only_a - only_b| - 1)^2 / discordant이고, discordant 가 0이면 0.0 입니다. significant 는 statistic 이 3.841459 보다 큰지입니다.flips <a> <b>응답:{"a","b","changed","to_wrong","to_right","changed_both_wrong","top_flip"}. changed 는 예측이 다른 표본 수, to_wrong 은 a 가 맞고 b 가 틀린 수, to_right 은 그 반대, changed_both_wrong 은 둘 다 틀렸는데 답이 바뀐 수입니다. top_flip 은 가장 많은 뒤집힘의[a 예측, b 예측, 건수]이고 동률이면 a 예측·b 예측이 작은 쪽, 뒤집힘이 없으면 null 입니다.outputs <a> <b>응답:{"a","b","max_abs_error","mean_abs_error","cos_min","cos_mean","argmax_changed"}. 평균 절대 오차는 원소 전체의 평균이고, 코사인은 표본마다 구해 최솟값과 평균을 냅니다. 분모가 0이면 그 표본의 코사인은 1.0 으로 둡니다.baseline <run>응답:{"run","baselines","vs","worst"}. baselines 는 run 을 뺀 나머지 이름을 정렬한 것이고, vs 의 각 항목은{"delta","only_a","only_b","discordant","statistic","significant"}로 그 기준선을 a 로, run 을 b 로 둔 값입니다. worst 는 delta 가 가장 작은 기준선의{"baseline","delta"}입니다.verdict.json모양:{"candidate","n","accuracy","delta_vs_fp32","delta_vs_prev","half_width","discordant_vs_fp32","statistic_vs_fp32","significant_vs_fp32","decision","reason"}. half_width 는 후보의 Wilson 반폭입니다. decision 은 이 실습이 고정한 규칙으로, significant_vs_fp32 가 참이고 delta_vs_fp32 가 0보다 작으면hold, 아니면ship입니다.accuracy_report.md는## 무엇을 견주었나## 같은 표본에서 본 차이## 이 차이가 재현되는가## 판정과 한계네 절입니다.- 공식 문서: [ONNX Runtime 양자화](https://onnxruntime.ai/docs/performance/model-optimizations/quantization.html) · [ONNX Concepts](https://onnx.ai/onnx/intro/concepts.html) · [QuantizeLinear](https://onnx.ai/onnx/operators/onnx__QuantizeLinear.html)
- 흔한 실수: 따로 잰 두 정확도를 빼서 보고하기, 구간이 겹친다는 이유로 차이가 없다고 말하기, 최대 절대 오차로 정확도를 대신하기, 기준선을 FP32 하나만 두기.
- 이 실습은 시간·처리량을 재지 않습니다. 이 맥은 에뮬레이션이라 지연이 두 배까지 흔들립니다.
단계 8개
- 세 판을 같은 표본에서 돌려 예측을 남기기
- 표본 수와 정확도를 한 자리에 모으기
- 정확도 하나에 구간을 붙이기
- 같은 표본에서 쌍으로 견주기
- 뒤집힌 예측만 방향별로 세기
- 출력 차이와 과제 지표를 갈라 재기
- 기준선을 둘로 두고 판정하기
- 읽는 사람이 판단할 수 있게 적기