2021년 4월 1일 목요일

Kubeflow(minikube)를 사용하여 모델 serving 하기


Kubeflow를 활용한 MLOps에 대해 공부를 시작하면서 알게 된 내용들을 기록한다.

Cloud 상이 아닌 로컬(on-premise) 환경에서 테스트했다.

 

Minikube 설치

  • Kubeflow 설치 안내 페이지에 가보면 kubeflow를 설치할 수 있는 여러 선택지가 있는데, 처음에는 Microk8s를 설치해 예제를 실행해보니 잘 안 되는 게 많았다.
  • 그 후에, Minikube를 설치해보니 훨씬 에러가 적어 minikube로 진행하게 됐다.
  • 리눅스 상에서 설치했고, 설치는 이곳을 보고 그대로 따라하면 어렵지 않다.
    • kubectl 버전은 1.15 -> 1.20로 변경했다.
    • Minikube start 시, cpu 8개, 12G 메모리를 사용했다.
    • kubeflow를 deploy할 때, 경로를 자신의 환경에 맞게 설정한다.
  • Prerequisites에 나와 있듯이 최소 8코어, 16G 메모리, 상당한 디스크 용량이 필요하며, cpu와 메모리가 부족할 시, 여러 컴포넌트들이 실행이 안되는 등 여러 문제가 생길 수 있다.

InferenceService 실행

  • 이제 모델 serving을 위한 컴포넌트를 실행해보겠다.
  • kfserving 깃허브의 예제를 따라했다. (0.4.1 버전임을 유의)
  • 'tensorflow.yaml' 파일을 실행한다.
tensorflow.yaml :
apiVersion: "serving.kubeflow.org/v1alpha2"
kind: "InferenceService"
metadata:
  name: "flowers-sample"
spec:
  default:
    predictor:
      tensorflow:
        storageUri: "gs://kfserving-samples/models/tensorflow/flowers"

  • metadata.name은 이 instance의 이름을 의미한다.
  • spec.default.predictor.tensorflow.storageUri는 모델 파일(.pb파일)이 저장되어 있는 위치를 의미하는 것 같다.
  • 실행 명령 :

kubectl apply -f tensorflow.yaml

inferenceservice.serving.kubeflow.org/flowers-sample created

  • 정상적으로 배포되다면 아래처럼 READY가 True로 되어 있는 것을 볼 수 있다.
kubectl get inferenceservice flowers-sample

NAME                URL                                              READY   DEFAULT TRAFFIC   CANARY TRAFFIC   AGE
flowers-sample   http://flowers-sample.default.example.com   True    100                                9m

  • default는 namespace를 뜻한다.


테스트

  • kfserving의 README를 참고했을 때 DNS가 없는 경우, HOST header와 INGRESS_HOST, INGRESS_PORT로 모델을 호출할 수 있다.
  • 모델을 호출하기 위한 엔드포인트는 로컬 환경 기준으로 NodePort로 되어 있고, external-ip는 <none>인 상태이다.
kubectl get -n istio-system svc/istio-ingressgateway

NAME                   TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                                                                                                      AGE
istio-ingressgateway   NodePort   10.104.40.48   <none>        15020:32026/TCP,80:31380/TCP...   129m
  • 페이지에서 좀 더 위로 가보면 INGRESS_HOST, PORT를 아래와 같이 얻을 수있다.
# Minikube
export INGRESS_HOST=$(minikube ip)

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')초
  • 최종적으로 input.json 파일을 이용하여 아래 명령을 실행하면 모델을 호출하여 결과를 확인해볼 수 있다.
CLUSTER_IP=$(kubectl -n istio-system get service flowers-sample -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -v -H "Host: ${SERVICE_HOSTNAME}" http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/flowers-sample:predict -d @./input.json'


*   Trying 192.168.49.2...
* TCP_NODELAY set
* Connected to 192.168.49.2 (192.168.49.2) port 31380 (#0)
> POST /v1/models/flowers-sample:predict HTTP/1.1
> Host: flowers-sample.default.example.com
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Length: 16193
> Content-Type: application/x-www-form-urlencoded
> Expect: 100-continue
> 
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< content-length: 220
< content-type: application/json
< date: Thu, 01 Apr 2021 07:33:01 GMT
< x-envoy-upstream-service-time: 1457
< server: istio-envoy
< 
{
    "predictions": [
        {
            "prediction": 0,
            "key": "   1",
            "scores": [0.999114931, 9.2098875e-05, 0.000136786475, 0.00033725836, 0.000300533167, 1.84814126e-05]
        }
    ]
* Connection #0 to host 192.168.49.2 left intact
}


참고 사이트 :

  • https://mokpolar.github.io/kfserving_custum_inference/

댓글 없음:

댓글 쓰기