Choisir une cible de déploiement
Déduis un moteur d'exécution et un format d'export à partir de l'appareil, du budget de latence et du parc, puis vérifie-les sur l'appareil.

Le même YOLO26n traite une image en 38.9 ms sur un CPU avec ONNX Runtime, et en 1.7 ms sur un GPU T4 avec TensorRT, selon les benchmarks YOLO26. Choisis le mauvais moteur d'exécution et tu paieras soit bien plus de matériel que nécessaire, soit tu déploieras des caméras incapables de suivre le rythme. Cette leçon transforme ce choix en une décision de dix minutes, que tu peux justifier avec des mesures réalisées directement sur l'appareil.
Pratique
Commencer par l'appareil#
Le moteur d'exécution dépend de l'endroit où l'inférence est effectuée, pas de tes habitudes. Suis l'arbre depuis le début et arrête-toi à la première correspondance :
Chaque moteur d'exécution correspond à une valeur format= dans le mode d'exportation :
| Objectif | Moteur d'exécution | format= | Attention à |
|---|---|---|---|
| GPU NVIDIA, Jetson | TensorRT | engine | Un moteur ne fonctionne que sur la famille de GPU et avec la version de TensorRT qui l'a compilé |
| CPU, iGPU, NPU Intel | OpenVINO | openvino | Optimisé pour Intel ; effectue des mesures avant de l'utiliser ailleurs |
| Tout CPU ou GPU | ONNX Runtime | onnx | Choisis explicitement le fournisseur d'exécution |
| iPhone, iPad, Mac | CoreML | coreml | L'exportation s'effectue sur macOS ou Linux, pas sur Windows |
| Android, systèmes embarqués | LiteRT | litert | INT8 nécessite des données d'étalonnage data |
| NPU Snapdragon | Qualcomm QNN | qnn | Export quantifié uniquement ; passe la cible Hexagon sous la forme name |
| Raspberry Pi, CPU ARM | NCNN | ncnn | Le format le plus rapide dans le guide Raspberry Pi |
| Navigateur | ONNX Runtime Web | onnx | Limite-toi aux modèles n ou s |
Sur les plateformes Apple récentes, tu peux aussi exporter au format Core AI plus récent d'Apple (format=coreai, exporté sur macOS 26+ avec Apple silicon ou sur Linux x86-64). Tu débutes dans l'export ? La leçon Exporter pour le déploiement présente les bases.
Si tu préfères ne pas exécuter de serveurs d'inférence, Ultralytics Platform déploie un modèle sous forme de point de terminaison dédié dans l'une des 42 régions, et l'onglet Deployments de ton profil indique où chacun s'exécute :

