딥러닝 모델의 성능을 최적화하고 배포하는 것은 현대 AI 애플리케이션의 핵심 요소 중 하나입니다. 그 중에서도 모델을 효율적으로 관리하고 운영하는 것은 매우 중요합니다. Triton Inference Server는 이러한 요구에 부응하기 위해 설계된 강력한 도구입니다. 이번 시리즈에서는 Triton Inference Server에 대해 샅샅히 파헤처보는 글을 작성해보려고 합니다.
지난 포스트 다시보기
Model Management
Triton Inference Server는 모델 관리를 위한 API를 제공하며, 이 API는 HTTP/REST 및 GRPC 프로토콜, 그리고 C API의 일부로 구성되어 있습니다. 이러한 API는 사용자가 모델을 관리하고 상호작용하는 방식에 중요한 역할을 합니다. 각 프로토콜은 특정 기능과 사용 용도에 맞춰 설계되어 서로 다른 사용자 요구를 충족시킬 수 있습니다.
Model Control Mode
Triton은 세 가지 모델 제어 모드(NONE, EXPLICIT, POLL) 중 하나에서 운영됩니다. 이 모드는 Triton이 모델 리포지토리의 변경사항을 어떻게 처리할지 결정하며, 사용 가능한 프로토콜과 API의 종류를 결정합니다. 각 모드는 다음과 같은 특성을 가지고 있습니다
NONE 모드: 이 모드에서는 모델 변경사항이 자동으로 감지되지 않습니다. 사용자는 모델 업데이트를 수동으로 관리해야 합니다.
EXPLICIT 모드: 사용자가 명시적으로 모델 업데이트를 요청할 때만 모델 변경이 이루어집니다. 이는 특정 조건 하에서 모델을 업데이트하거나 특별한 요구가 있을 때 유용합니다.
POLL 모드: Triton이 정기적으로 리포지토리를 체크하여 변경사항을 자동으로 감지하고 적용합니다. 이 모드는 지속적인 업데이트가 필요한 환경에서 이점을 제공합니다.
Model Control Mode NONE
Triton Inference Server는 NONE 모드에서 서버를 시작할 때 모델 리포지토리에 있는 모든 모델을 로드하려고 시도합니다. 이때 로드에 실패한 모델들은 'UNAVAILABLE'로 표시되며, 이러한 모델들은 추론(inferencing)을 위해 사용할 수 없습니다. 이 절차는 서버의 초기 구성 시 중요한 검증 단계를 제공하며, 어떤 모델이 즉시 사용 가능한지를 판단하는 데 도움을 줍니다.
서버가 운영 중일 때, 모델 리포지토리에 가해지는 변경사항은 모두 무시됩니다. 이는 NONE 모드가 주로 안정적인 환경에서 모델의 변경 없이 서비스를 지속적으로 제공하고자 할 때 선택됩니다. 따라서, 모델을 로드하거나 언로드하는 요청은 모델 제어 프로토콜을 사용하여도 아무런 효과가 없으며, 오류 응답을 반환하게 됩니다.
이 모델 제어 모드는 Triton을 시작할 때 --model-control-mode=none 옵션을 지정함으로써 선택할 수 있으며, 이는 기본 설정값입니다. Triton이 운영 중일 때 모델 리포지토리를 변경하는 것은 'Modifying the Model Repository' 섹션(아래에서 설명)에서 설명된 바와 같이 신중하게 이루어져야 합니다. 이 모드는 특히 서버의 운영 중단 없이 연속적인 서비스가 요구되는 환경에서 유리하며, 운영 중인 모델의 안정성을 보장하는 데 중점을 둡니다.
이러한 관리 방식은 시스템 관리자가 서버의 운영 상태를 철저히 통제하고, 예기치 않은 오류로부터 서비스의 연속성을 유지하는 데 도움을 줍니다. 하지만 모델의 업데이트가 필요한 경우, 서버를 재시작하는 등의 추가적인 조치가 필요할 수 있습니다, 이는 운영 중인 시스템에 중대한 영향을 줄 수 있으므로, 계획에 따라 체계적으로 관리되어야 합니다.
Model Control Mode EXPLICIT
Triton Inference Server는 EXPLICIT 모드에서 서버가 시작될 때 --load-model 명령줄 옵션으로 명시적으로 지정된 모델들만 로드합니다. 시작 시 모든 모델을 로드하려면, --load-model=*를 유일한 --load-model 인수로 지정해야 합니다. --load-model=*를 다른 --load-model 인수와 함께 지정하면 오류가 발생합니다. 만약 --load-model이 지정되지 않으면 시작 시 아무런 모델도 로드되지 않습니다. 로드할 수 없는 모델은 'UNAVAILABLE'로 표시되며 추론을 위해 사용할 수 없게 됩니다.
서버가 시작된 후, 모든 모델 로드 및 언로드 작업은 모델 제어 프로토콜을 사용하여 명시적으로 시작해야 합니다. 모델 제어 요청의 응답 상태는 로드 또는 언로드 작업의 성공 또는 실패를 나타냅니다. 이미 로드된 모델을 다시 로드하려고 시도할 때, 리로드가 어떤 이유로든 실패하면 이미 로드된 모델은 변경되지 않고 로드 상태를 유지합니다. 리로드가 성공하면, 새로 로드된 모델이 기존 모델을 대체하며, 모델의 가용성에 아무런 손실이 없습니다.
EXPLICIT 모드는 --model-control-mode=explicit를 지정하여 활성화됩니다. 모델 리포지토리를 변경하는 작업은 Triton이 실행 중일 때 신중하게 수행되어야 하며, 'Modifying the Model Repository' 섹션(아래에서 설명)에서 설명한 바와 같습니다. 모델 제어 프로토콜을 사용하여 모델을 로드하고 언로드할 때 일부 메모리 증가이 관찰된다면, 이는 실제 메모리 누수가 아닌 시스템의 malloc 휴리스틱 때문일 수 있습니다. 이는 메모리가 즉시 운영체제로 반환되지 않을 수 있습니다. 메모리 성능을 개선하기 위해, Triton을 실행할 때 LD_PRELOAD 환경 변수를 설정하여 malloc 대신 tcmalloc 또는 jemalloc으로 전환할 수 있습니다. 아래와 같이 설정합니다:
# Using tcmalloc
LD_PRELOAD=/usr/lib/$(uname -m)-linux-gnu/libtcmalloc.so.4:${LD_PRELOAD} tritonserver --model-repository=/models ...
# Using jemalloc
LD_PRELOAD=/usr/lib/$(uname -m)-linux-gnu/libjemalloc.so:${LD_PRELOAD} tritonserver --model-repository=/models ...
tcmalloc과 jemalloc을 실험하여 사용 사례에 더 잘 맞는 것을 결정하는 것이 좋습니다. 이 두 라이브러리는 메모리 할당 및 해제 전략이 다르며, 작업 부하에 따라 성능이 다를 수 있습니다. tcmalloc과 jemalloc 라이브러리는 이미 Triton 컨테이너 내에 설치되어 있지만, 필요한 경우 다음 명령을 사용하여 설치할 수 있습니다.
# Install tcmalloc
apt-get install gperf libgoogle-perftools-dev
# Install jemalloc
apt-get install libjemalloc-dev
Model Control Mode POLL
Triton Inference Server는 POLL 모드에서 시작 시 모델 리포지토리의 모든 모델을 로드하려 시도합니다. 로드할 수 없는 모델은 'UNAVAILABLE'로 표시되며, 이러한 모델은 추론을 위해 사용할 수 없습니다.
모델 리포지토리에 발생한 변경사항은 Triton에 의해 감지되며, 필요에 따라 모델을 로드하거나 언로드합니다. 이미 로드된 모델을 리로드하려고 할 때, 리로드가 실패하면 기존 모델은 변하지 않고 로드된 상태를 유지합니다. 리로드가 성공하면, 새로 로드된 모델이 기존 모델을 대체하며, 모델의 가용성에 손실이 없습니다.
모델 리포지토리 변경사항은 Triton이 레포지토리를 주기적으로 폴링하기 때문에 즉시 감지되지 않을 수 있습니다. 폴링 간격은 --repository-poll-secs 옵션을 통해 조정할 수 있습니다. 모델 리포지토리 변경이 적용되었는지 확인하기 위해 콘솔 로그, 모델 준비 프로토콜 또는 모델 제어 프로토콜의 인덱스 작업을 사용할 수 있습니다. 특히, Triton이 모델 레포지토리를 폴링하는 시간과 리포지토리를 변경하는 시간 사이에는 동기화가 없습니다. 이로 인해 부분적이고 불완전한 변경사항이 감지되어 예상치 못한 동작을 초래할 수 있으므로, POLL 모드는 프로덕션 환경에서 사용하는 것이 권장되지 않습니다.
POLL 모드에서의 모델 리포지토리 변경 반응은 다음과 같습니다.
- 모델 버전 추가 및 제거: 모델의 해당 버전 하위 디렉토리를 추가하거나 제거함으로써 이루어집니다. Triton은 사용 중인 모델 버전이 제거되더라도 진행 중인 요청을 완료할 수 있습니다. 제거된 모델 버전에 대한 새 요청은 실패합니다.
- 기존 모델 제거: 해당 모델 디렉토리를 제거함으로써 이루어집니다. 제거된 모델의 어떤 버전에 대한 진행 중인 요청도 완료할 수 있습니다. 제거된 모델에 대한 새 요청은 실패합니다.
- 새 모델 추가: 새 모델 디렉토리를 추가함으로써 이루어집니다.
- 모델 구성 파일 변경: config.pbtxt 파일을 변경하면 Triton이 모델을 언로드하고 새 모델 구성을 반영하기 위해 다시 로드합니다.
- 레이블 파일 변경: 출력을 분류로 표현하는 레이블 파일을 추가, 제거하거나 수정할 수 있으며, Triton은 새 레이블을 반영하기 위해 모델을 언로드하고 다시 로드합니다. 레이블 파일이 추가되거나 제거될 때는 모델 구성의 해당 출력의 label_filename 속성을 동시에 수정해야 합니다.
이러한 변경 관리 방식은 Triton 서버가 다이나믹하게 모델 업데이트를 반영할 수 있도록 하며, 시스템의 유연성을 증가시키지만, 관리가 복잡해지고 주의 깊은 조작이 필요함을 유의해야 합니다.
Model Repository
Triton Inference Server는 서버 시작 시 지정된 하나 이상의 모델 레포지토리에서 모델을 제공합니다. Triton이 실행되는 동안에는 위의 'Model Management'에 설명된 대로 제공되는 모델을 수정할 수 있습니다.
Repository Layout
이 모델 레포지토리 경로는 Triton이 시작될 때 '--model-repository' 옵션을 사용하여 지정됩니다. '--model-repository' 옵션은 여러 레포지토리에서 모델을 포함하기 위해 여러 번 지정될 수 있습니다. 모델 레포지토리를 구성하는 디렉토리와 파일은 필수 레이아웃을 따라야 합니다. 레포지토리 경로는 다음과 같이 지정합니다.
$ tritonserver --model-repository=<model-repository-path>
해당 레포지토리 레이아웃은 다음과 같아야 합니다:
<model-repository-path>/
<model-name>/
[config.pbtxt]
[<output-labels-file> ...]
<version>/
<model-definition-file>
<version>/
<model-definition-file>
...
<model-name>/
[config.pbtxt]
[<output-labels-file> ...]
<version>/
<model-definition-file>
<version>/
<model-definition-file>
...
...
최상위 모델 레포지토리 디렉토리에는 하나 이상의 하위 디렉토리가 있어야 합니다. 각 하위 디렉토리에는 해당 모델에 대한 레포지토리 정보가 포함되어 있습니다.
config.pbtxt 파일은 모델의 구성을 설명합니다. 일부 모델의 경우 config.pbtxt 파일이 필요하며, 다른 모델의 경우 선택 사항입니다. 이러한 config.pbtxt는 Auto-generated Model Configuration으로 자동으로 생성할 수도 있습니다.
각 디렉토리에는 모델의 버전을 나타내는 하나 이상의 숫자 하위 디렉토리가 있어야 합니다. 각 모델은 특정 백엔드에서 실행됩니다. 각 버전의 하위 디렉토리에는 해당 백엔드에서 요구하는 파일이 있어야 합니다. 예를 들어, TensorRT, PyTorch, ONNX, OpenVINO 및 TensorFlow와 같은 프레임워크 백엔드를 사용하는 모델은 프레임워크별 모델 파일을 제공해야 합니다.
Model Repository Locations
Triton은 Local File System, Google Cloud Storage, Amazon S3, 그리고 Azure Storage를 통해 모델에 접근할 수 있습니다.
Local File System
로컬 파일 시스템에 접근하기 위해서는 절대 경로를 명시해야 합니다.
$ tritonserver --model-repository=/path/to/model/repository ...
Google Cloud Storage
Google Cloud Storage에 위치한 모델 레포지토리의 경우, 레포지토리 경로는 'gs://'로 시작해야 합니다.
$ tritonserver --model-repository=gs://bucket/path/to/model/repository ...
기본적으로 Triton은 원격 모델 레포지토리의 사본을 임시 폴더에 로컬로 만들며, 이는 Triton 서버가 종료되면 삭제됩니다. 원격 모델 레포지토리의 사본을 특정 위치에 복사하고자 한다면, TRITON_GCS_MOUNT_DIRECTORY 환경 변수를 로컬 머신에 있는 기존 폴더를 가리키는 경로로 설정할 수 있습니다. TRITON_GCS_MOUNT_DIRECTORY가 로컬 머신에 존재하고 비어 있어야 합니다.
export TRITON_GCS_MOUNT_DIRECTORY=/path/to/your/local/directory
S3
Amazon S3에 위치한 모델 레포지토리의 경우, 경로는 's3://'로 시작해야 합니다.
$ tritonserver --model-repository=s3://bucket/path/to/model/repository ...
로컬 또는 프라이빗 S3 인스턴스의 경우, 's3://' 접두어 다음에는 호스트와 포트(세미콜론으로 구분)가 이어지고, 그 다음으로 버킷 경로가 명시되어야 합니다.
$ tritonserver --model-repository=s3://host:port/bucket/path/to/model/repository ...
기본적으로 Triton은 S3 인스턴스와 통신하기 위해 HTTP를 사용합니다. 만약 S3 인스턴스가 HTTPS를 지원하고 HTTPS 프로토콜을 사용하기 원한다면, 모델 레포지토리 경로에 호스트 이름 앞에 'https://'를 추가하여 지정할 수 있습니다.
$ tritonserver --model-repository=s3://https://host:port/bucket/path/to/model/repository ...
S3를 사용할 때, 인증 정보와 기본 리전은 aws config 명령을 사용하거나 해당 환경 변수를 통해 전달할 수 있습니다. 환경 변수가 설정되어 있다면, 이들이 우선 순위를 가지고 aws config 명령을 통해 설정된 인증 정보 대신 사용됩니다.
TRITON_AWS_MOUNT_DIRECTORY 환경 변수를 설정하여 원격 모델 레포지토리의 사본이 복사될 경로를 지정할 수 있으며, 이 폴더는 로컬 머신에 존재하고 비어 있어야 합니다.
export TRITON_AWS_MOUNT_DIRECTORY=/path/to/your/local/directory
Azure Storage
Azure Storage에 위치한 모델 레포지토리의 경우, 경로는 'as://'로 시작해야 합니다.
$ tritonserver --model-repository=as://account_name/container_name/path/to/model/repository ...
Azure Storage를 사용할 때는 AZURE_STORAGE_ACCOUNT과 AZURE_STORAGE_KEY 환경 변수를 설정해야 하며, 이는 Azure Storage 저장소에 접근 권한이 있는 계정을 가리켜야 합니다.
AZURE_STORAGE_KEY를 모르고 Azure CLI가 올바르게 설정되어 있다면, AZURE_STORAGE_ACCOUNT에 해당하는 키를 찾는 방법의 예시를 찾을 수 있습니다.
$ export AZURE_STORAGE_ACCOUNT="account_name"
$ export AZURE_STORAGE_KEY=$(az storage account keys list -n $AZURE_STORAGE_ACCOUNT --query "[0].value")
TRITON_AZURE_MOUNT_DIRECTORY 환경 변수를 설정하여 원격 모델 레포지토리의 사본이 복사될 경로를 지정할 수 있으며, 이 폴더는 로컬 머신에 존재하고 비어 있어야 합니다.
export TRITON_AZURE_MOUNT_DIRECTORY=/path/to/your/local/directory
Model Files
각 모델 버전의 하위 디렉토리 내용은 모델의 유형과 해당 모델을 지원하는 백엔드의 요구사항에 의해 결정됩니다.
TensorRT Models
TensorRT 모델 정의는 Plan이라고 불립니다. TensorRT Plan은 기본적으로 model.plan이라는 이름의 단일 파일입니다. 이 기본 이름은 모델 구성의 default_model_filename 속성을 사용하여 변경할 수 있습니다.
TensorRT Plan은 GPU의 CUDA Compute Capability에 특화되어 있습니다. 결과적으로, TensorRT 모델은 모델 구성에서 cc_model_filenames 속성을 설정하여 각 Plan 파일을 해당 Compute Capability와 연결해야 합니다.
TensorRT 모델에 대한 최소한의 모델 레포지토리는 다음과 같습니다:
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.plan
ONNX Models
ONNX 모델은 단일 파일 또는 여러 파일이 포함된 디렉토리일 수 있습니다. 기본적으로 파일 또는 디렉토리는 model.onnx라는 이름이어야 하며, 이는 모델 구성의 default_model_filename 속성을 사용하여 변경할 수 있습니다.
Triton은 Triton에서 사용 중인 ONNX Runtime 버전에서 지원하는 모든 ONNX 모델을 지원합니다. 구식 ONNX opset 버전을 사용하거나 지원되지 않는 유형의 연산자를 포함하는 모델은 지원되지 않습니다.
단일 파일에 포함된 ONNX 모델을 위한 최소한의 모델 레포지토리는 다음과 같습니다:
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.onnx
여러 파일로 구성된 ONNX 모델은 디렉토리에 포함되어야 합니다. 기본적으로 이 디렉토리는 model.onnx라는 이름이어야 하지만 모델 구성의 default_model_filename 속성을 사용하여 변경할 수 있습니다. 이 디렉토리 내의 주 모델 파일은 model.onnx라고 명명되어야 합니다. 디렉토리에 포함된 ONNX 모델을 위한 최소한의 모델 레포지토리는 다음과 같습니다:
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.onnx/
model.onnx
<other model files>
TorchScript Models
TorchScript 모델은 기본적으로 model.pt라는 이름의 단일 파일입니다. 이 기본 이름은 모델 구성의 default_model_filename 속성을 사용하여 변경할 수 있습니다. PyTorch의 다른 버전으로 추적된 일부 모델은 기본 opset의 변경으로 인해 Triton에서 지원되지 않을 수 있습니다.
TorchScript 모델을 위한 최소한의 모델 레포지토리는 다음과 같습니다:
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.pt
TensorFlow Models
TensorFlow는 모델을 GraphDef 또는 SavedModel 두 가지 형식으로 저장합니다. Triton은 두 형식 모두를 지원합니다.
TensorFlow GraphDef는 기본적으로 model.graphdef라는 이름의 단일 파일입니다. TensorFlow SavedModel은 여러 파일이 포함된 디렉토리입니다. 기본적으로 디렉토리는 model.savedmodel이라는 이름이어야 합니다. 이 기본 이름은 모델 구성의 default_model_filename 속성을 사용하여 변경할 수 있습니다.
TensorFlow GraphDef 모델을 위한 최소한의 모델 레포지토리는 다음과 같습니다:
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.graphdef
TensorFlow SavedModel 모델을 위한 최소한의 모델 레포지토리는 다음과 같습니다:
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.savedmodel/
<saved-model files>
OpenVINO Models
OpenVINO 모델은 .xml 파일과 .bin 파일 두 개로 표현됩니다. 기본적으로 .xml 파일은 model.xml이라는 이름이어야 하며, 이 기본 이름은 모델 구성의 default_model_filename 속성을 사용하여 변경할 수 있습니다.
OpenVINO 모델을 위한 최소한의 모델 레포지토리는 다음과 같습니다:
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.xml
model.bin
Python Models
Python 백엔드를 통해 Triton 내에서 Python 코드를 모델로 실행할 수 있습니다. 기본적으로 Python 스크립트는 model.py라는 이름이어야 하지만, 이 기본 이름은 모델 구성의 default_model_filename 속성을 사용하여 변경할 수 있습니다.
Python 모델을 위한 최소한의 모델 레포지토리는 다음과 같습니다:
<model-repository-path>/
<model-name>/
config.pbtxt
1/
model.py
'AI > MLOps' 카테고리의 다른 글
LitServe 리뷰 (1) | 2024.08.31 |
---|---|
Triton Inference Server #5. Python Backend (0) | 2024.05.12 |
Triton Inference Server #4. Model Configuration (0) | 2024.05.12 |
Triton Inference Server #2. 모델 스케쥴링 (0) | 2024.04.23 |
Triton Inference Server #1. Triton Inference Server란? (0) | 2024.04.22 |