[MLOps] BentoML 기초

BentoML

학습과 하이퍼 파라미터 튜닝이 끝난 머신러닝 모델을 인퍼런스에 사용하기 위해 배포하는 것을 모델 서빙 이라고 합니다. 보통은 FlaskFastAPI와 같은 경량 웹 프레임워크를 사용하여 앤드포인트를 생성하는 것이 일반적인데요. 요구조건이 까다로운 경우 (batch 크기가 크거나 트래픽이 크거나 등등), 데이터 분석가들에게 큰 부담이 됩니다. BentoML은 이러한 모델 서빙에 특화된 ML 프레임워크 입니다. Tensorflow, PyTorch, XGBoost 등 다양한 ML 프레임워크를 지원하고 API 서빙이나 배치 서빙에 높은 성능을 보여줍니다. 또한 YataiService를 통해 웹 대시보드를 제공하여 모델 레지스트리나 배포 관리를 체계적으로 할 수 있죠.

배포 과정

준비 사항

빈 디렉토리에 가상환경을 하나 생성하고 pip을 통해 bentoml 을 설치해줍니다.

python -m venv venv
. venv/bin/activate
pip install bentoml

모델 학습

모델 서빙을 위해선 모델 학습이 선행되어야 하겠죠? iris 데이터를 통해 간단하게 학습시켜 봅시다.

from sklearn import svm
from sklearn import datasets

# Load training data
iris = datasets.load_iris()
X, y = iris.data, iris.target

# Model Training
clf = svm.SVC(gamma='scale')
clf.fit(X, y)

예측 서비스 만들기

모델 학습이 끝나고 나면 인퍼런스를 위해 서비스 클래스를 생성해야 합니다. 여기서 사용할 모델과 인퍼런스 API 옵션 등에 대해 정의합니다.

import pandas as pd

from bentoml import env, artifacts, api, BentoService
from bentoml.adapters import DataframeInput
from bentoml.frameworks.sklearn import SklearnModelArtifact

@env(infer_pip_packages=True)
@artifacts([SklearnModelArtifact('model')])
class IrisClassifier(BentoService):
    """
    A minimum prediction service exposing a Scikit-learn model
    """

    @api(input=DataframeInput(), batch=True)
    def predict(self, df: pd.DataFrame):
        """
        An inference API named `predict` with Dataframe input adapter, which codifies
        how HTTP requests or CSV files are converted to a pandas Dataframe object as the
        inference API function input
        """
        return self.artifacts.model.predict(df)

@artifact(...) 에서 학습된 모델의 타입을 적어줍니다. 우리는 sklearn 으로 학습했기 때문에 SKlearnModelArtifact를 사용했습니다. sklearn 말고도 여러 ML 프레임워크 Artifact 가 내장되어 있습니다. @env 데코레이터는 인퍼런스에 필요한 디펜던시나 환경 정보 등을 명시할 때 사용합니다. 여기선 infer_pip_packages=True 인데, BentoML 이 자동으로 이 코드에 사용된 파이썬 패키지들을 찾아서 등록해줍니다.

@api 데코레이터는 인퍼런스 API 를 정의하는데, 실제로 인퍼런스 시 동작하는 메소드입니다. input=DataframeInput() 은 이 메소드가 pandas.Dataframe을 입력으로 사용한다는 의미입니다. batch=True 옵션으로 인해 이 메소드는 입력을 리스트 단위로 받고, 출력 또한 리스트 단위로 내뱉습니다. BentoML 은 자동으로 HTTP JSON 요청을 받아서 pandas.Dataframe 으로 변환시켜 줍니다. BentoML 은 API 요청들을 그룹으로 묶어서 여러개의 배치 단위로 처리하기 때문에 FlaskFastAPI 기반 인퍼런스 모델보다 월등한 성능을 보여줍니다.

모델 관리

위에서 만든 BentoService를 BentoML 형식으로 디스크에 저장하여 배포할 수 있습니다.

# import the IrisClassifier class defined above
from bento_service import IrisClassifier

# Create a iris classifier service instance
iris_classifier_service = IrisClassifier()

# Pack the newly trained model artifact
iris_classifier_service.pack('model', clf)

# Save the prediction service to disk for model serving
saved_path = iris_classifier_service.save()

BentoML은 패키지 된 모델들을 디폴트로 ~/bentoml/repository에 저장합니다. 여기에 배포에 필요한 코드, 파일, 설정 정보, 도커 파일 등이 저장됩니다. 모델 관리와 배포는 YataiService라는 것을 통해 웹 대시보드에서 관리할 수 있습니다.

bentoml yatai-service-start

모델 서빙

아래 명령어를 통해 REST API 서버를 실행할 수 있습니다. 모델 이름과 버전 정보를 넘겨주면 됩니다.

bentoml serve IrisClassfier:latest

5000번 포트로 접속하면 스웨거 문서를 볼 수 있습니다. /predict 에 POST 콜을 통해 인퍼런스를 수행합니다.

curl -i \
  --header "Content-Type: application/json" \
  --request POST \
  --data '[[5.1, 3.5, 1.4, 0.2]]' \
  http://localhost:5000/predict

혹은 bentoml cli 를 통해 인퍼런스를 수행할 수도 있습니다.

bentoml run IrisClassifier:latest predict --input '[[5.1, 3.5, 1.4, 0.2]]'

bentoml run IrisClassifier:latest predict --input-file './iris_data.csv'

모델 도커라이징

bentoml 명령어로 모델을 도커라이징하여 배포를 도커 상에 손쉽게 할 수 있습니다.

bentoml containerize IrisClassfier:latest -t iris-container

도커 상에 배포

docker run -p 5000:5000 iris-classifier:latest --workers=2

이렇게 도커라이징 된 모델은 Kubeflow 등에 배포되어 A/B 테스팅, 오토 스케일링 등 좀 더 다양한 요구 조건을 만족시킬 수 있습니다.


© 2021. All rights reserved.

Powered by Hydejack v9.1.4