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

비밀번호

댓글 작성자
 




... 31  32  33  34  35  [36]  37  38  39  40  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
13060정성태5/15/202220022.NET Framework: 2012. C# - async/await 그리고 스레드 (3) Task.Delay 재현파일 다운로드1
13059정성태5/14/202217947.NET Framework: 2011. C# - CLR ThreadPool의 I/O 스레드에 작업을 맡기는 방법 [1]파일 다운로드1
13058정성태5/13/202217890.NET Framework: 2010. C# - ThreadPool.SetMaxThreads 사용법 [1]
13057정성태5/12/202219365오류 유형: 812. 파이썬 - ImportError: cannot import name ...
13056정성태5/12/202215303.NET Framework: 2009. C# - async/await 그리고 스레드 (2) MyTask의 호출 흐름 [2]파일 다운로드1
13055정성태5/11/202219992.NET Framework: 2008. C# - async/await 그리고 스레드 (1) MyTask로 재현 [11]파일 다운로드1
13054정성태5/11/202216738.NET Framework: 2007. C# - 10진수 숫자를 담은 문자열을 숫자로 변환하는 방법 [11]파일 다운로드1
13053정성태5/10/202216135.NET Framework: 2006. C# - GC.KeepAlive 메서드의 역할
13052정성태5/9/202216514.NET Framework: 2005. C# - 생성한 참조 개체가 언제 GC의 정리 대상이 될까요?
13051정성태5/8/202215879.NET Framework: 2004. C# XingAPI - ACF 검색 결과로 구한 CSV 파일을 통해 퀀트 종목 찾기파일 다운로드1
13050정성태5/6/202216015.NET Framework: 2003. C# - COM 개체의 이벤트 핸들러에서 발생하는 예외에 대한 CLR의 특별 대우파일 다운로드1
13049정성태5/6/202213314오류 유형: 811. GoLand - Error: Cannot find package
13048정성태5/6/202215782오류 유형: 810. "ASUS TUF GAMING B550M-PLUS (WI-FI)" 모델에서 블루투스 장치가 인식이 안 되는 문제
13047정성태5/6/202215300오류 유형: 809. Speech Recognition could not start
13046정성태5/5/202215877.NET Framework: 2002. C# XingAPI - ACF 파일을 이용한 퀀트 종목 찾기(t1857)
13045정성태5/5/202216541.NET Framework: 2001. C# XingAPI - 주식 종목에 따른 PBR, PER, ROE 구하는 방법(t3341 예제)
13044정성태5/4/202215224오류 유형: 808. error : clang++ exited with code 127
13043정성태5/3/202213966오류 유형: 807. C# - 닷넷 응용 프로그램에서 Informix DB 사용 시 오류 메시지 정리
13042정성태5/3/202215605.NET Framework: 2000. C# - 닷넷 응용 프로그램에서 Informix DB 사용 방법파일 다운로드1
13041정성태4/28/202215427개발 환경 구성: 642. Informix 데이터베이스 docker 환경 구성
13040정성태4/27/202214724VC++: 156. 비주얼 스튜디오 - Linux C/C++ 프로젝트에서 openssl 링크하는 방법
13039정성태4/27/202218589.NET Framework: 1999. C# - Playwright를 이용한 간단한 브라우저 제어 실습
13038정성태4/26/202214478오류 유형: 806. twine 실행 시 ConfigParser.ParsingError: File contains parsing errors: /root/.pypirc
13037정성태4/25/202215357.NET Framework: 1998. Azure Functions를 사용한 간단한 실습
13036정성태4/24/202216235.NET Framework: 1997. C# - nano 시간을 가져오는 방법 [2]
13035정성태4/22/202217672Windows: 204. Windows 10부터 바뀐 QueryPerformanceFrequency, QueryPerformanceCounter
... 31  32  33  34  35  [36]  37  38  39  40  41  42  43  44  45  ...