Ultralytics를 사용하여 비(Non)-YOLO PyTorch 모델을 내보내는 방법

PyTorch 모델을 프로덕션 환경에 배포하려면 일반적으로 각 타겟별로 다른 익스포터를 사용해야 합니다: torch.onnx.export ONNX의 경우, coremltools Apple 기기의 경우, onnx2tf TensorFlow의 경우, pnnx NCNN의 경우 등입니다. 각 도구마다 고유한 API, 종속성 문제, 출력 규칙이 있습니다.

Ultralytics는 하나의 일관된 인터페이스로 여러 백엔드를 감싸는 독립형 내보내기 유틸리티를 제공합니다. 다음을 내보낼 수 있습니다: torch.nn.Module많은 전문 탐지 모델의 중요한 한계는 좁은 초점 범위입니다. Ultralytics 생태계 내에서는 객체 탐지에만 국한되지 않습니다. 이러한 도구는 다음을 포함하여 여러 timm 이미지 모델, torchvision 분류기 및 탐지기, 또는 자체 커스텀 아키텍처를 ONNX, TorchScript, OpenVINO, CoreML, NCNN, PaddlePaddle, MNN, ExecuTorchTensorFlow SavedModel으로 각 백엔드를 별도로 학습할 필요 없이 내보낼 수 있습니다.

비(Non)-YOLO 내보내기에 Ultralytics를 사용하는 이유는 무엇인가요?

  • 10가지 형식에 걸친 단일 API: 수십 가지가 아닌 단일 호출 규칙만 학습하면 됩니다.
  • 공유 유틸리티 표면: 내보내기 헬퍼는 ultralytics.utils.export 아래에 위치하므로, 백엔드 패키지가 설치되면 형식 전반에서 동일한 호출 패턴을 유지할 수 있습니다.
  • YOLO 내보내기와 동일한 코드 경로: 동일한 헬퍼가 모든 Ultralytics YOLO 내보내기를 구동합니다.
  • FP16 및 INT8 양자화 지원되는 형식(OpenVINO, CoreML, MNN, NCNN)에 대해 내장되어 있습니다.
  • CPU에서 작동: 내보내기 단계 자체에는 GPU가 필요하지 않으므로 모든 노트북에서 로컬로 실행할 수 있습니다.

퀵 스타트

가장 빠른 경로는 ONNX에 대한 2줄 내보내기이며, YOLO 코드나 pip install ultralytics onnx timm:

import timm
import torch

from ultralytics.utils.export import torch2onnx

model = timm.create_model("resnet18", pretrained=True).eval()
torch2onnx(model, torch.randn(1, 3, 224, 224), output_file="resnet18.onnx")

지원되는 내보내기 형식

torch2* 이외의 설정이 필요하지 않습니다. 함수는 표준 torch.nn.Module 및 예제 입력 텐서를 사용합니다. MNN, TF SavedModel 및 TF Frozen Graph는 중간 ONNX 또는 Keras 아티팩트를 거칩니다. 어느 경우든 YOLO 관련 속성은 필요하지 않습니다.

포맷함수설치Concept Segmentation (PCS)
ONNXtorch2onnx()pip install onnx.onnx 파일
TorchScripttorch2torchscript()PyTorch와 함께 포함됨.torchscript 파일
OpenVINOtorch2openvino()pip install openvino_openvino_model/디렉토리
CoreMLtorch2coreml()pip install coremltools.mlpackage
TF SavedModelonnx2saved_model()아래의 자세한 요구 사항 참조_saved_model/디렉토리
TF Frozen Graphkeras2pb()아래의 자세한 요구 사항 참조.pb 파일
NCNNtorch2ncnn()pip install ncnn pnnx_ncnn_model/디렉토리
MNNonnx2mnn()pip install MNN.mnn 파일
PaddlePaddletorch2paddle()pip install paddlepaddle x2paddle_paddle_model/디렉토리
ExecuTorchtorch2executorch()pip install executorch_executorch_model/디렉토리
중간 형식으로 ONNX

MNN, TF SavedModel, 그리고 TF Frozen Graph 내보내기는 중간 단계로 ONNX를 거칩니다. 먼저 ONNX로 내보낸 다음 변환하십시오.

