Ultralytics YOLO27:

YOLO Dışı PyTorch Modelleri Ultralytics ile Nasıl Dışa Aktarılır#

Ultralytics, birden fazla arka ucu tutarlı tek bir arayüzün arkasında birleştiren bağımsız dışa aktarma yardımcılarını ultralytics.utils.export altında sunar. Herhangi bir torch.nn.Module modelini; timm görüntü modelleri, torchvision sınıflandırıcıları ve algılayıcıları ya da kendi özel mimarilerin dâhil olmak üzere, her arka ucu ayrı ayrı öğrenmene gerek kalmadan TorchScript, ONNX, OpenVINO, CoreML, Core AI, TensorFlow SavedModel, TensorFlow Frozen Graph, PaddlePaddle, MNN, NCNN ve ExecuTorch biçimlerine aktarabilirsin.

PyTorch modellerini üretime dağıtmak genellikle her hedef için farklı bir dışa aktarıcı kullanmak demektir: ONNX için torch.onnx.export, Apple aygıtları için coremltools, TensorFlow için onnx2tf, NCNN için pnnx ve benzerleri. Her aracın kendine özgü API'si, bağımlılık kaynaklı pürüzleri ve çıktı kuralları vardır. Bu yardımcılar, tüm bunları tek bir çağrı biçiminde birleştirir.

YOLO Dışı Dışa Aktarım için Neden Ultralytics Kullanmalısın?#

  • 11 biçim için tek API: Bir düzine farklı çağrı biçimi yerine tek bir çağrı biçimini öğren.
  • YOLO dışa aktarımlarıyla aynı kod yolu: Tüm Ultralytics YOLO dışa aktarımlarında aynı yardımcılar kullanılır.
  • Bunu destekleyen biçimler için tek bir quantize argümanı üzerinden FP16 ve INT8 kuantizasyonu.
  • CPU'da çalışır: Dışa aktarma adımının kendisi için GPU gerekmez; böylece işlemi yerel olarak bir dizüstü bilgisayarda çalıştırabilirsin. CoreML dışa aktarma Windows'ta desteklenmez; Core AI dışa aktarma ise Apple silicon üzerinde macOS 26 veya sonraki sürümleri ya da glibc 2.34 veya daha yeni sürümünü kullanan x86_64 Linux ve Python 3.11-3.14 gerektirir.

Hızlı Başlangıç#

En hızlı yöntem, YOLO kodu veya pip install ultralytics onnx timm dışında kurulum gerektirmeyen, ONNX biçimine iki satırlık dışa aktarımdır:

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

Desteklenen Dışa Aktarma Biçimleri#

torch2* işlevleri, standart bir torch.nn.Module ve örnek giriş tensörü alır. MNN, TF SavedModel ve TF Frozen Graph, ara bir ONNX veya Keras çıktısı üzerinden oluşturulur. Her iki durumda da YOLO'ya özgü öznitelikler gerekmez.

BiçimİşlevYüklemeÇıktı
TorchScripttorch2torchscript()PyTorch ile birlikte gelir.torchscript dosyası
ONNXtorch2onnx()pip install onnx.onnx dosyası
OpenVINOtorch2openvino()pip install openvino_openvino_model/ dizini
CoreMLtorch2coreml()pip install coremltools.mlpackage
Core AItorch2coreai()pip install coreai-torch (Apple silicon macOS 26+; x86_64 Linux glibc 2.34+; Python 3.11-3.14).aimodel dizini
TF SavedModelonnx2saved_model()ayrıntılı gereksinimleri aşağıda gör_saved_model/ dizini
TF Frozen Graphkeras2pb()ayrıntılı gereksinimleri aşağıda gör.pb dosyası
PaddlePaddletorch2paddle()pip install paddlepaddle x2paddle_paddle_model/ dizini
MNNonnx2mnn()pip install MNN.mnn dosyası
NCNNtorch2ncnn()pip install ncnn pnnx_ncnn_model/ dizini
ExecuTorchtorch2executorch()pip install executorch_executorch_model/ dizini
Meta veri ekleme

