tech · 2026-03-22

Triton Inference Server

1. 서론

1.1 딥러닝 서빙 필요성

  • 딥러닝 모델이 다양한 산업 분야에서 실서비스로 도입되면서, 학습 이후의 "추론(inference)" 단계가 실질적인 성능과 사용자 경험을 좌우하는 핵심 구성 요소로 부상함

  • 특히 Transformer 기반의 자연어 처리, CNN 기반의 비전 모델, 멀티모달 통합 모델 등은 추론 시 계산량이 크고, 응답 지연(latency)이 길며, 하드웨어 자원 소모가 큼

  • 단일 모델을 단일 사용자 환경에서 테스트할 때는 문제가 되지 않지만, 실제 운영 환경에서는 다음과 같은 구조적 병목이 발생함:

    • Framework Dependency

      • 학습된 모델이 PyTorch, TensorFlow, ONNX 등 다양한 프레임워크에 걸쳐 존재하며, 이를 통합 운영하기 어렵고, 각기 다른 추론 코드와 환경을 요구함
      • 동일한 서버 혹은 클러스터에서 서로 다른 포맷의 모델을 효율적으로 실행하기 위해선, 일관된 추론 API와 자원 관리 인터페이스가 필요함
    • Dynamic Graph의 한계

      • PyTorch, TensorFlow Eager 모드와 같이 runtime 시점에 연산 그래프가 구성되는 모델은 컴파일 최적화, static scheduling, memory reuse와 같은 시스템 최적화 기법을 적용하기 어려움
      • 이는 추론 속도의 불확실성과 자원 비효율로 이어짐. 특히 고속 추론이 필요한 실시간 시스템에서는 치명적
    • Batch 및 병렬성 처리의 부재

      • 일반적인 추론 코드에서는 batch 구성, 다중 요청 간 동시 처리, 모델 인스턴스 분산 실행 등의 로직이 수동으로 구현되어야 함
      • GPU 자원을 활용하더라도 단일 요청 단위의 처리만을 반복하는 경우, throughput이 낮고 underutilization 발생
    • Latency & Throughput Tradeoff

      • 실시간 검색, 챗봇, 음성 비서와 같은 서비스에서는 ms 수준의 latency가 요구됨
      • 반면, 고밀도 트래픽 상황에서는 batch 처리 및 multi-instance 전략이 throughput 확보에 필수적
      • 기존 프레임워크들은 이 tradeoff를 운영 레벨에서 유연하게 해결하지 못함
    • MLOps 환경과의 통합 한계

      • 모델 배포, 버전 관리, rollback, Canary 배포, 메트릭 수집과 같은 운영 요구가 증가
      • 단순 API 서버 구조로는 CI/CD 파이프라인이나 운영 모니터링 시스템과의 통합이 어려움
  • 이처럼 딥러닝 서빙은 단순한 "모델 불러오기 + 예측하기"가 아니라, 다중 프레임워크 통합, 고속 추론 최적화, 자원 관리, 시스템 연계성까지 고려한 복합적인 시스템 설계 문제로 발전하고 있음

  • 이러한 필요성에 대응하기 위해서는 다음과 같은 요소를 갖춘 서빙 인프라가 요구됨:

    • 다양한 프레임워크 모델을 통합 실행할 수 있는 multi-backend 실행 환경
    • 요청 지연을 줄이고 GPU 활용률을 극대화할 수 있는 dynamic batching 및 parallel execution 지원
    • 추론 단계에서의 병목을 제거하고 시스템 자원을 효율적으로 분배할 수 있는 scheduler 및 resource manager
    • 운영 환경에서의 안정성과 확장성을 보장하는 모니터링, 로깅, hot-reloading 지원
    • MLOps 및 클라우드 네이티브 스택과의 연계 가능한 구성 가능성
  • 이러한 요건들을 체계적으로 만족시키는 대표적인 플랫폼이 바로 Triton Inference Server


1.2 Triton Inference Server 등장 배경

  • 위에서 정리한 바와 같이, 딥러닝 모델을 실제 서비스에 서빙하기 위해서는 단순한 추론 호출을 넘어 프레임워크 통합, 자원 효율화, latency 제어, 운영 자동화 등 복합적인 시스템 설계 과제가 뒤따름

  • 전통적인 서빙 접근 방식은 다음과 같은 한계를 가짐:

    • 프레임워크 종속 추론 서버

      • PyTorch는 TorchServe, TensorFlow는 TF Serving 등 각각 전용 서빙 서버를 가짐
      • 동일한 서버 내에서 서로 다른 프레임워크 모델을 동시에 실행하거나 일관된 API로 관리하는 것이 어려움
    • 커스텀 API 서버의 유지보수 비용

      • Python Flask, FastAPI 기반의 추론 서버가 많지만, 모델 버전 관리, 배치 처리, 다중 인스턴스 제어, 모니터링 기능이 부족함
      • 운영 환경으로 확장하기 어렵고, DevOps 및 MLops 파이프라인과의 연계도 복잡함
    • GPU 자원 활용의 비효율성

      • GPU는 높은 처리량을 요구하지만, 단일 요청에 대한 반복 추론은 GPU를 비효율적으로 소모
      • 다수의 모델을 띄워야 할 경우에도, GPU를 어떻게 분할하고 할당할지 수동으로 관리해야 함
    • Latency 및 Throughput Tradeoff 미해결

      • 실시간 요청의 지연 시간은 낮아야 하고, 동시에 시스템 전체 처리량도 유지되어야 함
      • 이 두 가지 목표는 상충 관계에 있으며, 정교한 스케줄링 및 배치 정책 없이는 만족시키기 어려움
  • Triton Inference Server는 위 문제들을 해결하기 위한 NVIDIA의 시스템 수준 서빙 프레임워크로 설계됨 단순한 추론 API 서버가 아니라, 다양한 모델을 하나의 추론 플랫폼에서 통합, 최적화, 자동화된 방식으로 실행하는 추론 인프라를 지향함

  • Triton은 다음과 같은 설계 철학과 구조를 갖고 있음:

    • Multi-Framework 지원

      • PyTorch (TorchScript), TensorFlow (SavedModel), ONNX Runtime, TensorRT, Python Script 기반 모델을 동시에 서빙
      • 모델마다 다른 포맷, 런타임을 가졌더라도 동일한 API를 통해 통합적으로 추론 요청 처리 가능
    • High-Performance Scheduling System

      • GPU 활용률을 극대화하기 위한 dynamic batching, model instance group, priority queueing 기능을 기본 제공
      • GPU 자원을 복수의 모델이 효율적으로 나눠 쓰도록 스케줄링하며, 실시간과 배치형 workload의 병행 처리를 지원
    • 자동 재로딩과 운영 효율성

      • 모델 저장소(repository)를 주기적으로 감시하여, 모델 변경 시 자동으로 reload
      • Prometheus 기반의 메트릭 노출, 로그 관리, 상태 조회 API를 통해 운영 가시성 확보
    • Production-Grade 확장성

      • REST/gRPC 기반 API 제공, Docker 및 Kubernetes 환경에 최적화된 배포 구조, Helm chart 제공
      • Ensemble 모델, Streaming inference, Python backend 등 고급 use-case도 지원
  • Triton은 연구·개발·운영 사이의 단절을 줄이는 플랫폼으로서, 하나의 통합된 추론 인프라 위에서 다양한 모델을 배포, 테스트, 운영할 수 있는 기반을 제공함

