ONNX Export Fidelity and Equivalence
마지막 수정:
ONNX와 ONNX Runtime은 다르다.
ONNX:
모델 그래프를 저장하는 파일 형식
ONNX Runtime:
ONNX 파일을 실제로 실행하는 inference engine
ONNX는 악보이고, ONNX Runtime은 연주자다. .onnx 파일이 있다고 해서 그 모델이 원래 PyTorch 모델과 같은 출력을 낸다는 보장은 없다.
Export fidelity
- Compare
- PyTorch FP -> ONNX FP
- Metric
- max |delta|, cosine, prediction agreement
- Read as
- 큰 차이면 quantization 전에 export 문제
Quantized equivalence
- Compare
- ONNX FP -> ONNX INT8
- Metric
- logit drift, task metric delta
- Read as
- 큰 차이면 calibration 또는 quantization scheme 문제
Task acceptance
- Compare
- FP baseline -> deployed artifact
- Metric
- accuracy, perplexity, slice eval
- Read as
- 품질 예산 안이면 ship, 아니면 targeted fix
먼저 FP export가 같은지 확인한다
가장 먼저 비교할 것은 quantized model이 아니다.
PyTorch FP32 / FP16
vs
ONNX FP32 / FP16
여기서 차이가 크면 quantization 문제가 아니다. 모델을 ONNX 그래프로 옮기는 export 단계에서 이미 의미가 달라진 것이다.
확인 지표는 raw output을 직접 비교한다.
max absolute logit difference
mean absolute error
cosine similarity
prediction agreement
task metric
ONNX checker가 통과해도 충분하지 않다. 그래프 구조가 유효하다는 것과 원래 모델과 같은 출력을 낸다는 것은 다른 문제다.
Export 문제가 보이면 quantization을 만지지 않는다
FP export부터 틀렸다면 처방은 export 쪽이다.
opset version 조정
legacy exporter 사용
dynamic axes / dynamic shapes 명시
custom operator 변환 확인
tracing input shape이 고정되어 있지 않은지 확인
예를 들어 PyTorch의 ONNX exporter 경로가 바뀌거나, dynamic shape 지원이 불완전하거나, custom op가 이상하게 변환되면 .onnx 파일은 만들어져도 output이 달라질 수 있다.
그래서 순서는 항상 이렇다.
1. ONNX FP가 PyTorch FP와 같은가?
2. 같다면 quantized ONNX를 본다.
3. 다르다면 export부터 고친다.
그다음 quantized equivalence를 본다
FP export가 안정적이면 그다음 quantized artifact를 비교한다.
ONNX FP
vs
ONNX INT8
여기서 생기는 차이는 quantization arithmetic, calibration range, static/dynamic 선택, granularity 때문에 생긴다.
중요한 것은 logit 차이와 task 결과를 같이 보는 것이다.
logit drift는 있지만 prediction agreement 유지
-> 허용 가능할 수 있음
logit drift 때문에 top-1이 뒤집힘
-> 실제 품질 문제
LLM이나 binary classifier처럼 output margin이 작으면 같은 logit shift도 더 위험할 수 있다.
문제를 분리해서 고친다
결과가 달라졌을 때 원인을 섞으면 안 된다.
PyTorch FP vs ONNX FP가 다름
-> export fidelity 문제
ONNX FP는 같고 ONNX INT8만 다름
-> quantization equivalence 문제
둘 다 괜찮은데 serving에서 다름
-> runtime/provider/config 문제
Quantization 문제라면 다음을 본다.
calibration data 보강
static vs dynamic quantization 변경
per-tensor vs per-channel 변경
sensitive node 제외
transformer-aware optimizer 사용
핵심은 “ONNX로 변환됐다”가 아니라 “같은 입력에 대해 같은 의미의 출력을 내는가”다.
확인
- ONNX와 ONNX Runtime은 각각 무엇인가?
- PyTorch FP와 ONNX FP가 다르면 왜 quantization을 먼저 고치면 안 되는가?
- Accuracy는 같은데 raw logits가 크게 다를 때 어떤 위험이 있는가?