Bazı dışa aktarma işlevleri, biçimin desteklediği durumlarda dışa aktarılan çıktıya özel anahtar-değer çiftleri ekleyen isteğe bağlı bir metadata sözlüğünü (ör. torch2torchscript(..., metadata={"author": "me"})) kabul eder.

Adım Adım Örnekler#

Aşağıdaki tüm örneklerde aynı kurulum kullanılır: değerlendirme modundaki, timm'den önceden eğitilmiş bir ResNet-18:

import timm
import torch

model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)
Dışa aktarmadan önce her zaman `model.eval()` çağır

Dropout, batch normalization ve yalnızca eğitimde kullanılan diğer katmanlar çıkarım sırasında farklı davranır. .eval() adımını atlarsan hatalı çıktılar üretilir.

ONNX'e aktar#

from ultralytics.utils.export import torch2onnx

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

Dinamik toplu iş boyutu için bir dynamic sözlüğü ilet:

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

Varsayılan opset 14, varsayılan giriş adı ise "images" değeridir. Bunları opset, input_names veya output_names bağımsız değişkenleriyle değiştirebilirsin.

TorchScript'e Dışa Aktar#

Ek bağımlılık gerekmez. Arka planda torch.jit.trace kullanılır.

from ultralytics.utils.export import torch2torchscript

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

OpenVINO'ya Dışa Aktar#

from ultralytics.utils.export import torch2openvino

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

Dizin, sabit adlı bir model.xml ve model.bin çiftini içerir:

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

Dinamik giriş şekilleri için dynamic=True, FP16 için quantize=16 veya INT8 niceleme için quantize=8 ilet. INT8 için ayrıca calibration_dataset bağımsız değişkeni gerekir.

openvino>=2024.0.0 (veya macOS 15.4+ üzerinde >=2025.2.0) ve torch>=2.1 gerekir.

CoreML'e Dışa Aktar#

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

Sınıflandırma modelleri için CoreML modeline sınıflandırma başlığı eklemek üzere classifier_names parametresine sınıf adlarından oluşan bir liste ilet.

coremltools>=9.0, torch>=1.11 ve numpy<=2.3.5 gerekir. Windows'ta desteklenmez.

`BlobWriter not loaded` hatası

coremltools>=9.0, macOS ve Linux'ta Python 3.10–3.13 için wheel paketleri sunar. Daha yeni Python sürümlerinde yerel C uzantısı yüklenemez. CoreML dışa aktarımı için Python 3.10–3.13 kullan.

Core AI'ye Dışa Aktar#

from ultralytics.utils.export import torch2coreai

torch2coreai(model, im, output_file="resnet18.aimodel")

.aimodel varlığı bir dizindir:

resnet18.aimodel/
├── main.mlirb
├── main.hash
└── metadata.json

Dışa aktarma, Apple silicon üzerinde macOS 26 veya sonraki sürümlerinde ya da glibc 2.34 veya daha yeni sürümünü kullanan x86_64 Linux'ta ve Python 3.11-3.14 ile çalışır (pip install coreai-torch); quantize=16 ise float16 girdiler alan bir FP16 varlığı yazar. Bu varlık iOS 27 ve macOS 27'de çalışır. Yükleme sırasında işlemi sonlandıran FP16 varlıklarla ilgili not da dahil olmak üzere Core AI entegrasyonuna göz at.

TensorFlow SavedModel'e Dışa Aktar#

TF SavedModel dışa aktarımında ara adım olarak ONNX kullanılır:

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

İşlev bir Keras modeli döndürür ve çıktı dizininde FP32 ve FP16 LiteRT dosyaları (.tflite) da oluşturur:

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

Yanlarına bir INT8 .tflite eklemek için quantize=8 ilet.

TensorFlow dışa aktarımı, Python 3.13 veya daha yeni bir sürümün yüklü olduğu macOS'ta çalışmaz; macOS'ta Python 3.12 veya daha eski bir sürüm ya da Linux kullan.