1.3 구성

  • Section 2: Triton Inference Server 개요

    • Triton이 어떤 플랫폼인지, 기존 서빙 방식과 어떤 점에서 차별적인지 개념적 수준에서 조망함
    • Multi-framework support, resource scheduling, production readiness 등 핵심 설계 방향을 요약함
  • Section 3: 아키텍처 구조 및 핵심 컴포넌트

    • Triton의 내부 구조와 실행 흐름을 분석함
    • Scheduler, Batcher, Model Instance Group 등 핵심 모듈의 상호작용을 구조적으로 설명함
  • Section 4: 주요 기능 상세 설명

    • Triton이 제공하는 기능을 분류별로 체계적으로 정리함
    • Dynamic batching, model priority, ensemble, streaming 등 실전 기능들을 config 수준에서 해석함
  • Seciton 5: 실무 구성 예시 및 운영 패턴

    • 다양한 산업 환경에서 Triton을 어떻게 구성할 수 있는지를 구체적인 사례 기반으로 제시함
    • Docker/Kubernetes 배포, Python backend 구성, ensemble pipeline 등 실전 시나리오 중심
  • Section 6: 결론


2. Triton Inference Server 개요

2.1 Triton의 역할 및 기본 개념

  • Triton Inference Server는 다양한 딥러닝 모델을 통합된 구조에서 효율적으로 서빙할 수 있도록 설계된 범용 추론 플랫폼
  • 단일 모델을 실행하는 엔진이 아니라, 다양한 모델 포맷과 실행 패턴을 처리하기 위한 시스템 계층의 실행 환경으로 작동함
  • 기존의 추론 시스템이 프레임워크 종속적 실행, 수작업 배치 구성, 정적 자원 관리 방식에 머물렀다면, Triton은 이를 극복하기 위해 다음과 같은 기능 계층 구조를 갖추고 설계됨

2.1.1 Backend Abstraction Layer

  • 다양한 프레임워크 기반의 모델을 실행하기 위한 런타임 추상화 계층
  • PyTorch (TorchScript), TensorFlow (SavedModel), ONNX Runtime, TensorRT 등 heterogeneous한 모델 포맷을 단일 API로 통일
  • Python Backend와 같은 사용자 정의 실행 환경도 이 계층에 통합되어 있음

2.1.2 Scheduling & Execution Layer

  • 클라이언트 요청을 모델, 인스턴스, 배치 크기, 우선순위에 따라 스케줄링하는 실행 계층
  • Dynamic batching, model queue, priority handling 기능을 통해 throughput과 latency를 모두 고려한 실행 경로 설계
  • 실시간/비실시간 workload를 분리하여 다중 요청 처리 구조 구성 가능

2.1.3 Resource Management Layer

  • GPU/CPU 자원을 다중 모델 간에 분배, 격리, 최적화하기 위한 자원 제어 계층
  • 모델별 인스턴스 수, 배치 크기, 메모리 우선순위 등을 설정 가능
  • Multi-Instance GPU(MIG), multi-process engine 구성 등 다양한 하드웨어 기반 분산 실행 방식 지원

2.1.4 Model Lifecycle & Repository Layer

  • 모델 저장소(repository)를 기반으로 한 자동화된 로딩 및 재시작 계층
  • 모델의 입력/출력 시그니처, 버전, 메타정보를 선언적으로 관리하고 변경 시 자동 reload, version swap, 상태 추적 등을 수행
  • 지속적 배포(CD) 및 Canary 운영을 위한 핵심 기반 기능 제공

2.1.5 Observability & Integration Layer

  • Prometheus 메트릭, 로그 스트리밍, 상태 체크 API 등 운영 관측 및 진단 기능 제공
  • gRPC 및 HTTP REST API를 통해 클라이언트와 통신하며, Docker/Kubernetes 배포에 최적화된 cloud-native 운영 구조 지원
  • CI/CD, 모델 레지스트리, 실험 추적 시스템 등 MLOps 스택과의 연계성 확보 가능

2.2 지원 프레임워크 및 모델 포맷

  • Triton Inference Server는 다양한 딥러닝 프레임워크에서 학습된 모델을 단일 시스템 내에서 통합 서빙할 수 있도록 설계됨
  • 이를 위해 내부적으로 다양한 **백엔드(Backend)**를 통해 각기 다른 모델 포맷을 지원하며, 이 백엔드 계층은 앞서 설명한 **Backend Abstraction Layer (2.1.1)**에 해당함

2.2.1 백엔드 구성 구조

  • Triton의 각 백엔드는 특정 모델 포맷과 런타임 환경을 바인딩하는 플러그인형 모듈로 구성됨
  • 백엔드는 공통된 추론 인터페이스를 따르며, 모델 로딩, 추론 실행, 결과 반환 과정을 일관되게 처리
  • Triton은 실행 시점에 /models 디렉토리 내의 모델 구성(config.pbtxt)을 기반으로 해당 백엔드를 동적으로 로딩함

2.2.2 기본 지원 백엔드

백엔드 지원 포맷 런타임 설명
TensorFlow Backend .pb, SavedModel TensorFlow Serving 기반으로, 그래프 모드 우선 지원 (TF 1.x, 2.x 모두 가능)
PyTorch Backend TorchScript (.pt) JIT 컴파일된 static graph 모델 우선 지원, eager 모드는 미지원
ONNX Runtime Backend .onnx 프레임워크 독립적 포맷으로, CPU/GPU 모두 실행 가능
TensorRT Backend .plan NVIDIA의 최적화된 추론 엔진, FP16/INT8 지원, GPU 실행 전용
Python Backend .py, shared object 사용자 정의 추론 로직 실행 가능, LLM inference, 후처리 등에 유용
OpenVINO Backend IR 포맷 Intel 하드웨어 최적화 추론, 선택적 활성화
RAPIDS FIL Backend XGBoost, RF CPU/GPU 기반 Tree 모델 추론 지원
DALI Backend DataLoader 형태 데이터 전처리 파이프라인과 추론 간 통합 처리 가능

2.2.3 복수 백엔드 통합의 의미

  • Triton은 복수의 모델 포맷을 동시에 서빙 가능 예: 검색 시스템에서 PyTorch 기반 임베딩 모델 + TensorRT 기반 Reranker 모델을 하나의 서버에서 통합 처리
  • 동일한 API 구조를 사용하여 모델 포맷과 관계없이 일관된 추론 요청 및 응답 처리 가능 클라이언트는 내부 백엔드 구성을 알 필요 없이 HTTP/gRPC 요청만으로 추론 가능
  • 프레임워크 간 실험 비교 및 교체 비용 절감 연구/실험 단계에서는 PyTorch로 빠르게 개발하고, 배포 단계에서는 TensorRT 변환 후 교체 가능 백엔드 변경은 config 수준에서 처리되므로, API 변경 없이 운영 가능
  • MLOps 및 CI/CD 파이프라인 구성의 단순화 다양한 팀에서 서로 다른 프레임워크를 사용해도, 최종 배포는 Triton 모델 저장소 기준으로 통합 가능 버전 관리, Canary 배포, Rollback을 모델 단위로 제어 가능

