Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (seongtaejeong at gmail.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

파이썬 - WSL/docker에 구성한 Triton 예제 개발 환경

"Triton Inference Server"는,

// https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tritonserver

What Is The Triton Inference Server?

Triton Inference Server provides a cloud and edge inferencing solution optimized for both CPUs and GPUs. Triton supports an HTTP/REST and GRPC protocol that allows remote clients to request inferencing for any model being managed by the server. For edge deployments, Triton is available as a shared library with a C API that allows the full functionality of Triton to be included directly in an application.


NVIDIA 측에서 오픈 소스로 공개한 추론 서버로, 기학습된 딥러닝 모델을 쉽고 빠르게 활용할 수 있도록 해줍니다. 사실, 서버 자체는 C/C++로 작성돼 사용이 불편할 거라고 오해할 수 있는데, 다행히 지원하는 백엔드 중의 하나로 파이썬을 제공하므로 적용 난이도가 현저하게 낮아집니다.

대충, 그럼 환경 구성을 해볼까요? ^^

개발 환경을 어지럽히지 않기 위해 이런 경우 docker를 사용하면 좋은데요, (물론 원한다면 소스 코드를 빌드해도 됩니다.) 관련해서 다양한 이미지가 제공되고 있지만,

  • The xx.yy-py3 image contains the Triton Inference Server with support for PyTorch, TensorRT, ONNX and OpenVINO models.
  • The xx.yy-py3-sdk image contains Python and C++ client libraries, client examples, GenAI-Perf, Performance Analyzer and the Model Analyzer.
  • The xx.yy-py3-min image is used as the base for creating custom Triton server containers as described in Customize Triton Container.
  • The xx.yy-pyt-python-py3 image contains the Triton Inference Server with support for PyTorch and Python backends only.
  • The xx.yy-py3-igpu image contains the Triton Inference Server with support for Jetson Orin devices. Please refer to the Frameworks Support Matrix for information regarding which iGPU hardware/software is supported by which container.
  • The xx.yy-py3-igpu-sdk image contains Python and C++ client libraries, client examples, and the Perf Analyzer.
  • The xx.yy-py3-igpu-min image is used as the base for creating custom iGPU Triton server containers.
  • The xx.yy-vllm-python-py3 image contains the Triton Inference Server with support for vLLM and Python backends only.
  • The xx.yy-trtllm-python-py3 image contains the Triton Inference Server with support for TensorRT-LLM and Python backends only.

이번 글에서는 그냥 단순 실습 정도만 할 것이기 때문에 "xx.yy-py3" 이미지를 쓰겠습니다. 그렇다면 이제 버전을 선택해야 하는데요, 제 시스템의 경우 Driver Version과 CUDA Version이 각각 576.02., 12.9로 나오기 때문에,

$ /usr/lib/wsl/lib/nvidia-smi
Tue May 17 11:00:59 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 575.51.02              Driver Version: 576.02         CUDA Version: 12.9     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4060 Ti     On  |   00000000:01:00.0  On |                  N/A |
|  0%   34C    P8              9W /  160W |    3643MiB /   8188MiB |     13%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+

Triton Inference Server 문서에 따라,

Frameworks Support Matrix
; https://docs.nvidia.com/deeplearning/frameworks/support-matrix/index.html

25.xx container images에 "Release 25.04 is based on CUDA 12.9.0.036 which requires NVIDIA Driver release 575 or later"라고 쓰여있기 때문에 그 버전의 이미지를 사용하겠습니다.

$ mkdir tis
$ cd tis

$ cat dockerfile

FROM nvcr.io/nvidia/tritonserver:25.04-py3

# 이건 필요 없지만 예제에서 사용한 model의 코드가 opencv 패키지를 사용하므로 포함
RUN apt-get update && apt-get install libgl1 -y

SHELL ["/bin/bash", "-c"]
WORKDIR /home/ubuntu

$ docker build -t tis .

(압축 파일 크기만 8GB가 넘고, 설치된 이미지 크기는 30GB가 넘어 시간이 제법 걸립니다.)

띄우기만 하면 뭔가 심심하니, 실제 동작하는 것까지 보고 싶은데요, 이 분야에 처음이라 제가 아는 바가 없어 ^^ 누군가가 작성한 예제를 활용해 보겠습니다.

Triton Inference Server 사용법
; https://velog.io/@dj_/Triton-Inference-Server-사용법

$ git clone https://github.com/fegler/triton_server_example.git
$ cd triton_server_example

우선, git clone을 했으면 save_model.py를 실행해야 하는데요, 이게 torchvision 패키지를 필요로 합니다. 하지만 triton에 올라갈 패키지에는 그것까지 포함할 필요는 없으므로 save_model.py는 별도의 환경에서 빌드하는 것이 좋겠습니다.

// 이번 글에서 사용하는 torchvision 0.20 패키지가 파이썬 3.9 ~ 3.12를 지원

$ conda create --name pybuild python=3.12 -y
$ conda activate pybuild
$ python -m pip install torchvision==0.20

$ python save_model.py

// 이하 작업은 확인 차원이므로 필요 없음
$ conda install opencv
$ python test_model.py
test finish

$ conda deactivate

저렇게 Model까지만 구성해도 triton 서버에서 돌아갈 수는 있는데요, 단지 예제 코드의 경우 파이썬 백엔드에서 pre/post processing 중에 부가적으로 로드하는 패키지들이 있어 좀 더 수고를 해야 합니다. 이에 대한 처리를 쉽게는, 그냥 해당 dockerfile 이미지에 패키지를 설치해 포함하는 것도 가능할 것 같은데요, 여기서는 conda로 패키징을 구성해 넣어 보겠습니다. 왜냐하면, ./triton/preprocessing과 ./triton/postprocessing 디렉터리 아래에 있는 config.pbtxt 파일에 파이썬의 실행 환경을 다음과 같이 명시하고 있기 때문입니다.

name: "preprocessing" 
backend: "python" 

input [
    {
        name: "image"
        data_type: TYPE_STRING 
        dims: [-1]
    }
]

output [
    {
        name: "input_image" 
        data_type: TYPE_FP32 
        dims: [-1, 3, -1, -1]
    }
]

parameters: {
    key: "EXECUTION_ENV_PATH", 
    value: {string_value: "$$TRITON_MODEL_DIRECTORY/pre_env.tar.gz"}
}

instance_group [
    {
        kind: KIND_CPU
    }
]

따라서, pre_env.tar.gz과 (./triton/postprocessing/config.pbtxt에 명시된) post_env.tar.gz 파일을 다음과 같이 각각 생성해 넣어야 합니다.

// Creating Custom Execution Environments
// ; https://github.com/triton-inference-server/python_backend?tab=readme-ov-file#creating-custom-execution-environments

$ export PYTHONNOUSERSITE=True

$ conda create --name triton_sample python=3.12 -y
$ conda activate triton_sample

// triton 25 버전인 경우 libstdcxx-ng=14로 구성
$ conda install -c conda-forge libstdcxx-ng=14 -y

$ conda install pip -y
$ conda install conda-pack -y
$ which conda-pack
/home/testusr/miniconda3/envs/triton_sample/bin/conda-pack

$ pip install -r pre_requirements.txt
$ conda-pack -n triton_sample -o pre_env.tar.gz
$ cp pre_env.tar.gz ./triton/preprocessing/pre_env.tar.gz

$ pip install -r post_requirements.txt
$ conda-pack -n triton_sample -o post_env.tar.gz
$ cp post_env.tar.gz ./triton/postprocessing/post_env.tar.gz

그럼, 최종적으로 이런 식의 Model 구성을 갖게 됩니다.

$ tree ./triton/
./triton/
├── core
│   ├── 1
│   │   └── model.pt
│   └── config.pbtxt
├── ensemble
│   ├── 1
│   │   └── placeholder
│   └── config.pbtxt
├── postprocessing
│   ├── 1
│   │   └── model.py
│   ├── config.pbtxt
│   └── post_env.tar.gz
└── preprocessing
    ├── 1
    │   └── model.py
    ├── config.pbtxt
    └── pre_env.tar.gz

$ ls ./triton/core/1/model.pt -l
-rw-r--r-- 1 kevin kevin 102594763 May 23 11:26 ./triton/core/1/model.pt

마지막으로 docker run 명령어로 triton 서버를 구동하면 끝!

$ export MODEL_FOLDER_PATH=/home/kevin/test/triton_server_example/triton

// gpu device=0 환경 설정
// SSL_CERT_DIR 설정

$ docker run --gpus='"device=0"' -it --rm --shm-size=8g -p 8005:8000 -e SSL_CERT_DIR=/etc/ssl/certs/ -v ${MODEL_FOLDER_PATH}:/model_dir tis tritonserver --model-repository=/model_dir --strict-model-config=false --model-control-mode=poll --repository-poll-secs=10 --backend-config=tensorflow,version=2 --log-verbose=1




고맙게도 triton_server_example repo는 테스트까지 할 수 있는 client.py를 제공하는데요, 적절하게 IP와 이미지 파일 경로만 맞춰준 다음,

$ cat client.py
import base64
import os
import requests
import json
import cv2
import numpy as np

from pytictoc import TicToc

# TicToc 클래스 생성
t = TicToc()

IP = "127.0.0.1"  ## use your ip

def inference(image_data, url="localhost", port="8005"):
    url = f"http://{url}:{port}/v2/models/ensemble/infer"
    data = {
        "inputs": [
            {
                "name": "image",
                "shape": [len(image_data)],
                "datatype": "BYTES",
                "data": image_data,
            }
        ]
    }
    headers = {"content-type": "application/json"}

    t.tic()
    response = requests.post(
        url, headers=headers, data=json.dumps(data, ensure_ascii=False)
    )
    tm = t.tocvalue()
    return response.text, tm


def read_image_data(im_paths):
    encode_ims = []
    for p in im_paths:
        if not os.path.exists(p):
            continue
        image = open(p, "rb")
        im_encode = base64.b64encode(image.read()).decode("ascii")
        encode_ims.append(im_encode)
    return encode_ims


if __name__ == "__main__":
    im_path = ["/home/testusr/test/triton_server_example/test_image.jpg"]
    images = read_image_data(im_path)
    response, tm = inference(images, IP)
    print("Inference Time: %f" % tm)
    response_json = json.loads(response)
    response_data = json.loads(response_json["outputs"][0]["data"][0])
    pred_probs = response_data["result"]
    print(pred_probs)

필요한 패키지 설치 후 triton 서버에 요청/응답까지 할 수 있습니다.

$ conda create --name triton_client -y
$ conda activate triton_client
$ conda install pip -y
 
$ pip install opencv-python
$ pip install requests
$ pip install pytictoc
$ python client.py
Inference Time: 3.681000
[[0.0007483039516955614, ...[생략]... 0.0009087992366403341]]

뭔지 모르지만... ^^; 아무튼, 잘 동작하는 것 같습니다.




참고로, 패키징된 tar.gz 파일의 경우 trtion 서버에 구동할 때 다시 unpack 작업을 거쳐야 하는데요, 이 과정을 생략할 수 있도록 미리 압축을 해제하는 것도 가능합니다.

예를 들어 위의 예제를 다시 (이번에는 pre/post를 위한 가상 환경을 각각 나눠서) 작성해 보면,

$ export PYTHONNOUSERSITE=True

$ conda create --name triton_sample_pre python=3.12 -y
$ conda activate triton_sample_pre

// triton 25 버전인 경우 libstdcxx-ng=14로 구성
$ conda install -c conda-forge libstdcxx-ng=14 -y

$ conda install pip -y
$ conda install conda-pack -y

$ pip install -r pre_requirements.txt
$ conda-pack -n triton_sample_pre -o pre_env.tar.gz

$ conda deactivate

$ conda create --name triton_sample_post python=3.12 -y
$ conda activate triton_sample_post

// triton 25 버전인 경우 libstdcxx-ng=14로 구성
$ conda install -c conda-forge libstdcxx-ng=14 -y

$ conda install pip -y
$ conda install conda-pack -y

$ pip install -r post_requirements.txt
$ conda-pack -n triton_sample_post -o post_env.tar.gz

$ conda deactivate

각각 pre_env.tar.gz, post_env.tar.gz 파일만 생성해 둔 다음 그대로 Model 디렉터리에 압축을 풀어 놓으면 됩니다.

$ mkdir -p ./triton/preprocessing/python_env
$ tar -xzf pre_env.tar.gz -C ./triton/preprocessing/python_env

$ mkdir -p ./triton/postprocessing/python_env
$ tar -xzf post_env.tar.gz -C ./triton/postprocessing/python_env

그럼 최종적으로 예제 디렉터리는 이런 식으로 구성되고,

./triton
├── core
│   ├── 1
│   │   └── model.pt
│   └── config.pbtxt
├── ensemble
│   ├── 1
│   │   └── placeholder
│   └── config.pbtxt
├── postprocessing
│   ├── 1
│   │   └── model.py
│   ├── config.pbtxt
│   └── python_env
|       ...[생략]...
├── postprocessing
│   ├── 1
│   │   └── model.py
│   ├── config.pbtxt
│   └── python_env
        ...[생략]...

그다음, 각각의 preprocessing, postprocessing 디렉터리에 있는 config.pbtxt 파일의 EXECUTION_ENV_PATH를 다음과 같이 수정합니다.

parameters: {
    key: "EXECUTION_ENV_PATH", 
    value: {string_value: "$$TRITON_MODEL_DIRECTORY/python_env"}
}

끝입니다, 이제 triton 서버를 실행하면 정상적으로, 이전보다 더 빠르게 구동됩니다. ^^




혹시나 이 분야에 연관이 있으신 분들이라면 아래의 글도 마저 읽어보시는 것이 좋을 듯합니다. ^^

Triton Inference Server #1. Triton Inference Server란?
; https://dytis.tistory.com/65

Triton Inference Server #2. 모델 스케쥴링
; https://dytis.tistory.com/66

Triton Inference Server #3. Model Management & Repository
; https://dytis.tistory.com/69

Triton Inference Server #4. Model Configuration
; https://dytis.tistory.com/70

Triton Inference Server #5. Python Backend
; https://dytis.tistory.com/71




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 5/30/2025]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




