본문 바로가기

MLOps

셀던 코어와 텐서플로우 서빙

텐서플로우 서빙 공식 문서 : https://www.tensorflow.org/tfx/guide/serving?hl=ko 

 

모델 적용하기  |  TFX  |  TensorFlow

도움말 Kaggle에 TensorFlow과 그레이트 배리어 리프 (Great Barrier Reef)를 보호하기 도전에 참여 모델 적용하기 소개 TensorFlow Serving은 운영 환경을 위해 설계되었으며 머신러닝 모델을 고성능으로 적용

www.tensorflow.org

A/B Testing with Seldon Core에서 inference 컴포넌트를 커스텀 컨테이너로 제작하였다. 구체적으로 모델 로드와 predict 함수를 파이썬 코드로 직접 구현하고 도커파일로 이미지를 만들었다. 이렇게 하면 말 그대로 커스텀이니까 자유도가 높다는 장점이 있지만 파이썬 웹 프레임워크인 Flask로 모델을 서빙하기 때문에 파이썬의 단점을 고스란히 갖게 된다.

 

파이썬은 Global Interpreter Lock(GIL) 때문에 진정한 multi-threading이 지원되지 않는다. 대신 한 쓰레드가 계속 번갈아가면서 실행하는 것이다. 그래서 파이썬 API에 한번에 많은 요청이 들어오면 오버헤드가 크다. Gunicorn worker를 여러 개 사용하면 이 문제가 완화되지만 여전히 C++ 등 멀티쓰레딩을 지원하는 언어로 작성된 코드에 비해 느리고 구니콘 워커 수를 최적화해야된다는 어려움이 있다.

 

Tensorflow serving을 사용하면 파이썬의 단점을 피해갈 수 있다. 텐서플로우 서빙은 텐서플로우 모델을 gRPC/REST API로 변환해주는, 상당히 최적화된 C++ 기반 모델 서빙 툴이다. 이번 포스트에서는 셀던 코어 ML 파이프라인에 텐서플로우 서빙으로 구현된 inference component를 넣어보기로 하였다. 아래 그림과 같이 전처리 다음에 inference를 하는 간단한 ML 파이프라인을 만들어볼 것이다.

 

전처리 컴포넌트는 A/B Testing with Seldon Core에서 만든 도커 이미지를 그대로 사용한다고 하자. 전처리 컴포넌트는 raw feature로 이루어진 numpy array X를 받아 전처리된 array로 응답한다. 텐서플로우 서빙으로 구현된 inference 컴포넌트는 이 전처리된 array를 받아서 모델의 예측값으로 응답한다.

 

학습된 모델은 텐서플로우의 save 메서드로 쿠버네티스의 PV(Persistent Volume)에 이미 저장되었다고 가정하자. 그 외에도 google cloud storage, s3, azure blob, 로컬 저장소에 저장된 모델을 사용할 수 있다.

 

텐서플로우 서빙을 사용하면 별도의 코드나 도커파일을 작성할 필요가 없다. 바로 yaml 파일 작성에 들어가자.

 

apiVersion: machinelearning.seldon.io/v1alpha2
kind: SeldonDeployment
metadata:
  labels:
    app: seldon
  name: tf-serving-test
spec:
  name: tf-serving-deployment
  predictors:
  - componentSpecs:
    - spec:
        containers:
        - image: {전처리 컴포넌트 이미지 URL}
          imagePullPolicy: Always
          name: {전처리 컨테이너 이름}
          resources:
            requests:
              cpu: "2"
              memory: 1Gi
            limits:
              cpu: "4"
              memory: 2Gi
        - image: {Inference 컴포넌트 이미지 URL}
          imagePullPolicy: Always
          name: {Inference 컨테이너 이름}
          resources:
            requests:
              cpu: "2" 
              memory: 1Gi
            limits:
              cpu: "4"
              memory: 2Gi         
    graph:
      name: {전처리 컨테이너 이름}
      endpoint:
        type: REST
      type: TRANSFORMER
      parameters:
        - name: container_name
          type: STRING
          value: 
        - name: run_name
          type: STRING
          value:
      children:
        - name: {Inference 컨테이너 이름}
          implementation: TENSORFLOW_SERVER
          modelUri: pvc://{pvc 이름}/{모델 경로}
          parameters:
            - name: signature_name
              type: STRING
              value: serving_default
            - model_name:
              type: STRING
              value:
          type: MODEL
          children: []        
    name:
    replicas: {Pod 개수}

 

주의할 것은 {모델 경로}가 만약 models/resnet이라면 models/resnet/{모델 버전} 폴더 안에 assets, variables와 saved_model.pb가 있어야 한다. 텐서플로우 서빙은 디폴트로 가장 최신의(모델 버전이 가장 큰) 모델을 선택한다.

 

마지막으로 Kubeflow 파이프라인을 만들고 쿠베네티스에 배포하면 된다.

 

 

 

'MLOps' 카테고리의 다른 글

AWS Serverless 1편  (0) 2023.01.02
Amazon SageMaker  (0) 2022.04.25
Multi-Armed Bandit with Seldon Core  (0) 2022.02.20
Ensemble with Seldon Core  (0) 2022.02.19
A/B Testing with Seldon Core  (0) 2022.02.07