Triton Inference Server¶
TL;DR
Triton은 ONNX Runtime, TensorRT, Python 등 여러 추론 백엔드를 하나의 서버에서 관리합니다. 이 저장소의 인코더에서는 TensorRT 경로가 p50 latency를 26.8ms에서 15.4ms로 낮췄습니다. 대신 config.pbtxt를 직접 관리해야 하고, TensorRT 컴파일 결과는 GPU 아키텍처와 버전에 종속됩니다.
개요¶
NVIDIA Triton Inference Server는 여러 추론 백엔드와 모델을 관리하는 오픈소스 서버입니다. SageMaker는 sagemaker-tritonserver DLC로 Triton을 제공합니다.
HF DLC는 PyTorch와 transformers처럼 정해진 런타임을 사용합니다. Triton은 모델별로 ONNX Runtime, TensorRT, Python 등의 백엔드를 선택할 수 있습니다.
Triton core는 다음 기능을 담당합니다.
- 동적 배치: 짧은 시간 안에 들어온 요청을 서버에서 하나의 배치로 결합합니다.
- 모델 관리: 모델 버전, 로드와 언로드, 여러 모델의 동시 서빙을 관리합니다.
- ensemble: 전처리, 추론, 후처리 단계를 서버 안에서 연결합니다.
SageMaker와 Triton의 모델 관리 기능이 일부 겹칩니다
Triton은 여러 모델의 버전과 로드 상태를 관리합니다 (Conceptual Guide Part 1). SageMaker 환경에서는 Model과 EndpointConfig도 배포 단위를 관리하므로 일부 역할이 중복됩니다.
단일 모델 endpoint에서 Triton을 선택할 주요 이유는 TensorRT 성능과 GPU multi-model endpoint 지원입니다.
모델 저장소와 config.pbtxt¶
Triton은 model repository 규칙에 따라 모델 파일과 버전을 읽습니다.
mdeberta/ ← 이름이 config.pbtxt의 name과 같아야 합니다
├── config.pbtxt
└── 1/ ← 버전 디렉터리, 숫자여야 합니다
└── model.onnx ← 파일명이 백엔드마다 고정입니다
SageMaker Triton DLC에서는 model.tar.gz의 최상위에 모델 디렉터리가 있어야 합니다. /opt/ml/model/config.pbtxt가 바로 위치하면 컨테이너가 Incorrect directory structure 오류로 종료됩니다.
config.pbtxt는 JSON이 아닌 protobuf text format을 사용합니다. 다음은 시나리오 07의 설정입니다.
name: "mdeberta"
platform: "onnxruntime_onnx"
max_batch_size: 32
input [
{ name: "input_ids" data_type: TYPE_INT64 dims: [ 512 ] }, # 쉼표 필수
{ name: "attention_mask" data_type: TYPE_INT64 dims: [ 512 ] }
]
output [
{ name: "logits" data_type: TYPE_FP32 dims: [ 3 ] }
]
instance_group [ { count: 1 kind: KIND_GPU } ]
dynamic_batching { max_queue_delay_microseconds: 1000 }
max_queue_delay_microseconds의 적용 조건
max_queue_delay_microseconds는 즉시 실행할 수 있는 배치가 없을 때 요청을 큐에 유지할 최대 시간을 지정합니다. 위 설정은 max_batch_size: 32이므로 최대 32개 요청을 하나의 배치로 처리할 수 있습니다.
지연과 처리량의 균형은 dynamic batching 권장 절차에 따라 dynamic_batching { }로 시작한 뒤 perf_analyzer로 측정해 조정하는 편이 안전합니다.
config.pbtxt 작성 시 주의 사항
1. 배열 원소는 쉼표로 구분합니다. 개행만 사용하면 Expected ",", found "{" 오류로 서버가 기동하지 않습니다.
2. dims에는 batch 차원을 포함하지 않습니다. max_batch_size > 0이면 실제 shape은 [-1] + dims로 해석됩니다. 시퀀스 길이가 512라면 dims: [512]를 사용합니다.
3. 버전 디렉터리 이름은 양의 정수여야 합니다. 공식 model repository 문서에 따르면 숫자가 아니거나 0으로 시작하는 하위 디렉터리는 무시됩니다. v1/이나 01/을 사용하면 해당 모델 버전이 로드되지 않습니다.
SageMaker endpoint에서 디렉터리 오류를 확인하려면 컨테이너 시작 실패와 CloudWatch 로그를 기다려야 합니다. 배포 전에 로컬 docker run으로 모델 로드를 확인하는 것이 효율적입니다.
일부 백엔드는 auto-complete로 input, output, max_batch_size 등의 기본 구성을 채울 수 있습니다. 그러나 optimization, model_warmup, response_cache 같은 성능 관련 설정은 직접 작성해야 합니다.
input과 output을 지정하면 ONNX auto-complete가 건너뛰어집니다
ONNX Runtime 백엔드는 config에 input과 output이 모두 있으면 auto-complete를 실행하지 않습니다.
시나리오 07의 config.pbtxt처럼 input과 output을 모두 지정했다면 max_batch_size도 명시해야 합니다.
반대로 아무 입출력도 지정하지 않고 max_batch_size를 생략하면 ONNX Runtime backend가 default-max-batch-size 기본값 4를 사용할 수 있습니다. 원하는 배치 크기를 명시적으로 설정해야 벤치마크 조건과 서버 설정이 일치합니다.
백엔드별 차이¶
표준 -py3 이미지에 포함된 백엔드는 Triton server 저장소의 build.py에 정의된 all_backends를 기준으로 확인했습니다.
| 백엔드 | 받는 파일 | 실행 | 인코더 관점 |
|---|---|---|---|
onnxruntime |
model.onnx |
GPU(CUDA EP) 또는 CPU | 시나리오 02의 ONNX 모델을 그대로 사용할 수 있음 |
tensorrt |
model.plan |
GPU 전용 | trtexec로 사전 컴파일해야 하며 GPU 아키텍처와 버전에 종속 |
python |
model.py |
주로 CPU | tokenization, 후처리, 사용자 정의 로직 구현 |
pytorch |
model.pt (TorchScript) |
GPU/CPU | TorchScript 변환 필요, auto-complete 미지원 |
openvino |
model.xml+.bin 또는 .onnx |
공식 이미지는 Intel CPU만 지원 | 이 저장소에서는 성능을 측정하지 않음 |
fil |
xgboost.json 등 |
GPU/CPU | 트리 모델 실행 |
dali |
model.dali |
GPU | 이미지와 오디오 전처리 |
ensemble |
없음 (config만 사용) | core 내장 | 여러 모델 단계를 연결하는 스케줄러 |
모델별 스케줄러는 하나만 선택할 수 있습니다
dynamic_batching, sequence_batching, ensemble_scheduling 은 protobuf의 oneof scheduling_choice에 속하므로 동시에 설정할 수 없습니다. 따라서 ensemble 모델 자체에는 dynamic_batching을 설정할 수 없습니다.
시나리오 07의 ensemble 요청이 배치 처리되는 이유는 dynamic_batching이 step 모델인 mdeberta에 설정되어 있기 때문입니다. Ensemble은 단계 간 텐서 전달을 관리하고, 배치 처리는 각 step 모델의 설정을 따릅니다.
Ensemble에는 실행 인스턴스가 없으므로 instance_group도 지정하지 않습니다. 처리량을 조정하려면 각 step 모델의 instance_group을 변경해야 합니다. 또한 ensemble의 max_batch_size는 연결된 step 모델이 지원하는 값을 초과할 수 없습니다.
vllm 백엔드는 -vllm-python-py3, tensorrtllm 백엔드는 -trtllm-python-py3 이미지가 별도로 필요합니다. 두 백엔드는 생성형 디코더 모델용이므로 이 저장소의 인코더 NLI 분류에는 사용하지 않았습니다.
26.05 -py3 이미지에는 TensorFlow 백엔드가 포함되지 않습니다
NGC 이미지 설명문에는 아직 TensorFlow 지원이 적혀 있는데, r26.05 의 build.py 전체에 tensorflow 문자열이 한 번도 나오지 않습니다. 릴리스 노트 구성요소 목록에도 24.08 이후 없습니다.
반대로 릴리스 노트에 이름이 없다는 사실만으로 백엔드가 제외되었다고 판단할 수는 없습니다. 릴리스 노트는 주로 프레임워크 런타임 버전을 나열하므로, 정확한 포함 여부는 해당 릴리스의 build.py와 실제 이미지에서 확인해야 합니다.
ONNX 모델을 GPU에서 실행하는 세 가지 경로¶
시나리오 07에서 비교한 경로는 다음과 같습니다.
| 경로 | 설정 | 실측 p50 |
|---|---|---|
A. onnxruntime 백엔드, CUDA EP |
기본값 | 27.3 ms |
B. onnxruntime 백엔드 + TensorRT EP |
execution_accelerators에 tensorrt |
15.4 ms |
C. tensorrt 백엔드 |
.plan을 미리 컴파일 |
측정하지 않음 |
시나리오 07은 B 경로를 사용합니다. ONNX 모델은 그대로 유지하고 config.pbtxt에서 ONNX Runtime의 TensorRT Execution Provider를 활성화합니다.
optimization {
execution_accelerators {
gpu_execution_accelerator [{
name: "tensorrt"
parameters { key: "precision_mode" value: "FP16" }
parameters { key: "trt_engine_cache_enable" value: "true" }
parameters { key: "trt_engine_cache_path" value: "/tmp/trt_cache" }
}]
}
}
ONNX Runtime TensorRT Execution Provider는 TensorRT가 지원하지 않는 노드를 CUDA Execution Provider로 실행합니다. 따라서 그래프 전체가 TensorRT로 컴파일되는 C 경로보다 느릴 수 있지만, 별도의 .plan 파일을 준비할 필요가 없습니다.
동적 배치를 사용하려면 입력 shape을 맞춰야 합니다
Triton은 같은 shape의 요청을 하나의 배치로 결합합니다. 입력 길이가 서로 다르면 원하는 배치가 형성되지 않을 수 있습니다. 이 저장소는 실제 입력 조건과 동적 배치 구성을 맞추기 위해 --pad-to-max로 시퀀스 길이를 512로 고정합니다.
Triton은 ragged batching도 지원하지만, 모델이 1차원 입력과 batch input을 처리하도록 변환되어야 합니다. 시나리오 07은 기존 ONNX 모델을 그대로 사용하기 위해 적용하지 않았습니다.
TensorRT 엔진 캐시는 GPU 간에 이식할 수 없습니다
ONNX Runtime TensorRT EP가 생성한 .engine과 .profile도 TensorRT .plan과 마찬가지로 GPU 아키텍처와 소프트웨어 버전에 종속됩니다. 세부 호환성 조건은 TensorRT engine compatibility를 참고하세요.
모델, ONNX Runtime 버전, TensorRT 버전, GPU 아키텍처가 변경되면 캐시를 다시 생성해야 합니다. A10G에서 생성한 엔진을 T4에서 로드하면 역직렬화 단계에서 실패합니다.
ONNX Runtime TensorRT EP는 모델을 로드할 때 엔진을 생성합니다. 공식 문서의 예시는 캐시가 없을 때 384초, 캐시가 있을 때 9초가 걸립니다. 시나리오 07에서 ContainerStartupHealthCheckTimeoutInSeconds를 900초로 설정한 이유입니다.
캐시 경로가 /tmp이면 컨테이너 재시작 후 삭제됩니다. 캐시를 유지하려면 모델 아티팩트에 포함되는 경로를 사용해야 합니다.
Python 백엔드의 오버헤드¶
Python 백엔드의 고정된 오버헤드는 모델과 데이터 이동 방식에 따라 달라집니다. AWS의 Triton Python backend 설명도 유연성을 제공하는 대신 추가 데이터 복사가 성능에 영향을 줄 수 있다고 설명합니다.
시나리오 07의 측정 결과는 다음과 같습니다.
| p50 | b=8 samples/s | |
|---|---|---|
| TensorRT 단독 (클라이언트가 tokenize) | 15.4 ms | 185/s |
| ensemble + TensorRT (서버가 tokenize) | 16.6 ms | 179/s |
서버 측 tokenization을 포함한 ensemble의 p50 latency는 1.2ms 증가했고 처리량은 약 3% 감소했습니다.
python_backend는 Triton core와 shared memory로 통신하고, 모델 인스턴스별로 별도 Python 프로세스를 사용합니다. SageMaker Triton DLC의 serve 스크립트는 SAGEMAKER_TRITON_SHM_DEFAULT_BYTE_SIZE의 기본값을 16MB로 설정합니다. 배치 크기나 시퀀스 길이를 늘릴 때는 공유 메모리 사용량도 확인해야 합니다.
Python 백엔드는 기본적으로 입력 텐서를 CPU 메모리로 전달합니다. GPU 모델과 직접 연결하는 경우에는 FORCE_CPU_ONLY_INPUT_TENSORS="no" 설정을 검토할 수 있습니다. 시나리오 07의 tokenization 단계는 CPU 작업이므로 기본값을 사용했습니다.
문자열 입력에 미해결 이슈가 있습니다
issue #7153(open)은 (batch, 256) 크기 문자열 배열을 pb_utils.Tensor 로 캐스팅할 때 지연이 약 300배 증가한다고 보고합니다. 시나리오 07의 ensemble tokenization 단계도 문자열을 입력으로 받으므로 배치 크기와 문자열 길이가 커질 때 별도 측정이 필요합니다.
사용 기준¶
| 상황 | Triton | 이유 |
|---|---|---|
| GPU에서 latency를 더 줄여야 함 | ✅ | TensorRT FP16으로 p50 1.7배, p99 2.6배 개선 |
| GPU multi-model endpoint | ✅ | SageMaker의 GPU MME는 Triton을 통해 지원 |
| 전처리와 추론을 서버에서 연결 | ✅ | ensemble로 서버 측 pipeline 구성 |
| 단일 모델이며 latency 여유가 있음 | ❌ | HF DLC가 더 단순한 구성 |
| CPU 서빙 | ⚠️ | -py3-cpu 이미지가 있지만 TensorRT를 사용할 수 없음 |
| 서버리스 | ❌ | GPU 미지원 + 이미지 크기 |
AWS Triton 문서는 GPU 기반 모델의 multi-model endpoint를 Triton Inference Server를 통해 지원한다고 명시합니다. 지원 인스턴스 목록은 배포 시점의 AWS 문서에서 다시 확인해야 합니다.
CPU 인코더에도 Triton을 사용해야 하나요?
SageMaker Triton DLC에는 -py3-cpu 태그가 있으며 sagemaker-tritonserver:26.05-py3-cpu로 배포할 수 있습니다. 이 태그는 us-east-1 ECR에서 확인했습니다.
다만 이 저장소에서는 CPU Triton의 성능상 이점을 확인하지 못했습니다. issue #7677(open)은 CPU에서 Triton + ONNX Runtime이 ONNX Runtime 직접 호출보다 느린 사례를 보고합니다. CNN 모델의 미해결 이슈이므로 인코더 모델에 그대로 일반화할 수는 없습니다.
CPU에서는 TensorRT를 사용할 수 없습니다. 시나리오 02는 컨테이너에서 ONNX Runtime을 직접 호출하므로 Triton을 추가하면 서버 계층이 하나 늘어납니다.
CPU Triton과 직접 ONNX Runtime 서빙을 같은 조건으로 비교하지 않았으므로 결론을 일반화하지 않습니다. 현재 검증된 CPU 경로는 ONNX Runtime 직접 서빙입니다.
Serverless Inference에서 Triton을 사용할 수 있나요?
이 저장소의 Triton 구성에는 적합하지 않습니다.
- Serverless Inference는 GPU를 지원하지 않으므로 TensorRT를 사용할 수 없습니다.
- Serverless Inference의 컨테이너 이미지 제한은 10GB이며,
26.05-py3이미지의 압축 크기는 NGC API 기준 8.06GB입니다. - Serverless Inference는 multi-model endpoint를 지원하지 않습니다.
06 Serverless와 07 Triton은 서로 다른 배포 조건을 대상으로 합니다.
자주 묻는 질문¶
Triton을 사용하면 세부 성능 지표를 볼 수 있나요?
로컬 환경에서는 가능하지만 SageMaker endpoint 외부에서는 Triton의 metrics 포트에 직접 접근할 수 없습니다.
Triton은 포트 8002의 /metrics로 Prometheus 지표를 제공합니다. 그중 nv_inference_queue_duration_us(큐 대기)와 nv_inference_compute_infer_duration_us (실제 추론)를 구분해 확인할 수 있습니다. SageMaker의 CloudWatch endpoint 지표는 같은 수준의 Triton 내부 구간을 제공하지 않습니다.
SageMaker용 Triton serve 스크립트는 표준 HTTP 포트를 비활성화하고 /ping, /invocations, /models 경로를 제공합니다. /metrics 포트는 endpoint 호출 경로로 노출되지 않으므로 로컬 컨테이너에서만 직접 조회할 수 있습니다.
같은 이유로 endpoint 외부에서 /v2/models를 직접 호출할 수 없습니다.
NVIDIA Dynamo가 Triton을 대체하나요?
NVIDIA Dynamo는 멀티노드 생성형 AI 추론을 조정하는 프레임워크입니다. SGLang, TensorRT-LLM, vLLM 같은 추론 엔진을 대체하기보다 여러 엔진과 워커를 조정하는 역할을 설명하고 있습니다.
Triton도 별도의 릴리스 주기를 유지하고 있습니다. 두 프로젝트의 역할과 적용 대상이 다르므로 이 문서에서는 대체 관계로 보지 않습니다.
일부 AWS 자료에는 단일 모델만 지원한다고 되어 있습니다
초기 SageMaker Triton 자료의 제약을 설명하는 문장입니다. 현재 AWS Triton 개발자 가이드는 GPU multi-model endpoint 지원을 안내하므로 최신 문서를 기준으로 판단해야 합니다.
인코더 모델에는 TEI(Text Embeddings Inference)가 더 적합하지 않나요?
지원되는 아키텍처라면 검토할 수 있습니다. 다만 TEI 지원 모델에는 이 저장소의 mDeBERTa 아키텍처가 포함되지 않습니다.
따라서 mDeBERTa에 GPU 최적화를 적용하려면 ONNX 또는 TensorRT로 변환한 후 Triton에서 실행하는 경로를 사용합니다.
SageMaker 환경에서의 동작¶
| 항목 | 값 |
|---|---|
| 이미지 | 763104351884.dkr.ecr.<region>.amazonaws.com/sagemaker-tritonserver:26.05-py3 |
| 호출 경로 | /invocations (boto3가 처리). 표준 /v2/models/<name>/infer는 사용하지 않음 |
| payload 스키마 | KServe v2 형식: {"inputs": [{"name", "shape", "datatype", "data"}]} |
| Content-Type | application/octet-stream (JSON 본문) |
| 모델 선택 | SAGEMAKER_TRITON_DEFAULT_MODEL_NAME |
| GPU 드라이버 | InferenceAmiVersion: al2023-ami-sagemaker-inference-gpu-4-1 |
호출 경로는 SageMaker 규약을 따르고 요청 본문은 KServe v2 형식을 사용합니다. common/triton_payload.py가 이 요청을 생성합니다.
SAGEMAKER_TRITON_DEFAULT_MODEL_NAME은 모델 디렉터리가 하나일 때 생략할 수 있습니다. 모델 디렉터리가 두 개 이상이면 serve 스크립트가 기본 모델을 선택할 수 없으므로, ensemble처럼 여러 디렉터리를 배포할 때는 반드시 지정해야 합니다.
SageMaker용 serve 스크립트에서 확인한 기본값
SAGEMAKER_TRITON_LOG_VERBOSE의 기본값은 true입니다. 운영 환경에서 상세 로그가 필요하지 않다면 false로 설정할 수 있습니다. 시나리오 07은 TensorRT 컴파일 진행을 확인하기 위해 상세 로그를 유지했습니다.
SAGEMAKER_MODEL_SERVER_TIMEOUT은 Triton DLC의 serve 스크립트에서 사용되지 않습니다. 컨테이너 시작과 TensorRT 컴파일에 필요한 시간은 ContainerStartupHealthCheckTimeoutInSeconds로 설정합니다.
두 동작은 NVIDIA 저장소의 docker/sagemaker/serve에서 확인할 수 있습니다.
관련 문서¶
- 실제 배포와 실측: 07 Triton + TensorRT
- CPU 경로 비교: ONNX Runtime으로 CPU 배포
- 문제 해결: 트러블슈팅
참고 자료¶
Triton 이미지와 포함 백엔드는 릴리스에 따라 변경됩니다. 아래 자료는 2026-08-07에 확인했으며, 이미지 태그를 변경할 때는 해당 버전의 릴리스 노트와 build.py를 다시 확인해야 합니다.
- SageMaker AI 개발자 가이드: Triton Inference Server
- Triton 릴리스 노트 26.05 (Triton 2.69.0, CUDA 13.2, TensorRT 10.16.1, ONNX Runtime 1.24.4)
- model_repository.md, model_configuration.md
- docker/sagemaker/serve (SageMaker 전용 환경변수와 실행 경로)
- onnxruntime_backend, python_backend
- ONNX Runtime TensorRT EP
- TensorRT engine compatibility
- Host ML models on SageMaker using Triton: Python backend