Cette approche est expliquée dans Déployer et appeler un point de terminaison. Le reste de ce cours s'adresse à ceux qui exécutent eux-mêmes le modèle.
Convertis la cible FPS en budget de latence en millisecondes#
« Temps réel » n'est pas une exigence ; un nombre, si. Calcule-le avant de mesurer quoi que ce soit :
| Étape | Exemple : 20 FPS par caméra |
|---|---|
| Budget par image = 1000 ÷ FPS | 50 ms |
| Moins le décodage (RTSP, 1080p) | environ 10 ms |
| Moins le suivi, le comptage et les sorties | environ 5 ms |
| Moins 20 % de marge pour les pics | 10 ms |
| Restant pour le modèle | environ 25–30 ms |
Applique ensuite ces règles de décision :
- Si YOLO26n dépasse le budget alloué au modèle sur le CPU de l'appareil, passe à un accélérateur (GPU, iGPU, NPU) ou réduis
imgszavant toute autre chose ; les benchmarks YOLO26 indiquent 38.9 ms pour YOLO26n sur CPU ONNX et 1.7 ms sur une T4 avec TensorRT. - Si un appareil doit servir plusieurs caméras, divise le budget du modèle par le nombre de caméras.
- Si le parc compte plus qu'une poignée de types d'appareils, privilégie les environnements d'exécution qui ne nécessitent pas de compilation par appareil, ou prévois une compilation par catégorie d'appareil.
- Si le code appelant est en Swift, Kotlin ou C++, vérifie que le SDK de l'environnement d'exécution prend en charge ce langage avant de t'engager.
Mesure les performances des candidats sur l'appareil#
Les fiches techniques et les benchmarks d'autres personnes constituent un point de départ. La décision se prend sur le matériel que tu vas déployer, et en tenant compte des images les plus lentes, pas de la moyenne : un environnement d'exécution rapide en médiane, mais qui se bloque sur une image sur vingt, continuera à perdre des images. Ce script exporte chaque candidat, mesure le temps de 100 inférences sur une image réelle et évalue chaque candidat à son 95e percentile (p95) :
from ultralytics import YOLO
from ultralytics.utils.downloads import safe_download
BUDGET_MS = 30 # the model's share of a 20 FPS frame budget
CANDIDATES = ("onnx", "openvino") # runtimes the decision tree allows on this machine
if __name__ == "__main__": # exports and inference can start worker processes on macOS and Windows
frame = str(safe_download("https://ultralytics.com/images/bus.jpg")) # use a real frame from your camera
for fmt in CANDIDATES:
model = YOLO(YOLO("yolo26n.pt").export(format=fmt))
for _ in range(5): # warm up: the first calls include one-time setup
model(frame, verbose=False)
runs = sorted(model(frame, verbose=False)[0].speed["inference"] for _ in range(100))
p50, p95 = runs[49], runs[94]
verdict = "meets" if p95 <= BUDGET_MS else "misses"
print(f"{fmt:9s} p50 {p50:5.1f} ms p95 {p95:5.1f} ms {verdict} the {BUDGET_MS} ms budget")Sur l'ordinateur portable Apple silicon utilisé pour tester ce cours, alors que d'autres tâches partageaient le CPU :
onnx p50 30.0 ms p95 46.4 ms misses the 30 ms budget
openvino p50 22.8 ms p95 113.5 ms misses the 30 ms budgetExaminons chaque ligne :
speed["inference"]correspond au temps pris par le modèle lui-même pour traiter cette image, sans décodage ni dessin, ce qui permet de comparer équitablement les environnements d'exécution.- OpenVINO gagne en médiane et perd au p95 avec un écart supérieur à un facteur deux. En te basant sur les moyennes, tu déploierais l'environnement d'exécution qui se bloque lors des périodes de forte charge ; en te basant sur le p95, ONNX Runtime est le choix le plus stable sur cette machine.
- Les deux dépassent le budget ; la prochaine étape consiste donc à utiliser un
imgszplus petit, un accélérateur ou moins de caméras par appareil, et non un autre environnement d'exécution CPU.
Pour comparer rapidement la précision et la vitesse de différents formats, le mode Benchmark exporte, valide et mesure chacun d'eux :
yolo benchmark model=yolo26n.pt data=coco8.yaml imgsz=640 format=onnxSupprime format= pour tester tous les formats pris en charge par la machine. COCO8 ne compte que quatre images de validation ; considère donc sa colonne mAP comme un simple test de bon fonctionnement et utilise le fichier YAML de ton propre jeu de données pour évaluer la précision.
Pièges#
Symptôme : le modèle atteint 60 FPS sur ta station de travail, mais perd des images sur l'appareil. Solution : effectue le benchmark sur le matériel de déploiement, ou sur la machine la plus proche que tu peux obtenir, et exécute-le sous la charge qu'il subira en production (autres processus, autres caméras).
Symptôme : un .engine créé sur un GPU de centre de données ne se charge pas sur un Jetson Orin. Solution : crée-le sur la cible au moment de l'installation (une compilation YOLO26n FP16 prend environ 5 minutes sur un Jetson Orin, selon la documentation d'export de la plateforme), ou conserve une compilation par catégorie d'appareils et version de TensorRT, puis livre .pt ou .onnx pour que chaque appareil puisse recompiler.
yolo benchmark effectue la mesure à la valeur imgsz que tu lui transmets. Si la production s'exécute à imgsz=1280, effectue le benchmark à 1280 : le calcul augmente avec le nombre de pixels, donc les valeurs à 640 sous-estiment d'environ 4× le coût d'un déploiement à 1280.
Quatre questions supplémentaires pour les appareils Edge#
Les guides Raspberry Pi, NVIDIA Jetson et DeepStream sur Jetson détaillent les cibles les plus courantes. Avant de choisir un appareil Edge, réponds aux questions suivantes :
- Démarrage à froid : où l'engine TensorRT est-il construit, et qui doit attendre sa création ?
- Alimentation et chaleur : le boîtier peut-il faire fonctionner le modèle à plein FPS toute la journée ?
- Mémoire : reste-t-il assez de place pour les buffers d'images et l'état du tracker à côté du modèle ? INT8 réduit de moitié la part du modèle.
- Mises à jour : comment un nouveau
best.ptest-il déployé sur 1 000 appareils ? Une image Docker garantit leur cohérence.
Afficher la solution
Exemple de brief pour le déploiement d'une solution d'analyse du commerce de détail :
| Question | Réponse |
|---|---|
| Appareil | 40 mini-PC en magasin avec des CPU Intel Core Ultra, sans GPU dédié |
| FPS et caméras | 10 FPS par caméra, 2 caméras par boîtier |
| Appelant | Service Python sous Linux |
| Parc | 40 boîtiers, mis à jour à partir d'une image Docker |
Budget : 1000 ÷ 10 = 100 ms par image ; moins environ 15 ms pour le décodage et le suivi, et 20 % de marge, il reste environ 65 ms, à partager entre deux caméras, soit environ 30 ms par inférence. L'arbre de décision indique OpenVINO (CPU Intel), avec ONNX Runtime comme solution de repli ; voici donc les résultats sur un boîtier de magasin :
python pick_runtime.py # CANDIDATES = ("onnx", "openvino"), BUDGET_MS = 30Le benchmark du CPU Core Ultra 7 155H dans la documentation OpenVINO indique 13.4 ms pour YOLO26n avec OpenVINO FP32 ; yolo26n devrait donc respecter le budget sans difficulté. Si le p95 sur le boîtier réel, avec les deux pipelines caméra en cours d'exécution, est inférieur à 30 ms, déploie OpenVINO. Si le résultat dépasse cette limite, essaie le GPU intégré du boîtier avec device="intel:gpu" avant d'acheter du matériel.