(mlflow는 실험, 프로젝트, 모델 관리와 서빙을 두루 한다면 bentoML은 모델 서빙에 집중한 라이브러리)
진행순서
1. 모델 훈련
2. BentoService 인스턴스 만들기
3. BentoService#pack 으로 학습된 모델 아티팩트 패키징
4. BentoService#save 로 Bento 에 저장
pip install bentoml
<Iris 데이터를 활용한 SVC 모델 구현>
from sklearn import svm
from sklearn import datasets
iris = datasets.load_iris()
X, y = iris.data, iris.target
clf=svm.SVC(gamma='scale')
clf.fit(X,y)
< 분류모델 서비스 생성 1>
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):
@api(input=DataframeInput(), batch=True)
def predict(self, df:pd.DataFrame):
rerturn self.artifacts.model.predict(df)
< 분류모델 서비스 생성 2>
@artifact는 예측 서비스에 필요한 모델파일들을 지정.
@env 에서 파이썬패키지 지정
@api는 예측 서비스에 액세스하기위한 endpoint, 추론 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):
@api(input=DataframeInput(), batch=True)
def predict(self, df:pd.DataFrame):
return self.artifacts.model.predict(df)
<배포를 위한 서비스 저장>
IrisClassifier 위에 정의한 예측 서비스 클래스로 학습 된 모델을 패키징.
배포를 위해 IrisClassifier 인스턴스를 BentoML 형식으로 디스크에 저장.
from iris_classifier import IrisClassifier
from sklearn import svm
from sklearn import datasets
iris = datasets.load_iris()
X,y = iris.data, iris.target
clf = svm.SVC(gamma='scale')
clf.fit(X, y)
iris_classifier_service = IrisCalssifier()
iris_classifier_service.pack('model', clf)
saved_path = iris_classifier_service.save()
<모델 서빙>
$ bentoml serve IrisClassifier:latest
<추론 요청 실행>
bentoml run IrisClassifier:latest predict --input '[[5.1, 3.5, 1.4, 0.2]]'
or
curl -i \
--header "Content-Type:application/json" \
--request POST \
--data '[[5.1, 3.5, 1.4, 0.2]]' \
http://localhost:5000/predict
<도커 컨테이너화>
$ bentoml containerize IrisClassifier:latest -t iris-classifier
<Fashion Mnist 데이터 텐서플로우2.0 이미지 분류 서빙 예제>
import io
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
fashion_mnist = tf.keras.datasets.fashion_mnist
(_train_images, train_labels) , (_test_images, test_labels) = fashion_mnist.load_data()
class_names = ['T-shirt/top' , 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
train_images = _train_images/255.0
test_images = _test_images/255.0
class FashionMnist(tf.keras.Model):
def__init__(self):
super(FashionMnist, self).__init__()
self.cnn = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28,28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax'),
])
@staticmethod
def image_bytes2tensor(inputs):
with tf.device("cpu:0"):
inputs = tf.map_fn(lambda i : tf.io.decode_png(i, channels=1), inputs, dtype=tf.unit8)
inputs = tf.cast(inputs, tf.float32)
inputs = (255.0 - inputs) / 255.0
inputs = tf.reshape(inputs, [-1, 28, 28])
return inputs
@tf.function(input_signature=[tf.TensorSpec(shape=(None,), dtype=tf.string)])
def predict_image(self, inputs):
inputs = self.image_bytes2tensor(inputs)
return self(inputs)
def call(self, inputs):
return self.cnn(inputs)
<테스트용 이미지 생성>
d_test_img = _test_images[0]
print(class_names[test_labels[0]])
plt.imshow(255.0 - d_test_img, cmap='gray')
plt.imsave("test.png", 255.0 - d_test_img, cmap='gray')
#바이트 읽기
with open("test.png", "rb") as f:
img_bytes = f.read()
#저장된 이미지 확인
assert tf.reduce_mean(FashionMnist.image_bytes2tensor(tf.constant([img_bytes])) - d_tes_img) < 0.01
<모델 학습>
model = FashionMnist()
model.compile(optimizer = 'adam',
loss='spare_categorical_crossentropy',
metrics = ['accuracy']
)
model.fit(train_images, train_labels, epochs=50)
<모델 추론 동작 확인>
predict = model.predict_image(tf.constant([img_bytes]))
klass = tf.argmax(predict, axis=1)
[class_names[c] for c in klass]
<BentoService 클래스 생성>
import bentoml
import tensorflow as tf
from bentoml.artifact import TensorflowSavedModelArtifact
from bentoml.adapters import TfTensorInput
FASHION_MNIST_CLASSES = ['T-shirt/top' , 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
@bentoml.env(pip_dependencies = ['tensorflow','numpy', 'pilow'])
@bentoml.artifacts([TensorflowSavedModelArtifact('model')])
class FashionMnistTensorflow(bentoml.BentoService):
@bentoml.api(input=TfTensorInput(), batch=True)
def predict(self, inputs):
outputs = self.artifacts.model.predict_image(inputs)
output_classes = tf.math.argmax(outputs, axis=1)
return [FASHION_MNIST_CLASSES[c] for c in output_classes]
from tensorflow_fashion_mnist import FashionMnistTensorflow
bento_svc = FashionMnistTensorflow()
bento_svc.pack("model", model)
saved_path = bento_svc.save()
<인퍼런스 서버 실행(모델 서빙)>
$ bentoml serve FashionMnistTensorflow:latest
<테스트이미지 base64 인코딩>
echo '{"instances":[{"b64":"'$(base64 test.png)'"}]}' > test.json
<테스트 이미지로 모델 실행>
curl -X POST http://localhost:5000/predict -d @test.json --header "Content-Type : application/json"
'스터디 > AI' 카테고리의 다른 글
[이론] 자연어처리 RNN (0) | 2023.03.17 |
---|---|
[이론] 자연어처리 intro (2) | 2023.03.17 |
[실무] 쿠베플로우 ML 파이프라인 예제2 (0) | 2023.03.03 |
[실무] 쿠베플로우 ML 파이프라인 개념,예제 (0) | 2023.03.01 |
[실무] WIT 모델 분석 (2) | 2023.02.26 |