Python 3.12 veya daha eski sürümlerdeki gereksinimler (Python 3.13 veya daha yeni bir sürümde dışa aktarım için bunun yerine tensorflow>2.19.0, tf_keras>2.19.0, onnx2tf>=2.3.0,<2.3.16 ve protobuf>=6.31.1,<7.0.0 gerekir):

  • 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'ta ai-edge-litert>=1.2.0,<1.4.0 (diğer platformlarda ai-edge-litert>=1.2.0)
  • onnxslim>=0.1.82
  • onnx>=1.12.0,<2.0.0
  • protobuf>=5

TensorFlow Frozen Graph'e Dışa Aktar#

Yukarıdaki SavedModel dışa aktarımına devam ederek, döndürülen keras_model modelini dondurulmuş bir .pb grafiğine dönüştür:

from pathlib import Path

from ultralytics.utils.export import keras2pb

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

NCNN'e Dışa Aktar#

from ultralytics.utils.export import torch2ncnn

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

Dizin, sabit adlı parametre ve bin dosyalarını ve bir Python sarmalayıcısını içerir:

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

MNN'ye Dışa Aktar#

MNN dışa aktarımı için giriş olarak bir ONNX dosyası gerekir. Önce ONNX biçimine aktar, ardından dönüştür:

from ultralytics.utils.export import onnx2mnn, torch2onnx

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

FP16 için quantize=16 ve INT8 niceleme için quantize=8 desteklenir. MNN>=2.9.6 ve torch>=1.10 gerekir.

PaddlePaddle'a Dışa Aktar#

from ultralytics.utils.export import torch2paddle

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

Dizin, PaddlePaddle modelini ve parametre dosyalarını içerir:

resnet18_paddle_model/
├── inference_model/
│   ├── model.json
│   └── model.pdiparams
├── model.pdparams
└── x2paddle_code.py

x2paddle ve platformuna uygun PaddlePaddle dağıtımı gerekir:

  • CUDA üzerinde paddlepaddle-gpu>=3.0.0,<3.3.0
  • ARM64 CPU üzerinde paddlepaddle==3.0.0
  • Diğer CPU'larda paddlepaddle>=3.0.0,<3.3.0

NVIDIA Jetson'da desteklenmez.

ExecuTorch'a Dışa Aktar#

from ultralytics.utils.export import torch2executorch

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

Dışa aktarılan .pte dosyası çıktı dizinine kaydedilir:

resnet18_executorch_model/
└── model.pte

torch>=2.9.0 ve uyumlu bir ExecuTorch çalışma zamanı (pip install executorch) gerekir. Çalışma zamanının kullanımı için ExecuTorch entegrasyonuna göz at.

Dışa Aktardığın Modeli Doğrula#

Dışa aktardıktan sonra modeli kullanıma almadan önce özgün PyTorch modeliyle sayısal uyumu doğrula. ultralytics.nn.backends içindeki ONNXBackend ile yapacağın hızlı bir ilk test, çıktıları karşılaştırır ve izleme ya da niceleme hatalarını erkenden belirler:

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}")  # ~1e-6 for an FP32 ONNX export
Beklenen fark

ResNet-18'de FP32 dışa aktarımlarının çoğu PyTorch'tan yaklaşık 1e-5 fark içinde kalır ve TorchScript tam olarak eşleşir. Yine de üç çalışma zamanı, FP32 dışa aktarımını düşük hassasiyetle hesaplayıp 1e-2 ile 1e-1 aralığına yakın sonuç verebilir: NCNN, destekleyen CPU'larda FP16 aritmetiğini etkinleştirir; MNNBackend, modelleri precision="low" ile yükler; OpenVINO CPU eklentisi ise Apple silicon gibi bazı donanımlarda varsayılan PERFORMANCE yürütme modunda otomatik olarak FP16 çalışır. Biçimin kendi temel değerinden çok daha büyük bir fark; desteklenmeyen işlemlere, yanlış girdi boyutuna veya değerlendirme modunda olmayan bir modele işaret eder. FP16 ve INT8 dışa aktarımlarında toleranslar daha geniştir. Rastgele tensörler yerine gerçek verilerle doğrula.

Diğer çalışma zamanlarında giriş tensörünün adı farklı olabilir. Örneğin OpenVINO, modelin forward bağımsız değişkeninin adını kullanırken (genel modellerde genellikle x), torch2onnx varsayılan olarak "images" değerini kullanır.

