Cómo exportarPyTorch YOLO con Ultralytics
La implementación PyTorch en producción suele implicar tener que utilizar un exportador diferente para cada destino: torch.onnx.export para ONNX, coremltools para dispositivos Apple, onnx2tf para TensorFlow, pnnx para NCNN, y así sucesivamente. Cada herramienta tiene su propia API, sus peculiaridades en cuanto a dependencias y sus propias convenciones de salida.
Ultralytics utilidades de exportación independientes que integran varios backends en una única interfaz unificada. Puedes exportar cualquier torch.nn.Module, entre otros timm modelos de imagen, torchvision clasificadores y detectores, o tus propias arquitecturas personalizadas, para ONNX, TorchScript, OpenVINO, CoreML, NCNN, PaddlePaddle, MNN, ExecuTorch, y TensorFlow SavedModel sin tener que aprender cada backend por separado.
¿Por qué utilizar Ultralytics YOLO ?
- Una sola API para 10 formatos: aprende una única forma de llamar a la API en lugar de una docena.
- Superficie de uso común: los auxiliares de exportación se encuentran en
ultralytics.utils.export, por lo que, una vez instalados los paquetes de backend, podrás mantener el mismo patrón de llamada en todos los formatos. - La misma ruta de código que YOLO : todasYOLO Ultralytics se basan en los mismos componentes auxiliares.
- Cuantificación FP16 e INT8 integrada para los formatos que la admiten (OpenVINO, CoreML, MNN, NCNN).
- Funciona en CPU: no GPU para el proceso de exportación en sí, por lo que puedes ejecutarlo localmente en cualquier ordenador portátil.
Inicio rápido
La forma más rápida es realizar una exportación de dos líneas a ONNX sin YOLO y sin necesidad de configuración adicional 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")
Formatos de exportación admitidos
El torch2* las funciones admiten un torch.nn.Module y un tensor de entrada de ejemplo. MNN, TF SavedModel y TF Graph pasan por un artefacto intermedio ONNX Keras. En ninguno de los dos casos se requieren atributos YOLO.
| Formato | Función | Instalar | Salida |
|---|---|---|---|
| ONNX | torch2onnx() | pip install onnx | .onnx archivo |
| TorchScript | torch2torchscript() | incluido en PyTorch | .torchscript archivo |
| OpenVINO | torch2openvino() | pip install openvino | _openvino_model/ directorio |
| CoreML | torch2coreml() | pip install coremltools | .mlpackage |
| TF SavedModel | onnx2saved_model() | Consulte los requisitos detallados a continuación | _saved_model/ directorio |
| Gráfico TF | keras2pb() | Consulte los requisitos detallados a continuación | .pb archivo |
| NCNN | torch2ncnn() | pip install ncnn pnnx | _ncnn_model/ directorio |
| MNN | onnx2mnn() | pip install MNN | .mnn archivo |
| PaddlePaddle | torch2paddle() | pip install paddlepaddle x2paddle | _paddle_model/ directorio |
| ExecuTorch | torch2executorch() | pip install executorch | _executorch_model/ directorio |
ONNX formato intermedio
MNN, TF SavedModely las exportaciones TF Graph pasan por ONNX paso intermedio. Exporta ONNX a ONNX y, a continuación, convierte.
Incorporación de metadatos
Varias funciones de exportación admiten un parámetro opcional metadata diccionario (p. ej., torch2torchscript(..., metadata={"author": "me"})) que incorpora pares clave-valor personalizados en el artefacto exportado, siempre que el formato lo permita.
Ejemplos paso a paso
Todos los ejemplos que se muestran a continuación utilizan la misma configuración: una red ResNet-18 preentrenada de timm en modo de evaluación:
import timm
import torch
model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)
Llama siempre model.eval() antes de exportar
Abandono escolar, normalización por lotes, y otras capas exclusivas del entrenamiento se comportan de manera diferente durante la inferencia. Saltar .eval() genera exportaciones con resultados incorrectos.
Exportar a ONNX
from ultralytics.utils.export import torch2onnx
torch2onnx(model, im, output_file="resnet18.onnx")
Para un tamaño de lote dinámico, pasa un dynamic diccionario:
torch2onnx(model, im, output_file="resnet18_dyn.onnx", dynamic={"images": {0: "batch_size"}})
El opset predeterminado es 14 y el nombre predeterminado del campo de entrada es "images". Sobrescribir con el opset, input_names, o output_names argumentos.
Exportar a TorchScript
No se necesitan dependencias adicionales. Usos torch.jit.trace por dentro.
from ultralytics.utils.export import torch2torchscript
torch2torchscript(model, im, output_file="resnet18.torchscript")
Exportar a OpenVINO
from ultralytics.utils.export import torch2openvino
ov_model = torch2openvino(model, im, output_dir="resnet18_openvino_model")
El directorio contiene un archivo con nombre fijo model.xml y model.bin par:
resnet18_openvino_model/
├── model.xml
└── model.bin
Pasar dynamic=True para formas de entrada dinámicas, half=True para FP16, o int8=True para la cuantificación INT8. Además, INT8 requiere un calibration_dataset argumento.
Requerir openvino>=2024.0.0 (o >=2025.2.0 en macOS 15.4 y versiones posteriores) y torch>=2.1.
Exportar a 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")
Para clasificación modelos, pasa una lista de nombres de clases a classifier_names para añadir una categoría de clasificación al CoreML .
Requerir coremltools>=9.0, torch>=1.11, y numpy<=2.3.5. No compatible con Windows.
BlobWriter not loaded Error
coremltools>=9.0 Es compatible con Python .10–3.13 en macOS y Linux. En Python más recientes Python , la extensión nativa en C no se carga. Utiliza Python .10–3.13 para CoreML .
Exportar a TensorFlow SavedModel
SavedModel TF SavedModel pasa por ONNX paso intermedio:
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")
La función devuelve un modelo de Keras y también genera TFLite (.tflite) dentro del directorio de salida:
resnet18_saved_model/
├── saved_model.pb
├── variables/
├── resnet18_float32.tflite
├── resnet18_float16.tflite
└── resnet18_int8.tflite
Requisitos:
tensorflow>=2.0.0,<=2.19.0onnx2tf>=1.26.3,<1.29.0tf_keras<=2.19.0sng4onnx>=1.0.1onnx_graphsurgeon>=0.3.26(instalar con--extra-index-url https://pypi.ngc.nvidia.com)ai-edge-litert>=1.2.0,<1.4.0en macOS (ai-edge-litert>=1.2.0(en otras plataformas)onnxslim>=0.1.71onnx>=1.12.0,<2.0.0protobuf>=5
Exportar a un gráfico TensorFlow
A continuación de la SavedModel anterior, convierte el modelo de Keras obtenido en un modelo congelado .pb gráfico:
from pathlib import Path
from ultralytics.utils.export import keras2pb
keras2pb(keras_model, output_file=Path("resnet18_saved_model/resnet18.pb"))
Exportar a NCNN
from ultralytics.utils.export import torch2ncnn
torch2ncnn(model, im, output_dir="resnet18_ncnn_model")
El directorio contiene archivos «param» y «bin» con nombres fijos, además de un Python :
resnet18_ncnn_model/
├── model.ncnn.param
├── model.ncnn.bin
└── model_ncnn.py
torch2ncnn() comprueba si ncnn y pnnx la primera vez que se utilice.
Exportar a MNN
La exportación de MNN requiere un ONNX como entrada. Exporta ONNX a ONNX y, a continuación, convierte:
from ultralytics.utils.export import onnx2mnn, torch2onnx
torch2onnx(model, im, output_file="resnet18.onnx")
onnx2mnn("resnet18.onnx", output_file="resnet18.mnn")
Compatible con half=True para FP16 y int8=True para la cuantificación INT8. Requiere MNN>=2.9.6 y torch>=1.10.
Exportar a PaddlePaddle
from ultralytics.utils.export import torch2paddle
torch2paddle(model, im, output_dir="resnet18_paddle_model")
El directorio contiene los archivos PaddlePaddle y parámetros de PaddlePaddle :
resnet18_paddle_model/
├── model.pdmodel
└── model.pdiparams
Requerir x2paddle y la PaddlePaddle correcta PaddlePaddle para tu plataforma:
paddlepaddle-gpu>=3.0.0,<3.3.0en CUDApaddlepaddle==3.0.0en CPU ARM64paddlepaddle>=3.0.0,<3.3.0en otras CPU
No es compatible con NVIDIA .
Exportar a ExecuTorch
from ultralytics.utils.export import torch2executorch
torch2executorch(model, im, output_dir="resnet18_executorch_model")
El archivo exportado .pte El archivo se guarda en el directorio de salida:
resnet18_executorch_model/
└── model.pte
Requerir torch>=2.9.0 y un tiempo de ejecución de ExecuTorch compatible (pip install executorch). Para obtener información sobre su uso en tiempo de ejecución, consulte el Integración con ExecuTorch.
Comprueba el modelo exportado
Después de la exportación, comprueba la paridad numérica con el PyTorch original PyTorch antes de la entrega. Una prueba rápida con ONNXBackend de ultralytics.nn.backends compara los resultados y señala los errores de trazado o cuantificación en una fase temprana:
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.forward(im)[0]
diff = np.abs(pytorch_output - onnx_output).max()
print(f"Max difference: {diff:.6f}") # should be < 1e-5
Diferencia prevista
En las exportaciones FP32, la diferencia absoluta máxima debe ser inferior a 1e-5. Las diferencias más grandes indican operaciones no admitidas, una forma de entrada incorrecta o un modelo que no está en modo de evaluación. Las exportaciones en FP16 e INT8 tienen tolerancias más amplias. Comprueba la validez con datos reales en lugar de tensores aleatorios.
En otros entornos de ejecución, el tensor de entrada puede variar. OpenVINO, por ejemplo, utiliza el nombre del argumento de propagación del modelo (normalmente x (para modelos genéricos), mientras que torch2onnx por defecto es "images".
Limitaciones Conocidas
- La compatibilidad con múltiples entradas es desigual:
torch2onnxytorch2openvinoaceptar una tupla o una lista de tensores de ejemplo para modelos con múltiples entradas.torch2torchscript,torch2coreml,torch2ncnn,torch2paddle, ytorch2executorchsuponer un único tensor de entrada. - ExecuTorch necesita
flatc: El entorno de ejecución de ExecuTorch requiere el compilador FlatBuffers. Instálalo conbrew install flatbuffersen macOS oapt install flatbuffers-compileren Ubuntu. - No se extraen conclusiones a través de Ultralytics:YOLO y que se hayan exportado no se pueden volver a cargar a través de
YOLO()para la inferencia. Utiliza el tiempo de ejecución nativo de cada formato (ONNX Runtime, OpenVINO, etc.). - FormatosYOLO: las exportaciones de Axelera y Sony IMX500 requieren atributos de modelo YOLO y no están disponibles para modelos genéricos.
- Formatos específicos para cada plataforma: TensorRT Requiere unaGPU NVIDIA . RKNN requiere el
rknn-toolkit2SDK (solo para Linux). Edge TPU requiere eledgetpu_compilerbinario (solo para Linux).
Preguntas frecuentes
¿Qué modelos puedo exportar con Ultralytics?
Cualquiera torch.nn.Module. Esto incluye modelos de timm, torchvision o cualquier PyTorch personalizado PyTorch . El modelo debe estar en modo de evaluación (model.eval()) antes de la exportación. ONNX OpenVINO admiten OpenVINO una tupla de tensores de ejemplo para modelos con múltiples entradas.
¿Qué formatos de exportación funcionan sin una GPU?
Todos los formatos compatibles (TorchScript, ONNX, OpenVINO, CoreML, TF SavedModel, TF Graph, NCNN, PaddlePaddle, MNN, ExecuTorch) se pueden exportar en CPU. No GPU necesita GPU para el proceso de exportación en sí. TensorRT el único formato que requiere unaGPU NVIDIA .
¿Qué Ultralytics necesito?
Use Ultralytics >=8.4.38, que incluye el ultralytics.utils.export módulo y el estándar output_file/output_dir argumentos.
¿Puedo exportar un modelo de Torchvision a CoreML iOS ?
Sí. Los clasificadores, detectores y modelos de segmentación de TorchVision se exportan a .mlpackage a través de torch2coreml. En el caso de los modelos de clasificación de imágenes, pasa una lista de nombres de clases a classifier_names para procesar en un clasificador. Ejecuta la exportación en macOS o Linux. CoreML no CoreML compatible con Windows. Consulta la CoreML para obtener más información sobre iOS .
¿Puedo cuantificar mi modelo exportado a INT8 o FP16?
Sí, para varios formatos. Aceptar half=True para FP16 o int8=True para INT8 al exportar a OpenVINO, CoreML, MNN o NCNN. El formato INT8 en OpenVINO requiere OpenVINO un calibration_dataset argumento para cuantificación posterior al entrenamiento. Consulte la página de integración de cada formato para conocer las ventajas e inconvenientes de la cuantización.