Meet YOLO26: next-gen vision AI.

Link to this sectionComo exportar modelos PyTorch que não são YOLO com Ultralytics#

Implantar modelos PyTorch em produção geralmente significa lidar com um exportador diferente para cada destino: torch.onnx.export para ONNX, coremltools para dispositivos Apple, onnx2tf para TensorFlow, pnnx para NCNN, e assim por diante. Cada ferramenta tem sua própria API, peculiaridades de dependência e convenções de saída.

A Ultralytics fornece utilitários de exportação independentes que envolvem vários backends atrás de uma interface consistente. Você pode exportar qualquer torch.nn.Module, incluindo modelos de imagem timm, classificadores e detectores do torchvision, ou suas próprias arquiteturas personalizadas para ONNX, TorchScript, OpenVINO, CoreML, NCNN, PaddlePaddle, MNN, ExecuTorch e TensorFlow SavedModel sem precisar aprender cada backend separadamente.

Link to this sectionPor que usar a Ultralytics para exportação de modelos que não são YOLO?#

  • Uma API para 10 formatos: aprenda uma única convenção de chamada em vez de uma dúzia.
  • Superfície utilitária compartilhada: os auxiliares de exportação residem em ultralytics.utils.export, então, uma vez que os pacotes de backend estejam instalados, você pode manter o mesmo padrão de chamada entre os formatos.
  • Mesmo caminho de código das exportações YOLO: os mesmos auxiliares impulsionam cada exportação YOLO da Ultralytics.
  • Quantização FP16 e INT8 integrada para formatos que a suportam (OpenVINO, CoreML, MNN, NCNN).
  • Funciona em CPU: nenhuma GPU é necessária para a etapa de exportação em si, então você pode executá-la localmente em qualquer laptop.

Link to this sectionInício rápido#

O caminho mais rápido é uma exportação de duas linhas para ONNX sem código YOLO e sem configuração além de 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")

Link to this sectionFormatos de Exportação Suportados#

As funções torch2* aceitam um torch.nn.Module padrão e um tensor de entrada de exemplo. MNN, TF SavedModel e TF Frozen Graph passam por um artefato intermediário ONNX ou Keras. Nenhum atributo específico de YOLO é necessário em ambos os casos.

FormatoFunçãoInstalarSaída
ONNXtorch2onnx()pip install onnxArquivo .onnx
TorchScripttorch2torchscript()incluído no PyTorchArquivo .torchscript
OpenVINOtorch2openvino()pip install openvinoDiretório _openvino_model/
CoreMLtorch2coreml()pip install coremltools.mlpackage
TF SavedModelonnx2saved_model()veja os requisitos detalhados abaixoDiretório _saved_model/
TF Frozen Graphkeras2pb()veja os requisitos detalhados abaixoArquivo .pb
NCNNtorch2ncnn()pip install ncnn pnnxDiretório _ncnn_model/
MNNonnx2mnn()pip install MNNArquivo .mnn
PaddlePaddletorch2paddle()pip install paddlepaddle x2paddleDiretório _paddle_model/
ExecuTorchtorch2executorch()pip install executorchDiretório _executorch_model/
ONNX como um formato intermediário

As exportações para MNN, TF SavedModel e TF Frozen Graph passam pelo ONNX como um passo intermediário. Exporte primeiro para ONNX e, em seguida, converta.

Incorporar metadados

Várias funções de exportação aceitam um dicionário metadata opcional (por exemplo, torch2torchscript(..., metadata={"author": "me"})) que incorpora pares de chave-valor personalizados no artefato exportado onde o formato permite.

Link to this sectionExemplos passo a passo#

Cada exemplo abaixo usa a mesma configuração, uma ResNet-18 pré-treinada do timm em modo de avaliação:

import timm
import torch

model = timm.create_model("resnet18", pretrained=True).eval()
im = torch.randn(1, 3, 224, 224)
Sempre chame `model.eval()` antes de exportar

