ONNX 변환기

ONNX 변환기 (Converters)

어떤 프레임워크에서 학습한 모델을 ONNX로 옮기려면 그 프레임워크 전용의 변환 라이브러리 를 쓰는 게 가장 쉬워요. 변환기는 모델의 예측 함수를 ONNX 연산자로 다시 써서, 원래 모델로 계산한 예측과 같거나 아주 가까운 결과를 보장해요. 각 머신러닝 라이브러리마다 설계가 달라서 변환 라이브러리도 각각 존재해요.

출처: ONNX 공식 문서 — Converters

변환 라이브러리란

대표적인 변환 라이브러리를 짧게 보면 이렇지만, 목록은 계속 늘어나고 있어요.

  • sklearn-onnx: scikit-learn 모델 변환.
  • tensorflow-onnx: TensorFlow 모델 변환.
  • jax2onnx: JAX 모델 변환.
  • onnxmltools: lightgbm, xgboost, pyspark, libsvm 등 변환.
  • torch.onnx: PyTorch 모델 변환.

이 라이브러리들의 주요 과제는 릴리스 속도를 따라가는 것이에요. ONNX나 대상 라이브러리가 새 버전을 낼 때마다 갱신돼야 해서, 보통 1년에 3~5번 릴리스가 필요해요. 또 변환 라이브러리끼리는 서로 호환되지 않아요. tensorflow-onnx 는 TensorFlow 전용, sklearn-onnx 는 scikit-learn 전용이에요.

커스터마이징도 어려운 부분이에요. 모델 안의 커스텀 조각을 지원하려면 그 조각을 위한 전용 변환기를 직접 작성해야 해요. 프레임워크의 기본 요소(pytorch나 tensorflow의 원시 연산)를 쓰는 경우는 비교적 쉽지만, scikit-learn처럼 numpy/scipy에 의존하는 경우엔 사용자가 ONNX 원시 연산으로 직접 구현해야 할 수 있어요.

대안: Array API 표준

ONNX 내보내기 능력을 구현하는 한 가지 대안은 Array API 표준 같은 공통 프로토콜을 활용하는 거예요. 이는 공통 배열 연산 집합을 표준화해서 NumPy, JAX, PyTorch, CuPy 등 여러 라이브러리 간에 코드를 재사용할 수 있게 해요. ndonnx 는 Array API 호환 코드에 ONNX 백엔드 실행과 즉시 ONNX 내보내기를 제공해서, 전용 변환 라이브러리 코드의 필요를 줄여줘요.

Opset

ONNX는 major.minor.fix 버전으로 배포돼요. 매번 minor 업데이트는 연산자 목록이 다르거나 시그니처가 바뀌는 것을 뜻해요. 모든 ONNX 그래프는 자신이 따르는 opset을 정의해야 해요. 변환 라이브러리는 보통 특정 opset용 그래프를 만드는 target_opset 을 지원해요. opset을 바꾸는 것은 라이브러리를 업그레이드하는 것과 비슷하고, onnx와 런타임은 하위 호환성을 지원해야 해요.

경험에서 얻은 요령

ONNX는 강타입이고 딥러닝에서 가장 흔한 float32 를 최적화 대상으로 삼아요. 표준 머신러닝 라이브러리는 float32와 float64를 함께 쓰는데, numpy는 보통 가장 범용적인 float64로 캐스팅해요. 피처가 어느 구간에 속하는지 보는 이산화(discretization) 같은 작업은 numpy로는 쉽지만 ONNX로는 비효율적일 수 있어서, 구간 인덱스를 출력하는 TreeEnsembleRegressor 를 쓰는 방식이 더 빠를 수 있어요.

더 알아보기