본문 바로가기

더 나은 엔지니어가 되기 위해/라이브러리 리뷰

BentoML - Quick Review

사전 준비

  • python 3.8.7 및 가상환경 세팅

Quick Start

설치

pip install bentoml

아래 코드 실행하려면 pandassklearn 도 깔아줘야 함.

pip install pandas sklean

코드

먼저 모델을 만들어 줌.

# model.py

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)

다음으로 모델 서빙할 코드를 적어줘야 함.

# service.py

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 IrisClassifierService(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)

위 두 코드를 사용하여 최종 결과물을 내는 코드를 짜줌.

# builder.py

# import the IrisClassifier class defined above
from service import IrisClassifierService
from model import clf

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

# 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()

이제 위 builder.py 를 실행

python builder.py

[2021-04-17 17:05:19,086] INFO - BentoService bundle 'IrisClassifierService:20210417170518_1C9E40' saved to: /Users/heumsi/bentoml/repository/IrisClassifierService/20210417170518_1C9E40

/Users/heumsi/bentoml/repository/IrisClassifierService/20210417170518_1C9E40 에 들어가보면

위처럼 하나의 서빙 프로젝트 코드가 만들어져있음. (ㄷ_ㄷ;;;;)

실행

이제 다음 명령어로 위 서빙 코드를 동작시켜보자. (서버 키는 것임)

bentoml serve IrisClassifierService:latest

2021-04-17 17:11:05,217] INFO - Getting latest version IrisClassifierService:20210417170518_1C9E40
[2021-04-17 17:11:05,250] INFO - Starting BentoML API proxy in development mode..
[2021-04-17 17:11:05,456] INFO - Your system nofile limit is 12800, which means each instance of microbatch service is able to hold this number of connections at same time. You can increase the number of file descriptors for the server process, or launch more microbatch instances to accept more concurrent connection.
======== Running on http://0.0.0.0:5000 ========
(Press CTRL+C to quit)
[2021-04-17 17:11:06,136] INFO - Starting BentoML API server in development mode..
 * Serving Flask app "IrisClassifierService" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:57169/ (Press CTRL+C to quit)

서버가 돈다.

http://127.0.0.1:57169/docs 에 가서 Open API 문서를 확인해보면

간단하게 /predict 로 요청을 날려보면

이렇게 서빙해준다. ㄷ_ㄷ...

도커 컨테이너 빌드

다음처럼 도커로 말수도 있다.

bentoml containerize IrisClassifierService:latest -t iris-classifier-service

[2021-04-17 17:37:55,019] INFO - Getting latest version IrisClassifierService:20210417172821_E99ECD
Found Bento: /Users/heumsi/bentoml/repository/IrisClassifierService/20210417172821_E99ECD
Containerizing IrisClassifierService:20210417172821_E99ECD with local YataiService and docker daemon from local environment\Build container image: iris-classifier-service:20210417172821_E99ECD

잘 말아졌는지 확인해보면

docker images

REPOSITORY                                TAG                     IMAGE ID            CREATED             SIZE
iris-classifier-service                   20210417172821_E99ECD   468e8e135479        48 seconds ago      1.42GB

docker 명령어까지 모두 래핑해놨네.
docker run 할 때 worker 인자로 워커 수 설정까지 가능ㅋ

docker run -p 5000:5000 iris-classifier-service:20210417172821_E99ECD --workers=2

Management 및 UI

그리고 위에서 만든 모델은 yatai service 라는 것으로 볼 수 있다.
다음 명령어로 yatai 서버를 실행하자.

bentoml yatai-service-start

* Starting BentoML YataiService gRPC Server
* Debug mode: off
* Web UI: running on http://127.0.0.1:3000
* Running on 127.0.0.1:50051 (Press CTRL+C to quit)
* Help and instructions: https://docs.bentoml.org/en/latest/guides/yatai_service.html
* Web server log can be found here: /Users/heumsi/bentoml/logs/yatai_web_server.log
-----
* Usage in Python:
*  bento_svc.save(yatai_url="127.0.0.1:50051")
*  from bentoml.yatai.client import get_yatai_client
*  get_yatai_client("127.0.0.1:50051").repository.list()
* Usage in CLI:
*  bentoml list --yatai-url=127.0.0.1:50051
*  bentoml containerize IrisClassifier:latest --yatai-url=127.0.0.1:50051
*  bentoml push IrisClassifier:20200918001645_CD2886 --yatai-url=127.0.0.1:50051
*  bentoml pull IrisClassifier:20200918001645_CD2886 --yatai-url=127.0.0.1:50051
*  bentoml retrieve IrisClassifier:20200918001645_CD2886 --yatai-url=127.0.0.1:50051 --target_dir="/tmp/foo/bar"
*  bentoml delete IrisClassifier:20200918001645_CD2886 --yatai-url=127.0.0.1:50051

127.0.0.1:3000 으로 들어가보면

요렇게 대시보드를 제공해준다. (프론트 서버는 3000 포트고, 백엔드 서버는 50051 이 기본 설정 값이다.)

물론 yatai 도 다음처럼 도커로 실행 가능하다.

docker run \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ~/bentoml:/bentoml \
  -p 3000:3000 \
  -p 50051:50051 \
  bentoml/yatai-service:latest

bentoml CLI

사실 지금까지 모든 기능은 bentoml CLI 에서 확인할 수 있음.


후기

  • CLI 가 해주는게 뭐가 이렇게 많냐... 해주는게 되게 많고 인터페이스가 짱좋다!
  • 모델, 인풋, 아웃풋만 잘 짜놓으면 서버 코드는 작성할 일이 없넹 ...
  • CI/CD 에 잘 녹여내면 한방에 배포까지 가능할텐데 어떻게 조합하면 좋을까?
  • 모델에 대한 내용은 잘 없는데, 이 앞에 모델 관리는 어떻게 해야할 지도 찾아봐야겠다!

더 보면 좋을 내용들