Dropout, normalização em lote e outras camadas apenas de treino se comportam de maneira diferente durante a inferência. Pular .eval() produz exportações com saídas incorretas.

Link to this sectionExportar para ONNX#

from ultralytics.utils.export import torch2onnx

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

Para tamanho de lote dinâmico, passe um dicionário dynamic:

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

O opset padrão é 14 e o nome de entrada padrão é "images". Substitua pelos argumentos opset, input_names ou output_names.

Link to this sectionExportar para TorchScript#

Não são necessárias dependências extras. Usa torch.jit.trace por baixo dos panos.

from ultralytics.utils.export import torch2torchscript

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

Link to this sectionExportar para OpenVINO#

from ultralytics.utils.export import torch2openvino

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

O diretório contém um par de model.xml e model.bin de nome fixo:

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

Passe dynamic=True para formas de entrada dinâmicas, half=True para FP16, ou int8=True para quantização INT8. INT8 requer adicionalmente um argumento calibration_dataset.

Requer openvino>=2024.0.0 (ou >=2025.2.0 no macOS 15.4+) e torch>=2.1.

Link to this sectionExportar para 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 modelos de classificação, passe uma lista de nomes de classes para classifier_names para adicionar um cabeçalho de classificação ao modelo CoreML.

Requer coremltools>=9.0, torch>=1.11 e numpy<=2.3.5. Não suportado no Windows.

Erro `BlobWriter not loaded`

coremltools>=9.0 fornece wheels para Python 3.10–3.13 no macOS e Linux. Em versões mais recentes do Python, a extensão C nativa falha ao carregar. Use Python 3.10–3.13 para exportação CoreML.

Link to this sectionExportar para TensorFlow SavedModel#

A exportação TF SavedModel passa pelo ONNX como um passo intermediário:

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

A função retorna um modelo Keras e também gera arquivos TFLite (.tflite) dentro do diretório de saída:

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

