Ir para o conteúdo

Como exportarPyTorch YOLO com Ultralytics

A implementação de PyTorch em produção implica, normalmente, ter de 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 a sua própria API, peculiaridades de dependências e convenções de saída.

Ultralytics utilitários de exportação autónomos que integram vários back-ends numa única interface consistente. Pode exportar qualquer torch.nn.Module, incluindo timm modelos de imagem, torchvision classificadores e detectores, ou as suas próprias arquiteturas personalizadas, para ONNX, TorchScript, OpenVINO, CoreML, NCNN, PaddlePaddle, MNN, ExecuTorch, e TensorFlow SavedModel sem ter de aprender cada backend separadamente.

Por que utilizar Ultralytics YOLO ?

  • Uma API para 10 formatos: aprenda uma única convenção de chamada em vez de uma dúzia.
  • Superfície de serviço comum: os auxiliares de exportação encontram-se em ultralytics.utils.export, pelo que, assim que os pacotes de backend estiverem instalados, poderá manter o mesmo padrão de chamada em todos os formatos.
  • O mesmo fluxo de código das YOLO : os mesmos auxiliares estão na base de todasYOLO Ultralytics .
  • Quantização FP16 e INT8 integrada para formatos que a suportam (OpenVINO, CoreML, MNN, NCNN).
  • Funciona na CPU: não GPU para a etapa de exportação em si, pelo que pode executá-la localmente em qualquer computador portátil.

Início Rápido

A forma mais rápida é uma exportação de duas linhas para ONNX sem YOLO e sem qualquer 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")

Formatos de Exportação Suportados

O torch2* as funções aceitam um padrão torch.nn.Module e um tensor de entrada de exemplo. O MNN, TF SavedModel e TF Graph passam por um artefacto ONNX Keras intermédio. Em nenhum dos casos são necessários atributos YOLO.

FormatoFunçãoInstalarSaída
ONNXtorch2onnx()pip install onnx.onnx arquivo
TorchScripttorch2torchscript()incluído no PyTorch.torchscript arquivo
OpenVINOtorch2openvino()pip install openvino_openvino_model/ diretório
CoreMLtorch2coreml()pip install coremltools.mlpackage
TF SavedModelonnx2saved_model()Consulte os requisitos detalhados abaixo_saved_model/ diretório
Gráfico TFkeras2pb()Consulte os requisitos detalhados abaixo.pb arquivo
NCNNtorch2ncnn()pip install ncnn pnnx_ncnn_model/ diretório
MNNonnx2mnn()pip install MNN.mnn arquivo
PaddlePaddletorch2paddle()pip install paddlepaddle x2paddle_paddle_model/ diretório
ExecuTorchtorch2executorch()pip install executorch_executorch_model/ diretório

ONNX formato intermédio

MNN, TF SavedModele as exportações de gráficos TF passam pelo ONNX um passo intermédio. Exporte ONNX para ONNX e, em seguida, converta.

Incorporar metadados

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

Exemplos passo a passo

Todos os exemplos abaixo utilizam a mesma configuração: uma rede 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)

Ligue sempre model.eval() antes de exportar

Abandono escolar, normalização em lote, e outras camadas treinadas exclusivamente para inferência comportam-se de forma diferente durante a inferência. Ignorar .eval() gera exportações com resultados incorretos.

Exportar para ONNX

from ultralytics.utils.export import torch2onnx

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

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

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

O opset predefinido é 14 e o nome padrão da entrada é "images". Substituir pelo opset, input_names, ou output_names argumentos.

Exportar para TorchScript

Não são necessárias dependências adicionais. Utiliza torch.jit.trace por baixo do capô.

from ultralytics.utils.export import torch2torchscript

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

Exportar para o OpenVINO

from ultralytics.utils.export import torch2openvino

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

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

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. O INT8 requer, além disso, um calibration_dataset argumento.

Requer openvino>=2024.0.0 ) e YOLO11 para executar o rastreamento de objetos em quadros de vídeo. Este script assume que os pacotes necessários ( >=2025.2.0 no macOS 15.4+) e torch>=2.1.

Exportar 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 classificação modelos, passe uma lista de nomes de classes para classifier_names para adicionar uma categoria de classificação ao CoreML .

Requer coremltools>=9.0, torch>=1.11, e numpy<=2.3.5. Não é compatível com o Windows.

BlobWriter not loaded erro

coremltools>=9.0 O ships wheels para Python .10–3.13 no macOS e no Linux. Nas Python mais recentes Python , a extensão nativa em C não consegue ser carregada. Utilize Python .10–3.13 para CoreML .

