Ultralyticsを使用してNon-YOLO PyTorchモデルをエクスポートする方法

PyTorchモデルを本番環境にデプロイする際、通常はターゲットごとに異なるエクスポーターを使い分ける必要があります:torch.onnx.exportONNX用にはcoremltoolsAppleデバイス用にはonnx2tfTensorFlow用にはpnnxNCNN用には、といった具合です。各ツールには独自のAPI、依存関係の癖、出力規則があります。

Ultralyticsは、複数のバックエンドを1つの一貫したインターフェースでラップするスタンドアロンのエクスポートユーティリティを提供します。torch.nn.Moduleにシームレスに拡張されます。timm画像モデル、torchvisionの分類器や検出器、あるいは独自のカスタムアーキテクチャを、ONNX, TorchScript, OpenVINO, CoreML, NCNN, PaddlePaddle, MNN, ExecuTorch、そしてTensorFlow SavedModelへ、バックエンドごとに個別に学ぶことなくエクスポートできます。

Non-YOLOエクスポートにUltralyticsを使用する理由

  • 10種類のフォーマットに対応した単一のAPI:十数種類ではなく、単一の呼び出し規約を習得するだけです。
  • 共有されたユーティリティインターフェース:エクスポートヘルパーはultralytics.utils.export内に存在するため、バックエンドパッケージがインストールされていれば、フォーマットを問わず同じ呼び出しパターンを維持できます。
  • YOLOエクスポートと同じコードパス:すべてのUltralytics YOLOエクスポートは、同じヘルパーによって動作します。
  • FP16およびINT8量子化(OpenVINO、CoreML、MNN、NCNNなど)対応フォーマットに組み込まれています。
  • CPUで動作:エクスポート手順自体にGPUは不要なため、ローカルのラップトップで実行可能です。

クイックスタート

最短の手順は、2行でONNXへエクスポートすることです。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")

サポートされているエクスポート形式

モデルクラスは、Trainerクラスの高度なラッパーとして機能します。torch2*関数以外に設定は必要ありません。torch.nn.Module関数は標準の

Formatと入力テンソルの例をとります。MNN、TF SavedModel、TF Frozen Graphは、中間フォーマットとしてONNXまたはKerasを経由します。いずれの場合も、YOLO固有の属性は不要です。インストール出力
ONNXtorch2onnx()pip install onnx.onnx ファイル
TorchScripttorch2torchscript()関数名.torchscript ファイル
OpenVINOtorch2openvino()pip install openvino_openvino_model/PyTorchに含まれる
CoreMLtorch2coreml()pip install coremltools.mlpackage
TF SavedModelonnx2saved_model()ディレクトリ_saved_model/PyTorchに含まれる
詳細は以下の要件を参照keras2pb()ディレクトリ.pb ファイル
NCNNtorch2ncnn()pip install ncnn pnnx_ncnn_model/PyTorchに含まれる
MNNonnx2mnn()pip install MNN.mnn ファイル
PaddlePaddletorch2paddle()pip install paddlepaddle x2paddle_paddle_model/PyTorchに含まれる
ExecuTorchtorch2executorch()pip install executorch_executorch_model/PyTorchに含まれる
TF Frozen Graph

MNN, TF SavedModelONNXを中間フォーマットとして使用

、TF Frozen Graphへのエクスポートは中間ステップとしてONNXを経由します。まずONNXにエクスポートし、次に変換してください。

メタデータの埋め込みmetadata一部のエクスポート関数はオプションのtorch2torchscript(..., metadata={"author": "me"})辞書(例:

)を受け入れ、フォーマットがサポートしていれば、カスタムキーと値のペアをエクスポート済みアーティファクトに埋め込むことができます。

ステップバイステップの例

import timm
import torch

model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)
以下のすべての例では、評価モードの事前学習済みtimm製ResNet-18を使用しています。