1  [2]  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13915정성태4/13/20252628닷넷: 2331. C# - 실행 시에 메서드 가로채기 (.NET 9)파일 다운로드1
13914정성태4/11/20253020디버깅 기술: 220. windbg 분석 사례 - x86 ASP.NET 웹 응용 프로그램의 CPU 100% 현상 (4)
13913정성태4/10/20251862오류 유형: 950. Process Explorer - 64비트 윈도우에서 32비트 프로세스의 덤프를 뜰 때 "Error writing dump file: Access is denied." 오류
13912정성태4/9/20251540닷넷: 2330. C# - 실행 시에 메서드 가로채기 (.NET 5 ~ .NET 8)파일 다운로드1
13911정성태4/8/20251883오류 유형: 949. WinDbg - .NET Core/5+ 응용 프로그램 디버깅 시 sos 확장을 자동으로 로드하지 못하는 문제
13910정성태4/8/20251979디버깅 기술: 219. WinDbg - 명령어 내에서 환경 변수 사용법
13909정성태4/7/20252838닷넷: 2329. C# - 실행 시에 메서드 가로채기 (.NET Framework 4.8)파일 다운로드1
13908정성태4/2/20253103닷넷: 2328. C# - MailKit: SMTP, POP3, IMAP 지원 라이브러리
13907정성태3/29/20253063VS.NET IDE: 198. (OneDrive, Dropbox 등의 공유 디렉터리에 있는) C# 프로젝트의 출력 경로 변경하기
13906정성태3/27/20253283닷넷: 2327. C# - 초기화되지 않은 메모리에 접근하는 버그?파일 다운로드1
13905정성태3/26/20253240Windows: 281. C++ - Windows / Critical Section의 안정화를 위해 도입된 "Keyed Event"파일 다운로드1
13904정성태3/25/20252770디버깅 기술: 218. Windbg로 살펴보는 Win32 Critical Section파일 다운로드1
13903정성태3/24/20252085VS.NET IDE: 197. (OneDrive, Dropbox 등의 공유 디렉터리에 있는) C++ 프로젝트의 출력 경로 변경하기
13902정성태3/24/20252495개발 환경 구성: 742. Oracle - 테스트용 hr 계정 및 데이터 생성파일 다운로드1
13901정성태3/9/20252877Windows: 280. Hyper-V의 3가지 Thread Scheduler (Classic, Core, Root)
13900정성태3/8/20253458스크립트: 72. 파이썬 - SQLAlchemy + oracledb 연동
13899정성태3/7/20252312스크립트: 71. 파이썬 - asyncio의 ContextVar 전달
13898정성태3/5/20252833오류 유형: 948. Visual Studio - Proxy Authentication Required: dotnetfeed.blob.core.windows.net
13897정성태3/5/20253390닷넷: 2326. C# - PowerShell과 연동하는 방법 (두 번째 이야기)파일 다운로드1
13896정성태3/5/20253250Windows: 279. Hyper-V Manager - VM 목록의 CPU Usage 항목이 항상 0%로 나오는 문제
13895정성태3/4/20253232Linux: 117. eBPF / bpf2go - Map에 추가된 요소의 개수를 확인하는 방법
13894정성태2/28/20253193Linux: 116. eBPF / bpf2go - BTF Style Maps 정의 구문과 데이터 정렬 문제
13893정성태2/27/20252857Linux: 115. eBPF (bpf2go) - ARRAY / HASH map 기본 사용법
13892정성태2/24/20254050닷넷: 2325. C# - PowerShell과 연동하는 방법파일 다운로드1
13891정성태2/23/20253118닷넷: 2324. C# - 프로세스의 성능 카운터용 인스턴스 이름을 구하는 방법파일 다운로드1
13890정성태2/21/20252889닷넷: 2323. C# - 프로세스 메모리 중 Private Working Set 크기를 구하는 방법(Win32 API)파일 다운로드1
1  [2]  3  4  5  6  7  8  9  10  11  12  13  14  15  ...