본문 바로가기
kubenetes

KServe를 이용한 scikit-learn 모델 배포 및 사용 가이드

by kyeongseo.oh 2024. 9. 26.

이 가이드에서는 KServe를 사용하여 scikit-learn 모델을 Kubernetes 클러스터에 배포하고 사용하는 방법을 설명한다.

 

1. 모델 생성 및 저장

먼저, scikit-learn을 사용하여 모델을 준비한다. 이 예제에서는 Iris 데이터셋을 사용한 SVM 분류기를 만들어 배포한다.

from sklearn import svm
from sklearn import datasets
from joblib import dump

# 데이터 로드
iris = datasets.load_iris()
X, y = iris.data, iris.target

# 모델 생성 및 학습
clf = svm.SVC(gamma='scale')
clf.fit(X, y)

# 모델을 'model.joblib' 파일로 저장
dump(clf, 'model.joblib')

 

저장된 모델 파일은 S3 버킷과 같은 스토리지에 업로드한다.

이 예제에서는 `s3://sandbox/iris_svm/v1/` 경로에 모델을 업로드한다.

 

2. S3 접근을 위한 서비스 계정을 생성

저장소에 저장되어 있는 모델 파일에 접근하기 위한 Secret과 ServiceAccount을 생성한다.

AWS_ACCESS_KEY_ID와 AWS_SECRET_ACCESS_KEY는 base64로 인코딩된 값을 입력한다.

apiVersion: v1
kind: Secret
metadata:
  name: s3-secret
  namespace: kubeflow-user-example-com
  annotations:
    serving.kserve.io/s3-endpoint: http://10.0.2.3 # 실제 MinIO 엔드포인트로 변경
    serving.kserve.io/s3-usehttps: "0" # MinIO가 HTTP를 사용하는 경우
type: Opaque
data:
  AWS_ACCESS_KEY_ID: dkwzQW92VXBsakVqRnVmd3UzSUE=
  AWS_SECRET_ACCESS_KEY: WVdMNWhzMkI4Q0xxYVhzN0tHcDBxemY2SnRrMmxmQ0NnT0pMUFQ5eA==
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: s3-sa
  namespace: kubeflow-user-example-com
secrets:
  - name: s3-secret

 

3. KServe InferenceService 정의

KServe InferenceService를 정의하는 YAML 파일을 생성한다. 이 파일은 모델 서빙을 위한 설정을 포함한다.

apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:
  name: "iris-svm"
spec:
  predictor:
    serviceAccountName: s3-sa
    model:
      modelFormat:
        name: sklearn
      protocolVersion: v2
      runtime: kserve-sklearnserver
      storageUri: "s3://sandbox/iris_svm/v1/"

 

 

4. 모델 배포

정의한 InferenceService를 Kubernetes 클러스터에 배포한다.

 

5. 모델 서비스 확인

배포된 pod의 상태를 확인한다.

[root@km ~]# k get pod -n kubeflow-user-example-com
NAME                                                              READY   STATUS    RESTARTS   AGE
iris-svm-predictor-00001-deployment-5f9b975bc5-9zjmr              3/3     Running   0          14h

 

배포된 inferenceservice의 상태와 엔드포인트를 확인한다.

[root@km ~]# k get isvc -n kubeflow-user-example-com
NAME                        URL                                                                            READY   PREV   LATEST   PREVROLLEDOUTREVISION   LATESTREADYREVISION                         AGE
iris-svm                    http://iris-svm.kubeflow-user-example-com.10.0.2.6.sslip.io                    True           100                              iris-svm-predictor-00001                    14h

 

서비스 엔드포인트를 사용해 모델 정보를 조회한다.

[root@km ~]# curl http://iris-svm.kubeflow-user-example-com.10.0.2.6.sslip.io/v2/models/iris-svm
{"name":"iris-svm","versions":null,"platform":"","inputs":[],"outputs":[]}

 

6. 예측 요청 보내기

배포된 모델에 예측 요청을 보낸다.

import requests
import json
from pprint import pprint

sklear_iris_input = {
  "inputs": [
    {
      "name": "input",
      "shape": [2, 4],
      "datatype": "FP32",
      "data": [
        [6.8, 2.8, 4.8, 1.4],
        [6.0, 3.4, 4.5, 1.6]
      ]
    }
  ]
}

resp = requests.post(
    "http://iris-svm.kubeflow-user-example-com.10.0.2.6.sslip.io/v2/models/iris-svm/infer", 
    data=json.dumps(sklear_iris_input)
)   
pprint(resp.json())

 

  • return 값
{'id': '9eac52a8-792b-4e38-b71b-1d011df0aa3d',
 'model_name': 'iris-svm',
 'model_version': None,
 'outputs': [{'data': [1, 1],
              'datatype': 'INT32',
              'name': 'output-0',
              'parameters': None,
              'shape': [2]}],
 'parameters': None}

 

7. 실제 모델과 비교 테스트

테스트를 통해 KServe로 배포된 모델이 원본 모델과 동일한 예측 결과를 제공하는지 확인한다.

import requests
import json
from sklearn import datasets

# Iris 데이터셋 로드
iris = datasets.load_iris()

# KServe 예측 요청
sklear_iris_input = {
  "inputs": [
    {
      "name": "input",
      "shape": iris.data.shape,
      "datatype": "FP32",
      "data": iris.data.tolist()
    }
  ]
}

resp = requests.post(
    "http://iris-svm.kubeflow-user-example-com.10.0.2.6.sslip.io/v2/models/iris-svm/infer", 
    data=json.dumps(sklear_iris_input)
)   
kserve_result = resp.json()['outputs'][0]['data']

# 원본 모델 예측
original_result = clf.predict(iris.data).tolist()

# 결과 비교
print(original_result == kserve_result)  # True이면 예측 결과가 일치함

 

댓글