python-backend
Python 백엔드
Python 백엔드의 목표는 C++ 코드를 한 줄도 쓰지 않고, Python으로 작성한 모델을 Triton Inference Server로 서빙하게 만드는 거예요. 전처리·후처리 코드든, PyTorch 같은 프레임워크를 직접 부르는 모델이든, Python으로 짠 로직을 그대로 Triton 위에서 돌릴 수 있게 해 주는 백엔드예요.
이 문서는 Python 백엔드의 핵심 사용법을 강사 목소리로 정리한 거예요. 코드 블록과 정확한 값은 원문을 그대로 보존했고, 전체 내용은 공식 문서에서 확인할 수 있어요.
Quick Start
Triton Inference Server 컨테이너를 실행해요. <xx.yy>를 Triton 버전(예: 21.05)으로 바꿔요.
docker run --shm-size=1g --ulimit memlock=-1 -p 8000:8000 -p 8001:8001 -p 8002:8002 --ulimit stack=67108864 -ti nvcr.io/nvidia/tritonserver:<xx.yy>-py3
컨테이너 안에서 Python 백엔드 저장소를 clone하고 예제 모델을 설치해요.
git clone https://github.com/triton-inference-server/python_backend -b r<xx.yy>
cd python_backend
mkdir -p models/add_sub/1/
cp examples/add_sub/model.py models/add_sub/1/model.py
cp examples/add_sub/config.pbtxt models/add_sub/config.pbtxt
tritonserver --model-repository=`pwd`/models
호스트에서 클라이언트 컨테이너를 띄우고 예제 클라이언트를 실행해요.
docker run -ti --net host nvcr.io/nvidia/tritonserver:<xx.yy>-py3-sdk /bin/bash
git clone https://github.com/triton-inference-server/python_backend -b r<xx.yy>
python3 python_backend/examples/add_sub/client.py
사용법 (Usage)
Python 백엔드를 쓰려면 아래와 같은 구조의 Python 파일을 만들어야 해요.
import triton_python_backend_utils as pb_utils
class TritonPythonModel:
"""Your Python model must use the same class name. Every Python model
that is created must have "TritonPythonModel" as the class name.
"""
@staticmethod
def auto_complete_config(auto_complete_model_config):
"""`auto_complete_config` is called only once when loading the model
assuming the server was not started with
`--disable-auto-complete-config`. Implementing this function is
optional. No implementation of `auto_complete_config` will do nothing.
"""
inputs = [{
'name': 'INPUT0',
'data_type': 'TYPE_FP32',
'dims': [4],
'optional': True
}, {
'name': 'INPUT1',
'data_type': 'TYPE_FP32',
'dims': [4]
}]
outputs = [{
'name': 'OUTPUT0',
'data_type': 'TYPE_FP32',
'dims': [4]
}, {
'name': 'OUTPUT1',
'data_type': 'TYPE_FP32',
'dims': [4]
}]
config = auto_complete_model_config.as_dict()
input_names = []
output_names = []
for input in config['input']:
input_names.append(input['name'])
for output in config['output']:
output_names.append(output['name'])
for input in inputs:
if input['name'] not in input_names:
auto_complete_model_config.add_input(input)
for output in outputs:
if output['name'] not in output_names:
auto_complete_model_config.add_output(output)
auto_complete_model_config.set_max_batch_size(0)
return auto_complete_model_config
def initialize(self, args):
"""`initialize` is called only once when the model is being loaded."""
print('Initialized...')
def execute(self, requests):
"""`execute` must be implemented in every Python model."""
responses = []
for request in requests:
# Perform inference on the request and append it to responses
pass
return responses
def finalize(self):
"""`finalize` is called only once when the model is being unloaded."""
print('Cleaning up...')
def is_ready(self):
return True
핵심 포인트를 짚어볼게요.
- 모델 클래스 이름은 반드시 **
TritonPythonModel**이어야 해요. 모든 Python 모델이 이 이름을 써야 해요. execute는 반드시 구현해야 해요.auto_complete_config,initialize,finalize,is_ready는 선택이에요.execute는pb_utils.InferenceRequest리스트를 받아, 각 요청에 대응하는pb_utils.InferenceResponse리스트를 반환해요. 응답 리스트 길이는 요청 리스트 길이와 같아야 해요.- 여러 요청에 같은
pb_utils.InferenceResponse객체를 재사용하면 세그멘테이션 오류가 날 수 있어요. 입력 Tensor를 클래스 속성에 저장하지 말고, 필요하면 NumPy 배열을 복사해서 저장해요.
auto_complete_config
서버가 --disable-auto-complete-config로 시작하지 않았다면, 모델 로드 시 딱 한 번 호출돼요. 구현은 선택이에요. 이 함수로 set_max_batch_size, set_dynamic_batching, add_input, add_output, set_model_transaction_policy를 써서 모델의 max_batch_size, dynamic_batching, input, output 속성을 정할 수 있어요. 이 속성들이 있으면 구성 파일 없이도 최소 모델 구성으로 로드할 수 있어요. 이 함수가 반환한 pb_utils.ModelConfig 객체가 모델의 최종 구성으로 쓰여요.
주의: 이 함수를 호출하는 Python 인터프리터는 함수 반환 시 파괴돼요. 그래서 여기서 만든 객체는
initialize,execute,finalize에서 사용할 수 없어요.
initialize
모델이 로드될 때 한 번 호출돼요. 구현은 선택이에요. args는 Python 딕셔너리로, 키와 값 모두 문자열이에요.
| key | 설명 |
|---|---|
model_config |
모델 구성을 담은 JSON 문자열 |
model_instance_kind |
모델 인스턴스 종류를 담은 문자열 |
model_instance_device_id |
모델 인스턴스 장치 ID를 담은 문자열 |
model_repository |
모델 저장소 경로 |
model_version |
모델 버전 |
model_name |
모델 이름 |
execute
추론 요청이 있을 때마다 호출되며, 모든 Python 모델이 반드시 구현해야 해요. 두 가지 구현 모드가 있어요: Default Mode와 Decoupled Mode.
Default Mode
가장 일반적인 방식으로, 요청 하나당 정확히 하나의 응답을 반환해야 해요.
execute함수가 길이 N 배열(pb_utils.InferenceRequest배치)을 받아요.- 각 요청에 대해 추론을 수행하고 대응하는
pb_utils.InferenceResponse를 응답 리스트에 추가해요. - 응답 리스트를 반환해요. 길이는 반드시 N이어야 해요.
- 리스트의 각 원소는 대응하는 요청의 응답이어야 하며, 텐서든 오류든 하나의 응답을 담아야 해요 (
None이면 안 돼요).
이 요구사항이 만족되지 않으면 Triton은 모든 추론 요청에 오류 응답을 반환해요. execute에서 반환될 때 전달된 모든 요청의 텐서 데이터는 삭제되므로, Python 모델이 InferenceRequest 객체를 붙잡고 있으면 안 돼요.
24.06부터 RequestCancellation처럼 Decoupled mode에서 설명하는 InferenceResponseSender로 응답을 보낼 수도 있어요. 다만 Default mode이므로 요청당 정확히 하나의 응답을 보내야 하고, pb_utils.TRITONSERVER_RESPONSE_COMPLETE_FINAL 플래그를 응답과 함께 보내야 해요.
오류 처리 — 요청 중 하나에 오류가 있으면 TritonError 객체로 그 요청의 오류 메시지를 설정할 수 있어요.
responses.append(pb_utils.InferenceResponse(
error=pb_utils.TritonError("An Error Occurred")))
23.09부터 두 번째 파라미터로 Triton 오류 코드를 지정할 수 있어요. 지정하지 않으면 pb_utils.TritonError.INTERNAL이 기본으로 쓰여요. 지원되는 코드: UNKNOWN, INTERNAL, NOT_FOUND, INVALID_ARG, UNAVAILABLE, UNSUPPORTED, ALREADY_EXISTS, CANCELLED(23.10부터).
요청 취소 처리 — 23.10부터 request.is_cancelled()로 요청이 취소됐는지 확인할 수 있어요. 취소 확인은 선택이지만, 응답이 더 이상 필요 없을 때 실행을 일찍 끝낼 수 있는 전략적 실행 지점에서 확인하는 걸 권해요.
Decoupled mode
이 모드는 요청 하나에 여러 응답을 보내거나 아예 응답을 안 보낼 수도 있고, 요청 배치가 실행된 순서와 다르게 응답을 보낼 수도 있어요. 이런 모델을 decoupled model이라고 해요. 이 모드를 쓰려면 모델 구성에서 transaction policy를 decoupled로 설정해야 해요.
Decoupled 모드에서 모델은 요청마다 InferenceResponseSender 객체를 사용해 원하는 만큼 응답을 만들고 보내요.
execute가 길이 N 배열을 받아요.- 각 요청에 대해
InferenceRequest.get_response_sender()로InferenceResponseSender를 얻어요. - 보낼
pb_utils.InferenceResponse를 만들고 채워요. InferenceResponseSender.send()로 응답을 보내요. 마지막 요청이면pb_utils.TRITONSERVER_RESPONSE_COMPLETE_FINAL플래그를 함께 전달해요.- 이 모드의
execute반환값은None이어야 해요.
응답 안 보내고 싶으면 응답 없이 flag만 TRITONSERVER_RESPONSE_COMPLETE_FINAL로 해서 send()를 호출하면 돼요. 요청 데이터와 InferenceResponseSender 객체를 모델의 별도 스레드에 넘길 수도 있어서, 메인 호출 스레드가 execute에서 빠져나와도 sender 객체를 들고 있으면 계속 응답을 생성할 수 있어요. 23.10부터는 response_sender.is_cancelled()로 sender에서 직접 취소를 확인할 수 있고, 취소돼도 마지막에 TRITONSERVER_RESPONSE_COMPLETE_FINAL을 보내야 해요.
비동기 execute — 24.04부터 decoupled Python 모델에서 async def execute(self, requests)를 지원해요. 그 코루틴은 같은 모델 인스턴스의 요청들과 공유하는 AsyncIO 이벤트 루프에서 실행돼요. 현재 요청이 기다리는 동안 다음 요청이 실행을 시작할 수 있으므로, 대부분 시간을 기다리며 보내는 모델의 인스턴스 수를 최소화할 때 유용해요. 단, async execute가 대기(예: 네트워크 다운로드) 중 이벤트 루프를 막지 않도록 하는 게 중요해요. 실행 중인 이벤트 루프를 모델이 수정하면 안 되고, 모델 인스턴스가 이벤트 루프에 추가하는 요청 수를 서버/백엔드가 제어하지 않아요.
요청 재스케줄링 — 23.11부터 request.set_release_flags(pb_utils.TRITONSERVER_REQUEST_RELEASE_RESCHEDULE)로 요청을 미래 배치에 재스케줄링할 수 있어요. 반복적 시퀀스 처리에 유용해요. 이 API를 쓰려면 모델 구성에서 iterative sequence batching을 켜야 해요.
sequence_batching {
iterative_sequence : true
}
비-decoupled 모델에서는 요청당 응답이 하나뿐이므로, 재스케줄된 요청(원본과 동일)의 응답 리스트에 None 객체를 추가해야 해요. Decoupled 모델에서는 execute에서 반환하기 전에 요청을 재스케줄해야 해요.
finalize
구현은 선택이에요. 모델이 Triton 서버에서 언로드되기 전에 필요한 정리를 할 수 있어요.
is_ready
구현은 선택이에요. 정의하면 모델 준비 상태를 v2/models/<model>/ready health 엔드포인트로 확인할 때마다 호출돼요. True/False 불리언을 반환해야 하며 동기·비동기(async def) 구현 모두 지원돼요. 흔한 용도로는 외부 의존성 확인(DB/원격 API/피처 스토어 도달 가능), 지연 리소스 로딩(백그라운드 다운로드 완료 전까지 False), graceful drain(K8s가 라우팅을 끊도록), 내부 상태 검증(캐시/커넥션 풀 건강)이 있어요.
구현하지 않으면 stub 프로세스가 건강한 한 모델이 준비된 것으로 간주돼요(기본 동작). 이 경우 IPC 오버헤드가 없어요. 구현하면 준비 확인 타임아웃 5초가 적용되고, 모델 인스턴스당 한 번에 하나의 내부 준비 IPC 호출만 실행돼요. is_ready는 가능한 한 가볍고 효율적으로 유지해야 해요 — 내부 메시지 큐를 BLS decoupled 응답 전송과 공유하므로, 느린 준비 확인은 BLS decoupled 스트리밍 응답 전달을 지연시킬 수 있어요.
모델 구성 파일 (Model Config File)
모든 Python Triton 모델은 모델 구성을 설명하는 config.pbtxt 파일을 제공해야 해요. 이 백엔드를 쓰려면 backend 필드를 python으로 설정해야 하고, platform 필드는 설정하면 안 돼요.
models
└── add_sub
├── 1
│ └── model.py
└── config.pbtxt
추론 요청/응답 파라미터
요청 파라미터는 inference_request.parameters()로 가져올 수 있어요. 이 함수는 JSON 문자열을 반환하며, json.loads로 파싱해 딕셔너리로 바꿔야 해요. 23.11부터 파라미터를 InferenceRequest 생성 시 딕셔너리로 제공할 수도 있어요 ({"key": "value"} 형태, 키는 str·값은 bool/int/str). 응답 파라미터도 InferenceResponse 생성 시 선택적으로 설정할 수 있어요.
Python 런타임과 라이브러리 관리
NVIDIA GPU Cloud 컨테이너에 포함된 Python backend는 Python 3.12를 사용해요. 현재 Python 환경에 있는 라이브러리(virtualenv, conda, 시스템 Python)를 쓸 수 있는데, Python 버전이 Python 백엔드 stub 실행 파일의 버전과 일치해야만 사용돼요.
커스텀 Python 백엔드 stub 빌드
Triton 컨테이너가 기본 제공하는 Python 3.12와 다른 Python 버전을 쓰려면만 커스텀 stub을 컴파일하면 돼요. Python 백엔드는 stub 프로세스로 model.py를 Triton C++ 코어에 연결하는데, 이 stub이 특정 libpython<X>.<Y>.so 버전에 동적으로 링크돼요. 다른 버전을 쓰려면 아래처럼 빌드해요.
git clone https://github.com/triton-inference-server/python_backend -b <GIT_BRANCH_NAME>
cd python_backend
mkdir build && cd build
cmake -DTRITON_ENABLE_GPU=ON -DTRITON_BACKEND_REPO_TAG=<GIT_BRANCH_NAME> -DTRITON_COMMON_REPO_TAG=<GIT_BRANCH_NAME> -DTRITON_CORE_REPO_TAG=<GIT_BRANCH_NAME> -DCMAKE_INSTALL_PREFIX:PATH=`pwd`/install ..
make triton-python-backend-stub
ldd triton_python_backend_stub로 연결된 libpython<major>.<minor>m.so.1.0을 확인하고, stub을 그 stub을 쓰려는 모델의 모델 디렉터리에 복사해요.
models
|-- model_a
|-- 1
| |-- model.py
|-- config.pbtxt
`-- triton_python_backend_stub
커스텀 실행 환경 만들기
Python 백엔드는 모델마다 다른 Python 환경을 쓰거나 모든 Python 의존성을 담은 tar 파일을 만들고 싶을 때 Custom Execution Environment를 지원해요. 현재 conda-pack을 지원해요.
export PYTHONNOUSERSITE=True
conda-pack
PYTHONNOUSERSITE를 export해야 격리된 환경에 필요한 모든 의존성이 tar에 포함돼요. 패킹된 파일을 만들고 나서 config.pbtxt에 EXECUTION_ENV_PATH를 추가해 그 환경을 쓰게 해요.
parameters: {
key: "EXECUTION_ENV_PATH",
value: {string_value: "/home/iman/miniconda3/envs/python-3-6/python3.6.tar.gz"}
}
모델 폴더 기준 상대 경로도 제공할 수 있어요 ($$TRITON_MODEL_DIRECTORY/python3.6.tar.gz). 이렇게 하면 S3/GCS/Azure처럼 절대 경로를 몰라도 되는 상황에 유용해요.
중요: 실행 환경의 Python 인터프리터 버전은 반드시 triton_python_backend_stub 버전과 일치해야 해요. 기본 stub 버전은 Python 3.12예요. 실행 환경을 여러 모델이 공유할 수 있고, $$TRITON_MODEL_DIRECTORY를 쓰면 최종 경로가 그 디렉터리 밖을 벗어나면 안 돼요. stub은 공식 Triton NGC 컨테이너에서 컴파일하는 걸 권해요 (다른 OS에서 컴파일하면 배포 환경에 없는 의존성이 생길 수 있어요).
오류 처리
initialize, execute, finalize 함수에 영향을 주는 오류가 있으면 TritonModelException을 쓸 수 있어요.
def finalize(self):
if error_during_finalize:
raise pb_utils.TritonModelException("An error occurred during finalize.")
공유 메모리 관리
21.04부터 Python 백엔드는 사용자 코드를 Triton에 연결하는 데 공유 메모리를 사용해요. 기본적으로 모델 인스턴스당 1MB를 할당하고, 필요할 때마다 1MB 단위로 키워요. shm-default-byte-size와 shm-growth-byte-size 플래그로 조정할 수 있고, 연결 타임아웃은 stub-timeout-seconds(기본 30초)로 설정해요.
/opt/tritonserver/bin/tritonserver --model-repository=`pwd`/models --backend-config=python,<config-key>=<config-value>
Docker 안에서 실행한다면 입출력 크기에 맞춰 --shm-size를 제대로 설정해야 해요 (기본 64MB는 매우 작음).
다중 모델 인스턴스 지원
Python 인터프리터는 GIL이라는 전역 락을 써요. GIL 때문에 같은 인터프리터에서 여러 스레드가 동시에 실행될 수 없어요. 이 문제를 해결하기 위해 Python 백엔드는 모델 인스턴스마다 별도 프로세스를 생성해요. 이것은 ONNXRuntime, TensorFlow, PyTorch 같은 다른 백엔드가 인스턴스 수를 늘릴 때 추가 스레드를 만드는 것과 대조적이에요.
Triton 서버 다중 인스턴스 실행
24.04부터 Python 백엔드는 공유 메모리 영역의 고유한 이름을 만들기 위해 UUID를 사용해서, 여러 서버 인스턴스가 충돌 없이 동시에 실행될 수 있어요. 24.04 이전 버전이라면 shm-region-prefix-name을 다르게 지정해 충돌을 피해야 해요. 단, /dev/shm을 공유하지 않는 별도 컨테이너에서 실행하면 지정할 필요 없어요.
비즈니스 로직 스크립팅 (BLS)
Triton의 앙상블 기능은 여러 모델을 파이프라인(DAG)으로 조합하는 많은 사용 사례를 지원해요. 하지만 모델 실행에 루프, 조건문(if-then-else), 데이터 의존적 제어 흐름 같은 커스텀 로직이 섞여야 하는 경우는 지원하지 못해요. 이렇게 **커스텀 로직과 모델 실행을 결합한 것을 Business Logic Scripting(BLS)**이라고 불러요.
21.08부터 Python 모델에서 BLS를 구현할 수 있어요. BLS는 execute 함수 안에서만 써야 하고 initialize/finalize에서는 지원되지 않아요.
inference_request = pb_utils.InferenceRequest(
model_name='model_name',
requested_output_names=['REQUESTED_OUTPUT_1', 'REQUESTED_OUTPUT_2'],
inputs=[<pb_utils.Tensor object>])
inference_response = inference_request.exec()
if inference_response.has_error():
raise pb_utils.TritonModelException(
inference_response.error().message())
else:
output1 = pb_utils.get_output_tensor_by_name(
inference_response, 'REQUESTED_OUTPUT_1')
pb_utils.InferenceRequest는 request_id, correlation_id, model_version, timeout, preferred_memory도 지원해요. correlation_id는 24.03부터 문자열과 부호 없는 정수 모두 지원해요.
- 비동기 BLS:
inference_request.async_exec()는async def execute안에서 사용하며, 여러 인플라이트 요청을 보내고 필요할 때만 응답을 기다릴 수 있어요. - Decoupled 모델 BLS: 23.03부터
exec/async_exec에decoupled=True를 주면 decoupled 모델의 응답 이터레이터를 반환해요.timeout(마이크로초)을InferenceRequest생성자에 줄 수 있고, 응답 이터레이터의cancel()메서드로 decoupled BLS 요청을 취소할 수 있어요. - 모델 로딩 API: 23.07부터
pb_utils.is_model_ready(),pb_utils.load_model(),pb_utils.unload_model()로 BLS 모델이 필요한 모델을 로드/언로드할 수 있어요. 이 API는 서버가 explicit model control 모드일 때만 지원되고, 서버 시작 후에만 써야 해요.auto_complete_config와finalize에서는 지원되지 않아요. - Stateful 모델 BLS: 시퀀스 시작/끝을 나타내는 플래그를
InferenceRequest의flags인자에 줄 수 있어요 (TRITONSERVER_REQUEST_FLAG_SEQUENCE_START/TRITONSERVER_REQUEST_FLAG_SEQUENCE_END, 둘 다면 비트 OR).
제한: BLS 요청이 순환 의존성을 만들지 않아야 해요 (모델 A가 자기 자신에 요청을 보내고 더 이상 실행할 인스턴스가 없으면 영원히 블록돼요). decoupled 모드에서 Python 모델을 실행할 때는 비동기 BLS가 지원되지 않아요.
상호운용성과 GPU 지원
21.09부터 Python 백엔드는 텐서를 다른 프레임워크로 제로카피 전송하는 DLPack을 지원해요.
pb_utils.Tensor.to_dlpack() -> PyCapsule: 기존 텐서를 DLPack으로 변환. 예:from_dlpack(input0.to_dlpack())로 PyTorch 텐서로.pb_utils.Tensor.from_dlpack() -> Tensor: DLPack 인코딩에서 Tensor 생성.to_dlpack(torch)으로 변환한 텐서를pb_utils.Tensor.from_dlpack("INPUT0", to_dlpack(pytorch_tensor))처럼. 이 메서드는 C-order 연속(contiguous) 텐서만 지원하며 아니면 예외가 발생해요.- BF16(BFloat16) 입출력 텐서를 가진 Python 모델은
as_numpy()를 지원하지 않으므로 반드시from_dlpack/to_dlpack을 써야 해요. pb_utils.Tensor.is_cpu() -> bool: 텐서가 CPU에 있는지 확인.
입력 텐서 장치 배치: 기본적으로 Python 백엔드는 모든 입력 텐서를 CPU로 옮긴 뒤 Python 모델에 제공해요. 21.09부터 FORCE_CPU_ONLY_INPUT_TENSORS를 "no"로 설정하면 입력을 CPU로 옮기지 않아요. 대신 마지막 사용 방식에 따라 CPU 또는 GPU 메모리로 제공돼요. 각 입력에 어떤 메모리가 쓰일지 예측할 수 없으므로, 모델은 CPU와 GPU 메모리의 텐서를 모두 처리할 수 있어야 해요.
parameters: { key: "FORCE_CPU_ONLY_INPUT_TENSORS" value: {string_value:"no"}}
프레임워크 (PyTorch / TensorFlow)
Python 백엔드 모델은 대부분의 Python 패키지를 지원하므로, model.py 구현에 PyTorch 같은 딥러닝 프레임워크를 쓰는 게 흔한 워크플로예요. 중요: Python 백엔드 모델에서 프레임워크를 쓰는 것(import torch)은 대응하는 Triton 백엔드 구현(PyTorch 백엔드)과 같지 않아요. 프레임워크로 실행한 모델과 Python 백엔드가 같은 프레임워크를 돌린 결과가 크게 다르다면, 프레임워크 버전과 입출력 준비가 같은지 먼저 확인해 보세요.
- PyTorch 결정성: 하드웨어, 시스템 부하, 드라이버, 배치 크기에 따라 실행 간 출력에 약간의 차이가 있을 수 있어요. 대부분 모델의 최종 예측에는 영향을 주지 않을 만큼 작아요. Ampere 이상 장치에서는 FP32 연산에 관련된 TF32 최적화가 있는데 보통 미세한 정밀도 손실을 대가로 성능을 높여요.
- TensorFlow 결정성: PyTorch와 유사하게, 내부 CUDA 커널 선택 과정 때문에 하드웨어·시스템 구성·배치 크기에 따라 출력에 약간의 차이가 있을 수 있어요.
커스텀 메트릭
23.05부터 Python 모델의 initialize, execute, finalize 함수에서 Custom Metrics API로 커스텀 메트릭을 등록·수집할 수 있어요. 생성한 커스텀 메트릭의 소유권과 수명을 직접 관리해야 해요.
def initialize(self, args):
self.metric_family = pb_utils.MetricFamily(
name="preprocess_latency_ns",
description="Cumulative time spent pre-processing requests",
kind=pb_utils.MetricFamily.COUNTER
)
self.metric = self.metric_family.Metric(
labels={"model" : "model_name", "version" : "1"}
)
def execute(self, requests):
start_ns = time.time_ns()
self.preprocess(request)
end_ns = time.time_ns()
self.metric.increment(end_ns - start_ns)
...
예제
Triton Python 클라이언트를 쓰려면 Triton Python Client Library를 설치해야 해요. 각 예제의 클라이언트는 client.py 파일에 있어요.
- AddSub in NumPy: 의존성 없음.
examples/add_sub. - AddSubNet in PyTorch: PyTorch 설치 필요.
examples/pytorch. - AddSub in JAX: JAX 서빙 예제.
examples/jax. - Business Logic Scripting:
examples/bls,examples/bls_decoupled. - Preprocessing: 전처리 예제.
examples/preprocessing. - Decoupled Models:
examples/decoupled. - Model Instance Kind: 인스턴스 그룹 kind 설정을 존중하도록 모델을 작성하는 예제.
- Auto-complete config:
examples/auto_complete. - Custom Metrics:
examples/custom_metrics. - Running with Inferentia:
python_backend/inferentia하위 폴더 README 참고.
로깅
22.09부터 Python 모델은 pb_utils.Logger로 로그를 남길 수 있어요.
logger = pb_utils.Logger
logger.log_info("Info Msg!")
logger.log_warn("Warning Msg!")
logger.log_error("Error Msg!")
logger.log_verbose("Verbose Msg!")
로그 레벨을 명시적으로 지정할 수도 있어요 (logger.log("Specific Msg!", logger.INFO)). 레벨 미지정 시 INFO로 남겨요. 어떤 로그가 서버 로그에 나타날지는 Triton 서버 설정이 결정해요.
모델 구성에 커스텀 파라미터 추가
모델에 커스텀 파라미터가 필요하면 모델 구성의 parameters 섹션에 지정할 수 있어요.
parameters {
key: "custom_key"
value: {
string_value: "custom_value"
}
}
그리고 initialize 함수의 args 인자에서 접근할 수 있어요.
def initialize(self, args):
print(json.loads(args['model_config'])['parameters'])