Skip to main content

Guangzhou, China

Triton Inference Server

Triton is optimized to provide the best inferencing performance by using GPUs, but it can also work on CPU-only systems. In both cases you can use the same Triton Docker image.

docker pull nvcr.io/nvidia/tritonserver:24.06-py3

Its primary use cases are:

  • Serving multiple models from a single server instance.
  • Dynamic model loading and unloading without server restart.
  • Ensemble inference, allowing multiple models to be used together to achieve results.
  • Model versioning for A/B testing and rolling updates.

Prerequisites​

pip install tritonclient\[all\]
import contextlib
from pathlib import Path
import subprocess
import time

from tritonclient.http import InferenceServerClient
from ultralytics import YOLO

Exporting YOLO Models into the ONNX Format​

# Load the PyTorch model
model_8n = YOLO("weights/yolov8n.pt")
# Export the ONNX model
onnx_file = model_8n.export(format="onnx", dynamic=True) # export to weights/yolov8n.onnx

Setting Up Triton Model Repository​

# Define paths
model_name = "yolo8n"
triton_repo_path = Path("deploy") / "triton"
triton_model_path = triton_repo_path / model_name
# Create directories
(triton_model_path / "1").mkdir(parents=True, exist_ok=True)
# Copy ONNX model to Triton path
Path(onnx_file).rename(triton_model_path / "1" / "model.onnx")
# Create config file
(triton_model_path / "config.pbtxt").touch()

Running Triton Inference Server (CPU)​

docker run --rm -v ./deploy/triton:/models -p 8000:8000 --name tritonserver nvcr.io/nvidia/tritonserver:24.06-py3 tritonserver --model-repository=/models
=============================
== Triton Inference Server ==
=============================

NVIDIA Release 24.06 (build 98458813)
Triton Server Version 2.47.0

I0630 10:50:50.713271 1 onnxruntime.cc:3010] "TRITONBACKEND_ModelInitialize: yolo8n (version 1)"
I0630 10:50:50.713306 1 onnxruntime.cc:3010]
W0630 10:50:50.811660 1 onnxruntime.cc:1104] "autofilled max_batch_size to 4 for model 'yolo8n' since batching is supporrted but no max_batch_size is specified in model configuration. Must specify max_batch_size to utilize autofill with a larger max batch size"
I0630 10:50:50.814366 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolo8n_0 (CPU device 0)"
I0630 10:50:50.814429 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolo8n_1 (CPU device 0)"
I0630 10:50:50.944107 1 onnxruntime.cc:3075]
I0630 10:50:51.123288 1 model_lifecycle.cc:838] "successfully loaded 'yolo8n'"
I0630 10:50:51.382747 1 model_lifecycle.cc:838] "successfully loaded 'yolo9s'"

+--------+---------+--------+
| Model | Version | Status |
+--------+---------+--------+
| yolo8n | 1 | READY |
+--------+---------+--------+
# Wait for the Triton server to start
triton_client = InferenceServerClient(url="localhost:8000", verbose=False, ssl=False)

# Wait until model is ready
for _ in range(10):
with contextlib.suppress(Exception):
assert triton_client.is_model_ready(model_name)
break
time.sleep(1)
!curl -v 192.168.2.210:8000/v2/health/ready