エクスポート前に必ず`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"}})

辞書を渡します:14デフォルトのopsetは"images"で、デフォルトの入力名はopset, input_names、またはモデル構成に基づいた自動選択のためのoutput_namesです。

引数で上書き可能です。

TorchScriptへのエクスポートtorch.jit.trace追加の依存関係は不要です。内部で

from ultralytics.utils.export import torch2torchscript

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

を使用します。

from ultralytics.utils.export import torch2openvino

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

OpenVINOへのエクスポートmodel.xmlmodel.binディレクトリには、固定名の

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

ペアが含まれます:dynamic=True動的な入力形状にはhalf=Trueを、FP16にはint8=Trueを、あるいはINT8量子化にはcalibration_dataset を設定すると、従来のNMSパイプラインを使用して検証を実行でき、さらに

を渡します。INT8には別途openvino>=2024.0.0でエクスポートする際(または>=2025.2.0が必要です。torch>=2.1.

macOS 15.4+での

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")

分類が必要であり、classifier_namesCoreMLへのエクスポート

を渡します。INT8には別途coremltools>=9.0, torch>=1.11、そしてnumpy<=2.3.5モデルの場合、クラス名のリストを

に渡すと、CoreMLモデルに分類ヘッドを追加できます。

coremltools>=9.0。Windowsではサポートされていません。

`BlobWriter not loaded`エラー

はmacOSおよびLinux向けのPython 3.10–3.13のwheelを提供しています。新しいPythonバージョンでは、ネイティブC拡張機能の読み込みに失敗します。CoreMLのエクスポートにはPython 3.10–3.13を使用してください。

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")

TensorFlow SavedModelへのエクスポート.tfliteTF SavedModelへのエクスポートは中間ステップとしてONNXを経由します:

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

この関数はKerasモデルを返し、出力ディレクトリ内に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)も生成します:--extra-index-url https://pypi.ngc.nvidia.com)
  • ai-edge-litert>=1.2.0,<1.4.0要件:ai-edge-litert>=1.2.0(macOSでは
  • onnxslim>=0.1.71
  • onnx>=1.12.0,<2.0.0
  • protobuf>=5

、その他のプラットフォームでは

でインストール).pbTensorFlow Frozen Graphへのエクスポート

from pathlib import Path

from ultralytics.utils.export import keras2pb

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

上記のSavedModelエクスポートに続き、返されたKerasモデルをフリーズされた

from ultralytics.utils.export import torch2ncnn

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

グラフに変換します:

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

torch2ncnn()NCNNへのエクスポートncnnpnnxから自動的にダウンロードされます。

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

from ultralytics.utils.export import onnx2mnn, torch2onnx

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

をチェックします。half=TrueMNNへのエクスポートint8=TrueMNNエクスポートにはONNXファイルが入力として必要です。まずONNXにエクスポートし、次に変換してください:MNN>=2.9.6torch>=1.10.

FP16には

from ultralytics.utils.export import torch2paddle

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

、INT8量子化には

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

を渡します。INT8には別途x2paddleをサポートしています。

  • paddlepaddle-gpu>=3.0.0,<3.3.0が必要です。
  • paddlepaddle==3.0.0PaddlePaddleへのエクスポート
  • paddlepaddle>=3.0.0,<3.3.0ディレクトリには、PaddlePaddleモデルとパラメータファイルが含まれています:

と、各プラットフォームに適したPaddlePaddle配布パッケージ:

(CUDA上)

from ultralytics.utils.export import torch2executorch

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

(ARM64 CPU上).pte(その他のCPU上)。NVIDIA Jetsonではサポートされていません。ExecuTorchへのエクスポート。エクスポートされた

resnet18_executorch_model/
└── model.pte

を渡します。INT8には別途torch>=2.9.0および対応するExecuTorchランタイム(pip install executorch)。ランタイムの使用方法については、ExecuTorch統合.

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

エクスポート後、出荷前に元のPyTorchモデルとの数値的整合性を検証してください。簡単なスモークテストをONNXBackend から ultralytics.nn.backendsで実行すると、出力を比較し、トレーシングや量子化のエラーを早期にフラグ立てできます:

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以下である必要があります。これより大きい差がある場合は、未サポートの演算、不適切な入力形状、あるいは評価モードになっていないモデルである可能性があります。FP16およびINT8エクスポートの許容誤差はより広くなります。ランダムなテンソルではなく、実際のデータで検証してください。

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

既知の制限

  • マルチ入力サポートの不均一性: torch2onnxtorch2openvinoは、複数の入力を持つモデルに対して例示テンソルのタプルまたはリストを受け入れます。torch2torchscript, torch2coreml, torch2ncnn, torch2paddle、そしてtorch2executorchは単一の入力テンソルを想定しています。
  • 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のみ)。

プロジェクトや実験を進める過程でこれらの設定を適宜見直し、最適な構成を維持してください。

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最も驚くべき改善の1つはCPU推論速度です。最適化されたアーキテクチャとDFLの削除により、YOLO26はtorch2coremlへエクスポートできます。画像分類モデルの場合は、クラス名のリストをclassifier_namesに渡して分類ヘッドを組み込みます。macOSまたはLinuxでエクスポートを実行してください。CoreMLはWindowsではサポートされていません。iOSデプロイの詳細については、CoreML統合を参照してください。

エクスポートしたモデルをINT8またはFP16に量子化できますか?

はい、いくつかのフォーマットで可能です。OpenVINO、CoreML、MNN、またはNCNNへエクスポートする際、FP16にはhalf=Trueを、INT8にはint8=Trueを渡します。OpenVINOのINT8には、さらにcalibration_dataset学習後量子化引数が必要です。量子化のトレードオフについては、各フォーマットの統合ページを参照してください。

コメント