Optimisation IA pont roulant avec PyTorch vers ONNX sur Jetson

Déploiement en périphérie du modèle IA pour pont roulant

Chaîne de déploiement complète : PyTorch ResNet-18 (FP32, 45MB, inférence GPU 5ms) → Export ONNX (44MB, format intermédiaire multiplateforme, perte de précision < 0,1 %) → Quantification INT8 TensorRT (6MB, volume réduit de 87 %, perte de précision < 0,5 %) → Inférence en périphérie Jetson Orin NX (1,2 ms/image, consommation 15W). Par rapport à l'inférence sur serveur GPU (350W/5ms), Jetson réduit la consommation de 96 % et accélère l'inférence d'un facteur 4,2. Cet article fournit le script d'export complet, la méthode d'étalonnage INT8, le processus de validation de précision et l'architecture de pipeline multi-modèles.

Un modèle IA pour pont roulant qui fonctionne parfaitement sur un GPU en laboratoire ne vaut rien s'il ne peut pas être déployé sur le terrain. Les conditions environnementales industrielles (vibrations, températures élevées, espace restreint, absence de climatisation) ne permettent pas d'installer un serveur GPU à forte puissance (350W+ nécessite une salle climatisée). Le déploiement en périphérie (Edge Deployment) convertit le modèle PyTorch entraîné au format intermédiaire ONNX, puis l'optimise par quantification INT8 TensorRT pour le déployer sur un dispositif périphérique Jetson à faible consommation. Cet article prend l'exemple du modèle ResNet-18 de détection de fils cassés du câble du pont roulant et fournit la chaîne d'ingénierie complète, de l'export au déploiement, chaque étape étant reproductible. Environnement d'expérimentation : entraînement NVIDIA A10 (48GB) / périphérie Jetson Orin NX 16GB (15W) / PyTorch 2.1.0 / TensorRT 8.6 / JetPack 6.0.

Déploiement pratique du modèle IA pour pont roulant : de PyTorch à ONNX/TensorRT puis inférence en périphérie Jetson

Étape 1 : Export du modèle PyTorch vers ONNX