Dışa Aktardığın Modeli Çalıştır#

YOLO dışı dışa aktarılmış modelleri, normal YOLO() API'siyle yeniden yükleyebilirsin. Yukarıdaki dışa aktarımlarda Ultralytics görev veya giriş boyutu meta verisi bulunmadığından, task değerini açıkça ilet ve imgsz değerini dışa aktarırken kullandığın örnek tensörle eşleştir:

from ultralytics import YOLO

results = YOLO("resnet18.onnx", task="classify")("path/to/image.jpg", imgsz=224)
print(results[0].probs.top1)

imgsz, dışa aktarımda sabit bir giriş şekli kullanıldığında önemlidir: yukarıdaki ONNX ve TF SavedModel dışa aktarımları varsayılan 640 değerini kabul etmez. Yukarıdaki TorchScript ve NCNN dışa aktarımları başka boyutları kabul eder, ancak hiçbir dışa aktarıcı bunu garanti etmez: ikisi de örnek tensörden iz çıkarır; bu nedenle Linear katmanına düzleştirme yapan bir model sabit boyutlu kalır. Kendi dışa aktarımını kontrol et.

Değer daha sonra model stride'ının katına yukarı yuvarlanır; meta veri olmadığında bu değer 32'dir. Bu nedenle 200x200 boyutundaki sabit şekilli bir dışa aktarıma 224x224 boyutunda giriş verilir ve imgsz=200 bu boyutla eşleşse bile giriş reddedilir. 32'nin katı olmayan giriş boyutlarında arka ucu doğrudan çağır.

Arka Ucu Doğrudan Çağırma#

Ultralytics ön işleme ve son işleme olmadan ham tensörler kullanmak için, yukarıdaki doğrulama örneğinde olduğu gibi ultralytics.nn.backends içindeki her biçime özgü sınıfları kullan. Her sınıf dışa aktarılan varlığı ve bir aygıtı alır, ardından çağrılabilir:

BiçimArka uçGiriş düzeni
TorchScriptTorchScriptBackendBCHW
ONNXONNXBackendBCHW
OpenVINOOpenVINOBackendBCHW
CoreMLCoreMLBackendBHWC
Core AICoreAIBackendBCHW
TF SavedModel, Frozen GraphTensorFlowBackendBHWC
LiteRTLiteRTBackendBCHW
PaddlePaddlePaddleBackendBCHW
MNNMNNBackendBCHW
NCNNNCNNBackendBCHW
ExecuTorchExecuTorchBackendBCHW

TensorFlowBackend iki biçimi kapsar ve varsayılan olarak format="saved_model" değerini kullanır; bu nedenle dondurulmuş grafik için format="pb" ilet.

YOLO() yolunun senin için hallettiği, doğrudan çağrının ise halletmediği üç konu:

  • Giriş düzeni: CoreMLBackend ve TensorFlowBackend BHWC biçimini bekler. Önce im.permute(0, 2, 3, 1) ile transpoze et; BCHW tensörü şekil uyuşmazlığı hatasına yol açar.
  • Autograd: Çağrıları torch.inference_mode() içine al. TorchScriptBackend, gradyan grafiğini hâlâ taşıyan bir tensör döndürür.
  • Son işleme: Meta veri olmadığında arka uç, task değerini None olarak bırakır ve names boş olur. LiteRTBackend ise 3B boyutlu tüm çıktıları YOLO kutuları içerdiğini varsayarak görüntü boyutuna göre ölçeklendirir. Bu, 3B çıktısı olan YOLO dışı bir modelde yanlıştır. Sınıflandırıcı logitleri gibi 2B çıktılar etkilenmez.

Bilinen Sınırlamalar#

  • Çoklu girdi desteği tutarsızdır: torch2onnx, torch2openvino ve torch2torchscript, birden fazla girdisi olan modeller için örnek tensörlerden oluşan bir demet kabul eder. torch2coreml, torch2coreai, torch2ncnn, torch2paddle ve torch2executorch tek bir girdi tensörü olduğunu varsayar.
  • Yalnızca YOLO'ya özgü biçimler: Axelera ve Sony IMX500 dışa aktarımları YOLO'ya özgü model öznitelikleri gerektirir ve genel modeller için kullanılamaz.
  • Platforma özgü biçimler: TensorRT için NVIDIA GPU gerekir. RKNN için rknn-toolkit2 SDK'sı gerekir (yalnızca Linux). Edge TPU için edgetpu_compiler ikilisi gerekir (yalnızca Linux).

