파이썬으로 ONNX 다루기
파이썬으로 ONNX 다루기 (ONNX with Python)
ONNX 그래프를 파이썬으로 직접 만드는 법을 알면, 모델을 어떻게 표현하고 검증하는지 이해할 수 있어요. ONNX 파이썬 API는 헬퍼 함수 몇 개로 그래프의 요소(입력·출력·노드)를 만들고, 이들을 묶어 모델로 만드는 방식이에요. 선형 회귀 예제로 흐름을 따라가 보죠.
선형 회귀 예제
선형 회귀는 Y = XA + B 로 표현되는 가장 단순한 머신러닝 모델이에요. 이를 y = Add(MatMul(X, A), B) 로 ONNX 연산자로 표현해요. ONNX는 강타입이라 함수의 입력과 출력 모두 모양과 타입을 정의해야 해요. 그래프를 만드는 핵심 헬퍼 함수는 네 가지예요.
make_tensor_value_info: 주어진 모양과 타입으로 변수(입력 또는 출력) 선언.make_node: 연산(연산자 타입), 입력, 출력으로 정의되는 노드 생성.make_graph: 앞 두 함수가 만든 객체들로 ONNX 그래프 생성.make_model: 그래프와 추가 메타데이터를 합치는 마지막 함수.
from onnx import TensorProto
from onnx.helper import (
make_model, make_node, make_graph,
make_tensor_value_info)
from onnx.checker import check_model
# 입력
X = make_tensor_value_info('X', TensorProto.FLOAT, [None, None])
A = make_tensor_value_info('A', TensorProto.FLOAT, [None, None])
B = make_tensor_value_info('B', TensorProto.FLOAT, [None, None])
# 출력, 모양은 미정
Y = make_tensor_value_info('Y', TensorProto.FLOAT, [None])
# 노드
node1 = make_node('MatMul', ['X', 'A'], ['XA'])
node2 = make_node('Add', ['XA', 'B'], ['Y'])
# 노드들로 그래프 구성
graph = make_graph([node1, node2], 'lr', [X, A, B], [Y])
# ONNX 모델 생성
onnx_model = make_model(graph)
# 모델이 일관적인지 확인
check_model(onnx_model)
텐서 타입은 정수 값이에요(예: FLOAT 는 1). 헬퍼 onnx.helper.tensor_dtype_to_np_dtype() 이 그 정수를 넘파이 dtype(float32)으로 바꿔줘요.
직렬화와 numpy 변환
onnx 는 numpy와 onnx를 오가는 두 함수를 제공해요. onnx.numpy_helper.to_array 는 onnx에서 numpy로, onnx.numpy_helper.from_array 는 numpy에서 onnx로 변환해요.
속성
Transpose 같이 속성이 필요한 연산자도 있어요. y = XA' + B 같은 표현에서 Transpose는 축 순열을 정의하는 속성 perm=[1, 0] 이 필요하고, make_node 의 명명된 속성으로 추가돼요.
Opset과 메타데이터
opset domain='' version=14
opset 버전이 달라지면 연산자 정의 방식이 달라질 수 있어요. 예를 들어 Reshape 연산자 버전 5는 모양을 속성이 아니라 입력으로 정의해요. opset은 그래프를 설명할 때 어떤 규격을 따르는지 알려줘요.
파싱
onnx.parser 모듈은 그래프를 정의하는 더 빠르고 읽기 쉬운 방법을 제공해요. 그래프를 단일 함수로 만들 때 특히 편리해요.
import onnx.parser
from onnx.checker import check_model
input = '''
<
ir_version: 8,
opset_import: ["" : 15]
>
agraph (float[I,J] X, float[I] A, float[I] B) => (float[I] Y) {
XA = MatMul(X, A)
Y = Add(XA, B)
}
'''