Requisitos:

  • 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 (instale com --extra-index-url https://pypi.ngc.nvidia.com)
  • ai-edge-litert>=1.2.0,<1.4.0 no macOS (ai-edge-litert>=1.2.0 em outras plataformas)
  • onnxslim>=0.1.71
  • onnx>=1.12.0,<2.0.0
  • protobuf>=5

Link to this sectionExportar para TensorFlow Frozen Graph#

Continuando a partir da exportação SavedModel acima, converta o modelo Keras retornado para um grafo .pb congelado:

from pathlib import Path

from ultralytics.utils.export import keras2pb

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

Link to this sectionExportar para NCNN#

from ultralytics.utils.export import torch2ncnn

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

O diretório contém arquivos param e bin de nome fixo, juntamente com um wrapper Python:

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

torch2ncnn() verifica a presença de ncnn e pnnx no primeiro uso.

Link to this sectionExportar para MNN#

A exportação MNN requer um arquivo ONNX como entrada. Exporte primeiro para ONNX e, em seguida, converta:

from ultralytics.utils.export import onnx2mnn, torch2onnx

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

Suporta half=True para FP16 e int8=True para quantização INT8. Requer MNN>=2.9.6 e torch>=1.10.

Link to this sectionExportar para PaddlePaddle#

from ultralytics.utils.export import torch2paddle

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

O diretório contém o modelo PaddlePaddle e os arquivos de parâmetro:

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

Requer x2paddle e a distribuição correta do PaddlePaddle para sua plataforma:

  • paddlepaddle-gpu>=3.0.0,<3.3.0 no CUDA
  • paddlepaddle==3.0.0 na CPU ARM64
  • paddlepaddle>=3.0.0,<3.3.0 em outras CPUs

Não suportado no NVIDIA Jetson.

Link to this sectionExportar para ExecuTorch#

from ultralytics.utils.export import torch2executorch

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

O ficheiro .pte exportado é guardado dentro do diretório de saída:

resnet18_executorch_model/
└── model.pte

Requer torch>=2.9.0 e um runtime ExecuTorch correspondente (pip install executorch). Para utilização do runtime, vê a integração com ExecuTorch.

Link to this sectionVerifica o Teu Modelo Exportado#

Após a exportação, verifica a paridade numérica com o modelo PyTorch original antes de o colocar em produção. Um teste rápido com ONNXBackend de ultralytics.nn.backends compara os resultados e identifica erros de rastreio ou quantização precocemente:

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
Diferença esperada

Para exportações FP32, a diferença absoluta máxima deve ser inferior a 1e-5. Diferenças maiores indicam operações não suportadas, formato de entrada incorreto ou um modelo que não está em modo de avaliação. As exportações FP16 e INT8 têm tolerâncias mais flexíveis. Valida com dados reais em vez de tensores aleatórios.

For other runtimes, the input tensor name may differ. OpenVINO, for example, uses the model's forward-argument name (typically x for generic models), while torch2onnx defaults to "images".

Link to this sectionLimitações Conhecidas#

  • Suporte a múltiplas entradas é inconsistente: torch2onnx e torch2openvino aceitam um tuplo ou lista de tensores de exemplo para modelos com múltiplas entradas. torch2torchscript, torch2coreml, torch2ncnn, torch2paddle e torch2executorch assumem um único tensor de entrada.
  • ExecuTorch precisa de flatc: O runtime ExecuTorch requer o compilador FlatBuffers. Instala com brew install flatbuffers no macOS ou apt install flatbuffers-compiler no Ubuntu.
  • Sem inferência via Ultralytics: Modelos não-YOLO exportados não podem ser carregados de volta através de YOLO() para inferência. Usa o runtime nativo para cada formato (ONNX Runtime, OpenVINO Runtime, etc.).
  • Formatos apenas YOLO: As exportações para Axelera e Sony IMX500 requerem atributos de modelo específicos do YOLO e não estão disponíveis para modelos genéricos.
  • Formatos específicos de plataforma: TensorRT requer uma GPU NVIDIA. RKNN requer o SDK rknn-toolkit2 (apenas Linux). Edge TPU requer o binário edgetpu_compiler (apenas Linux).

Link to this sectionFAQ#

Link to this sectionQue modelos posso exportar com a Ultralytics?#

Qualquer torch.nn.Module. Isto inclui modelos de timm, torchvision ou qualquer modelo PyTorch personalizado. O modelo deve estar em modo de avaliação (model.eval()) antes da exportação. O ONNX e o OpenVINO aceitam adicionalmente um tuplo de tensores de exemplo para modelos com múltiplas entradas.

Link to this sectionQue formatos de exportação funcionam sem uma GPU?#

Todos os formatos suportados (TorchScript, ONNX, OpenVINO, CoreML, TF SavedModel, TF Frozen Graph, NCNN, PaddlePaddle, MNN, ExecuTorch) podem exportar em CPU. Não é necessária nenhuma GPU para o processo de exportação em si. O TensorRT é o único formato que requer uma GPU NVIDIA.

Link to this sectionQual a versão da Ultralytics que preciso?#

Usa a Ultralytics >=8.4.38, que inclui o módulo ultralytics.utils.export e os argumentos estandardizados output_file/output_dir.

Link to this sectionPosso exportar um modelo torchvision para CoreML para implementação em iOS?#

Sim. Classificadores, detetores e modelos de segmentação torchvision exportam para .mlpackage via torch2coreml. Para modelos de classificação de imagem, passa uma lista de nomes de classes para classifier_names para incluir um cabeçalho de classificação. Executa a exportação no macOS ou Linux. O CoreML não é suportado no Windows. Vê a integração com CoreML para detalhes de implementação em iOS.

Link to this sectionPosso quantizar o meu modelo exportado para INT8 ou FP16?#

Sim, para vários formatos. Passa half=True para FP16 ou int8=True para INT8 ao exportar para OpenVINO, CoreML, MNN ou NCNN. O formato INT8 no OpenVINO requer adicionalmente um argumento calibration_dataset para quantização pós-treino. Consulta a página de integração de cada formato para conhecer as vantagens e desvantagens da quantização.

Comentários