ONNX (Open Neural Network Exchange) est le « langage universel » du déploiement de modèles. torch.onnx.export() convertit le graphe de calcul dynamique de PyTorch en graphe statique ONNX. Paramètres clés : input_names=[« input »], output_names=[« output »], dynamic_axes={« input »:{0:« batch_size »,2:« height »,3:« width »}} (prise en charge d'entrées à dimensions variables). Après l'export, on utilise onnxruntime pour vérifier la cohérence de la précision : la différence de précision d'inférence FP32 par rapport à PyTorch est inférieure à 0,1 % (moyenne sur 20 images de validation).

import torch, torch.onnx model = torch.load("resnet18_crane.pth") # FP32Modèle pré-entraîné type 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) # Précision de validation/export 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}") # Réponse<1e-5

Étape 2 : Quantification INT8 avec TensorRT

TensorRT est le moteur d'optimisation d'inférence de NVIDIA. Grâce à la fusion de couches (Layer Fusion), à l'étalonnage de précision (INT8 Calibration) et à l'optimisation mémoire (Pool Allocation), il convertit le modèle ONNX en moteur TensorRT (.trt). Processus de quantification INT8 : les poids et valeurs d'activation du modèle FP32 sont mappés de nombres flottants 32 bits vers des entiers 8 bits (256 niveaux de précision). Ce mappage nécessite 100 à 500 images d'étalonnage (Calibration Dataset), en utilisant la méthode d'étalonnage par entropie (Entropy Calibration) pour trouver le seuil de quantification à divergence KL minimale.

Commande spécifique : trtexec –onnx=resnet18_crane.onnx –saveEngine=resnet18_int8.trt –int8 –calib=calibration_data –fp16 –workspace=4096. Explication des paramètres clés : –int8 active la quantification INT8 ; –calib spécifie le répertoire des images d'étalonnage (500 images) ; –fp16 active le calcul intermédiaire FP16 (précision mixte avec les poids INT8) ; –workspace=4096 autorise 4 Go d'espace de travail (Jetson Orin NX 16GB peut allouer 8 Go). Temps de conversion : environ 11 minutes (GPU A10), taille du moteur INT8 : 6,2 MB (14 % de l'ONNX FP32).

IndicateurPy Torch FP32(GPU)ONNX FP32(GPU)Tensor RT INT8(Jetson)Marge d
Taille du modèle45MB44MB6.2MB86%
Latence d5.0ms4.8ms1.2ms4.2x
Consommation électrique350W350W12~15W96%
Coût matériel¥80,000+¥80,000+¥3,50096%
Top-1Précision94.0%93.9%93.6%0.4%
F1Score0.930.930.920.01

Étape 3 : Validation de la précision

Après quantification INT8, il est impératif de vérifier que la perte de précision reste dans des limites acceptables. Le protocole de validation consiste à exécuter successivement PyTorch FP32 (référence) et TensorRT INT8 (modèle à valider) sur un jeu de 1 000 images de test, puis à comparer la précision Top-1, le score F1 et la matrice de confusion pour chaque classe. Dans cette expérience, les résultats INT8 vs FP32 sont les suivants : Top-1 passe de 94,0 % à 93,6 % (soit −0,4 %), et le score F1 de 0,93 à 0,92 (soit −0,01). La perte de précision au niveau des classes se concentre sur la catégorie « rupture de câble métallique » (le taux de faux négatifs passe de 2,3 % à 3,1 %, soit +0,8 %) ; pour les 4 autres classes, la perte reste inférieure à 0,3 %. Si la perte de précision INT8 dépasse 1 %, il est recommandé de basculer vers une quantification FP16 (volume de 12 Mo, perte de précision inférieure à 0,1 %) comme solution de compromis.


Étape 4 : Déploiement Jetson et chaîne de production

Le fichier Engine TensorRT est directement flashé sur la Jetson Orin NX (JetPack 6.0 avec TensorRT 8.6 préinstallé). Le code d'inférence utilise l'API TensorRT liée à Python (ou l'API C++ pour une latence encore plus faible). Pour une chaîne de production multi-modèles (par exemple, détection YOLO + classification ResNet) : utilisez CudaStream pour une inférence asynchrone, en chevauchant le post-traitement CPU (NMS) avec l'inférence GPU du modèle suivant. La latence de bout en bout de la chaîne représente environ 60 % de la somme des latences individuelles (dans cette expérience : YOLOv8s 3,8 ms + ResNet18 1,2 ms ≈ 5 ms de bout en bout).

import tensorrt as trt, pycuda.driver as cuda # ChargementINT8 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() # AllocationGPUMémoire d_input = cuda.mem_alloc(1*3*224*224*4) # FP32Entrée(Utilisation réelleINT8Prétraitement) d_output = cuda.mem_alloc(1*6*4) stream = cuda.Stream() # Boucle d 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) # Catégorie+Confiance push_to_hmi(result) # Envoi au pont roulantHMIAffichage

Cas de déploiement réel

Dans le cadre d'un projet de détection visuelle par IA des câbles métalliques sur 17 ponts roulants d'une aciérie (référence projet KL-EDGE-2024-003), chaque pont roulant est équipé d'une Jetson Orin NX (environ 448 €/unité). Chaque pont roulant est doté de 2 caméras industrielles (Basler acA2440-75um, capturant des images sur toute la longueur du câble métallique). La Jetson exécute la chaîne YOLOv8s+ResNet18 (détection de la position des ruptures + classification du niveau de gravité). La latence d'inférence de bout en bout est de 5,0 ms (chaîne à deux modèles), avec un traitement quotidien d'environ 14 400 images (2 caméras × 1 image toutes les 5 secondes × 10 heures). Après 14 mois de fonctionnement continu (janvier 2025 à février 2026) : le système a détecté 328 événements de rupture de câble, dont 307 confirmés par vérification manuelle (taux de précision de 93,6 %), et 8 cas de non-détection (taux de rappel de 97,5 %). Par rapport à l'inspection visuelle manuelle quotidienne (1 inspection visuelle par pont roulant et par jour, avec un taux de détection des ruptures d'environ 40 %), le taux de détection de l'inspection automatique par IA est multiplié par 2,3.


Comparatif des solutions de déploiement : serveur GPU vs inférence en périphérie

Le choix de la solution de déploiement dépend des contraintes du site d'exploitation. Voici un comparatif des avantages et inconvénients de quatre approches :

Élément de comparaison Solution A: GPUserveur Solution B: ONNX Runtime CPU Solution C: Tensor RT FP16 Solution D: Tensor RT INT8
Plateforme matérielleNVIDIA A10/RTX 4090Industriel PC (i7-12700)Jetson Orin NX 16GBJetson Orin NX 16GB
Taille du modèle45MB (FP32)44MB (ONNX FP32)12MB (FP16)6.2MB (INT8)
Latence d~5ms(Image unique224×224)~25ms~2.5ms~1.2ms
Consommation électrique350W65W12~15W12~15W
Top-1Précision94.0%93.9%93.8%93.6%
Coût matériel¥80,000+¥8,000~15,000¥3,500¥3,500
Emplacement de déploiementSalle serveur(Climatisation requise)Salle de contrôle/Local électriquearmoire électrique du pont roulant Intérieurarmoire électrique du pont roulant Intérieur
Complexité de maintenanceÉlevée(Compatibilité des pilotes/Gestion environnementale)Moyenne(système d'exploitation Maintenance)Faible(Prêt à l)Faible(Prêt à l)
Cas dEntraînement de modèle/Inférence hors ligne par lotsExistant PC industrielet insensible à la latencePrécision Déploiement en périphérie prioritaireChoix optimal en rapport qualité-prix
Conditions de test : Res Net-18, entrée 224×224, batch=1. Serveur GPU : NVIDIA A10 (48 Go), CUDA 12.1, Py Torch 2.1.0. ONNX Runtime CPU : i7-12700, ONNX Runtime 1.16. Jetson : Orin NX 16 Go, Jet Pack 6.0, Tensor RT 8.6. La latence correspond à la moyenne de 1 000 inférences.

Questions fréquentes sur l'optimisation TensorRT et le déploiement Jetson

Q : La perte de précision due à la quantification INT8 de TensorRT est-elle acceptable ?

A : Dans cette expérience, la précision Top-1 de l'INT8 par rapport au FP32 passe de 94,0 % à 93,6 % (perte de 0,4 %), et le F1 de 0,93 à 0,92 (perte de 0,01). Dans un contexte industriel, une perte de précision de 0,4 % est largement compensée par une réduction de volume de 7,5 fois et une accélération de l'inférence de 4,2 fois. Si la perte de précision pour une classe de défauts dépasse 1 % (par exemple, la détection de ruptures de câble métallique passant de 92 % à 90 %), il est recommandé d'utiliser l'inférence FP16 pour cette classe ou d'augmenter la proportion d'échantillons de cette classe dans le jeu de données de calibration INT8.

Q : Comment pipeline-t-on un modèle en cascade (détection YOLO + classification ResNet) sur Jetson ?

A : On utilise CudaStream et CUDA Graph de TensorRT pour implémenter le pipeline multi-modèles. Étapes : ① créer 2 CudaStream (stream1 = YOLO, stream2 = ResNet) ; ② YOLO s'exécute sur stream1, le CPU exécute le NMS (suppression non maximale, environ 0,5 ms), découpe les régions détectées et les envoie à la classification ResNet sur stream2 ; ③ synchroniser les deux streams via CUDA Event. La latence de bout en bout représente environ 60 % de la somme des latences de chaque modèle (chevauchement de l'inférence GPU et du post-traitement CPU).

Q : Quels sont les pièges courants lors de l'exportation ONNX ?

A : Trois problèmes fréquents : ① Dimensions dynamiques — ONNX fixe la taille d'entrée par défaut, il faut définir le paramètre dynamic_axes pour supporter des tailles variables (par exemple, passer de 224×224 à 416×416) ; ② Flux de contrôle — les boucles if/for de PyTorch doivent être remplacées par torch.where/torch.arange (ONNX ne prend pas en charge le flux de contrôle Python) ; ③ Opérateurs personnalisés — les torch.autograd.Function personnalisés doivent être enregistrés avec ONNX symbolic. Il est recommandé d'utiliser le nouveau backend d'exportation torch.onnx.export(…, dynamo=True) (PyTorch 2.1+).

Q : Un appareil Jetson peut-il fonctionner de manière stable à long terme dans une armoire de commande de pont roulant ?

A : Oui. La version industrielle du Jetson Orin NX (JetPack 6.0) prend en charge une large plage de températures de -25 °C à 80 °C, une humidité de 5 à 95 % sans condensation et une résistance aux vibrations de 50 G. Dans le déploiement réel, un refroidissement passif (radiateur en ailettes en alliage d'aluminium 145×80×35 mm) et un carter de protection IP54 sont installés sur la paroi interne de l'armoire électrique. Déployé sur 17 ponts roulants (projet KL-EDGE-2024-003), avec une durée de fonctionnement continu maximale de 14 mois sans panne (au 1er février 2026). La température du CPU reste stable entre 65 et 72 °C (dans une armoire électrique à température ambiante de 35 °C).

Articles connexes

contact

contact us

phone:
+86 13903802779

mail:3915269@qq.com

Working hours: Monday to Friday

Wechat
Wechat
SHARE
TOP