YOLO Vision 2026:

Ultralyticsを使用した非YOLO PyTorchモデルのエクスポート方法#

Ultralytics は、複数のバックエンドを1つの統一されたインターフェースでラップするスタンドアロンのエクスポートユーティリティを ultralytics.utils.export の下で提供しています。timm の画像モデル、torchvision の分類器や検出器、あるいは独自のカスタムアーキテクチャを含むあらゆる torch.nn.Module を、個別のバックエンドを個別に学ぶことなく、ONNXTorchScriptOpenVINOCoreMLNCNNPaddlePaddleMNNExecuTorchTensorFlow SavedModel にエクスポートできます。

PyTorch モデルの本番環境へのデプロイでは通常、ターゲットごとに異なるエクスポーター(ONNX には torch.onnx.export、Apple デバイスには coremltools、TensorFlow には onnx2tf、NCNN には pnnx など)を使い分ける必要があります。それぞれのツールには独自の API、依存関係の癖、出力規約があります。これらのユーティリティは、それを単一の呼び出しパターンに統合します。

非YOLOモデルのエクスポートにUltralyticsを使用する理由#

  • 10種類のフォーマットに対応した単一のAPI: 多数の呼び出し規約を覚える必要はなく、一つだけ学習すれば済みます。
  • 共有ユーティリティサーフェス: エクスポートヘルパーは ultralytics.utils.export の下に配置されているため、バックエンドパッケージをインストールすれば、フォーマット間で同じ呼び出しパターンを維持できます。
  • YOLOエクスポートと同じコードパス: すべてのUltralytics YOLOエクスポートを支えるのと同じヘルパーが使用されています。
  • FP16およびINT8量子化: 対応するフォーマット(OpenVINO、CoreML、MNN、NCNN)には標準で組み込まれています。
  • CPUで動作可能: エクスポート手順自体にGPUは不要なため、どのノートパソコンからでもローカルで実行できます。

クイックスタート#

最も早い方法は、YOLOコードを使用せず、pip install ultralytics onnx timm 以外のセットアップも必要とせずに、2行で ONNX にエクスポートすることです。

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 固有の属性は必要ありません。

形式関数インストール出力
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