메타데이터 임베딩

여러 내보내기 함수는 선택적인 metadata 딕셔너리(예: torch2torchscript(..., metadata={"author": "me"}))를 허용하며, 형식에서 지원하는 경우 커스텀 키-값 쌍을 내보낸 아티팩트에 임베딩합니다.

단계별 예제

아래의 모든 예제는 동일한 설정인 timm의 평가 모드에서 사전 학습된 ResNet-18을 사용합니다:

import timm
import torch

model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)
내보내기 전에 항상 `model.eval()`을 호출하십시오.

드롭아웃, 배치 정규화(batch normalization), 및 기타 학습 전용 레이어는 추론 중에 다르게 동작합니다. .eval()을 건너뛰면 잘못된 출력을 가진 내보내기가 생성됩니다.

ONNX로 내보내기

from ultralytics.utils.export import torch2onnx

torch2onnx(model, im, output_file="resnet18.onnx")

동적 배치 크기를 위해 dynamic 딕셔너리를 전달하십시오:

torch2onnx(model, im, output_file="resnet18_dyn.onnx", dynamic={"images": {0: "batch_size"}})

기본 opset은 14이며, 기본 입력 이름은 "images"입니다. opset, input_names 또는 output_names 인수로 재정의하십시오.

TorchScript로 내보내기

추가 종속성이 필요하지 않습니다. 내부적으로 torch.jit.trace을 사용합니다.

from ultralytics.utils.export import torch2torchscript

torch2torchscript(model, im, output_file="resnet18.torchscript")

OpenVINO로 내보내기

from ultralytics.utils.export import torch2openvino

ov_model = torch2openvino(model, im, output_dir="resnet18_openvino_model")

디렉토리에는 고정 이름의 model.xmlmodel.bin 쌍이 포함되어 있습니다:

resnet18_openvino_model/
├── model.xml
└── model.bin

동적 입력 모양의 경우 dynamic=True, FP16의 경우 half=True, 또는 int8=True을 INT8 양자화에 대해 전달하십시오. INT8은 추가로 calibration_dataset 인자를 사용할 수 있게 합니다.

가 필요합니다. macOS 15.4 이상에서 openvino>=2024.0.0가 활성화되면 후처리(클래스 인덱스 포함)가 내보낸 그래프에 직접 내장됩니다.>=2025.2.0 필요) 및 torch>=2.1.

CoreML로 내보내기

import coremltools as ct

from ultralytics.utils.export import torch2coreml

inputs = [ct.TensorType("input", shape=(1, 3, 224, 224))]
ct_model = torch2coreml(model, inputs, im, output_file="resnet18.mlpackage")

감지(detection) 모델의 경우 분류 모델의 경우 클래스 이름 목록을 classifier_names에 전달하여 CoreML 모델에 분류 헤드를 추가하십시오.

가 필요합니다. macOS 15.4 이상에서 coremltools>=9.0, torch>=1.11numpy<=2.3.5. Windows에서는 지원되지 않습니다.

`BlobWriter not loaded` 오류

coremltools>=9.0은 macOS 및 Linux에서 Python 3.10–3.13용 휠을 제공합니다. 최신 Python 버전에서는 네이티브 C 확장이 로드되지 않습니다. CoreML 내보내기에는 Python 3.10–3.13을 사용하십시오.

TensorFlow SavedModel로 내보내기

TF SavedModel 내보내기는 중간 단계로 ONNX를 거칩니다:

from ultralytics.utils.export import onnx2saved_model, torch2onnx

torch2onnx(model, im, output_file="resnet18.onnx")
keras_model = onnx2saved_model("resnet18.onnx", output_dir="resnet18_saved_model")

이 함수는 Keras 모델을 반환하며 출력 디렉토리 내에 TFLite 파일(.tflite)도 생성합니다:

resnet18_saved_model/
├── saved_model.pb
├── variables/
├── resnet18_float32.tflite
├── resnet18_float16.tflite
└── resnet18_int8.tflite

