AI 다이어트 실패 사건 · 작은 모델의 과장 광고를 잡는다 · 실습
AI 다이어트 실패 사건
목표
손글씨 분류기를 실제 INT8 ONNX로 변환하고 잘못된 보정 모델을 거절합니다. Linux CPU에서 정확도·지연·메모리를 측정하며 MCU·NPU·GPU나 실물 전력 측정은 하지 않습니다.
왜 중요한가
모델이 작아도 입력 단위와 보정 자료가 틀리면 정상처럼 실행되며 오답을 냅니다. 파일 크기·정확도·실행 커널·지연·메모리를 따로 확인해야 배포 판단에 근거가 생깁니다. Python·NumPy·JSON 기초가 필요합니다. 모델과 의존성은 제공되므로 인터넷 설치는 필요 없습니다.
단계
1. 숫자 판독기의 입력 계약을 적는다 — contract.json에 features=64, divisor=16, train=1077, calibration=360, test=360을 정수로 저장하세요. 제공 digits.npz 배열의 모양과 ID 개수를 직접 확인하세요. 다른 키는 넣지 않습니다.
2. 255로 나누던 입력을 고친다 — preprocess.py의 normalize(pixels)를 구현하세요. uint8 N×64 배열을 float32로 바꾸고 16으로 나눈 새 배열을 반환합니다. 입력 모양을 유지하고 원본 배열을 변경하지 않습니다. 파일을 직접 실행할 필요는 없습니다.
3. 보정 자료에 평가 표본이 섞이지 않게 한다 — calibration.json의 ids 키에 제공 ids_calibration의 정수 ID 360개를 중복 없이 저장하세요. 순서는 자유지만 학습·평가 ID를 섞지 않습니다. 행 위치와 원본 ID를 혼동하지 마세요.
4. AI를 다이어트시킨다 — quantize.py를 작성해 실행하고 candidate.onnx를 만드세요. 제공 fp32.onnx를 source.onnx로 복사한 뒤 calibration.json의 ID에 해당하는 x_calibration을 normalize로 변환해 CalibrationDataReader로 읽힙니다. 입력 이름 pixels, 한 표본 모양 1×64입니다. quantize_static의 QDQ·활성 QInt8·가중치 QInt8·per_channel=True를 사용하세요. 세 선형층의 정수 가중치·실제 정수 커널 실행·FP32 대비 정확도 손실 0.01 이하를 검사합니다.
5. 틀린 숫자의 방향을 기록한다 — metrics.py의 summarize(predictions, labels)를 구현하세요. 같은 길이의 비어 있지 않은 0–9 정수 목록 둘을 받고 count·correct·accuracy·confusion만 반환합니다. count와 correct는 정수, accuracy는 0–1 비율, confusion은 실제 클래스 행 × 예측 클래스 열의 정수 10×10 배열입니다. 대각합이 correct입니다.
6. 작지만 멍청해진 모델을 거절한다 — FP32·candidate.onnx·제공 bad-calibration.onnx를 같은 x_test/16으로 CPU 추론하고 y_test와 비교해 regression.json을 작성하세요. fp32·int8·bad 각각에 5단계 지표를 저장하고 reject_bad에는 FP32 정확도에서 bad 정확도를 뺀 값이 0.01보다 큰지 불리언으로 적습니다. 문자열 true는 불리언이 아닙니다. 정확도를 외워 쓰지 말고 실행 결과를 기록하세요.
7. 작아졌다고 빨라졌다고 말하지 않는다 — benchmark.py에 latency_stats(samples_us, batch_size)를 구현하세요. 양의 유한한 시간 목록에 대해 p50_us는 중앙값, p95_us는 nearest-rank ceil(0.95×n)번째 값, samples_per_second는 batch_size×n×1e6/시간합입니다. 제공 bench.py --work /root/quantization을 실행해 benchmark.json을 만드세요. 각 모델·배치 1/32에 300개 원시 시간, 3라운드, threads=1, unit=us/batch, 데이터·모델 SHA-256, proc/VmHWM 출처의 양의 peak_rss_bytes가 필요합니다. 요약 통계는 원시 표본과 같아야 합니다.
8. 근거와 한계를 함께 배포한다 — release.json에 model=candidate.onnx, sha256=현재 후보 해시, max_file_bytes=32768, max_accuracy_drop=0.01, target_benchmark_required=true, universally_faster=false를 저장하세요. 다른 키는 넣지 않습니다. 실제 모델이 32KiB 이하여야 하며 정확도 회귀·통계·측정 모델 연결도 다시 검사합니다. 후보를 바꾸었다면 6~7단계 결과도 다시 생성하세요.
참고
모든 작성·생성 파일은 /root/quantization 아래입니다. 먼저 mkdir -p /root/quantization 후 cd /root/quantization을 실행하세요. Python은 /opt/onnx-lab/bin/python을 사용합니다. 스크립트 실행 예: /opt/onnx-lab/bin/python quantize.py. 제공 재료 폴더는 /opt/lab/quantization입니다. digits.npz는 x_train/x_calibration/x_test, y_train/y_calibration/y_test, ids_train/ids_calibration/ids_test 배열을 담습니다. fp32.onnx는 기준 모델, bad-calibration.onnx는 거절할 비교군이며 reference.json·splits.json·DATA-LICENSE.json은 계약·분할·출처입니다. 이 바이너리 재료는 이미지에 들어 있으므로 텍스트로 재작성하지 않습니다. 후보 ONNX 역시 변환기가 생성합니다. 7단계 명령: /opt/onnx-lab/bin/python /opt/lab/quantization/bench.py --work /root/quantization. benchmark.json은 측정 도우미가 생성하므로 표본을 손으로 꾸며 넣지 마세요. 채점은 수치 계산과 해시 연결을 검사할 뿐 측정의 진실성을 인증하지 않습니다. 제출 소스·JSON은 각각 64KiB 이하의 일반 파일, 후보 모델은 검사 시 128KiB 이하·최종 배포 시 32KiB 이하입니다. 학생 함수는 별도 프로세스에서 호출하며 출력 로그를 넣지 마세요. 앞 단계 함수가 필요하면 가져오기를 지원하는 정답지와 실행 스크립트를 참고하세요. 함수 검사 시간 제한은 호출당 10초입니다. 실습 시간이 부족하면 +시간으로 연장하고, 종료 전 파일을 별도로 보관하세요. 세션 종료 후 파일은 유지되지 않습니다.
단계 8개
- 숫자 판독기의 입력 계약을 적는다
- 255로 나누던 입력을 고친다
- 보정 자료에 평가 표본이 섞이지 않게 한다
- AI를 다이어트시킨다
- 틀린 숫자의 방향을 기록한다
- 작지만 멍청해진 모델을 거절한다
- 작아졌다고 빨라졌다고 말하지 않는다
- 근거와 한계를 함께 배포한다