MNNTF 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()`を呼び出してください

ドロップアウト、バッチ正規化、およびその他の訓練専用レイヤーは、推論時に異なる動作をします。.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" です。opsetinput_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 には quantize=16 を、INT8 量子化には quantize=8 を渡します。INT8 には追加で calibration_dataset 引数が必要です。

openvino>=2024.0.0(または macOS 15.4+ では >=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, classifier_names=None, output_file="resnet18.mlpackage")

分類モデルの場合、クラス名のリストを classifier_names に渡して、CoreML モデルに分類ヘッドを追加します。

coremltools>=9.0torch>=1.11、および numpy<=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 では ai-edge-litert>=1.2.0,<1.4.0(他のプラットフォームでは ai-edge-litert>=1.2.0
  • onnxslim>=0.1.82
  • onnx>=1.12.0,<2.0.0
  • protobuf>=5

TensorFlow Frozen Graphへのエクスポート#

上記の SavedModel エクスポートに続き、返された keras_model を凍結された .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")

ディレクトリには、Pythonラッパーとともに固定名のparamおよびbinファイルが含まれます:

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

torch2ncnn() は、初回使用時に ncnnpnnx をチェックします。

MNNへのエクスポート#

MNNエクスポートには、入力としてONNXファイルが必要です。最初にONNXへエクスポートしてから変換してください:

from ultralytics.utils.export import onnx2mnn, torch2onnx

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

FP16 の場合は quantize=16 を、INT8 量子化の場合は quantize=8 をサポートします。MNN>=2.9.6torch>=1.10 が必要です。

PaddlePaddleへのエクスポート#

from ultralytics.utils.export import torch2paddle

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

ディレクトリにはPaddlePaddleモデルとパラメータファイルが含まれます:

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

x2paddle と、プラットフォームに一致する PaddlePaddle ディストリビューションが必要です。

  • CUDA上の paddlepaddle-gpu>=3.0.0,<3.3.0
  • ARM64 CPU上の paddlepaddle==3.0.0
  • その他のCPU上の paddlepaddle>=3.0.0,<3.3.0

NVIDIA Jetsonではサポートされていません。

ExecuTorchへのエクスポート#

from ultralytics.utils.export import torch2executorch

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

エクスポートされた .pte ファイルは出力ディレクトリ内に保存されます。

resnet18_executorch_model/
└── model.pte

torch>=2.9.0 と一致する ExecuTorch ランタイム(pip install executorch)が必要です。ランタイムの使用方法については、ExecuTorch インテグレーションを参照してください。

エクスポートしたモデルの検証#

エクスポート後、本番稼働の前に元の PyTorch モデルとの数値の一致を検証してください。ultralytics.nn.backends からの ONNXBackend を使用した簡単なスモークテストにより、出力が比較され、トレーシングや量子化のエラーが早期にフラグ付けされます。

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}")  # typically ~1e-5, well under 1e-4 for FP32
予想される誤差

FP32 エクスポートの場合、最大絶対差は通常 1e-5 程度であり、1e-4 を大きく下回る必要があります。差が大きい場合は、サポートされていない演算、不正な入力形状、または評価モードになっていないモデルを示しています。FP16 および INT8 エクスポートの許容誤差はより緩やかです。ランダムなテンソルではなく、実際のデータで検証してください。

他のランタイムでは、入力テンソル名が異なる場合があります。たとえば、OpenVINO はモデルの順伝播引数名(汎用モデルの場合は通常 x)を使用し、torch2onnx はデフォルトで "images" になります。

既知の制限事項#

  • マルチ入力のサポートは不均一です: torch2onnxtorch2openvino は、複数の入力を持つモデルに対してテンソルのタプルまたはリストを受け入れます。torch2torchscripttorch2coremltorch2ncnntorch2paddletorch2executorch は、単一の入力テンソルを前提としています。
  • ExecuTorch には flatc が必要です: ExecuTorch ランタイムには FlatBuffers コンパイラが必要です。macOS では brew install flatbuffers、Ubuntu では apt install flatbuffers-compiler でインストールしてください。
  • Ultralytics による推論なし: エクスポートされた非 YOLO モデルは、推論のために YOLO() を介して再度読み込むことはできません。各フォーマットのネイティブランタイム(ONNX RuntimeOpenVINO Runtime など)を使用してください。
  • YOLO専用フォーマット: Axelera および Sony IMX500 のエクスポートには YOLO 固有のモデル属性が必要であり、汎用モデルでは利用できません。
  • プラットフォーム固有のフォーマット: TensorRT には NVIDIA GPU が必要です。RKNN には rknn-toolkit2 SDK(Linux のみ)が必要です。Edge TPU には edgetpu_compiler バイナリ(Linux のみ)が必要です。

結論#

これらのユーティリティは、プレーンな torch.nn.Module から、デプロイ準備が整った ONNX、OpenVINO、CoreML、TensorFlow、またはモバイルランタイムのアーティファクトまで、一貫した API を介して任意の PyTorch モデルを変換します。ターゲットハードウェアに一致するフォーマットを選択し、元のモデルに対して数値的パリティを検証してから、ランタイム固有のデプロイ手順について一致するインテグレーションガイドに従ってください。

よくある質問 (FAQ)#

  • 任意の torch.nn.Module。これには、timm、torchvision、または任意のカスタム PyTorch モデルからのモデルが含まれます。モデルはエクスポート前に評価モード(model.eval())である必要があります。ONNX および OpenVINO は、マルチ入力モデル用の例示テンソルのタプルも追加で受け付けます。

  • サポートされているすべてのフォーマット(TorchScript、ONNX、OpenVINO、CoreML、TF SavedModel、TF Frozen Graph、NCNN、PaddlePaddle、MNN、ExecuTorch)は CPU 上でエクスポート可能です。エクスポートプロセス自体に GPU は不要です。TensorRT のみが NVIDIA GPU を必要とする唯一のフォーマットです。

  • Ultralytics の >=8.4.38 を使用します。これには、ultralytics.utils.export モジュールと、標準化された output_file/output_dir 引数が含まれています。

  • はい。torchvision の分類器、検出器、およびセグメンテーションモデルは、torch2coreml を介して .mlpackage にエクスポートされます。画像分類モデルの場合は、分類ヘッドを組み込むためにクラス名のリストを classifier_names に渡します。 macOS または Linux でエクスポートを実行してください。CoreML は Windows ではサポートされていません。iOS デプロイの詳細については、CoreML 統合 をご覧ください。

  • はい、いくつかのフォーマットで可能です。OpenVINO、CoreML、MNN、または NCNN にエクスポートする場合は、FP16 の場合は quantize=16 を、INT8 の場合は quantize=8 を渡します。OpenVINO での INT8 には、さらに ポストトレーニング量子化 用の calibration_dataset 引数が必要です。量子化のトレードオフについては、各フォーマットの統合ページをご覧ください。

  • 元の PyTorch モデルとエクスポートされたモデルを同じ入力で実行し、出力を比較します。一致するバックエンド(ONNX の場合は ONNXBackend など)を使用してエクスポートされたファイルを読み込み、最大絶対差を確認します。FP32 エクスポートの場合、通常は 1e-5 程度であり、1e-4 を大幅に下回る必要があります。ギャップが大きい場合は、サポートされていない演算、誤った入力形状、または評価モードになっていないモデルを示しています。実行可能な例については、エクスポートしたモデルの検証を参照してください。

コメント