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.
| Formato | Função | Instalar | Saída |
|---|---|---|---|
| ONNX | torch2onnx() | pip install onnx | .onnx arquivo |
| TorchScript | torch2torchscript() | incluído no PyTorch | .torchscript arquivo |
| OpenVINO | torch2openvino() | pip install openvino | _openvino_model/ diretório |
| CoreML | torch2coreml() | pip install coremltools | .mlpackage |
| TF SavedModel | onnx2saved_model() | Consulte os requisitos detalhados abaixo | _saved_model/ diretório |
| Gráfico TF | keras2pb() | Consulte os requisitos detalhados abaixo | .pb arquivo |
| NCNN | torch2ncnn() | pip install ncnn pnnx | _ncnn_model/ diretório |
| MNN | onnx2mnn() | pip install MNN | .mnn arquivo |
| PaddlePaddle | torch2paddle() | pip install paddlepaddle x2paddle | _paddle_model/ diretório |
| ExecuTorch | torch2executorch() | 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.0onnx2tf>=1.26.3,<1.29.0tf_keras<=2.19.0sng4onnx>=1.0.1onnx_graphsurgeon>=0.3.26(instalar com--extra-index-url https://pypi.ngc.nvidia.com)ai-edge-litert>=1.2.0,<1.4.0no macOS (ai-edge-litert>=1.2.0(em outras plataformas)onnxslim>=0.1.71onnx>=1.12.0,<2.0.0protobuf>=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.0sobre CUDApaddlepaddle==3.0.0na CPU ARM64paddlepaddle>=3.0.0,<3.3.0em 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:
torch2onnxetorch2openvinoaceitar uma tupla ou uma lista de tensores de exemplo para modelos com múltiplas entradas.torch2torchscript,torch2coreml,torch2ncnn,torch2paddle, etorch2executorchassumir um único tensor de entrada. - O ExecuTorch necessita de
flatc: O ambiente de execução do ExecuTorch requer o compilador FlatBuffers. Instale combrew install flatbuffersno macOS ouapt install flatbuffers-compilerno 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-toolkit2SDK (apenas para Linux). Edge TPU exige que oedgetpu_compilerbinario (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.