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

파이썬 - 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

비밀번호

댓글 작성자
 




... 61  [62]  63  64  65  66  67  68  69  70  71  72  73  74  75  ...
NoWriterDateCnt.TitleFile(s)
12411정성태11/12/202018023오류 유형: 680. C# 9.0 - Error CS8889 The target runtime doesn't support extensible or runtime-environment default calling conventions.
12410정성태11/12/202018762디버깅 기술: 174. windbg - System.TypeLoadException 예외 분석 사례
12409정성태11/12/202020393.NET Framework: 968. C# 9.0의 Function pointer를 이용한 함수 주소 구하는 방법파일 다운로드1
12408정성태11/9/202035490도서: 시작하세요! C# 9.0 프로그래밍 [8]
12407정성태11/9/202020570.NET Framework: 967. "clr!JIT_DbgIsJustMyCode" 호출이 뭘까요?
12406정성태11/8/202021535.NET Framework: 966. C# 9.0 - (15) 최상위 문(Top-level statements) [5]파일 다운로드1
12405정성태11/8/202019986.NET Framework: 965. C# 9.0 - (14) 부분 메서드에 대한 새로운 기능(New features for partial methods)파일 다운로드1
12404정성태11/7/202020581.NET Framework: 964. C# 9.0 - (13) 모듈 이니셜라이저(Module initializers)파일 다운로드1
12403정성태11/7/202018704.NET Framework: 963. C# 9.0 - (12) foreach 루프에 대한 GetEnumerator 확장 메서드 지원(Extension GetEnumerator)파일 다운로드1
12402정성태11/7/202020966.NET Framework: 962. C# 9.0 - (11) 공변 반환 형식(Covariant return types) [1]파일 다운로드1
12401정성태11/5/202020223VS.NET IDE: 153. 닷넷 응용 프로그램에서의 "My Code" 범위와 "Enable Just My Code"의 역할 [1]
12400정성태11/5/202016295오류 유형: 679. Visual Studio - "Source Not Found" 창에 "Decompile source code" 링크가 없는 경우
12399정성태11/5/202019385.NET Framework: 961. C# 9.0 - (10) 대상으로 형식화된 조건식(Target-typed conditional expressions)파일 다운로드1
12398정성태11/4/202019427오류 유형: 678. Windows Server 2008 R2 환경에서 Powershell을 psexec로 원격 실행할 때 hang이 발생하는 문제
12397정성태11/4/202019519.NET Framework: 960. C# - 조건 연산자(?:)를 사용하는 경우 달라지는 메서드 선택 사례파일 다운로드1
12396정성태11/3/202015943VS.NET IDE: 152. Visual Studio - "Tools" / "External Tools..."에 등록된 외부 명령어에 대한 단축키 설정 방법
12395정성태11/3/202019331오류 유형: 677. SSMS로 DB 접근 시 The server principal "..." is not able to access the database "..." under the current security context.
12394정성태11/3/202016840오류 유형: 676. cacls - The Recycle Bin on ... is corrupted. Do you want to empty the Recycle Bin for this drive?
12393정성태11/3/202015834오류 유형: 675. Visual Studio - 닷넷 응용 프로그램 디버깅 시 Disassembly 창에서 BP 설정할 때 "Error while processing breakpoint." 오류
12392정성태11/2/202020367.NET Framework: 959. C# 9.0 - (9) 레코드(Records) [4]파일 다운로드1
12390정성태11/1/202020790디버깅 기술: 173. windbg - System.Configuration.ConfigurationErrorsException 예외 분석 방법
12389정성태11/1/202019826.NET Framework: 958. C# 9.0 - (8) 정적 익명 함수 (static anonymous functions)파일 다운로드1
12388정성태10/29/202018235오류 유형: 674. 어느 순간부터 닷넷 응용 프로그램 실행 시 System.Configuration.ConfigurationErrorsException 예외가 발생한다면?
12387정성태10/28/202019119.NET Framework: 957. C# - static 필드의 정보가 GC Heap에 저장될까요? [3]파일 다운로드1
12386정성태10/28/202020100Linux: 34. 사용자 정보를 함께 출력하는 리눅스의 ps 명령어 사용 방법
12385정성태10/28/202017331오류 유형: 673. openssl - req: No value provided for Subject Attribute CN, skipped
... 61  [62]  63  64  65  66  67  68  69  70  71  72  73  74  75  ...