Ultralytics YOLO27 : Inscris-toi sur la liste d’attente.
Get Started
Ultralytics YOLO en production·Choisir un moteur d'exécution·Leçon 1/9
Leçonintermédiaire

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.

Caméra de circulation surplombant une autoroute urbaine au coucher du soleil, avec Ultralytics YOLO qui suit des voitures, une camionnette et des camions, chacun identifié par une classe et un ID

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.

Résultat

Choisis le moteur d'exécution et la valeur format= adaptés à un appareil, convertis une cible en FPS en budget de latence exprimé en millisecondes, puis confirme ton choix avec des benchmarks répétés.

Parcours accéléré
Si tu connais déjà les bases, voici la version courte.
  1. GPU NVIDIA ou Jetson → TensorRT (engine), compilé sur la cible. CPU, iGPU ou NPU Intel → OpenVINO (openvino).

  2. Apple → CoreML (coreml). Android → LiteRT (litert). NPU Snapdragon → QNN (qnn). Raspberry Pi → NCNN (ncnn).

  3. Tout autre appareil → ONNX Runtime (onnx). Tu ne veux pas de serveurs ? Utilise un point de terminaison géré d'Ultralytics Platform.

  4. Budget = 1000 ÷ FPS, moins le décodage et le post-traitement. Mesure les différentes options sur l'appareil et base-toi sur leur p95, pas sur la moyenne.

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 :

ObjectifMoteur d'exécutionformat=Attention à
GPU NVIDIA, JetsonTensorRTengineUn moteur ne fonctionne que sur la famille de GPU et avec la version de TensorRT qui l'a compilé
CPU, iGPU, NPU IntelOpenVINOopenvinoOptimisé pour Intel ; effectue des mesures avant de l'utiliser ailleurs
Tout CPU ou GPUONNX RuntimeonnxChoisis explicitement le fournisseur d'exécution
iPhone, iPad, MacCoreMLcoremlL'exportation s'effectue sur macOS ou Linux, pas sur Windows
Android, systèmes embarquésLiteRTlitertINT8 nécessite des données d'étalonnage data
NPU SnapdragonQualcomm QNNqnnExport quantifié uniquement ; passe la cible Hexagon sous la forme name
Raspberry Pi, CPU ARMNCNNncnnLe format le plus rapide dans le guide Raspberry Pi
NavigateurONNX Runtime WebonnxLimite-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 :

Onglet Deployments du profil Ultralytics Platform avec une carte du monde des régions de déploiement et des cartes récapitulatives des déploiements actifs, des requêtes HTTP, du taux d'erreur et de la latence P95

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 :

ÉtapeExemple : 20 FPS par caméra
Budget par image = 1000 ÷ FPS50 ms
Moins le décodage (RTSP, 1080p)environ 10 ms
Moins le suivi, le comptage et les sortiesenviron 5 ms
Moins 20 % de marge pour les pics10 ms
Restant pour le modèleenviron 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 imgsz avant 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 budget

Examinons 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 imgsz plus 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=onnx

Supprime 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#

Évaluer les performances sur la mauvaise machine

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).

Les moteurs TensorRT dépendent de l'appareil

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.

Effectue le benchmark à la taille de déploiement

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.pt est-il déployé sur 1 000 appareils ? Une image Docker garantit leur cohérence.
Essayer

Rédige un brief de déploiement de cinq lignes pour un projet réel ou prévu : appareil cible, FPS par caméra, caméras par appareil, langage appelant et taille du parc. Convertis-le en budget modèle exprimé en millisecondes, choisis des candidats dans l'arbre de décision et exécute pick_runtime.py (avec ton modèle et les candidats) sur la cible ou sur la machine dont tu disposes qui s'en rapproche le plus.

Terminé lorsque
Tu as terminé la leçon lorsque tous les éléments suivants sont réunis.
  • Ton brief indique l'appareil, l'environnement d'exécution et la valeur exacte de format=.

  • Tu as calculé le budget du modèle en millisecondes à partir de la cible FPS en précisant les éléments soustraits.

  • Tu as les temps d'inférence p50 et p95 de chaque candidat, mesurés sur l'appareil, ainsi qu'une conclusion par rapport au budget.

Afficher la solution

Exemple de brief pour le déploiement d'une solution d'analyse du commerce de détail :

QuestionRéponse
Appareil40 mini-PC en magasin avec des CPU Intel Core Ultra, sans GPU dédié
FPS et caméras10 FPS par caméra, 2 caméras par boîtier
AppelantService Python sous Linux
Parc40 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 = 30

Le 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.

Et ensuite ?

Une fois la cible choisie, la leçon suivante explique comment exporter au format ONNX et vérifier que l'export produit les mêmes résultats que PyTorch.