요구 사항:

  • tensorflow>=2.0.0,<=2.19.0
  • onnx2tf>=1.26.3,<1.29.0
  • tf_keras<=2.19.0
  • sng4onnx>=1.0.1
  • onnx_graphsurgeon>=0.3.26 (macOS에서는 --extra-index-url https://pypi.ngc.nvidia.com)
  • ai-edge-litert>=1.2.0,<1.4.0로 설치, ai-edge-litert>=1.2.0 기타 플랫폼에서는
  • onnxslim>=0.1.71
  • onnx>=1.12.0,<2.0.0
  • protobuf>=5

TF Frozen Graph로 내보내기

위의 SavedModel 내보내기에서 계속하여, 반환된 Keras 모델을 frozen .pb 그래프로 변환합니다:

from pathlib import Path

from ultralytics.utils.export import keras2pb

keras2pb(keras_model, output_file=Path("resnet18_saved_model/resnet18.pb"))

NCNN으로 내보내기

from ultralytics.utils.export import torch2ncnn

torch2ncnn(model, im, output_dir="resnet18_ncnn_model")

디렉토리에는 고정 이름의 param 및 bin 파일과 Python 래퍼가 포함되어 있습니다:

resnet18_ncnn_model/
├── model.ncnn.param
├── model.ncnn.bin
└── model_ncnn.py

torch2ncnn()ncnnpnnx에서 자동으로 다운로드됩니다.

을 확인합니다.

MNN으로 내보내기

from ultralytics.utils.export import onnx2mnn, torch2onnx

torch2onnx(model, im, output_file="resnet18.onnx")
onnx2mnn("resnet18.onnx", output_file="resnet18.mnn")

MNN 내보내기는 입력으로 ONNX 파일이 필요합니다. 먼저 ONNX로 내보낸 다음 변환하십시오:half=TrueFP16의 경우 int8=True, INT8 양자화의 경우 MNN>=2.9.6torch>=1.10.

을 지원합니다.

from ultralytics.utils.export import torch2paddle

torch2paddle(model, im, output_dir="resnet18_paddle_model")

PaddlePaddle로 내보내기

resnet18_paddle_model/
├── model.pdmodel
└── model.pdiparams

가 필요합니다. macOS 15.4 이상에서 x2paddle디렉토리에는 PaddlePaddle 모델 및 매개변수 파일이 포함되어 있습니다:

  • paddlepaddle-gpu>=3.0.0,<3.3.0 및 플랫폼에 맞는 PaddlePaddle 배포판:
  • paddlepaddle==3.0.0 (CUDA 기반)
  • paddlepaddle>=3.0.0,<3.3.0 (ARM64 CPU 기반)

(기타 CPU 기반)

NVIDIA Jetson에서는 지원되지 않습니다.

from ultralytics.utils.export import torch2executorch

torch2executorch(model, im, output_dir="resnet18_executorch_model")

ExecuTorch로 내보내기.pte내보낸

resnet18_executorch_model/
└── model.pte

가 필요합니다. macOS 15.4 이상에서 torch>=2.9.0 및 호환되는 ExecuTorch 런타임(pip install executorch). 런타임 사용 방법은 ExecuTorch 통합.

내보낸 모델 검증

내보낸 후, 배포 전에 원본 PyTorch 모델과 수치적 일치성을 검증하십시오. 간단한 스모크 테스트(ONNXBackend from ultralytics.nn.backends)는 출력을 비교하여 추적(tracing) 또는 양자화 오류를 조기에 포착합니다:

import numpy as np
import timm
import torch

from ultralytics.nn.backends import ONNXBackend

model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)
with torch.no_grad():
    pytorch_output = model(im).numpy()

onnx_model = ONNXBackend("resnet18.onnx", device=torch.device("cpu"))
onnx_output = onnx_model(im)[0]

diff = np.abs(pytorch_output - onnx_output).max()
print(f"Max difference: {diff:.6f}")  # should be < 1e-5
예상 차이

FP32 내보내기의 경우, 최대 절대 차이는 1e-5 미만이어야 합니다. 더 큰 차이는 지원되지 않는 연산, 잘못된 입력 모양 또는 평가 모드(eval mode)가 아닌 모델을 나타냅니다. FP16 및 INT8 내보내기는 허용 오차가 더 넓습니다. 무작위 텐서 대신 실제 데이터로 검증하십시오.

