IA em Ponte Rolante com PyTorch para ONNX e TensorRT

Implementação de inferência de IA em pontes rolantes na periferia

Fluxo completo de implementação: PyTorch ResNet-18 (FP32, 45MB, inferência GPU 5ms) → exportação ONNX (44MB, formato intermédio multiplataforma, perda de precisão <0,1%) → quantização INT8 TensorRT (6MB, volume 87%, perda de precisão <0,5%) → inferência na periferia Jetson Orin NX (1,2ms/imagem, consumo 15W). Em comparação com a inferência em servidor GPU (350W/5ms), o Jetson reduz o consumo de energia em 96% e aumenta a velocidade de inferência em 4,2 vezes. Este artigo fornece o fluxo completo de exportação, métodos de calibração INT8, procedimentos de validação de precisão e arquitetura de pipeline para múltiplos modelos.

Um modelo de IA para pontes rolantes pode ter um excelente desempenho numa GPU de laboratório, mas se não for implementado no terreno, não tem valor. As condições ambientais industriais (vibração, altas temperaturas, espaço limitado, sem ar condicionado) não são adequadas para servidores GPU de alta potência (350W+ exigem ar condicionado em sala de servidores). A implementação na periferia (Edge Deployment) converte o modelo PyTorch treinado para o formato intermédio ONNX, otimiza-o através da quantização INT8 TensorRT e implementa-o em dispositivos Jetson de baixo consumo. Este artigo utiliza o modelo ResNet-18 para detecção de fios rompidos em cabo de aço de ponte rolante como exemplo, fornecendo o fluxo completo de engenharia, desde a exportação até à implementação, com todos os passos reproduzíveis. Ambiente experimental: treino NVIDIA A10(48GB) / periferia Jetson Orin NX 16GB(15W) / PyTorch 2.1.0 / TensorRT 8.6 / JetPack 6.0.

Implementação prática de IA em pontes rolantes: do PyTorch ao ONNX/TensorRT e inferência na periferia Jetson

Exportação do modelo PyTorch para ONNX

ONNX (Open Neural Network Exchange) é a “linguagem universal” para implementação de modelos. A função torch.onnx.export() converte o grafo computacional dinâmico do PyTorch num grafo estático ONNX. Parâmetros essenciais: input_names=[“input”], output_names=[“output”], dynamic_axes={“input”:{0:”batch_size”,2:”height”,3:”width”}} (suporta entradas de dimensões variáveis). Após a exportação, utilize onnxruntime para validar a consistência da precisão: a diferença de precisão de inferência FP32 em relação ao PyTorch é <0,1% (média de 20 imagens do conjunto de validação).

import torch, torch.onnx model = torch.load("resnet18_crane.pth") # modelo pré-treinado FP32 dummy = torch.randn(1, 3, 224, 224) torch.onnx.export(model, dummy, "resnet18_crane.onnx", input_names=["input"], output_names=["output"], dynamic_axes={"input": {0: "batch", 2: "h", 3: "w"}}, opset_version=17) # Precisão de exportação verificada import onnxruntime as ort sess = ort.InferenceSession("resnet18_crane.onnx") out_ort = sess.run(None, {"input": dummy.numpy()})[0] out_pt = model(dummy).detach().numpy() print(f"Max diff: {abs(out_ort - out_pt).max():.6f}") # deve<1e-5

Quantização INT8 com TensorRT

O TensorRT é o motor de otimização de inferência da NVIDIA, que converte modelos ONNX em motores TensorRT (.trt) através de fusão de camadas (Layer Fusion), calibração de precisão (Calibração INT8) e otimização de memória (Pool Allocation). O processo de quantização INT8: mapeia os pesos e ativações do modelo FP32 de números de vírgula flutuante de 32 bits para inteiros de 8 bits (256 níveis de precisão). O mapeamento requer 100 a 500 imagens de calibração (Dataset de Calibração), utilizando o método de calibração por entropia (Calibração por Entropia) para encontrar o limiar de quantização com divergência KL mínima.

Comando específico: trtexec –onnx=resnet18_crane.onnx –saveEngine=resnet18_int8.trt –int8 –calib=calibration_data –fp16 –workspace=4096. Explicação dos parâmetros essenciais: –int8 ativa a quantização INT8; –calib especifica o diretório de imagens de calibração (500 imagens); –fp16 ativa o cálculo intermédio FP16 (precisão mista com pesos INT8); –workspace=4096 permite 4GB de espaço de trabalho (o Jetson Orin NX 16GB pode alocar 8GB). O tempo de conversão é de aproximadamente 11 minutos (GPU A10), e o tamanho do motor INT8 é de 6,2MB (14% do ONNX FP32).