Sonuç#

Bu yardımcılarla herhangi bir PyTorch modelini yalın bir torch.nn.Module modelinden, tutarlı tek bir API üzerinden dağıtıma hazır ONNX, OpenVINO, CoreML, TensorFlow veya mobil çalışma zamanı varlığına dönüştürebilirsin. Hedef donanımına uygun biçimi seç, özgün modelle sayısal uyumu doğrula ve ardından çalışma zamanına özgü dağıtım adımları için uygun entegrasyon kılavuzunu izle.

Sık Sorulan Sorular#

  • Herhangi bir torch.nn.Module. Buna timm, torchvision veya özel bir PyTorch modelinden gelen modeller dahildir. Dışa aktarmadan önce model değerlendirme modunda (model.eval()) olmalıdır. ONNX, OpenVINO ve TorchScript ayrıca çoklu girdili modeller için örnek tensörlerden oluşan bir demet kabul eder.

  • Desteklenen tüm biçimler (TorchScript, ONNX, OpenVINO, CoreML, Core AI, TF SavedModel, TF Frozen Graph, PaddlePaddle, MNN, NCNN, ExecuTorch) CPU'da dışa aktarılabilir. Dışa aktarma işleminin kendisi için GPU gerekmez. NVIDIA GPU gerektiren tek biçim TensorRT'dir.

  • En son sürümü kullan. quantize argümanı Ultralytics >=8.4.81 gerektirir; Core AI dışa aktarma ise Linux'ta >=8.4.163 veya coreai-torch>=0.4.3 ile birlikte >=8.4.131 gerektirir.

  • Evet. torchvision sınıflandırıcıları, algılayıcıları ve segmentasyon modelleri torch2coreml aracılığıyla .mlpackage biçimine aktarılır. Görüntü sınıflandırma modellerinde, sınıflandırma başlığını modele yerleştirmek için classifier_names parametresine sınıf adlarından oluşan bir liste ver. Dışa aktarma işlemini macOS veya Linux'ta çalıştır. CoreML Windows'ta desteklenmez. iOS dağıtımıyla ilgili ayrıntılar için CoreML entegrasyonu sayfasına bak.

  • Evet, birkaç biçim için. OpenVINO, CoreML veya MNN'ye dışa aktarırken FP16 için quantize=16, INT8 için quantize=8 kullan; onnx2saved_model, INT8 LiteRT dosyası için quantize=8 değerini alır; NCNN ve Core AI varsayılan olarak FP32 dışa aktarır, FP16 için quantize=16 değerini alır ve INT8 yoluna sahip değildir. OpenVINO'da INT8 için ayrıca eğitim sonrası kuantizasyon amacıyla bir calibration_dataset argümanı gerekir. Kuantizasyonun ödünleşimleri için her biçimin entegrasyon sayfasına göz at.

  • Orijinal PyTorch modelini ve dışa aktarılan modeli aynı girdiyle çalıştır, ardından çıktıları karşılaştır. Dışa aktarılan dosyayı eşleşen arka uçla yükle (örneğin ONNX için ONNXBackend) ve en büyük mutlak farkı denetle. Farkı, biçimin kendi temel değerine göre değerlendir: NCNN, MNNBackend ve bazı CPU'larda OpenVINO, FP32 dışa aktarımlarını düşük hassasiyetle çalıştırıp 1e-2 ile 1e-1 aralığına yakın sonuç verebilir; diğer biçimlerin çoğu ise 1e-5 civarında sonuç verir. Çok daha büyük bir fark; desteklenmeyen işlemlere, yanlış girdi boyutuna veya değerlendirme modunda olmayan bir modele işaret eder. Çalıştırılabilir bir örnek için Dışa Aktardığın Modeli Doğrula sayfasına göz at.

Yorumlar