인공지능 모델을 학습시킨 후 가장 처음 마주치는 어려움은 '배포'입니다. 연구실이나 로컬 PC 환경에서는 잘 동작하던 PyTorch 코드가 실제 환경이나 리소스가 제한된 엣지 디바이스에서는 먹통이 되거나 느려지는 일이 발생합니다.이러한 문제를 해결하기 위해 다양한 플랫폼 간의 호환성을 보장하는 ONNX(Open Neural Network Exchange) 포맷이 많이 쓰입니다. 이번 포스팅에서는 PyTorch로 개발한 모델을 ONNX로 변환하고, 클라우드(AWS, FastAPI)와 엣지(TensorRT, 라즈베리파이) 환경에 맞춰 최적화하고 배포하는 방법을 살펴보겠습니다.

핵심 요약
- ONNX 변환의 필요성: PyTorch 모델을 ONNX 표준 포맷으로 변환하면 다양한 프레임워크와 하드웨어 가속 엔진(TensorRT 등)에서 최적의 성능을 낼 수 있습니다.
- 클라우드 배포 전략: 높은 확장성이 필요할 때는 AWS SageMaker를 활용하고, 가볍고 빠른 커스텀 API 서버를 구축할 때는 FastAPI와 ONNX Runtime 조합이 유리합니다.
- 엣지 배포 최적화: 엔비디아 젯공지능 모델을 학습시킨 후 가장 처음 마주치는 어려움은 '배포'입니다. 연구실이나 로컬 PC 환경에서는 잘 동작하던 PyTorch 코드가 실제 환경이나 리소스가 제한된 엣지 디바이스에서는 먹통이 되거나 느려지는 일이 발생합니다.이러한 문제를 해결하기 위해 다양한 플랫폼 간의 호환성을 보장하는 ONNX(Open Neural Network Exchange) 포맷이 많이 쓰입니다. 이번 포스팅에서는 PyTorch로 개발한 모델을 ONNX로 변환하고, 클라우드(AWS, FastAPI)와 엣지(TensorRT, 라즈베리파이) 환경에 맞춰 최적화하고 배포하는 방법을 살펴보겠습니다.
- 
- Generated by Gemini AI.
- 핵심 요약
- ONNX 변환의 필요성: PyTorch 모델을 ONNX 표준 포맷으로 변환하면 다양한 프레임워크와 하드웨어 가속 엔진(TensorRT 등)에서 최적의 성능을 낼 수 있습니다.
- 클라우드 배포 전략: 높은 확장성이 필요할 때는 AWS SageMaker를 활용하고, 가볍고 빠른 커스텀 API 서버를 구축할 때는 FastAPI와 ONNX Runtime 조합이 유리합니다.
- 엣지 배포 최적화: 엔비디아 젯슨 계열 디바이스에서는 TensorRT 엔진 변환을, 라즈베리파이와 같은 저사양 기기에서는 ONNX Runtime 라이트 버전을 사용하여 하드웨어 한계를 극복합니다.
1. 배포 환경별 특징 비교
모델을 배포하기 전에 우리가 타깃으로 하는 환경의 특성을 이해해야 합니다. 클라우드와 엣지는 구성과 제약 사항이 다릅니다.
| 배포 환경 | 주요 장점 | 주요 단점 | 추천 기술 스택 |
|---|---|---|---|
| 클라우드 (Cloud) | 고성능 자원(GPU/CPU), 유연한 확장성, 관리가 용이함 | 네트워크 지연(Latency), 인프라 이용 비용 | AWS SageMaker, FastAPI, Docker, ONNX Runtime |
| 엣지 (Edge) | 지연 시간 거의 없음, 오프라인 작동, 보안성 강화 | 제한된 하드웨어 성능(메모리/연산력), 디바이스별 파편화 | NVIDIA TensorRT, OpenVINO, ONNX Runtime Mobile |
2. PyTorch 모델을 ONNX로 변환하기
2.1. 모델 정의 및 준비
먼저 배포할 간단한 PyTorch 신경망 모델을 정의합니다. 예제 코드는 28x28 크기의 이미지를 입력받아 10개의 클래스로 분류하는 구조입니다.
import torch.nn as nn
# 간단한 신경망 모델 정의
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(28 * 28, 128)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# 모델 인스턴스 생성 (실제 환경에서는 학습된 가중치를 로드합니다)
model = SimpleNN()
model.eval() # 배포 전 평가 모드 전환은 필수입니다
2.2. ONNX 포맷 파일 내보내기
PyTorch 모델을 ONNX로 변환할 때는 추적(Tracing) 방식을 사용하므로 가상의 더미 입력 데이터가 필요합니다.
# 모델 구조에 맞는 더미 입력 데이터 생성 (배치 사이즈 1)
dummy_input = torch.randn(1, 28 * 28)
# ONNX 모델 변환 및 저장
torch.onnx.export(
model,
dummy_input,
"simple_model.onnx",
input_names=["input"],
output_names=["output"],
# 가변적인 배치 사이즈 처리를 위한 설정
dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}
)
print("ONNX 모델 변환이 완료되었습니다.")
3. 클라우드 환경에서 모델 배포
3.1. AWS SageMaker 활용한 완전 관리형 배포
대규모 트래픽을 안정적으로 처리해야 한다면 AWS SageMaker가 좋은 선택이 될 수 있습니다.
import boto3
import sagemaker
from sagemaker.model import Model
s3_bucket = "your-s3-bucket"
model_path = f"s3://{s3_bucket}/simple_model.onnx"
sagemaker_session = sagemaker.Session()
role = "your-sagemaker-role"
# SageMaker PyTorch 추론 이미지 사용
model = Model(
model_data=model_path,
role=role,
image_uri="763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-inference:2.0-cpu"
)
# 인스턴스에 엔드포인트 배포
predictor = model.deploy(initial_instance_count=1, instance_type="ml.m5.large")
print("AWS SageMaker 엔드포인트 배포가 완료되었습니다.")
3.2. FastAPI와 ONNX Runtime 기반 커스텀 API 배포
가볍고 독립적인 마이크로서비스를 구축하고 싶다면 FastAPI와 ONNX Runtime 조합이 좋습니다. PyTorch 무거운 라이브러리 없이 엔진만 돌리므로 컨테이너 용량이 줄어듭니다.
from fastapi import FastAPI
import onnxruntime as ort
import numpy as np
app = FastAPI()
# 서버 시작 시 ONNX 세션을 한 번만 로드하여 효율성 확보
session = ort.InferenceSession("simple_model.onnx")
@app.post("/predict")
def predict(input_data: list):
input_array = np.array(input_data, dtype=np.float32)
# ONNX Runtime 추론 실행
outputs = session.run(None, {"input": input_array})
return {"prediction": outputs[0].tolist()}
서버 실행 명령은 다음과 같습니다.
uvicorn app:app --host 0.0.0.0 --port 8000
4. 엣지(Edge) 환경에서 모델 배포
4.1. TensorRT를 활용한 엔비디아 디바이스 최적화
엔비디아 젯슨과 같은 하드웨어에서는 TensorRT를 사용하여 ONNX 모델을 하드웨어 전용 런타임 엔진으로 압축 변환해야 제 성능이 나옵니다.
import tensorrt as trt
logger = trt.Logger(trt.Logger.WARNING)
builder = trt.Builder(logger)
# 최신 TensorRT API 스펙에 맞춘 네트워크 플래그 설정
explicit_batch = 1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
network = builder.create_network(explicit_batch)
parser = trt.OnnxParser(network, logger)
with open("simple_model.onnx", "rb") as f:
if not parser.parse(f.read()):
for error in range(parser.num_errors):
print(parser.get_error(error))
config = builder.create_builder_config()
# 필요에 따라 FP16 정밀도 양자화 활성화 가능
# config.set_flag(trt.BuilderFlag.FP16)
serialized_engine = builder.build_serialized_network(network, config)
with open("simple_model.engine", "wb") as f:
f.write(serialized_engine)
print("TensorRT 엔진 파일이 성공적으로 빌드되었습니다.")
4.2. 라즈베리파이에서 ONNX Runtime 실행
라즈베리파이와 같은 소형 CPU 기반 엣지 장치에서는 무거운 프레임워크 대신 onnxruntime 라이브러리만 설치하여 가볍게 구동합니다.
import onnxruntime as ort
import numpy as np
# 라즈베리파이 환경에서 ONNX 세션 초기화
session = ort.InferenceSession("simple_model.onnx")
# 입력 데이터 생성 및 추론
input_data = np.random.randn(1, 28 * 28).astype(np.float32)
outputs = session.run(None, {"input": input_data})
print("엣지 디바이스 추론 결과:", outputs)
개발을 위한 팁
- 모델 변환 전 검증하기: PyTorch 모델을 ONNX로 내보낸 후에는 반드시 onnx.checker.check_model() 함수를 사용해 파일 구조가 깨지지 않았는지 확인하세요.
- Netron 도구 활용: 변환된 .onnx 파일의 내부 연산 그래프와 입출력 텐서의 이름, 형태를 시각적으로 확인하고 싶다면 무료 오픈소스 시각화 도구인 Netron(netron.app)을 사용하는 것이 좋습니다.
- 동적 배치(Dynamic Axes) 관리: FastAPI나 클라우드 배포 환경에서는 요청마다 데이터 개수가 다를 수 있으므로 변환 단계에서 dynamic_axes를 정확히 지정해야 에러가 나지 않습니다.
흔히 하는 실수
- model.eval() 호출 누락: PyTorch 모델을 ONNX로 변환하기 전에 model.eval()을 호출하지 않으면 드롭아웃(Dropout)이나 배치 정규화(Batch Normalization) 레이어가 학습 모드로 고정되어 변환되어 버립니다. 이 경우 추론할 때마다 결과가 일관되지 않게 나옵니다.
- 데이터 타입(DataType) 불일치: PyTorch는 기본적으로 float32 연산을 주로 사용하지만, 파이썬 리스트나 다른 라이브러리 데이터를 가공하다 보면 float64로 변환되는 경우가 많습니다. ONNX Runtime 입력 시 타입 불일치 에러가 발생하므로 반드시 astype(np.float32) 처리를 해주어야 합니다.
- 하드웨어 종속적인 연산자 사용: PyTorch의 일부 특수한 커스텀 연산자나 최신 레이어는 ONNX 표준 연산자로 변환되지 않을 수 있습니다. 배포 대상 환경의 ONNX 런타임 버전이 해당 연산자를 지원하는지 미리 리스트를 교차 검증해야 합니다.
5. 결론
모델 배포는 단순히 코드를 실행하는 것을 넘어 목적 시스템의 자원 한계를 고려하는 엔지니어링 영역입니다. 대규모 트래픽 분산과 안정적인 API 관리가 중심이라면 AWS나 FastAPI 기반의 클라우드 배포가 정답입니다. 반면 전력 소모를 줄이고 로컬에서 실시간 처리를 달성해야 한다면 TensorRT나 ONNX Runtime을 활용한 엣지 최적화가 필수적입니다.내가 서비스하고자 하는 비즈니스의 요건과 인프라 비용, 지연 시간 기준을 종합적으로 고려하여 가장 알맞은 배포 파이프라인을 구축하시길 바랍니다.
'Python for AI, Embedded > Deep Learning: PyTorch & AI Modeling' 카테고리의 다른 글
| PyTorch 모델 배포 마스터: TensorRT로 추론 속도 극대화하는 방법 (0) | 2026.05.31 |
|---|---|
| PyTorch 모델을 ONNX로 변환하고 ONNX Runtime으로 배포하는 방법 (0) | 2026.05.30 |
| PyTorch OpenCV 실시간 객체 탐지: YOLOv5 웹캠 연동 가이드 (0) | 2026.05.29 |
| PyTorch 라이브러리로 사전 학습된 Faster R-CNN 객체 탐지 모델 구현하기 (0) | 2026.05.28 |
| YOLO vs Faster R-CNN 비교: 내 프로젝트에 맞는 객체 탐지 모델 선택 가이드 (0) | 2026.05.27 |