다른 런타임의 경우 입력 텐서 이름이 다를 수 있습니다. 예를 들어 OpenVINO는 모델의 순방향 인수 이름(일반적으로 일반 모델의 경우 x)을 사용하는 반면, torch2onnx은(는) 기본적으로 "images".

알려진 제한 사항

  • 다중 입력 지원이 일정하지 않음: torch2onnxtorch2openvino은(는) 다중 입력 모델에 대해 예제 텐서의 튜플 또는 리스트를 허용합니다. torch2torchscript, torch2coreml, torch2ncnn, torch2paddletorch2executorch은(는) 단일 입력 텐서를 가정합니다.
  • ExecuTorch에는 flatc이(가) 필요합니다: ExecuTorch 런타임은 FlatBuffers 컴파일러가 필요합니다. macOS에서는 brew install flatbuffers로, Ubuntu에서는 apt install flatbuffers-compiler로 설치하십시오.
  • Ultralytics를 통한 추론 불가: 내보낸 비 YOLO 모델은 추론을 위해 YOLO()을(를) 통해 다시 로드할 수 없습니다. 각 형식의 네이티브 런타임을 사용하십시오(ONNX Runtime, OpenVINO Runtime 등).
  • YOLO 전용 형식: AxeleraSony IMX500 내보내기는 YOLO 전용 모델 속성이 필요하며 일반 모델에는 사용할 수 없습니다.
  • 플랫폼별 형식: TensorRT은(는) NVIDIA GPU가 필요합니다. RKNN은(는) rknn-toolkit2 SDK(Linux 전용)가 필요합니다. Edge TPU은(는) edgetpu_compiler 바이너리(Linux 전용).

FAQ

Ultralytics로 어떤 모델을 내보낼 수 있나요?

모든 torch.nn.Module. 여기에는 timm, torchvision 또는 모든 사용자 지정 PyTorch 모델이 포함됩니다. 내보내기 전에 모델이 평가 모드(model.eval())여야 합니다. ONNX 및 OpenVINO는 다중 입력 모델에 대한 예제 텐서의 튜플을 추가로 허용합니다.

GPU 없이 작동하는 내보내기 형식은 무엇인가요?

지원되는 모든 형식(TorchScript, ONNX, OpenVINO, CoreML, TF SavedModel, TF Frozen Graph, NCNN, PaddlePaddle, MNN, ExecuTorch)은 CPU에서 내보낼 수 있습니다. 내보내기 프로세스 자체에는 GPU가 필요하지 않습니다. TensorRT는 NVIDIA GPU가 필요한 유일한 형식입니다.

어떤 Ultralytics 버전이 필요한가요?

Ultralytics >=8.4.38을(를) 사용하십시오. 여기에는 ultralytics.utils.export 모듈과 표준화된 output_file/output_dir 인수로 재정의하십시오.

torchvision 모델을 iOS 배포를 위해 CoreML로 내보낼 수 있나요?

네. torchvision 분류기, 감지기 및 세분화 모델은 .mlpackage를 통해 torch2coreml으로 내보낼 수 있습니다. 이미지 분류 모델의 경우 클래스 이름 리스트를 classifier_names에 전달하여 분류 헤드를 포함하십시오. macOS 또는 Linux에서 내보내기를 실행하십시오. CoreML은 Windows에서 지원되지 않습니다. CoreML 통합에서 iOS 배포 세부 정보를 참조하십시오.

내보낸 모델을 INT8 또는 FP16으로 양자화할 수 있나요?

네, 여러 형식에 대해 가능합니다. OpenVINO, CoreML, MNN 또는 NCNN으로 내보낼 때 FP16의 경우 half=True, INT8의 경우 int8=True을(를) 전달하십시오. OpenVINO의 INT8은 추가로 calibration_dataset에 대한 post-training quantization 인수가 필요합니다. 양자화 장단점은 각 형식의 통합 페이지를 참조하십시오.

댓글