2.2.4 사용자 정의 백엔드 확장

  • Triton은 기본 제공되는 백엔드 외에도, 사용자가 직접 C++ 또는 Python 기반 커스텀 백엔드를 구현 가능
  • 예: Pre/Post-processing이 포함된 LLM Inference Wrapper, External Tool Invocation 모델 등
  • Python Backend는 가볍고 유연하여, LLM용 텍스트 응답 생성, 벡터 조합, 리랭커 추론 등에서 매우 널리 사용됨

2.3 Triton의 주요 특징 요약

  • Triton Inference Server는 추론 기능을 넘어서, 운영 가능하고 확장 가능한 추론 시스템 인프라를 구성하기 위한 기능 집합을 제공함
  • 이러한 기능들은 크게 추론 성능 최적화, 운영 자동화, 서비스 연계성 강화의 세 축으로 구분할 수 있음

2.3.1 추론 성능 최적화 기능

  • Dynamic Batching

    • 클라이언트의 단일 요청을 일정 시간 윈도우 내에서 수집한 뒤 하나의 배치로 처리
    • GPU 자원을 고정된 크기의 batch 단위로 처리함으로써 연산 효율을 극대화하고, per-query latency도 최소화
  • Model Instance Group

    • 동일한 모델을 다수의 GPU 인스턴스로 복제하여 병렬 처리 가능
    • 고빈도 요청 처리 또는 multi-core GPU 환경에서 GPU 활용률을 향상시킴
  • Execution Scheduling (Priority Queueing)

    • 모델 혹은 요청 유형에 따라 우선순위를 설정하여 처리 순서 제어
    • 예: 실시간 검색 요청은 높은 우선순위, 백그라운드 배치는 낮은 우선순위로 설정
  • TensorRT 엔진 통합 지원

    • 사전 최적화된 TensorRT plan 파일을 사용하여 FP16, INT8 기반 고속 추론 실행
    • Transformer, CNN 기반 모델의 latency를 수배 단위로 줄일 수 있음

2.3.2 운영 자동화 기능

  • Model Repository Auto-Reload

    • 지정된 모델 디렉토리를 지속적으로 감시하여, 파일 변경 시 자동으로 모델을 reload
    • 새로운 버전 반영, config 변경 적용을 재시작 없이 수행 가능
  • Version Management

    • 동일 모델의 다중 버전을 디렉토리 구조로 관리 가능
    • config를 통해 어떤 버전을 활성화할지 선택 가능하며, A/B 테스트나 Canary 배포에 활용 가능
  • Runtime Configurability

    • 모델의 배치 크기, 인스턴스 수, 자원 할당, timeout 설정 등을 config 파일로 선언적으로 제어
    • 추론 흐름과 배포 환경을 코드 수정 없이 실시간 조정 가능
  • Logging & Error Trace

    • 각 요청의 추론 처리 로그, 에러 스택, 응답 시간 등을 실시간 기록
    • 문제 발생 시 디버깅에 용이하며, 운영 모니터링과 연동 가능

2.3.3 시스템 연계 및 확장 기능

  • gRPC / HTTP REST API 지원

    • 추론 요청 및 상태 조회에 대해 두 가지 통신 방식 모두 지원
    • 클라이언트 환경(모바일, 백엔드, 프론트엔드 등)에 맞춰 유연하게 선택 가능
  • Prometheus Metrics Export

    • 모델별 요청 수, 평균 latency, batch 크기, 자원 사용률 등 다양한 메트릭을 Prometheus 포맷으로 노출
    • Grafana 등과 연계하여 운영 상태 시각화 가능
  • Streaming Inference (gRPC Stream)

    • 텍스트 생성, 음성 스트리밍 등과 같은 지속형 추론 요청 처리 지원
    • LLM, 음성 합성 시스템에서 활용 가능
  • Ensemble Model Composition

    • 다수의 모델을 순차적 또는 병렬적으로 실행하여 추론 파이프라인 구성 가능
    • 예: 텍스트 전처리 → LLM 추론 → 후처리 로직을 하나의 ensemble로 구성

3. 아키텍처 구조 및 핵심 컴포넌트

3.1 전체 시스템 아키텍처

  • Triton Inference Server는 클라이언트 요청 수신부터 추론 실행, 결과 반환, 메트릭 수집까지의 전 과정을 비동기 이벤트 기반의 컴포넌트 아키텍처로 처리함
  • 전체 아키텍처는 다음과 같은 주요 경로를 중심으로 구성됨

3.1.1 요청 수신 계층 (Request Ingress Layer)

  • 클라이언트는 REST(HTTP) 또는 gRPC 인터페이스를 통해 추론 요청을 전송함

  • Triton은 각각의 요청을 비동기 메시지 큐로 수신하며, 요청 메시지에는 모델명, 입력 텐서, 요청 옵션(execution priority 등)이 포함됨

  • 이 계층은 단순 수신뿐만 아니라, streaming 요청 처리(gRPC streaming), multipart input 관리, payload validation 등의 기능을 포함함

    # gRPC Request
    import grpc
    import tritonclient.grpc as grpcclient
    import numpy as np
    
    model_name = "my_model"
    inputs = [grpcclient.InferInput("input_ids", [1, 128], "INT32")]
    inputs[0].set_data_from_numpy(np.random.randint(0, 10000, size=(1, 128), dtype=np.int32))
    
    with grpcclient.InferenceServerClient("localhost:8001") as client:
        results = client.infer(model_name=model_name, inputs=inputs)
        print(results.as_numpy("output"))
    
    -----------------------------------------------------------------
    # HTTP Request
    import requests
    import numpy as np
    import json
    import base64
    
    model_name = "my_model"
    url = f"http://localhost:8000/v2/models/{model_name}/infer"
    
    # 입력 데이터를 base64로 인코딩
    input_data = np.random.randint(0, 10000, size=(1, 128), dtype=np.int32)
    b64_input = base64.b64encode(input_data.tobytes()).decode("utf-8")
    
    # HTTP 요청 payload 구성
    payload = {
        "inputs": [
            {
                "name": "input_ids",
                "shape": [1, 128],
                "datatype": "INT32",
                "data": [],  # data 대신 base64_data 사용
                "parameters": {"binary_data": True}
            }
        ]
    }
    
    headers = {"Content-Type": "application/json"}
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    print(response.json())
    

3.1.2 모델 라우팅 및 스케줄링 계층 (Scheduler Layer)

  • 요청이 수신되면 Triton은 요청된 모델 이름을 기반으로 해당 모델의 스케줄러로 요청을 라우팅

  • 각 모델은 고유한 scheduler thread를 가지며, 다음과 같은 정책에 따라 요청을 처리함:

    • Dynamic Batching: 일정 시간 동안 요청을 수집하여 하나의 batch로 처리
    • Priority Queueing: 요청 우선순위 기반의 큐 관리
    • Model Instance Selection: 사용 가능한 인스턴스를 선택하여 실행
  • 이 계층은 Triton의 추론 병렬화 및 자원 최적화의 핵심 로직이 집중된 구성 요소임

    # config.pbtxt 예시
    dynamic_batching {
      # Dynamic Batching
      max_batch_size: 8
      preferred_batch_size: [4, 8]
      max_queue_delay_microseconds: 100
    
    # Prioirty Queueing
      priority_levels: 3
      default_priority_level: 1
    }
    
    # Model Instance Selection
    instance_group [
      {
        kind: KIND_GPU
        count: 2
      }
    ]
    