Exportar paraSavedModel TensorFlow

SavedModel TF passa pelo ONNX etapa intermédia:

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 devolve um modelo Keras e também gera 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 (instalar 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

Exportar para o gráfico TensorFlow

Dando continuidade à SavedModel acima, converta o modelo Keras obtido num 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 para a NCNN

from ultralytics.utils.export import torch2ncnn

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

O diretório contém ficheiros «param» e «bin» com nomes fixos, juntamente com um Python :

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

torch2ncnn() verifica se ncnn e pnnx na primeira utilização.

Exportar para o MNN

A exportação do MNN requer um ONNX como entrada. ONNX , exporte 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")

Compatível com half=True para o FP16 e int8=True para quantização INT8. Requer MNN>=2.9.6 e torch>=1.10.

Exportar para o PaddlePaddle

from ultralytics.utils.export import torch2paddle

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

O diretório contém os ficheiros PaddlePaddle e dos parâmetros PaddlePaddle :

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

Requer x2paddle e a PaddlePaddle correta PaddlePaddle para a sua plataforma:

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

Não é compatível com NVIDIA .

Exportar para o ExecuTorch

from ultralytics.utils.export import torch2executorch

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

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

resnet18_executorch_model/
└── model.pte

Requer torch>=2.9.0 e um ExecuTorch de execução correspondente (pip install executorch). Para utilização em tempo de execução, consulte o Integração com o ExecuTorch.

Verifique o seu modelo exportado

Após a exportação, verifique a correspondência numérica com o PyTorch original antes da entrega. Um teste rápido com ONNXBackend de ultralytics.nn.backends compara os resultados e sinaliza erros de rastreamento ou quantização numa fase inicial:

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

Diferença esperada

Para exportações em 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á no modo de avaliação. As exportações em FP16 e INT8 têm tolerâncias mais flexíveis. Valide com dados reais em vez de tensores aleatórios.

Noutros ambientes de execução, o tensor de entrada pode ser diferente. OpenVINO, por exemplo, utiliza o nome do argumento de propagação do modelo (normalmente x (para modelos genéricos), enquanto torch2onnx o valor padrão é "images".

Limitações Conhecidas

  • O suporte a múltiplas entradas é desigual: torch2onnx e torch2openvino aceitar uma tupla ou uma lista de tensores de exemplo para modelos com múltiplas entradas. torch2torchscript, torch2coreml, torch2ncnn, torch2paddle, e torch2executorch assumir um único tensor de entrada.
  • O ExecuTorch necessita de flatc: O ambiente de execução do ExecuTorch requer o compilador FlatBuffers. Instale com brew install flatbuffers no macOS ou apt install flatbuffers-compiler no Ubuntu.
  • Sem inferência através da Ultralytics:YOLO exportados não podem ser carregados novamente através de YOLO() para inferência. Utilize o ambiente de execução nativo para cada formato (ONNX, OpenVINO, etc.).
  • FormatosYOLO: as exportações do Axelera e do Sony IMX500 requerem atributos de modelo YOLO e não estão disponíveis para modelos genéricos.
  • Formatos específicos para cada plataforma: TensorRT requer umaGPU NVIDIA . RKNN exige que o rknn-toolkit2 SDK (apenas para Linux). Edge TPU exige que o edgetpu_compiler binario (apenas para Linux).

FAQ

Que modelos posso exportar com Ultralytics?

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

Quais são os formatos de exportação que funcionam sem uma GPU?

Todos os formatos suportados (TorchScript, ONNX, OpenVINO, CoreML, TF SavedModel, TF Graph, NCNN, PaddlePaddle, MNN, ExecuTorch) podem ser exportados na CPU. Não GPU necessária GPU para o próprio processo de exportação. TensorRT o único formato que requer umaGPU NVIDIA .

Que Ultralytics do Ultralytics preciso?

Usar Ultralytics >=8.4.38, que inclui o ultralytics.utils.export módulo e o padronizado output_file/output_dir argumentos.

Posso exportar um modelo do TorchVision para CoreML iOS ?

Sim. Os classificadores, detetores e modelos de segmentação do torchvision exportam para .mlpackage através de torch2coreml. Para modelos de classificação de imagens, passe uma lista de nomes de classes para classifier_names para processar num classificador. Execute a exportação no macOS ou no Linux. CoreML não CoreML compatível com o Windows. Consulte o CoreML para obter detalhes sobre iOS .

Posso quantizar o meu modelo exportado para INT8 ou FP16?

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



📅 Criado há 0 dias ✏️ Atualizado há 0 dias
raimbekovm

Comentários