* Trying 192.168.2.210:8000...
* Connected to 192.168.2.210 (192.168.2.210) port 8000 (#0)
> GET /v2/health/ready HTTP/1.1
> Host: 192.168.2.210:8000
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Length: 0
< Content-Type: text/plain
<
* Connection #0 to host 192.168.2.210 left intact
curl http://192.168.2.210:8000/v2/models/yolo8n/config

{"name":"yolo8n","platform":"onnxruntime_onnx","backend":"onnxruntime","runtime":"","version_policy":{"latest":{"num_versions":1}},"max_batch_size":0,"input":[{"name":"images","data_type":"TYPE_FP32","format":"FORMAT_NONE","dims":[1,3,640,640],"is_shape_tensor":false,"allow_ragged_batch":false,"optional":false}],"output":[{"name":"output0","data_type":"TYPE_FP32","dims":[1,21,8400],"label_filename":"","is_shape_tensor":false}],"batch_input":[],"batch_output":[],"optimization":{"priority":"PRIORITY_DEFAULT","input_pinned_memory":{"enable":true},"output_pinned_memory":{"enable":true},"gather_kernel_buffer_threshold":0,"eager_batching":false},"instance_group":[{"name":"yolo8n","kind":"KIND_GPU","count":1,"gpus":[0],"secondary_devices":[],"profile":[],"passive":false,"host_policy":""}],"default_model_filename":"model.onnx","cc_model_filenames":{},"metric_tags":{},"parameters":{},"model_warmup":[]}
# Load the Triton Server model
triton_model = YOLO("http://192.168.2.210:8000/yolo8n", task="detect")
# Run inference on the server
results = triton_model("datasets/test/face2.jpg")

image 1/1 /opt/app/datasets/test/face2.jpg: 640x640 3 class0s, 52.0ms
Speed: 2.4ms preprocess, 52.0ms inference, 3.3ms postprocess per image at shape (1, 3, 640, 640)

Exporting YOLO Models for Triton Inference​

# Load the PyTorch model
model_9s = YOLO("runs/detect/yolov9s/weights/best.pt")
# Export the TensorRT model
onnx_file9s = model_9s.export(format="onnx", device=0) # export to runs/detect/yolov9s/weights/best.onnx

Setting Up Triton Model Repository​

# Define paths
model9s_name = "yolo9s"
triton9s_repo_path = Path("deploy") / "triton"
triton9s_model_path = triton9s_repo_path / model9s_name
# Create directories
(triton9s_model_path / "1").mkdir(parents=True, exist_ok=True)
# Copy ONNX model to Triton path
Path(onnx_file9s).rename(triton9s_model_path / "1" / "model.onnx")
# Create config file
(triton9s_model_path / "config.pbtxt").touch()

Running Triton Inference Server (GPU)​

Use the following command to run Triton with the example model repository you just created. The NVIDIA Container Toolkit must be installed for Docker to recognize the GPU(s). The --gpus=1 flag indicates that 1 system GPU should be made available to Triton for inferencing.

docker run --gpus=all --rm -v ./deploy/triton:/models \
-p 8000:8000 -p 8001:8001 -p 8002:8002 --name tritonserver \
nvcr.io/nvidia/tritonserver:24.06-py3 tritonserver --model-repository=/models --model-control-mode=poll --repository-poll-secs 30
=============================
== Triton Inference Server ==
=============================

NVIDIA Release 24.06 (build 98458813)
Triton Server Version 2.47.0

I0702 08:51:29.912004 1 onnxruntime.cc:3010] "TRITONBACKEND_ModelInitialize: yolo8n (version 1)"
I0702 08:51:29.912052 1 onnxruntime.cc:3010] "TRITONBACKEND_ModelInitialize: yolo8m (version 1)"
I0702 08:51:29.912073 1 onnxruntime.cc:3010] "TRITONBACKEND_ModelInitialize: yolo9s (version 1)"
I0702 08:51:29.912091 1 onnxruntime.cc:3010] "TRITONBACKEND_ModelInitialize: yolo9m (version 1)"
I0702 08:51:31.036723 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolo9m_0 (GPU device 0)"
I0702 08:51:31.764582 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolo8m_0 (GPU device 0)"
I0702 08:51:32.050735 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolo9s_0 (GPU device 0)"
I0702 08:51:32.181237 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolo8n_0 (GPU device 0)"
I0702 08:51:32.302135 1 model_lifecycle.cc:838] "successfully loaded 'yolo9m'"
I0702 08:51:32.302465 1 onnxruntime.cc:3010] "TRITONBACKEND_ModelInitialize: yolo9t (version 1)"
I0702 08:51:32.410140 1 model_lifecycle.cc:838] "successfully loaded 'yolo8m'"
I0702 08:51:32.410426 1 onnxruntime.cc:3010] "TRITONBACKEND_ModelInitialize: yolov10n (version 1)"
I0702 08:51:32.518006 1 model_lifecycle.cc:838] "successfully loaded 'yolo9s'"
I0702 08:51:32.518282 1 onnxruntime.cc:3010] "TRITONBACKEND_ModelInitialize: yolov10s (version 1)"
I0702 08:51:32.556986 1 model_lifecycle.cc:838] "successfully loaded 'yolo8n'"
I0702 08:51:32.557358 1 onnxruntime.cc:3010] "TRITONBACKEND_ModelInitialize: yolo8s (version 1)"
I0702 08:51:32.712628 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolo9t_0 (GPU device 0)"
I0702 08:51:32.830182 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolov10n_0 (GPU device 0)"
I0702 08:51:33.154025 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolov10s_0 (GPU device 0)"
I0702 08:51:33.530147 1 onnxruntime.cc:3075] "TRITONBACKEND_ModelInstanceInitialize: yolo8s_0 (GPU device 0)"
I0702 08:51:33.617135 1 model_lifecycle.cc:838] "successfully loaded 'yolo9t'"
I0702 08:51:33.677292 1 model_lifecycle.cc:838] "successfully loaded 'yolov10n'"
I0702 08:51:33.772530 1 model_lifecycle.cc:838] "successfully loaded 'yolov10s'"
I0702 08:51:33.822564 1 model_lifecycle.cc:838] "successfully loaded 'yolo8s'"
I0702 08:51:33.823015 1 server.cc:604]