3.1.3 실행 엔진 계층 (Execution Backend Layer)

  • 스케줄러로부터 전달받은 요청은 선택된 모델 인스턴스에서 실행

  • 각 인스턴스는 연결된 백엔드(runtime)와 함께 동작하며, PyTorch, TensorFlow, ONNX, TensorRT, Python 등 다양한 백엔드를 포함함

  • 주요 동작 흐름은 다음과 같음:

    • 입력 텐서 디코딩 및 메모리 로딩
    • 해당 백엔드를 통해 추론 함수 호출
    • 결과 텐서 생성 및 반환 포맷팅
  • 이 계층은 대부분의 경우 비동기적으로 처리되며, batch 크기 및 백엔드 종류에 따라 처리 latency가 다르게 발생

    # model.py
    def execute(inputs, outputs):
        input_tensor = inputs[0]
        result = input_tensor.as_numpy() * 2  # 단순 연산 예시
        outputs[0].set_data_from_numpy(result)
    

3.1.4 응답 처리 및 반환 계층 (Response Egress Layer)

  • 추론 결과는 내부 메모리 버퍼에 저장된 후, 비동기 콜백을 통해 클라이언트 응답 채널로 반환됨
  • REST의 경우 JSON, gRPC의 경우 protobuf 포맷으로 직렬화되어 전송됨
  • 이 과정에서는 응답 로그, latency 측정, 에러 코드 반환 등의 부가 처리도 수행됨

3.1.5 운영 및 관측 계층 (Observability & Control Layer)

  • Triton은 각 모델 및 서버 전반의 상태를 관측 가능하게 설계됨

  • 주요 컴포넌트는 다음과 같음:

    • Metrics Exporter: Prometheus 포맷으로 추론 성능 메트릭 제공
    • Health API: 모델 로딩 상태, 인스턴스 가용성, 에러 여부 확인 가능
    • Model Control: 모델 저장소 변경 감지 후 자동 reload 수행
  • 이러한 관측 기능은 대규모 시스템 운영 및 CI/CD 파이프라인 통합에 필수적인 기반 기능

    # http://localhost:8002/metrics
    nv_inference_request_success{model="my_model"} 12345
    nv_inference_request_duration_us_bucket{model="my_model",le="1000"} 100
    nv_inference_request_duration_us_sum{model="my_model"} 912300
    

3.2 Scheduler 및 실행 파이프라인

  • Triton Inference Server는 요청이 들어오면 단순히 순서대로 실행하는 것이 아니라, 우선순위 기반의 큐 관리와 동적 배치(Dynamic Batching), 인스턴스 분산 실행을 결합한 파이프라인을 통해 효율적으로 처리함

3.2.1 요청 분류 및 큐 진입

  • 수신된 요청은 요청 메시지에 포함된 model_name, priority, input tensor 정보를 기반으로 각 모델별 요청 큐로 분류되어 진입함
  • 모델별로 독립된 Scheduler thread와 실행 큐가 구성되며, 클라이언트가 priority 필드를 지정한 경우 우선순위 큐에 따라 요청이 정렬됨
  • 배치가 가능한 요청인지 여부는 입력 텐서의 shape 및 dtype, 배치 설정 등에 따라 결정됨

3.2.2 Dynamic Batching과 실행 트리거

  • 요청이 큐에 적재되면 Triton은 max_batch_size, preferred_batch_size, max_queue_delay_microseconds에 따라 실행 타이밍을 판단함

  • 다음 조건 중 하나가 만족되면 batch 실행이 트리거됨:

    • preferred_batch_size 만족 시 즉시 실행
    • 최대 지연 시간 초과 시 현재 큐된 요청 수만큼 실행
    • max_batch_size 도달 시 강제 실행
  • 이 과정을 통해 GPU 자원 효율성과 지연 최소화를 동시에 달성함

    dynamic_batching {
      preferred_batch_size: [4, 8]
      max_batch_size: 8
      max_queue_delay_microseconds: 100
    }
    

3.2.3 Priority Queueing과 실행 순서 제어

  • 요청 우선순위는 priority_levelspriority_queue_policy 설정에 따라 실행 순서를 조정함

  • 높은 우선순위 요청은 동일한 실행 조건에서 낮은 우선순위 요청보다 선행 처리되며, 필요한 경우 낮은 우선순위 요청의 실행을 유예하거나 큐에서 제거할 수 있음

  • 각 우선순위 큐에 대해 timeout, 최소 슬롯 활용률 등 정책을 별도로 설정 가능

    dynamic_batching {
      priority_levels: 3
      default_priority_level: 1
      default_queue_policy {
        default_timeout_microseconds: 10000
        allow_timeout_override: true
        timeout_action: REJECT
      }
      priority_queue_policy {
        key: 0
        value {
          default_timeout_microseconds: 5000
          minimum_slot_utilization: 0.95
        }
      }
      priority_queue_policy {
        key: 2
        value {
          default_timeout_microseconds: 20000
        }
      }
    }
    

3.2.4 인스턴스 선택 및 분산 실행

  • 배치가 준비되면 Triton은 해당 모델의 instance group 내에서 현재 사용 가능한 인스턴스를 선택하여 추론을 실행함

  • 인스턴스 선택 시 고려 요소:

    • idle 여부 및 큐 상태
    • GPU 자원 사용률
    • 지정된 GPU 번호 혹은 multi-instance 환경
  • 같은 모델이라도 서로 다른 GPU에서 병렬로 실행 가능하며, 모델 당 인스턴스 수는 instance_group.count로 제어함

    instance_group [
      {
        kind: KIND_GPU
        count: 2
        gpus: [0, 1]
      }
    ]
    

3.2.5 추론 완료 및 응답 반환

  • 추론이 완료되면 결과는 Triton 내부 메모리에서 응답 객체로 직렬화되며, gRPC 또는 HTTP를 통해 클라이언트로 반환됨
  • 이와 동시에 메트릭 수집기(metrics exporter)는 latency, batch size, 실행된 instance ID 등을 기록함
  • 최종 응답은 요청과 1:1 매핑되어 비동기 콜백 형태로 전달되며, 실패 시에는 에러 메시지 및 상태 코드가 포함됨

3.3 Model Repository 구조 및 모델 로딩 방식

  • Triton Inference Server는 모델을 외부 파일 시스템 기반 디렉토리 구조로 관리하며, 이 디렉토리를 Model Repository라고 부름
  • 모델 저장소는 서버 구동 시 지정되며, 이후에는 해당 경로의 변화에 따라 **모델 자동 로딩 및 재시작(hot-reload)**가 이루어짐

3.3.1 모델 저장소의 디렉토리 구조

  • Model Repository는 다음과 같은 계층 구조를 가짐:

    • 상위 디렉토리 이름이 Triton에서 인식되는 model_name이 되며, 하위 디렉토리는 버전 디렉토리로 간주됨 (정수 형태의 디렉토리명)

    • 각 버전 디렉토리에는 백엔드에 따라 .onnx, model.pt, saved_model.pb, model.plan, model.py 등의 파일이 포함됨

      /models/
       └── sentiment_classifier/
           ├── 1/
           │   └── model.onnx
           ├── 2/
           │   └── model.onnx
           └── config.pbtxt
      