IndicadorPy Torch FP32(GPU)ONNX FP32(GPU)Tensor RT INT8(Jetson)Margem de otimização
Tamanho do modelo45MB44MB6.2MB86%
Latência de inferência5.0ms4.8ms1.2ms4.2x
Consumo de energia350W350W12~15W96%
Custo de hardware¥80,000+¥80,000+¥3,50096%
Top-1Precisão94.0%93.9%93.6%0.4%
F1Pontuação0.930.930.920.01

Validação da Precisão Pós-Quantização

Após a quantização INT8, é obrigatório confirmar se a perda de precisão permanece dentro dos limites aceitáveis. O procedimento de validação consiste em executar, num conjunto de teste de 1.000 imagens, o PyTorch FP32 (referência) e o TensorRT INT8 (em validação), comparando a precisão Top-1, o score F1 e a matriz de confusão de cada classe. Nesta experiência, INT8 vs FP32: Top-1 desceu de 94,0% para 93,6% (0,4%), e o F1 de 0,93 para 0,92 (0,01). Ao nível das classes, a perda concentra-se na classe "rotura de fios do cabo de aço" (taxa de falsos negativos subiu de 2,3% para 3,1%, +0,8%); nas restantes 4 classes, a perda foi inferior a 0,3%. Se a perda de precisão INT8 exceder 1%, recomenda-se a quantização FP16 (volume de 12 MB, perda de precisão <0,1%) como solução de compromisso.


Implementação no Jetson e Pipeline de Inferência

O ficheiro do motor TensorRT é gravado diretamente no Jetson Orin NX (JetPack 6.0 com TensorRT 8.6 pré-instalado). O código de inferência utiliza a API TensorRT com bindings Python (ou a API C++ para latências mais baixas). Para um pipeline com múltiplos modelos (ex.: deteção YOLO + classificação ResNet), recorre-se a CudaStream para inferência assíncrona, sobrepondo o pós-processamento na CPU (NMS) com a inferência GPU do modelo seguinte. A latência total do pipeline corresponde a cerca de 60% da soma das latências individuais (nesta experiência: YOLOv8s 3,8 ms + ResNet18 1,2 ms ≈ 5 ms de ponta a ponta).

import tensorrt as trt, pycuda.driver as cuda # carregamentoINT8 engine with open("resnet18_int8.trt", "rb") as f, trt.Runtime(trt.Logger()) as r: engine = r.deserialize_cuda_engine(f.read()) ctx = engine.create_execution_context() # alocaçãoGPUmemória d_input = cuda.mem_alloc(1*3*224*224*4) # FP32entrada(uso realINT8pré-processamento) d_output = cuda.mem_alloc(1*6*4) stream = cuda.Stream() # ciclo de inferência for img in camera_stream(): cuda.memcpy_htod_async(d_input, preprocess(img), stream) ctx.execute_async_v2([int(d_input), int(d_output)], stream.handle) cuda.memcpy_dtoh_async(output, d_output, stream) stream.synchronize() result = postprocess(output) # categoria+confiança push_to_hmi(result) # enviar para ponte rolanteHMIexibição

Caso Real: Inspeção de Cabos de Aço em Ponte Rolante

Num projeto de inspeção visual por IA de cabos de aço em 17 pontes rolantes de uma siderurgia (n.º de projeto KL-EDGE-2024-003), cada ponte rolante foi equipada com um Jetson Orin NX (€448/unidade). Cada ponte tem 2 câmeras industriais (Basler acA2440-75um) que captam imagens de todo o comprimento do cabo de aço. O Jetson executa o pipeline YOLOv8s+ResNet18 (deteção de roturas + classificação do grau de gravidadeau de gravidade). A latência de inferência é de 5,0 ms de ponta a ponta (pipeline de dois modelos), processando cerca de 14.400 imagens por dia (2 câmeras × 1 imagem a cada 5 segundos × 10 horas). Durante 14 meses contínuos de operação (janeiro de 2025 a fevereiro de 2026), o sistema detetou 328 eventos de rotura de fios; a verificação manual confirmou 307 (precisão de 93,6%) e registaram-se 8 falsos negativos (recall de 97,5%) de 97,5%). Em comparação com a inspeção visual diária (1 inspeção ocular por ponte por dia, com taxa de deteção de roturas de cerca de 40%), a deteção automática por IA aumentou a taxa de deteção em 2,3 vezes.


Servidor GPU vs. Inferência na Borda: Qual Escolher?

A escolha da arquitetura de implementação depende das condicionantes do local — segue-se uma comparação entre quatro abordagens:

Item de comparação Solução A: GPUservidor Solução B: ONNX Runtime CPU Solução C: Tensor RT FP16 Solução D: Tensor RT INT8
Plataforma de hardwareNVIDIA A10/RTX 4090Industrial PC (i7-12700)Jetson Orin NX 16GBJetson Orin NX 16GB
Tamanho do modelo45MB (FP32)44MB (ONNX FP32)12MB (FP16)6.2MB (INT8)
Latência de inferência~5ms(Por imagem224×224)~25ms~2.5ms~1.2ms
Consumo de energia350W65W12~15W12~15W
Top-1Precisão94.0%93.9%93.8%93.6%
Custo de hardware¥80,000+¥8,000~15,000¥3,500¥3,500
Local de implantaçãoSala de servidores(Requer climatização)Sala de controle/Sala de distribuição elétricainterior do quadro elétrico da ponte rolantequadro elétrico da ponte rolante Interno
Complexidade operacionalAlto(Compatibilidade de drivers/Gestão ambiental)Médio(sistema operacional Manutenção)Baixo(Pronto para uso após flash)Baixo(Pronto para uso após flash)
Cenário recomendadoTreinamento de modelo/Inferência offline em loteExistentecomputador industrial E insensível à latênciaPrecisão Implantação de borda prioritáriaMelhor opção custo-benefício

Condições de teste: ResNet-18, entrada 224×224, batch=1. Servidor GPU: NVIDIA A10 (48GB), CUDA 12.1, PyTorch 2.1.0. ONNX Runtime CPU: i7-12700, ONNX Runtime 1.16. Jetson: Orin NX 16GB, JetPack 6.0, TensorRT 8.6. Latência calculada como média de 1000 inferências.

Perguntas Frequentes sobre Otimização de Inferência

P: A perda de precisão com quantização INT8 no TensorRT é aceitável?

R: Neste experimento, a precisão Top-1 do INT8 vs FP32 caiu de 94,0% para 93,6% (perda de 0,4%), e o F1 de 0,93 para 0,92 (perda de 0,01). Em cenários industriais, uma perda de precisão de 0,4% em troca de uma compressão de volume de 7,5x e uma aceleração de inferência de 4,2x é totalmente justificável. Se a perda de precisão para uma classe específica de defeito for superior a 1% (por exemplo, Cabo de Aço com fios rompidos caindo de 92% para 90%), recomenda-se usar inferência FP16 para essa classe ou aumentar a proporção de amostras dessa classe no conjunto de dados de calibração INT8.

P: Como fazer o pipeline de múltiplos modelos em cascata (detecção YOLO + classificação ResNet) no Jetson?

R: Use CudaStream e CUDA Graph do TensorRT para implementar o pipeline de múltiplos modelos. Passos: ①Criar 2 CudaStreams (stream1=YOLO, stream2=ResNet); ②YOLO executa no stream1, a CPU executa NMS (supressão não máxima, ~0,5ms), recorta as regiões detectadas e envia os resultados para o stream2 para classificação ResNet; ③Sincronizar os dois streams via CUDA Event. A latência ponta-a-ponta é cerca de 60% da soma das latências de cada modelo (sobreposição de inferência GPU e pós-processamento CPU).

P: Quais são os problemas comuns ao exportar para ONNX?

R: Três problemas frequentes: ①Dimensões dinâmicas — o ONNX fixa o tamanho de entrada por padrão, é necessário definir o parâmetro dynamic_axes para suportar tamanhos variáveis (ex.: alternar entre 224×224 e 416×416); ②Fluxo de controle — loops if/for em PyTorch precisam ser substituídos por torch.where/torch.arange (o ONNX não suporta fluxo de controle Python); ③Operadores personalizados — funções torch.autograd.Function personalizadas precisam ser registradas como symbolic ONNX. Recomenda-se usar o novo backend de exportação torch.onnx.export(…, dynamo=True) (PyTorch 2.1+).

P: O dispositivo Jetson pode operar de forma estável a longo prazo dentro do painel de controle de ponte rolante?

R: Sim. A versão industrial do Jetson Orin NX (JetPack 6.0) suporta temperatura ampla de -25°C a 80°C, umidade de 5% a 95% sem condensação e resistência a vibração de 50G. Na implantação real, foi utilizado resfriamento passivo (radiador de alumínio com aletas 145×80×35mm) + Cobertura de proteção IP54 montado na parede interna do Gabinete elétrico. Já implantado em 17 pontes rolantes (projeto KL-EDGE-2024-003), com operação contínua mais longa de 14 meses sem falhas (até fevereiro de 2026). A temperatura da CPU permanece estável entre 65~72°C (dentro do Gabinete elétrico com Temperatura Ambiente de 35°C).

Artigos relacionados

contact

contact us

phone:
+86 13903802779

mail:3915269@qq.com

Working hours: Monday to Friday

Wechat
Wechat
SHARE
TOP