Triton ์ถ๋ก ์๋ฒ Ultralytics YOLO11
Triton ์ถ๋ก ์๋ฒ (์ด์ ๋ช ์นญ: TensorRT ์ถ๋ก ์๋ฒ)๋ NVIDIA ์์ ๊ฐ๋ฐํ ์คํ ์์ค ์ํํธ์จ์ด ์๋ฃจ์ ์ ๋๋ค. NVIDIA GPU์ ์ต์ ํ๋ ํด๋ผ์ฐ๋ ์ถ๋ก ์๋ฃจ์ ์ ์ ๊ณตํฉ๋๋ค. Triton ์ ํ๋ก๋์ ํ๊ฒฝ์์ ๋๊ท๋ชจ๋ก AI ๋ชจ๋ธ์ ๋ฐฐํฌํ๋ ์์ ์ ๊ฐ์ํํฉ๋๋ค. Ultralytics YOLO11 ๊ณผ Triton ์ถ๋ก ์๋ฒ๋ฅผ ํตํฉํ๋ฉด ํ์ฅ ๊ฐ๋ฅํ ๊ณ ์ฑ๋ฅ ๋ฅ ๋ฌ๋ ์ถ๋ก ์ํฌ๋ก๋๋ฅผ ๋ฐฐํฌํ ์ ์์ต๋๋ค. ์ด ๊ฐ์ด๋๋ ํตํฉ์ ์ค์ ํ๊ณ ํ ์คํธํ๋ ๋จ๊ณ๋ฅผ ์ ๊ณตํฉ๋๋ค.
Watch: ์์ํ๊ธฐ NVIDIA Triton ์ถ๋ก ์๋ฒ.
Triton ์ถ๋ก ์๋ฒ๋ ๋ฌด์์ธ๊ฐ์?
Triton ์ถ๋ก ์๋ฒ๋ ํ๋ก๋์ ํ๊ฒฝ์์ ๋ค์ํ AI ๋ชจ๋ธ์ ๋ฐฐํฌํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. TensorFlow ๋ค์์ ํฌํจํ ๊ด๋ฒ์ํ ๋ฅ ๋ฌ๋ ๋ฐ ๋จธ์ ๋ฌ๋ ํ๋ ์์ํฌ๋ฅผ ์ง์ํฉ๋๋ค, PyTorch, ONNX ๋ฐํ์ ๋ฐ ๊ธฐํ ์ฌ๋ฌ ํ๋ ์์ํฌ๋ฅผ ์ง์ํฉ๋๋ค. ์ฃผ์ ์ฌ์ฉ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๋จ์ผ ์๋ฒ ์ธ์คํด์ค์์ ์ฌ๋ฌ ๋ชจ๋ธ์ ์๋น์คํฉ๋๋ค.
- ์๋ฒ ์ฌ์์ ์์ด ๋์ ๋ชจ๋ธ ๋ก๋ฉ ๋ฐ ์ธ๋ก๋ฉ.
- ์์๋ธ ์ถ๋ก ์ ํตํด ์ฌ๋ฌ ๋ชจ๋ธ์ ํจ๊ป ์ฌ์ฉํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
- A/B ํ ์คํธ ๋ฐ ๋กค๋ง ์ ๋ฐ์ดํธ๋ฅผ ์ํ ๋ชจ๋ธ ๋ฒ์ ๊ด๋ฆฌ.
์ ์ ์กฐ๊ฑด
๊ณ์ ์งํํ๊ธฐ ์ ์ ๋ค์ ์ฌ์ ์๊ตฌ ์ฌํญ์ด ์ถฉ์กฑ๋๋์ง ํ์ธํ์ธ์:
- ๋จธ์ ์ Docker๊ฐ ์ค์น๋์ด ์์ต๋๋ค.
- ์ค์น
tritonclient
:
YOLO11 ์์ ONNX ํ์์ผ๋ก ๋ด๋ณด๋ด๊ธฐ
๋ชจ๋ธ์ Triton ์ ๋ฐฐํฌํ๊ธฐ ์ ์ ONNX ํ์์ผ๋ก ๋ด๋ณด๋ด์ผ ํฉ๋๋ค. ONNX ํ์์ ์๋ก ๋ค๋ฅธ ๋ฅ ๋ฌ๋ ํ๋ ์์ํฌ ๊ฐ์ ๋ชจ๋ธ์ ์ ์กํ ์ ์๋ ํ์(Open Neural Network Exchange)์
๋๋ค. ๋ชจ๋ธ์ ๋ฐฐํฌํ๊ธฐ ์ ์ export
ํจ์์์ YOLO
ํด๋์ค:
from ultralytics import YOLO
# Load a model
model = YOLO("yolo11n.pt") # load an official model
# Retreive metadata during export
metadata = []
def export_cb(exporter):
metadata.append(exporter.metadata)
model.add_callback("on_export_end", export_cb)
# Export the model
onnx_file = model.export(format="onnx", dynamic=True)
Triton ๋ชจ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ ์ค์
Triton ๋ชจ๋ธ ์ ์ฅ์๋ Triton ์์ ๋ชจ๋ธ์ ์ก์ธ์คํ๊ณ ๋ก๋ํ ์ ์๋ ์ ์ฅ ์์น์ ๋๋ค.
-
ํ์ํ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋ง๋ญ๋๋ค:
-
๋ด๋ณด๋ธ ONNX ๋ชจ๋ธ์ Triton ๋ฆฌํฌ์งํ ๋ฆฌ๋ก ์ด๋ํฉ๋๋ค:
from pathlib import Path # Move ONNX model to Triton Model path Path(onnx_file).rename(triton_model_path / "1" / "model.onnx") # Create config file (triton_model_path / "config.pbtxt").touch() # (Optional) Enable TensorRT for GPU inference # First run will be slow due to TensorRT engine conversion data = """ optimization { execution_accelerators { gpu_execution_accelerator { name: "tensorrt" parameters { key: "precision_mode" value: "FP16" } parameters { key: "max_workspace_size_bytes" value: "3221225472" } parameters { key: "trt_engine_cache_enable" value: "1" } parameters { key: "trt_engine_cache_path" value: "/models/yolo/1" } } } } parameters { key: "metadata" value: { string_value: "%s" } } """ % metadata[0] with open(triton_model_path / "config.pbtxt", "w") as f: f.write(data)
Triton ์ถ๋ก ์๋ฒ ์คํ
Docker๋ฅผ ์ฌ์ฉํ์ฌ Triton ์ถ๋ก ์๋ฒ๋ฅผ ์คํํฉ๋๋ค:
import contextlib
import subprocess
import time
from tritonclient.http import InferenceServerClient
# Define image https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tritonserver
tag = "nvcr.io/nvidia/tritonserver:24.09-py3" # 8.57 GB
# Pull the image
subprocess.call(f"docker pull {tag}", shell=True)
# Run the Triton server and capture the container ID
container_id = (
subprocess.check_output(
f"docker run -d --rm --gpus 0 -v {triton_repo_path}:/models -p 8000:8000 {tag} tritonserver --model-repository=/models",
shell=True,
)
.decode("utf-8")
.strip()
)
# 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)
๊ทธ๋ฐ ๋ค์ Triton ์๋ฒ ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์ถ๋ก ์ ์คํํฉ๋๋ค:
from ultralytics import YOLO
# Load the Triton Server model
model = YOLO("http://localhost:8000/yolo", task="detect")
# Run inference on the server
results = model("path/to/image.jpg")
์ปจํ ์ด๋๋ฅผ ์ ๋ฆฌํฉ๋๋ค:
# Kill and remove the container at the end of the test
subprocess.call(f"docker kill {container_id}", shell=True)
์์ ๋จ๊ณ์ ๋ฐ๋ผ Triton ์ถ๋ก ์๋ฒ์์ Ultralytics YOLO11 ๋ชจ๋ธ์ ํจ์จ์ ์ผ๋ก ๋ฐฐํฌํ๊ณ ์คํํ์ฌ ๋ฅ ๋ฌ๋ ์ถ๋ก ์์ ์ ์ํ ํ์ฅ ๊ฐ๋ฅํ ๊ณ ์ฑ๋ฅ ์๋ฃจ์ ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ์ถ๊ฐ ์ง๋ฌธ์ด ์๋ ๊ฒฝ์ฐ ๊ณต์ Triton ์ค๋ช ์๋ฅผ ์ฐธ์กฐํ๊ฑฐ๋ Ultralytics ์ปค๋ฎค๋ํฐ์ ๋ฌธ์ํ์ฌ ์ง์์ ๋ฐ์ผ์ธ์.
์์ฃผ ๋ฌป๋ ์ง๋ฌธ
Ultralytics YOLO11 NVIDIA ์ถ๋ก ์๋ฒ๋ฅผ ์ด๋ป๊ฒ ์ค์ ํ๋์?Triton
์ค์ Ultralytics YOLO11 NVIDIA Triton ์ถ๋ก ์๋ฒ ์ค์ ์๋ ๋ช ๊ฐ์ง ์ฃผ์ ๋จ๊ณ๊ฐ ํฌํจ๋ฉ๋๋ค:
-
YOLO11 ์ ONNX ํ์์ผ๋ก ๋ด๋ณด๋ ๋๋ค:
-
Triton ๋ชจ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ์ค์ ํฉ๋๋ค:
from pathlib import Path # Define paths model_name = "yolo" triton_repo_path = Path("tmp") / "triton_repo" triton_model_path = triton_repo_path / model_name # Create directories (triton_model_path / "1").mkdir(parents=True, exist_ok=True) Path(onnx_file).rename(triton_model_path / "1" / "model.onnx") (triton_model_path / "config.pbtxt").touch()
-
Triton ์๋ฒ๋ฅผ ์คํํฉ๋๋ค:
import contextlib import subprocess import time from tritonclient.http import InferenceServerClient # Define image https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tritonserver tag = "nvcr.io/nvidia/tritonserver:24.09-py3" subprocess.call(f"docker pull {tag}", shell=True) container_id = ( subprocess.check_output( f"docker run -d --rm --gpus 0 -v {triton_repo_path}/models -p 8000:8000 {tag} tritonserver --model-repository=/models", shell=True, ) .decode("utf-8") .strip() ) triton_client = InferenceServerClient(url="localhost:8000", verbose=False, ssl=False) for _ in range(10): with contextlib.suppress(Exception): assert triton_client.is_model_ready(model_name) break time.sleep(1)
์ด ์ค์ ์ ์ฌ์ฉํ๋ฉด ๊ณ ์ฑ๋ฅ AI ๋ชจ๋ธ ์ถ๋ก ์ ์ํด Triton ์ถ๋ก ์๋ฒ์์ YOLO11 ๋ชจ๋ธ์ ๋๊ท๋ชจ๋ก ํจ์จ์ ์ผ๋ก ๋ฐฐํฌํ ์ ์์ต๋๋ค.
NVIDIA Triton ์ถ๋ก ์๋ฒ์ ํจ๊ป Ultralytics YOLO11 ์ ์ฌ์ฉํ๋ฉด ์ด๋ค ์ด์ ์ด ์๋์?
ํตํฉ Ultralytics YOLO11 NVIDIA Triton ์ถ๋ก ์๋ฒ์ ํตํฉํ๋ฉด ๋ช ๊ฐ์ง ์ด์ ์ด ์์ต๋๋ค:
- ํ์ฅ ๊ฐ๋ฅํ AI ์ถ๋ก : Triton ๋จ์ผ ์๋ฒ ์ธ์คํด์ค์์ ์ฌ๋ฌ ๋ชจ๋ธ์ ์ ๊ณตํ ์ ์์ผ๋ฉฐ, ๋์ ๋ชจ๋ธ ๋ก๋ ๋ฐ ์ธ๋ก๋๋ฅผ ์ง์ํ๋ฏ๋ก ๋ค์ํ AI ์ํฌ๋ก๋์ ๋ง๊ฒ ํ์ฅ์ฑ์ด ๋ฐ์ด๋ฉ๋๋ค.
- ๊ณ ์ฑ๋ฅ: NVIDIA GPU์ ์ต์ ํ๋ Triton ์ถ๋ก ์๋ฒ๋ ๊ณ ์ ์ถ๋ก ์์ ์ ๋ณด์ฅํ๋ฉฐ, ๋ฌผ์ฒด ๊ฐ์ง์ ๊ฐ์ ์ค์๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉํฉ๋๋ค.
- ์์๋ธ ๋ฐ ๋ชจ๋ธ ๋ฒ์ ๊ด๋ฆฌ: Triton ์ ์์๋ธ ๋ชจ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ๋ชจ๋ธ์ ๊ฒฐํฉํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ํ ์ ์์ผ๋ฉฐ, ๋ชจ๋ธ ๋ฒ์ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ A/B ํ ์คํธ ๋ฐ ๋กค๋ง ์ ๋ฐ์ดํธ๋ฅผ ์ง์ํฉ๋๋ค.
YOLO11 ์ค์ ๋ฐ ์คํ์ ๋ํ ์์ธํ ์ง์นจ์ ์ค์ ๊ฐ์ด๋( Triton)๋ฅผ ์ฐธ์กฐํ์ธ์.
Triton ์ถ๋ก ์๋ฒ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ YOLO11 ๋ชจ๋ธ์ ONNX ํ์์ผ๋ก ๋ด๋ณด๋ด์ผ ํ๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?
๋ชจ๋ธ์ ONNX (์คํ ์ ๊ฒฝ๋ง ๊ตํ) ํ์ ์ฌ์ฉ Ultralytics YOLO11 NVIDIA Triton ์ถ๋ก ์๋ฒ๋ ๋ช ๊ฐ์ง ์ฃผ์ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
- ์ํธ ์ด์ฉ์ฑ: ONNX ํ์์ ์๋ก ๋ค๋ฅธ ๋ฅ ๋ฌ๋ ํ๋ ์์ํฌ(์: PyTorch, TensorFlow)๊ฐ์ ์ ์ก์ ์ง์ํ์ฌ ๋ณด๋ค ํญ๋์ ํธํ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
- ์ต์ ํ: Triton ๋ฅผ ํฌํจํ ๋ง์ ๋ฐฐํฌ ํ๊ฒฝ์ด ONNX ์ ์ต์ ํ๋์ด ๋ ๋น ๋ฅธ ์ถ๋ก ๊ณผ ๋ ๋์ ์ฑ๋ฅ์ ์ง์ํฉ๋๋ค.
- ๋ฐฐํฌ ์ฉ์ด์ฑ: ONNX ์ ๋ค์ํ ์ด์ ์ฒด์ ์ ํ๋์จ์ด ๊ตฌ์ฑ์์ ๋ฐฐํฌ ํ๋ก์ธ์ค๋ฅผ ๊ฐ์ํํ์ฌ ํ๋ ์์ํฌ์ ํ๋ซํผ ์ ๋ฐ์์ ํญ๋๊ฒ ์ง์๋ฉ๋๋ค.
๋ชจ๋ธ์ ๋ด๋ณด๋ด๋ ค๋ฉด ๋ค์์ ์ฌ์ฉํ์ธ์:
from ultralytics import YOLO
model = YOLO("yolo11n.pt")
onnx_file = model.export(format="onnx", dynamic=True)
๋ด๋ณด๋ด๊ธฐ ๊ฐ์ด๋์ ๋จ๊ณ์ ๋ฐ๋ผ ํ๋ก์ธ์ค๋ฅผ ์๋ฃํ ์ ์์ต๋๋ค.
Triton ์ถ๋ก ์๋ฒ์์ Ultralytics YOLO11 ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์ถ๋ก ์ ์คํํ ์ ์๋์?
์, ์ถ๋ก ์ ์คํํ ์ ์์ต๋๋ค. Ultralytics YOLO11 ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์ถ๋ก ์ ์คํํ ์ ์์ต๋๋ค( NVIDIA Triton ์ถ๋ก ์๋ฒ). Triton ๋ชจ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์์ ๋ชจ๋ธ์ ์ค์ ํ๊ณ ์๋ฒ๊ฐ ์คํ ์ค์ด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ชจ๋ธ์์ ์ถ๋ก ์ ๋ก๋ํ๊ณ ์คํํ ์ ์์ต๋๋ค:
from ultralytics import YOLO
# Load the Triton Server model
model = YOLO("http://localhost:8000/yolo", task="detect")
# Run inference on the server
results = model("path/to/image.jpg")
YOLO11 ์ ์ฌ์ฉํ์ฌ Triton ์๋ฒ๋ฅผ ์ค์ ํ๊ณ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ๊ฐ์ด๋๋ triton ์ถ๋ก ์๋ฒ ์คํํ๊ธฐ ์น์ ์ ์ฐธ์กฐํ์ธ์.
Ultralytics YOLO11 ๊ณผ TensorFlow ๋ฐ PyTorch ๋ชจ๋ธ๊ณผ ์ด๋ป๊ฒ ๋ค๋ฅธ๊ฐ์?
Ultralytics YOLO11 ๋ ๋ฐฐํฌ ์ TensorFlow ๋ฐ PyTorch ๋ชจ๋ธ์ ๋นํด ๋ช ๊ฐ์ง ๊ณ ์ ํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
- ์ค์๊ฐ ์ฑ๋ฅ: ์ค์๊ฐ ๊ฐ์ฒด ๊ฐ์ง ์์ ์ ์ต์ ํ๋ YOLO11 ์ ์ต์ฒจ๋จ ์ ํ๋์ ์๋๋ฅผ ์ ๊ณตํ๋ฏ๋ก ์ค์๊ฐ ๋น๋์ค ๋ถ์์ด ํ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด์์ ์ ๋๋ค.
- ์ฌ์ฉ ํธ์์ฑ: YOLO11 Triton ์ถ๋ก ์๋ฒ์ ์ํํ๊ฒ ํตํฉ๋๋ฉฐ ๋ค์ํ ๋ด๋ณด๋ด๊ธฐ ํ์(ONNX, TensorRT, CoreML)์ ์ง์ํ๋ฏ๋ก ๋ค์ํ ๋ฐฐํฌ ์๋๋ฆฌ์ค์ ์ ์ฐํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ๊ณ ๊ธ ๊ธฐ๋ฅ: YOLO11 ์๋ ํ์ฅ ๊ฐ๋ฅํ๊ณ ์์ ์ ์ธ AI ๋ฐฐํฌ์ ์ค์ํ ๋์ ๋ชจ๋ธ ๋ก๋, ๋ชจ๋ธ ๋ฒ์ ๊ด๋ฆฌ ๋ฐ ์์๋ธ ์ถ๋ก ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ด ํฌํจ๋์ด ์์ต๋๋ค.
์์ธํ ๋ด์ฉ์ ๋ชจ๋ธ ๋ฐฐํฌ ๊ฐ์ด๋์์ ๋ฐฐํฌ ์ต์ ์ ๋น๊ตํ์ธ์.