3.3.2 모델 구성 파일 (config.pbtxt)

  • config.pbtxt는 Triton에서 해당 모델의 입출력 시그니처, 실행 전략, 배치 조건 등을 선언하는 정적 설정 파일

  • 서버 구동 시 이 config를 기준으로 모델을 로딩하고, 요청 validation 및 실행 전략을 결정함

  • config를 생략하면 Triton이 모델을 분석하여 **자동 추론(auto-complete)**을 시도하나, 이 기능은 복잡한 모델이나 고급 설정에는 한계가 있음

    name: "sentiment_classifier"
    platform: "onnxruntime_onnx"
    max_batch_size: 8
    
    input [
      {
        name: "input_ids"
        data_type: TYPE_INT32
        dims: [128]
      }
    ]
    output [
      {
        name: "logits"
        data_type: TYPE_FP32
        dims: [2]
      }
    ]
    

3.3.3 모델 버전 관리와 선택

  • Triton은 각 모델에 대해 여러 버전을 동시에 보유할 수 있으며 config.pbtxt에서 다음 중 하나로 설정 가능:

    • strict model versioning: 명시적으로 버전 지정 요청이 필요
    • latest version only: 항상 가장 높은 버전 자동 선택
    • custom version policy: 특정 버전만 활성화
  • 클라이언트 요청 시 version 필드를 지정하지 않으면 기본 정책에 따라 자동 선택됨

    version_policy: {
      latest {
        num_versions: 1
      }
    }
    

3.3.4 모델 로딩 트리거 및 자동 재시작

  • Triton은 주기적으로 Model Repository를 감시하며, 다음과 같은 이벤트에 반응함:

    • 모델 디렉토리 추가 → 모델 자동 로딩
    • config.pbtxt 변경 → 자동 재로드
    • 버전 디렉토리 추가/삭제 → 상태 변경 및 재초기화
  • 이러한 동작은 model control mode 설정을 통해 조절할 수 있음:

    • MODE_POLL: 기본값. 주기적으로 파일시스템을 감시

    • MODE_EXPLICIT: API를 통해 명시적으로 로딩 요청

    • MODE_NONE: 서버 시작 시 로딩한 모델만 사용

      tritonserver \
        --model-repository=/models \
        --model-control-mode=poll \
        --repository-poll-secs=60
      

3.3.5 서빙 중 모델 상태 확인

  • Triton은 모델의 상태를 다음과 같은 API로 노출함:

    • /v2/models/{model_name} → 모델 상태 조회
    • /v2/models/{model_name}/ready → 사용 가능 여부
    • /v2/repository/index → 전체 모델 목록 확인
  • 운영자가 모델 상태를 실시간으로 점검하고 문제 발생 시 대응 가능


3.4 Backend 실행 흐름 및 메모리 모델

  • Triton Inference Server는 모델을 실행할 때 각 백엔드(PyTorch, TensorRT, ONNX 등)에 맞는 실행 경로를 사용함
  • 이 실행 경로는 크게 입력 데이터 변환 → 실행 호출 → 출력 생성 → 응답 변환의 4단계로 구성됨

3.4.1 Backend별 실행 흐름

  • Triton은 각 백엔드별로 별도의 실행 모듈을 가지며, 공통 인터페이스를 통해 요청을 처리함
백엔드 실행 엔진 지원 포맷 실행 특징
TensorFlow TF Serving SavedModel static graph 우선, GPU/CPU 모두 지원
PyTorch LibTorch TorchScript (.pt) eager mode 미지원, JIT 기반
ONNX ONNX Runtime .onnx 프레임워크 독립적, CPU/GPU 모두 사용 가능
TensorRT TensorRT Runtime .plan FP16/INT8 최적화, GPU only
Python 사용자 정의 .py 후처리, LLM wrapper 등 유연하게 구성 가능
  • 각 백엔드는 initialize(), execute(), finalize() 함수 흐름을 따르며, 추론 전후 자원 할당과 해제를 명시적으로 처리함

    # model.py
    import numpy as np
    import triton_python_backend_utils as pb_utils
    
    class TritonPythonModel:
        def initialize(self, args):
            self.model_config = args['model_config']
            print("Model initialized.")
    
        def execute(self, requests):
            responses = []
            for request in requests:
                input_tensor = pb_utils.get_input_tensor_by_name(request, "input_ids")
                input_array = input_tensor.as_numpy()
    
                result = input_array * 2  # 예시: 간단한 스칼라 연산
    
                output_tensor = pb_utils.Tensor("output", result.astype(np.float32))
                inference_response = pb_utils.InferenceResponse(output_tensors=[output_tensor])
                responses.append(inference_response)
            return responses
    
        def finalize(self):
            print("Model finalized.")
    

3.4.2 입력 데이터 처리 및 메모리 버퍼 구조

  • 클라이언트 요청이 들어오면 Triton은 입력 데이터를 다음 절차로 처리함:

    • InferRequest를 내부 Tensor 객체로 변환
    • 필요한 경우 zero-copy 또는 pinned memory 기반으로 GPU에 로딩
    • dynamic batching이 활성화된 경우, 여러 요청의 입력을 하나의 contiguous batch tensor로 병합
  • 이 과정에서 메모리 alignment, dtype 변환, padding 등이 자동 적용됨

    import tritonclient.grpc as grpcclient
    import numpy as np
    
    input_data = np.random.randint(0, 10000, size=(4, 128)).astype(np.int32)
    
    inputs = [
        grpcclient.InferInput("input_ids", input_data.shape, "INT32")
    ]
    inputs[0].set_data_from_numpy(input_data)
    
    with grpcclient.InferenceServerClient("localhost:8001") as client:
        result = client.infer("my_model", inputs=inputs)
        output = result.as_numpy("output")
    

3.4.3 실행 컨텍스트 및 동시 처리

  • Triton은 각 모델 인스턴스마다 **독립된 실행 컨텍스트(execution context)**를 유지함

  • 컨텍스트는 다음 요소로 구성됨:

    • 입력 버퍼 포인터
    • 출력 버퍼 메타정보
    • GPU context 및 stream handle
    • backend-specific allocator 및 executor
  • 이를 통해 모델 간 자원 간섭 없이, 동시에 여러 인스턴스가 실행될 수 있음

  • 각 컨텍스트는 독립적이므로 Thread-safe한 방식으로 실행 가능

    ExecutionContext {
      model_name: "my_model"
      device_id: 0
      stream: cudaStream_t
      backend_executor: TensorRT / ONNXRuntime / PyTorch
      input_buffer: void*
      output_buffer: void*
    }
    

