Triton Inference Server
Triton Inference Server héberge un model repository et répond aux requêtes d'inférence en HTTP. LibreYOLO exporte le graphe ONNX, génère un config.pbtxt qui transporte les métadonnées de l'export sous forme d'un unique paramètre Triton, et traite une URL de modèle comme un chemin de modèle chargeable.
- Appel
LibreYOLO("http://127.0.0.1:8000/yolo9")- Fonction utilitaire
create_triton_config(onnx_path, config_path, model_name=..., max_batch_size=8)- Extra
pip install "libreyolo[onnx,triton]"- Protocole
- Inférence V2 en HTTP et HTTPS uniquement. Pas de gRPC, d'authentification, de mémoire partagée, ni de chargement et déchargement de modèles.
- Timeouts
- Les timeouts de connexion et de réseau sont de 30 secondes par défaut
Installation
pip install "libreyolo[onnx,triton]"L'extra triton installe tritonclient[http]. Les extras gRPC et mémoire
partagée sont exclus volontairement : cette intégration ne fait que de
l'inférence V2 en HTTP et HTTPS. onnx est nécessaire parce que l'artefact servi
et le générateur de config travaillent tous deux à partir d'un graphe ONNX.
Construire le model repository
Exportez avec un axe de batch dynamique, dans la structure de répertoires attendue par Triton.
from pathlib import Path from libreyolo import LibreYOLO model_dir = Path("triton_repo/yolo9/1")model_dir.mkdir(parents=True, exist_ok=True) LibreYOLO("LibreYOLO9t.pt").export( format="onnx", output_path=str(model_dir / "model.onnx"), dynamic=True, simplify=False,)from libreyolo import create_triton_config create_triton_config( "triton_repo/yolo9/1/model.onnx", "triton_repo/yolo9/config.pbtxt", model_name="yolo9", max_batch_size=8,)triton_repo/ yolo9/ config.pbtxt 1/ model.onnxTriton ne conserve pas les métadonnées ONNX personnalisées dans sa réponse de
configuration de modèle, donc les métadonnées exportées complètes doivent voyager
autrement. create_triton_config les encode sous forme d'un unique paramètre de
type chaîne JSON nommé libreyolo_metadata dans config.pbtxt, émet les
déclarations d'entrées et de sorties dans l'ordre du graphe, gère l'échappement
JSON et fixe le modèle à KIND_CPU.
La fonction utilitaire valide avant d'écrire. Elle exige exactement une entrée de
graphe ONNX, au moins une sortie, des formes de tenseur résolvables, et des
métadonnées dont la table names définit tous les indices de classe de 0 à
nc - 1. Un modèle qui échoue à l'une de ces vérifications est rejeté au moment
de la génération du config, plutôt qu'à la première requête.
max_batch_size: 8 correspond à un export dynamique et permet au serveur de
regrouper jusqu'à huit images par requête. Pour un graphe ONNX à batch fixe de 1,
utilisez max_batch_size=0 ; LibreYOLO envoie alors les images les unes après
les autres.
Démarrer le serveur
docker run --rm --name libreyolo-triton \ -p 8000:8000 -p 8002:8002 \ -v "$(pwd)/triton_repo:/models:ro" \ nvcr.io/nvidia/tritonserver:26.04-py3 \ tritonserver --model-repository=/models --exit-on-error=trueuntil curl --fail --silent http://127.0.0.1:8000/v2/health/ready; do sleep 1; donedocker stop libreyolo-tritonLes commandes fixent Triton Server 26.04 et omettent délibérément les flags GPU
de Docker, puisque KIND_CPU dans le config généré empêche de toute façon le
placement sur GPU.
Exécuter l'artefact
Une URL de modèle Triton est un chemin de modèle. LibreYOLO() vérifie la
présence d'un schéma http ou https avant tout traitement de chemin local et
renvoie un backend qui dialogue avec le serveur, si bien que le site d'appel est
identique à celui d'un checkpoint local, tout comme l'objet Results renvoyé.
from libreyolo import LibreYOLO, SAMPLE_IMAGE remote = LibreYOLO("http://127.0.0.1:8000/yolo9")result = remote.predict(SAMPLE_IMAGE)print(result.boxes.xyxy[:3])from libreyolo import LibreYOLO, SAMPLE_IMAGE remote = LibreYOLO("http://127.0.0.1:8000/yolo9").predict(SAMPLE_IMAGE)native = LibreYOLO("LibreYOLO9t.pt").predict(SAMPLE_IMAGE) print(len(remote.boxes), len(native.boxes))print(remote.boxes.xyxy[:3])print(native.boxes.xyxy[:3])from libreyolo import LibreYOLOfrom libreyolo.backends.triton import TritonBackend # Un deuxième segment de chemin choisit la version du modèle. Sans lui,# la politique de versions configurée dans Triton décide.pinned = LibreYOLO("http://127.0.0.1:8000/yolo9/1") # Les timeouts de connexion et de réseau valent 30 secondes par défaut.patient = TritonBackend("http://127.0.0.1:8000/yolo9", timeout=120)La forme de l'URL est http(s)://host:port/model avec un segment de version
optionnel. Le port doit être explicite. Les identifiants intégrés, une query
string et un fragment sont tous rejetés, de même qu'un chemin de plus de deux
segments.
device est accepté et ignoré avec une ligne de log, parce que le placement est
la décision du serveur.
Contraintes
Le backend échoue avec une erreur directe plutôt qu'avec un résultat dégradé lorsque le contrat n'est pas respecté : métadonnées LibreYOLO absentes du config du modèle, plus d'une entrée de modèle, désaccord entre les sorties configurées et les métadonnées du modèle, type de données d'entrée qu'il ne prend pas en charge, ou serveur ou modèle qui n'est pas prêt.
Hors contrat dans cette version : gRPC, l'authentification, la mémoire partagée, et le chargement ou le déchargement de modèles via l'API.
N'importe quel format que Triton prend lui-même en charge peut être servi, mais le paramètre de métadonnées et le config généré ont ici une forme ONNX, donc le chemin LibreYOLO passe par ONNX dans le repository. Pour un pipeline vidéo complet plutôt qu'un serveur requête-réponse, voir DeepStream.