+----------+---------+--------+
| Model | Version | Status |
+----------+---------+--------+
| yolo8m | 1 | READY |
| yolo8n | 1 | READY |
| yolo8s | 1 | READY |
| yolo9m | 1 | READY |
| yolo9s | 1 | READY |
| yolo9t | 1 | READY |
| yolov10n | 1 | READY |
| yolov10s | 1 | READY |
+----------+---------+--------+

I0702 08:51:33.839930 1 grpc_server.cc:2463] "Started GRPCInferenceService at 0.0.0.0:8001"
I0702 08:51:33.840086 1 http_server.cc:4692] "Started HTTPService at 0.0.0.0:8000"
I0702 08:51:33.882137 1 http_server.cc:362] "Started Metrics Service at 0.0.0.0:8002"
!curl -v 192.168.2.210:8000/v2/health/ready

* Trying 192.168.2.210:8000...
* Connected to 192.168.2.210 (192.168.2.210) port 8000 (#0)
> GET /v2/health/ready HTTP/1.1
> Host: 192.168.2.210:8000
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Length: 0
< Content-Type: text/plain
<
* Connection #0 to host 192.168.2.210 left intact
curl http://192.168.2.210:8000/v2/models/yolo8n/config

{"name":"yolo8n","platform":"onnxruntime_onnx","backend":"onnxruntime","runtime":"","version_policy":{"latest":{"num_versions":1}},"max_batch_size":0,"input":[{"name":"images","data_type":"TYPE_FP32","format":"FORMAT_NONE","dims":[1,3,640,640],"is_shape_tensor":false,"allow_ragged_batch":false,"optional":false}],"output":[{"name":"output0","data_type":"TYPE_FP32","dims":[1,21,8400],"label_filename":"","is_shape_tensor":false}],"batch_input":[],"batch_output":[],"optimization":{"priority":"PRIORITY_DEFAULT","input_pinned_memory":{"enable":true},"output_pinned_memory":{"enable":true},"gather_kernel_buffer_threshold":0,"eager_batching":false},"instance_group":[{"name":"yolo8n","kind":"KIND_GPU","count":1,"gpus":[0],"secondary_devices":[],"profile":[],"passive":false,"host_policy":""}],"default_model_filename":"model.onnx","cc_model_filenames":{},"metric_tags":{},"parameters":{},"model_warmup":[]}