본문 바로가기
🌿 Data Engineering/MLOps

Triton Inference Server 모델서빙2 - 직접 우리 모델을 서빙해보자!

by 카프리썬_ 2024. 8. 3.
728x90
728x90

https://pearlluck.tistory.com/821

 

Triton Inference Server 모델서빙1 - NVIDA Triton(트리톤)이란?

최근 사내에 GPU를 도입하면서 다양한 ML 모델을 개발하고 있다. 반면 ML 모델 서빙 측면에서는 단순히 FastAPI를 사용하고 있다.알다시피 FastAPI는 파이썬 웹 프레임워크이기 때문에 사실상 모델 서

pearlluck.tistory.com

 

지난 글에서 트리톤 인퍼런스 서버 개념에 대해서 알아보았다.

이번에는 직접 trition inference server를 실행해보고, 우리 모델을 서빙해보는 테스트를 해보려고 한다. 

그래서 최종적으로 트리톤 API를 통해 inference response를 받는것까지 확인할수 있었다. 

 

    테스트 대상: OCR 모델

    트리톤을 통해 우리 OCR 모델을 서빙해보려고 한다.  

    출처 :

    OCR(Optical Character Recognition)은

    이미지에 있는 문자를 인식하여 텍스트로 변환하는 기술로,

    문자를 찾는 Text Detection 부분과, 문자를 인식하는 Text Recognition으로 구분 된다. 

     

    현재 우리가 서비스하고 있는 OCR 모델의 Detector와 Recoginzer는

    ONNX runtime으로 구현되어 있고, 직접 onnx inference Session을 만들어서 CPU와 GPU로 추론한다. 

    그리고 각각 모델에 대해 전처리와 후처리를 python으로 한 뒤, 이를 fastAPI로 서빙하고 있는 상황이다.

     

    이러한 전체적인 흐름을 바탕으로 OCR 모델을 추론하여 서빙하는 API의 구조는

    이미지를 input으로 받고 (정확히는 이미지를 load하기 위한 이미지 url),  이미지 안에서 인식된 텍스트가 output이 된다.

     

     

    참고로 onnx 모델과 전처리하는 부분이 별도로 있다는 점에서

    엔비디아 공식문서에서 제공해준  preprocessing Example과 유사한것 같다. 

     

    NVIDIA Inference Server에 모델 load 하기 

    그럼 본격적으로 엔비디아 인퍼런스 서버를 실행해보자. 공식문서의 Quickstart 에도 잘 나와있었다.

    1. Trition Server Container 버전 찾기 

    아주 편하게도 trition server container가 존재한다. (릴리즈문서)

    그래서 Ubuntu, CUDA 버전에 맞는 컨테이너 버전을 찾기만 하면 전반적인 환경설정이 세팅이 되는것 같다. 

     

    참고로 cuda 11.8랑 맞추기 위해 22.12를 사용하려다가, cuda 12.5로 업그레이드하면서 24.06 버전의 container를 사용하기로 했다.

    이렇게 컨테이너로 바로 제공되기 때문에 실제로 서비스할때 base 컨테이너로 세팅하면 된다.

     

    트리톤 서버만 테스트해보고자 한다면 그냥 이 컨테이너를 바로 run하기만 하면 된다. 

     

    2. 모델 Repository 만들기

    뭔가 트리톤 인퍼런스 서버는 config기반으로 동작하는 것 같다. (개인적인 내 생각일뿐..)

    그래서 config 파일이 정해진 구조에 따라 잘 작성되고, 거기에 모델 파일이 있으면, 그 모델을 트리톤 서버에 load할수 있다. 

    (결국 config를 잘 맞춰 작성해야되는데, 파일 구조가 잘못되거나 오타가 있거나 하면 디버깅이 쉽지 않다;;)

     

    Trition Model Configuration 관련 공식문서

     

    Model Configuration — NVIDIA Triton Inference Server

    TRITONBACKEND_ModelBatchFinalize Deallocates the record-keeping data structure after a batch is formed

    docs.nvidia.com

     

     

    model repository 구조

    예를 들어, 나는 ocr_detect 라는 onnx모델과, ocr_reco라는 onnx모델을 트리톤 서버에 load하려고 한다. 

    먼저, 로컬의 /home/local/models 경로에 아래와 같은 구조로 트리톤 model repository를 만든다.

    각각 모델의 이름을 하위경로에, config.pbtxt 파일을 넣을 것이다.

    그리고 1이라는 하위경로에 직접 모델 파일을 넣는다. (아마 확실하진 않지만 모델이름도 <model> 이여야 하는것 같다)

    1은 버전 이름이다. 이렇게 버전에 따라 경로를 구분하니 모델들을 버전에 따라 관리 할 수 있다.

     

    config.pbtxt 구조

    예를 들어, ocr_detect와 ocr_reco 라는 모델의 config.pbtxt는 아래와 같다.

    name은 모델이름이며, backend는 모델의 포맷이다. 

    참고로 트리톤 20.08 이전버전에서는 backend대신 platform이라는 키워드를 쓴다. 

    trtion confifg에서 plaform:onnxruntime_onnx와 backend:onnxruntime 설정차이 

     

    그리고 아래처럼 Input, output을 지정하면 된다. 리스트타입이기 때문에 여러개의 input,output도 가능하다. 

    data_type또한 Bool,INT,Float,String이 가능하다.

     

    이외에도 다양한 옵션을 config에서 지정할수 있다. 

    instance_group 옵션 

    예를들어, instance_group옵션의 경우 실행환경과 동시성 개수를 조절할수 있다. (기본적으로 GPU인듯;;)

    CPU에서 수행할건지 GPU에서 수행할건지 그리고 각 코어 개수를 직접 지정할수 있는것이다. 

    dynamic_batch 옵션 

    트리톤 서버의 장점은 batch inference를 지원해주는 것이다. 그래서 각각의 request를 batch로 묶어서 처리한다. 

    각각 추론요청이 독립적이고 상태가 없는 stateless 모델만 가능하다.  (우리 모델은 적용이 되는 조건이다)

     

     

    아래처럼 로컬 경로(/home/local/models)를 컨테이너 경로(/models)로 마운트하고,

    model respository 경로를 그 컨테이너 경로로 지정하며 트리톤 서버를 실행하는 것이다.

    docker run --rm -p8000:8000 -p8001:8001 -p8002:8002

    -v /home/local/models:/models nvcr.io/nvidia/tritonserver:22.12-py3 tritonserver --model-repository=/models

    그리고 

    3. Trition Server 실행하기 : 모델 Load 확인 

    로컬 경로(/home/local/models)가 Model repository가 되었으니, 이제 서버를 실행하면 된다. 

    컨테이너를 run할때 단지 그 경로를 마운트하고, 그 경로를 model-repository라고 지정해주기만 하면 된다.

     

    CPU

    docker run --rm -p8000:8000 -p8001:8001 -p8002:8002

    -v /home/local/models:/models nvcr.io/nvidia/tritonserver:22.12-py3 
    tritonserver --model-repository=/models

     

    GPU (gpus 옵션추가)

    docker run --gpus=1  --rm -p8000:8000 -p8001:8001 -p8002:8002

    -v /home/local/models:/models nvcr.io/nvidia/tritonserver:22.12-py3 
    tritonserver --model-repository=/models

     

    뿐만 아니라 S3경로를 model repository 경로로 지정할수도 있다. 

    docker run --rm -p8000:8000 -p8001:8001 -p8002:8002

    -v /home/local/models:/models nvcr.io/nvidia/tritonserver:22.12-py3 
    tritonserver --model-repository=s3://<bucket-name>/<s3-dir>

     

    또는 그냥 트리톤 서버 컨테이너에 접속해서 tritonserver--model-repository=./models 명령어를 날리기만 해도 된다.

     

     

    그럼 이렇게 ocr_detect 모델과 ocr_reco 모델이 Ready가 된 상태를 볼수 있다!! 

    최종적으로 트리톤에 우리 ocr모델이 성공적으로 load된 것이다! 

     

    트리톤 서버 프로토콜 (Inference Request)

    trtiton protocol 관련 공식 문서

     

    server/docs/protocol at main · triton-inference-server/server

    The Triton Inference Server provides an optimized cloud and edge inferencing solution. - triton-inference-server/server

    github.com

     

    트리톤 서버를 띄우면 8001 포트로 GPRC endpoint, 8000 포트로 HTTP endpoint, 8002 포트의 Metric endpoint가 제공된다. 

    요기에 해당하는 endpoint로 서버를 찔러 볼수 있는것이다.

     

    예를들어, 컨테이너 안에서 localhost에 8000포트에 아래의 endpoint에서는 트리톤 서버의 상태체크를 확인할수 있다.

     

    이밖에도 여러가지 extension이 있다. 그중에서 몇가지 내가 직접 확인해본거로는 아래와 같다. 

    - model config 관련 : GET v2/models/${MODEL_NAME}[/versions/${MODEL_VERSION}]/config

    - logging 관련 : GET v2/logging

    - statistics 관련 : GET v2/models[/${MODEL_NAME}[/versions/${MODEL_VERSION}]]/stats

     

    그리고 컨테이너를 run할때 port forwarding을 해서, 이렇게 로컬에서 같은 포트로 바로 확인해볼수 있다! 

     

     

    결국 최종적으로 inference 결과를 response로 받는 endpoint는 아래와 같다. required_api 공식문서 

    POST v2/models/${MODEL_NAME}/[versions/${MODEL_VERSION}]/infer

     

    대신 request를 JSON 형식으로 보내야한다. 아직 우리 OCR모델에는 추가적인 설정이 더 필요해서 example를 가지고 왔다. 

    이런식으로 모델에 필요한 intput,output을 json형식으로 만들어서 POST 요청을 보내야한다. 

     

    참고로 위에서 load한 모델이 아니라 전처리 및 후처리까지 붙여서 ensemble_ocr 모델을 구성했다.

    그리고 이 모델의 input은 바로 이미지 URL이 되고, 이 이미지에 있는 텍스트를 읽은 결과가 output의 data인걸 확인할수 있다! 

     

     

     

     

    728x90
    반응형