3.4.4 출력 텐서 생성 및 응답 직렬화

  • 추론이 완료되면 Triton은 다음 절차로 응답을 생성함:

    • 결과 텐서를 클라이언트 형식(NumPy, JSON, Protobuf 등)에 맞게 변환
    • 필요한 경우 base64 인코딩 또는 binary tensor 포맷으로 압축
    • 응답 메시지와 batch id를 매핑하여 최종 응답 생성
  • 이 단계에서는 성능을 위해 메모리 복사 최소화, lazy materialization 등의 최적화가 사용됨

    # Python Backend 예시 - outputs 직렬화
    output_array = np.array([[0.7, 0.3]], dtype=np.float32)
    output_tensor = pb_utils.Tensor("logits", output_array)
    response = pb_utils.InferenceResponse(output_tensors=[output_tensor])
    return [response]
    

3.4.5 메모리 풀 및 allocator 정책

  • Triton은 고성능 실행을 위해 내부적으로 메모리 풀을 관리하며 요청당 메모리 할당을 반복하지 않도록 최적화

  • 설정 가능한 allocator 전략:

    • cuda_malloc: 요청마다 CUDA malloc/free 호출 (권장하지 않음)
    • pinned memory: host-GPU 간 전송 최적화에 사용
    • custom allocator: Python backend 등에서 사용자 정의 가능
  • 모델의 출력 크기가 예측 가능할 경우, 고정 크기 버퍼를 미리 할당하여 재사용하는 방식도 가능함

    tritonserver
      --model-repository=/models
      --cuda-memory-pool-byte-size=0:268435456 #  GPU 0에 256MB 풀 확보
      --response-cache-byte-size=134217728
    

4. config.pbtxt 구성과 기능별 설정

  • Triton Inference Server는 각 모델 디렉토리 내에 존재하는 config.pbtxt 파일을 통해 모델의 입출력 정의, 실행 정책, 자원 사용 전략 등을 선언적으로 지정함
  • 이 파일은 모델 실행 시 핵심 기준이 되며, 잘 설계된 config는 latency, throughput, stability에 모두 영향을 미침

4.1 입력/출력 텐서 정의

  • 가장 기본적인 설정으로, 모델의 입력과 출력 텐서 이름, dtype, shape을 정의함

  • 입력/출력 이름은 클라이언트 요청 시 지정한 이름과 일치해야 함

  • 동적 차원은 -1로 명시 가능하며, shape 필드는 실행 시점에 실 데이터로 채워짐

    input [
      {
        name: "input_ids"
        data_type: TYPE_INT32
        dims: [128]
      }
    ]
    output [
      {
        name: "logits"
        data_type: TYPE_FP32
        dims: [2]
      }
    ]
    

4.2 배치 관련 설정

  • Triton은 단일 요청뿐만 아니라 다수 요청을 모아 한 번에 실행하는 Dynamic Batching을 지원함

  • 이를 설정하려면 max_batch_size를 1 이상으로 설정하고, dynamic_batching 블록을 명시함

  • 주요 파라미터:

    • preferred_batch_size: 선호하는 batch 크기 (도달 시 즉시 실행)

    • max_queue_delay_microseconds: 최대 대기 시간 (초과 시 현재 요청들로 실행)

      max_batch_size: 8
      
      dynamic_batching {
        preferred_batch_size: [4, 8]
        max_queue_delay_microseconds: 200
      }
      

4.3 인스턴스 및 실행 자원 설정

  • Triton은 하나의 모델을 여러 인스턴스로 복제하여 병렬로 실행할 수 있음

  • instance_group을 통해 실행 단위의 수와 할당 장치를 지정함

  • 주요 파라미터:

    • count: 인스턴스 수

    • kind: KIND_GPU, KIND_CPU 중 선택

    • gpus: 특정 GPU 지정 가능 (multi-GPU 환경에서 유용)

      instance_group [
        {
          kind: KIND_GPU
          count: 2
          gpus: [0, 1]
        }
      ]
      

4.4 우선순위 및 큐 정책 설정

  • 실시간 서비스와 백그라운드 처리를 분리하기 위해 Triton은 Priority Queueing을 지원함

  • dynamic_batching 내부에서 priority_levels, priority_queue_policy 등을 설정함

  • 레벨별 queue timeout, 최소 실행 조건 등을 설정해 정교한 제어 가능

    dynamic_batching {
      max_queue_delay_microseconds: 100
      priority_levels: 3
      default_priority_level: 1
    
      priority_queue_policy {
        key: 0
        value {
          default_timeout_microseconds: 5000
          minimum_slot_utilization: 0.9
        }
      }
    
      default_queue_policy {
        default_timeout_microseconds: 10000
        timeout_action: REJECT
      }
    }
    

4.5 백엔드 및 최적화 옵션 설정

  • 모델의 실행 백엔드를 명시하거나, 특정 실행기 설정을 fine-tune 가능

  • 예: TensorRT의 FP16 모드, Python Backend의 env path 등

  • 주요 필드:

    • backend: "tensorflow", "onnxruntime", "python", "tensorrt" 등

    • parameters: Python backend 등에서 환경 경로 설정

    • optimization: precision, execution accelerator, memory policy 등 지정

      backend: "python"
      
      parameters: {
        key: "EXECUTION_ENV_PATH"
        value: { string_value: "/models/my_python_model/1" }
      }
      ------------------------------------------------------------
      backend: "tensorrt"
      
      optimization {
        execution_accelerators {
          gpu_execution_accelerator : [
            {
              name : "tensorrt"
              parameters { key: "precision_mode" value: "FP16" }
            }
          ]
        }
      }
      

4.6 버전 정책 및 모델 수명주기 제어

  • Triton은 여러 버전의 모델을 동시에 유지하며, version policy로 제어 가능

  • 주요 정책:

    • all {}: 모든 버전 사용

    • latest { num_versions: 1 }: 최신 버전 1개만 사용

    • specific { versions: [1, 3, 5] }: 명시된 버전만 활성화

      version_policy: {
        specific {
          versions: [1, 3, 5]
        }
      }
      

4.7 Ensemble Scheduling

  • Triton은 다단계 추론 파이프라인을 하나의 요청으로 처리할 수 있도록 Ensemble 모델 구성 기능을 지원함

  • 예를 들어, 전처리 모델 → 메인 모델 → 후처리 모델이 순차적으로 실행되어야 하는 경우, 이를 Ensemble로 선언하면 클라이언트는 하나의 모델로 요청만 보내면 전체 파이프라인이 자동 실행됨

  • 구성 방법:

    • ensemble_scheduling 블록 내에 step을 정의하여 실행 순서를 명시
    • 각 step마다 model_name, input_map, output_map을 선언
  • 대표적인 활용 예: LLM Inference (토큰화 → 추론 → 사후 처리)

    name: "reranking"
    platform: "ensemble"
    
    input [
      {
        name: "query_text"
        data_type: TYPE_STRING
        dims: [1]
      },
      {
        name: "doc_text"
        data_type: TYPE_STRING
        dims: [1]
      }
    ]
    
    output [
      {
        name: "relevance_score"
        data_type: TYPE_FP32
        dims: [1]
      }
    ]
    
    ensemble_scheduling {
      step [
        {
          model_name: "embedder"
          input_map {
            key: "text"
            value: "query_text"
          }
          output_map {
            key: "embedding"
            value: "query_emb"
          }
        },
        {
          model_name: "embedder"
          input_map {
            key: "text"
            value: "doc_text"
          }
          output_map {
            key: "embedding"
            value: "doc_emb"
          }
        },
        {
          model_name: "reranker"
          input_map {
            key: "query_emb"
            value: "query_emb"
            key: "doc_emb"
            value: "doc_emb"
          }
          output_map {
            key: "score"
            value: "relevance_score"
          }
        }
      ]
    }
    

