본문 바로가기
kubenetes

KServe v2 프로토콜: 모델 메타데이터

by kyeongseo.oh 2024. 10. 1.

개요

KServe v2 프로토콜은 모델 메타데이터를 제공하는 기능을 포함하고 있다. 이 기능을 통해 모델의 입력 및 출력 형식, 모델 이름, 버전 등의 정보를 클라이언트에게 제공할 수 있다.

 

아래 링크에서 개발한 모델에 메타 데이터 구현을 위한 메서드를 추가한다.

KServe Custom Predictor 이미지 빌드 가이드 - v2 protocol

 

프로젝트 구조

프로젝트 구조는 다음과 같다.

project_root/
│
├── predictor.py
├── requirements.txt
├── Dockerfile
└── model/
    └── model.joblib

 

모델 메타데이터 구현

모델 메타데이터를 제공하기 위해서는 커스텀 예측기 클래스에 다음 메서드들을 구현해야 한다.

 

  • get_input_types(): 모델 입력 형식 정의
  • get_output_types(): 모델 출력 형식 정의

example:

    def get_input_types(self) -> List[Dict]:
        return [{
            "name": "INPUT_0",
            "datatype": "FP32",
            "shape": [-1, 4]
        }]

    def get_output_types(self) -> List[Dict]:
        return [{
            "name": "OUTPUT_0",
            "datatype": "INT32",
            "shape": [-1]
        }]

 

Custom Predictor 구현

import argparse

from typing import Dict, Union, List
import numpy as np
import kserve
from kserve import logging
from kserve.model import PredictorConfig
from kserve import (
    Model,
    ModelServer,
    InferInput,
    InferResponse,
)
from joblib import load
from kserve.utils.utils import generate_uuid

class IrisSVMModel(Model):
    def __init__(
        self,
        name: str,
        predictor_host: str,
        predictor_protocol: str,
        predictor_use_ssl: bool,
    ):
        super().__init__(
            name, PredictorConfig(predictor_host, predictor_protocol, predictor_use_ssl)
        )

        self.load()

    def load(self):
        self.model = load('/mnt/model/model.joblib')
        self.ready = True

    def get_input_types(self) -> List[Dict]:
        return [{
            "name": "INPUT_0",
            "datatype": "FP32",
            "shape": [-1, 4]
        }]

    def get_output_types(self) -> List[Dict]:
        return [{
            "name": "OUTPUT_0",
            "datatype": "INT32",
            "shape": [-1]
        }]

    def predict(self, payload: Dict, headers: Dict[str, str] = None) -> Dict:
        data = payload.inputs[0].data
        inputs = np.array(data)
        results = self.model.predict(inputs).tolist()

        return InferResponse(
            model_name=self.name,
            infer_outputs=[InferInput(name="OUTPUT_0", datatype="INT64", shape=[len(results)], data=results)],
            response_id=generate_uuid()
        )

    def postprocess(
        self, infer_response: Union[Dict, InferResponse], headers: Dict[str, str] = None
    ) -> Union[Dict, InferResponse]:

        categories = ['setosa', 'versicolor', 'virginica']

        predictions = infer_response.outputs[0].data

        results = [categories[int(pred)] for pred in predictions]

        return InferResponse(
            model_name=self.name,
            infer_outputs=[InferInput(name="OUTPUT__0", datatype="BYTES", shape=[len(results)], data=results)],
            response_id=infer_response.id
        )


parser = argparse.ArgumentParser(parents=[kserve.model_server.parser])
args, _ = parser.parse_known_args()

if __name__ == "__main__":
    if args.configure_logging:
        logging.configure_logging(args.log_config_file)  # Configure kserve and uvicorn logger
    model = IrisSVMModel(
        args.model_name,
        predictor_host=args.predictor_host,
        predictor_protocol=args.predictor_protocol,
        predictor_use_ssl=args.predictor_use_ssl,
    )

    ModelServer().start([model])

 

requirements.txt 파일 작성

kserve==0.13.1
joblib
scikit-learn
numpy

 

Dockerfile 작성

FROM python:3.8-slim

COPY requirements.txt .
COPY predictor.py .
COPY model/ /mnt/model/

RUN pip install -U pip && pip install -r requirements.txt

ENTRYPOINT ["python", "-m", "predictor", "--predictor_protocol", "v2"]

 

Docker 이미지 빌드 및 푸시

docker build -t registry.dd.io/shared/iris-predictor:v2 .
docker push registry.dd.io/shared/iris-predictor:v2

 

InferenceService 배포

apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: iris-custom2
spec:
  predictor:
    serviceAccountName: s3-sa
    containers:
      - name: kserve-container
        image: registry.dd.io/shared/iris-predictor:v2
        args:
        - --model_name=iris-custom2

 

메타데이터 확인

<model-endpoint>/v2/models/<model-name>에 curl을 날려 모델 메타데이터를 확인할 수 있다.

curl http://iris-custom2.kubeflow-user-example-com.10.0.2.6.sslip.io/v2/models/iris-custom2

 

응답 예시:

{
  "name": "iris-custom2",
  "versions": null,
  "platform": "",
  "inputs": [
    {
      "name": "INPUT_0",
      "datatype": "FP32",
      "shape": [
        -1,
        4
      ]
    }
  ],
  "outputs": [
    {
      "name": "OUTPUT_0",
      "datatype": "INT32",
      "shape": [
        -1
      ]
    }
  ]
}

댓글