Why ONNX Became the Silent Industry Standard for Model Deployment
딥러닝 프레임워크가 달라도 모델을 “옮겨 쓰게” 만든 표준이 ONNX이고, 이게 조용히 업계의 공동어가 되었다
Hun Jang Nov 26, 2025
ONNX가 모델 교환의 표준이 된 이유
요약하면: 딥러닝 프레임워크가 달라도 모델을 “옮겨 쓰게” 만든 표준이 ONNX이고, 이게 조용히 업계의 공동어가 되었다는 얘기다.
왜 ONNX가 중요해졌나
- TensorFlow vs. PyTorch: TF는 배포(Serving, TFLite, XLA)에 강했고, PyTorch는 연구/프로토타이핑에 강했다. 서로 생태계가 달라 모델을 재학습하거나 이식 비용이 컸다.
- ONNX(2017~): 그래프와 연산(opset)을 표준화해 **프레임워크‑무관 내보내기/가져오기(export/import)**를 가능하게 했다. 그 뒤 ONNX Runtime(ORT), TensorRT‑ONNX, OpenVINO‑ONNX 같은 런타임이 붙으며 “한 번 학습 → 어디서나 추론” 흐름이 굳어졌다.
- 정치/현실: 각 진영의 저장형식(SavedModel, TorchScript/torch.package)만으로는 타 진영 배포망에 쉽게 못 실었다. 클라우드/엣지 벤더들이 ONNX를 공통 인터페이스로 채택하면서 사실상 배포 표준으로 굳었다.
개발자가 체감하는 효용
- 벤더 락인 완화: 엔진을 ORT, TensorRT, OpenVINO, CoreML 등으로 바꿔가며 같은 모델을 테스트/배포.
- 성능 포터블: EP(Execution Provider)만 갈아끼워 CPU→CUDA→TensorRT→DirectML 등으로 옮기기 쉽다.
- 수명 연장: 연구는 PyTorch 최신, 배포는 하위 호환 EP로—프레임워크/버전 교체 주기를 분리.
실전 메모 (xvoice/음성 TTS에 바로 쓰는 관점)
- Export 팁(PyTorch → ONNX)
opset_version은 보수적으로(예: 17~19대) 고정. 새 opset은 엔진별 지원 편차가 크다.- dynamic axes로 길이 가변 입력(텍스트/멜 프레임)을 지정해 배치·길이 유연성 확보.
- 커스텀 함수는 torch.onnx.export() 이전에 TorchScript/FX로 치환하거나 CustomOp로 분리.
- ORT 통합 체크리스트
- 세션 옵션 고정: API/ABI 흔들림 방지(예: 1.17/1.20/1.23 간 미세 차).
- I/O 바인딩: CPU‑GPU 간 메모리 복사 최소화(특히 멜→보코더 파이프).
- EP 우선순위:
CUDA > TensorRT(가능 시) > CPU순서로 시도, 실패 시 폴백. - 스레딩:
intra_op,inter_op를 모델 특성(보코더는 SIMD/스레드 효율 큼)에 맞춰 튜닝. - 프로파일러: ORT 프로파일 JSON 켜서 op별 병목 확인, 필요 시 Fusion/MatMulPrecision 옵션 조정.
- VITS 계열 분리 배포
- Decoder(모듈화) / Vocoder(독립 세션): 세션을 나눠 로드/해제와 캐시 전략을 다르게 운용.
- 정밀도 전략: FP16(AMP) → 품질 민감 구간(포스트넷 등)은 FP32 유지로 균형.
흔한 함정
- opset만 맞춘다고 끝이 아님: 특정 연산자(ConvTranspose, GroupNorm, Einsum 등)의 수치차가 엔진별로 존재. 샘플‑투‑샘플 재현성 검증 필수.
- shape 추론 실패: 동적 축 미지정/잘못 지정 시 런타임에서 불필요한 리셰이프/복사가 발생.
- 커스텀 토치 연산: 미지원 op는 그래프 분해 후 표준 op로 재작성하거나 커스텀 EP가 필요.
빠른 스타터(의사 코드)
정리
- 연구는 PyTorch, 배포는 ONNX(+각종 EP)로 분업하는 시대다.
- TTS 스택을 직접 빌드하는 경우, **“훈련 포맷 ≠ 배포 포맷”**로 사고하면 출시 속도와 이식성이 커진다.