5. 실무 구성 예시 및 배포 시나리오

5.1 모델별 추론 경로 최적화 전략 개요

목적

  • 딥러닝 모델은 종류에 따라 추론 구조, 자원 사용 방식, 최적화 가능성이 다름
  • 특히 검색 시스템에서는 Query Embedding, Context Embedding, Reranker가 각각 다른 추론 특성과 latency 민감도를 가짐
  • 이에 따라 모델별로 최적화 경로를 분리 설계하는 것이 전체 시스템 성능 최적화의 핵심 전략임

문제 상황

  • 모든 모델을 동일한 방식(TorchScript 또는 TensorRT)으로 처리할 경우 다음과 같은 문제가 발생함:

    • 실시간 쿼리의 latency가 비일관적이며, throughput 개선이 어려움
    • TensorRT는 높은 성능을 제공하지만 복잡한 구성과 전후처리 제약이 존재
    • TorchScript는 유연하지만 latency 개선 여력이 제한적
  • 우선순위(priority), 동시성 처리, 전후처리 유무 등 요구 조건이 모델마다 상이함

구성 전략

  • Triton Inference Server의 multi-backend, ensemble, Python backend 기능을 활용하여 모델별로 최적화된 추론 경로를 구성하고 이를 병렬적으로 운영함
모델 유형 적용 방식 추론 엔진 구성 방식 특이사항
Query Embedding 실시간, 단건 TorchScript 단일 모델, Dynamic Batching 우선순위 스케줄링 적용
Context Embedding 비실시간, 고용량 TensorRT Polling 기반 독립 엔진 batching 기반 throughput 극대화
Reranker 중간 속도, 고정 입력 TensorRT 전처리 + 추론 + 후처리 ensemble Python backend 사용 필요
  • 위 구조를 통해 실시간 응답 성능, 시스템 자원 활용률, 유지보수 복잡도 간의 균형을 달성할 수 있음

도입 효과

  • 모델별 요구사항에 맞는 최적화 경로 설계 가능
  • 실시간성과 처리량을 모두 확보한 하이브리드 추론 파이프라인 구성
  • Triton이 제공하는 기능을 최대한 활용하여 코드 복잡도 최소화

5.2 Reranker 모델의 TensorRT 최적화 및 Ensemble 구조

목적

  • Cross-Encoder 기반 Reranker는 연산량이 높고, 대부분의 입력이 고정된 양식으로 구성되어 있음
  • 이처럼 연산 패턴이 일정한 모델은 TensorRT로 정적 최적화 시 latency 개선 효과가 큼
  • TorchScript 기반 서빙 구조와 비교하여 실제 latency를 단축시키는 구조를 설계하고자 함

문제 상황

  • TensorRT는 추론 전용 엔진으로 설계되어, tokenizer 처리나 postprocessing을 자체적으로 포함할 수 없음

  • Triton 상에서 TensorRT 모델을 사용하려면 다음과 같은 제약이 존재함:

    • 전처리/후처리를 별도 Python backend로 구현해야 함
    • Ensemble 내부에서는 우선순위(priority), multi-instance 정책이 동작하지 않음
    • config.pbtxt 구성과 경로 구조가 정형화되어 있어 orchestration 설계가 복잡함

해결 방안

  • 기존 HuggingFace 기반 Reranker 모델을 ONNX로 변환한 뒤, TensorRT FP16 엔진으로 빌드

  • 전체 추론 경로를 다음 세 가지 모델로 분리하여 Triton에 구성함:

    • reranker_preproc: 텍스트 토큰화 (Python backend)
    • reranker_trt: FP16 추론 수행 (TensorRT 엔진)
    • reranker_postproc: logits → sigmoid 확률로 변환 (Python backend)
  • 위 세 모델을 reranker_ensemble로 묶어 클라이언트는 단일 추론 API로 호출 가능

구현 구조

  • 전체 모델 디렉토리는 다음과 같은 구성으로 배포됨

    triton_models/
    ├── reranker_ensemble/
    │   └── config.pbtxt
    ├── reranker_preproc/
    │   ├── 1/
    │   │   └── model.py
    │   └── config.pbtxt
    ├── reranker_trt/
    │   ├── 1/
    │   │   └── model.plan
    │   └── config.pbtxt
    ├── reranker_postproc/
    │   ├── 1/
    │   │   └── model.py
    │   └── config.pbtxt
    

도커 및 엔진 빌드

  • trtexec를 활용해 TensorRT plan 파일을 빌드하고, Dockerfile로 실행 환경을 맞춤 구성

    trtexec \
      --onnx=/workspace/models/reranker_onnx/1/model.onnx \
      --saveEngine=/workspace/models/reranker_trt/1/model.plan \
      --fp16 \
      --minShapes=input_ids:1x1,attention_mask:1x1 \
      --optShapes=input_ids:16x1024,attention_mask:16x1024 \
      --maxShapes=input_ids:64x4096,attention_mask:64x4096 \
      --useCudaGraph \
      --memPoolSize=workspace:22528
    

성능 비교 결과

  • 동일한 로직을 실행했을 때 logit 차이는 거의 없으며 Reranking에서는 relative order가 핵심이므로 손실 없음.
  • 단, priority queue, multi-instance 설정이 Ensemble 내에서는 적용되지 않음

운영 측면 이슈

  • Ensemble 구조는 단일 추론 경로를 단순화해주지만, 다음과 같은 제한이 존재함:

    • 우선순위 설정이 내부 step 모델에 전파되지 않음 (ref: GitHub #3354)
    • 서브모델 간의 인스턴스 간섭을 막기 어려움
  • 따라서 Context Embedding만 TensorRT + Ensemble 구조로 운영하고, Query Embedding은 TorchScript 기반으로 유지하는 이원화 전략을 채택


5.3 Embedding 모델의 조건별 최적화 구성

목적

  • Embedding 모델은 요청의 종류(Query vs Context)에 따라 latency 민감도, 처리량 요구, 전처리 방식이 다름
  • 단일 구성으로 모든 embedding 요청을 처리할 경우 성능 trade-off 발생
  • Triton에서 지원하는 다양한 backend 및 인스턴스 구성을 활용하여 Query Embedding과 Context Embedding을 구분 서빙하고, 목적에 맞는 최적화를 적용

문제 상황

  • Query Embedding: 실시간 응답성이 중요하며, 소량 요청이 자주 발생함 → 우선순위 스케줄링과 dynamic batching이 효과적
  • Context Embedding: 대량 문서 벡터화를 지속적으로 처리해야 함 → batch-oriented, polling 기반 구조로 throughput 최적화가 필요
  • Ensemble을 사용할 경우 priority, instance 분리 등의 고급 기능이 제한됨 → 실제 운영에서 스케줄링 전략 적용이 어려움

해결 방안

  • Query Embedding은 TorchScript 모델로 유지하고, Triton의 priority_levelinstance_group을 활용해서 우선순위 모델로 분리 구성
  • Context Embedding은 TensorRT 엔진으로 변환 후 별도 polling 작업자로 운영 → trtexec로 빌드된 FP16 plan 파일을 단일 추론 엔진으로 구성
  • Query Embedding은 Ensemble 구조 미사용. 대신 독립된 모델 단위 배포로 스케줄링 정책을 효과적으로 적용

구현 구조

  • Query 모델: 단일 TorchScript (.pt) 기반 추론 모델
  • Context 모델: ONNX → TensorRT로 빌드된 추론 전용 엔진
  • Triton config에서 각각의 모델은 서로 다른 GPU 혹은 instance group으로 분리되어 배포됨

성능 비교 결과

Triton Scheduler & Multi Instance를 활용해 query embedding의 동시 처리량과 latency 개선 Context Embedding Latency (left: TensorRT Engine, right: TorchScript Engine)

  • Context Embedding의 경우 polling 기반 처리에서도 TorchScript 대비 약 30% latency 단축 효과가 확인됨
  • Query Embedding은 TorchScript 구성 상태로 유지하되, Triton config 내에서 priority: 1, instance_group.count: 5 등의 설정을 통해 실시간 추론 안정성 확보

운영 측면 고려사항

  • Ensemble을 사용하면 내부 step 모델에 priority/multi-instance 설정이 전파되지 않음 → Triton 내부 철학상 ensemble은 논리적 연결 구조로만 인식됨 (ref: GitHub Issue #3354)
  • 따라서 실제 운영에서는 Ensemble을 피하고 모델 간 병렬 배포 및 스케줄링 전략을 분리 설계해야 함

5.4 Docker 및 배포 전략

목적

  • Triton Inference Server는 NVIDIA에서 제공하는 Docker 이미지를 기반으로 동작함
  • 모델별 구성, 실행 환경, 의존성 버전 등을 일관되게 유지하기 위해 컨테이너 기반 배포 전략이 필수적
  • 특히 Python backend 및 TensorRT plan 기반 모델을 함께 구성하는 경우, 사용자 정의 Dockerfile을 활용한 환경 통합이 필요

문제 상황

  • 기본 제공 이미지(nvcr.io/nvidia/tritonserver:xx.yy-py3)는 PyTorch, ONNX 등은 포함하지만 Python backend 실행을 위한 사용자 패키지, tokenizer, onnxruntime 등은 포함되어 있지 않음
  • TensorRT plan 파일은 별도로 빌드되어야 하며, 이를 Triton container에 mount하는 구조가 필요함

해결 방안

  • 사용자 정의 Dockerfile을 통해 필요한 패키지 및 Python 환경을 사전 구성
  • 모델 저장소(/models)를 볼륨 마운트하고, Triton은 해당 경로를 기준으로 모델을 관리
  • Python backend를 사용할 경우, triton_python_backend_utils, transformers, torch, numpy 등의 패키지를 사전 설치

도커 환경 구성

  • 기본 베이스 이미지: nvcr.io/nvidia/tritonserver:25.03-py3

  • 필요한 라이브러리 및 tokenizer 설치

    FROM nvcr.io/nvidia/tritonserver:25.03-py3
    
    RUN pip install torch \
        transformers \
        onnx \
        onnxruntime \
        sentencepiece \
        numpy \
        tritonclient \
        protobuf
    

실행 명령어

  • Triton 실행 시 --model-repository=/models 옵션을 통해 모델 경로 설정

  • REST/gRPC/metrics 포트 지정, GPU 자원 마운트, 로컬 디스크 볼륨 연결

    docker run --rm --gpus all \
      -p8000:8000 -p8001:8001 -p8002:8002 \
      -v /home/ubuntu/triton/triton_models:/models \
      tritonserver:custom \
      tritonserver --model-repository=/models
    

모델 경로 구조 및 배포

  • /models 디렉토리 하위에 각 모델별 디렉토리를 구성

  • Python backend는 model.py, TensorRT는 model.plan, TorchScript는 model.pt 기반으로 동작

    triton_models/
    ├── qry_embedding_ts/
    │   ├── 1/
    │   │   └── model.pt
    │   └── config.pbtxt
    ├── ctx_embedding_trt/
    │   ├── 1/
    │   │   └── model.plan
    │   └── config.pbtxt
    ├── reranker_preproc/
    │   ├── 1/
    │   │   └── model.py
    │   └── config.pbtxt
    ├── reranker_postproc/
    │   ├── 1/
    │   │   └── model.py
    │   └── config.pbtxt
    ├── reranker_trt/
    │   ├── 1/
    │   │   └── model.plan
    │   └── config.pbtxt
    ├── reranker_ensemble/
    │   └── config.pbtxt
    

운영 전략

  • 로컬 테스트 환경에서는 docker run 명령어로 수동 실행
  • 운영 환경에서는 Kubernetes 혹은 Docker Compose 기반 자동 재시작, 롤링 배포 구성 가능
  • GPU 자원은 --gpus all 또는 --device 옵션으로 세분화하여 제어 가능
  • Prometheus scrape, health check API(/v2/health/ready) 기반 로드밸런서 연동 가능

6. 결론

Triton Inference Server는 다양한 딥러닝 모델을 하나의 플랫폼에서 서빙할 수 있도록 설계된 고성능 추론 인프라로, 실시간성, 처리량, 확장성 측면에서 우수한 특성을 보여줌. 특히 multi-backend 지원, dynamic batching, priority queueing, ensemble pipeline 등 다양한 기능을 통해 모델별 특성과 자원 요구에 맞춘 유연한 추론 경로 구성이 가능.

핵심 사항:

  • 딥러닝 서빙은 단순한 모델 호출을 넘어, 프레임워크 통합, 자원 효율화, latency 제어, 운영 자동화 등을 종합적으로 고려해야 하는 시스템 설계 문제.
  • Triton은 다양한 모델 포맷을 통합하고, 모델별 실행 스케줄링동시성 제어를 지원하여 추론 효율성을 크게 향상.
  • 실시간성이 중요한 Query Embedding에는 TorchScript 기반 모델을 우선순위 큐와 함께 구성하고, 고연산량 Context Embedding은 TensorRT 기반 batch-oriented 구조로 분리해 운영하는 것이 효과적.
  • Reranker 모델은 전처리, 추론, 후처리를 ensemble 구성으로 연결할 수 있으며, TensorRT 엔진을 활용해 latency를 대폭 단축할 수 있음.
  • Python backend는 tokenizer, 후처리 함수, LLM 래퍼 등 유연한 로직 구성이 필요한 구성에 적합하며, Triton과의 결합으로 다양한 확장성을 제공.
  • Ensemble 구조는 추론 경로를 단순화할 수 있지만, 내부 서브모델에는 priority 및 multi-instance 설정이 적용되지 않기 때문에 실시간 모델에는 독립 구성 방식이 권장.
  • Docker 및 Kubernetes 환경에서 Triton은 표준화된 배포 구성을 제공하며, Helm chart, REST/gRPC API, Prometheus 기반 모니터링 등 다양한 운영 도구와 쉽게 통합.

Triton Inference Server는 학습된 모델을 실제 서비스에 안정적으로 연결하기 위한 서빙 인프라의 실질적인 해법으로, 대규모 AI 시스템의 추론 성능을 극대화하고 운영 복잡도를 낮추는 데 강력한 역할을 할 수 있음.