def test_artifact_pip_packages(tmpdir): @bentoml.artifacts([SklearnModelArtifact('model')]) @bentoml.env(pip_packages=['scikit-learn==0.23.0']) class ServiceWithList(bentoml.BentoService): @bentoml.api(input=DataframeInput()) def predict(self, df): return df service_with_list = ServiceWithList() service_with_list.save_to_dir(str(tmpdir)) requirements_txt_path = os.path.join(str(tmpdir), 'requirements.txt') with open(requirements_txt_path, 'rb') as f: saved_requirements = f.read() module_list = saved_requirements.decode('utf-8').split('\n') assert 'scikit-learn==0.23.0' in module_list
import bentoml from bentoml.adapters import DataframeInput from bentoml.artifact import SklearnModelArtifact @bentoml.env(auto_pip_dependencies=True) @bentoml.artifacts([SklearnModelArtifact('model')]) class IrisClassifier(bentoml.BentoService): @bentoml.api(input=DataframeInput()) def predict(self, df): return self.artifacts.model.predict(df)
from bentoml import env, artifacts, api, BentoService from bentoml.adapters import DataframeInput from bentoml.artifact import SklearnModelArtifact @env(auto_pip_dependencies=True) @artifacts([SklearnModelArtifact('model')]) class IrisClassifier(BentoService): @api(input=DataframeInput()) def predict(self, df): # Optional pre-processing, post-processing code goes here return self.artifacts.model.predict(df)
import os import pickle import boto3 import numpy as np from bentoml import env, artifacts, api, BentoService from bentoml.adapters import JsonInput from bentoml.artifact import SklearnModelArtifact # dependency thing: https://github.com/bentoml/BentoML/issues/984 @env(conda_channels=["conda-forge"], conda_dependencies=["ruamel.yaml"], auto_pip_dependencies=True) @artifacts([SklearnModelArtifact('scikit_model')]) class DiabetesRegressor(BentoService): @api(input=JsonInput()) def predict(self, parsed_json): # note: I think .pack(), @artifacts and self.artifacts all need to refer to the same model name # in this case, "scikit_model" # also, parsed json has a list of parsed inputs! # https://docs.bentoml.org/en/latest/api/adapters.html?highlight=JsonInput#bentoml.adapters.JsonInput # this means that if you are NOT doing batched input, you need to send exactly one input and force to [0] inp_data = np.array(parsed_json[0]['input']) return self.artifacts.scikit_model.predict(inp_data) if __name__ == "__main__": """
from bentoml import BentoService, api, env, artifacts from bentoml.artifact import SklearnModelArtifact from bentoml.adapters import DataframeInput @env(auto_pip_dependencies=True) @artifacts([SklearnModelArtifact('clf')]) class IrisClassifier(BentoService): @api(input=DataframeInput()) def predict(self, df): return self.artifacts.clf.predict(df)
from sklearn.ensemble import RandomForestRegressor import bentoml from bentoml.saved_bundle import save_to_dir from bentoml.adapters import ( DataframeInput, ImageInput, LegacyImageInput, JsonInput, # FastaiImageInput, ) from bentoml.handlers import DataframeHandler # deprecated from bentoml.artifact import PickleArtifact, SklearnModelArtifact @bentoml.artifacts([PickleArtifact("model"), SklearnModelArtifact('sk_model')]) @bentoml.env(auto_pip_dependencies=True) class ExampleBentoService(bentoml.BentoService): """ Example BentoService class made for testing purpose """ @bentoml.api( input=JsonInput(), mb_max_latency=1000, mb_max_batch_size=2000, ) def predict_with_sklearn(self, jsons): """predict_dataframe expects dataframe as input """ return self.artifacts.sk_model.predict(jsons) @bentoml.api(
# https://github.com/bentoml/BentoML/blob/master/guides/quick-start/iris_classifier.py from bentoml import env, artifacts, api, BentoService from bentoml.handlers import DataframeHandler from bentoml.artifact import SklearnModelArtifact @env(auto_pip_dependencies=True) @artifacts([SklearnModelArtifact("model")]) class IrisClassifier(BentoService): @api(DataframeHandler) def predict(self, df): # Mapping between predicted value and actual name iris_mapping = {0: "setosa", 1: "versicolor", 2: "virginica"} inference_list = self.artifacts.model.predict(df) output = [iris_mapping[element] for element in inference_list] return output
import json import bentoml import lightgbm as lgb import pandas as pd import xgboost as xgb from bentoml.adapters import JsonInput from bentoml.artifact import SklearnModelArtifact @bentoml.artifacts([SklearnModelArtifact("xgb"), SklearnModelArtifact("lgb")]) @bentoml.env( conda_channels=["conda-forge"], conda_dependencies=["lightgbm==2.3.*", "pandas==1.0.*", "xgboost==1.2.*"], ) class TitanicSurvivalPredictionService(bentoml.BentoService): @bentoml.api(input=JsonInput()) def predict(self, datain): # datain is a list of a json object. df = pd.read_json(json.dumps(datain[0]), orient="table") data = df[["Pclass", "Age", "Fare", "SibSp", "Parch"]] result = pd.DataFrame() result["xgb_proba"] = self.artifacts.xgb.predict_proba(data)[:, 1] result["lgb_proba"] = self.artifacts.lgb.predict_proba(data)[:, 1] # make sure to return as a list of json return [result.to_json(orient="table")]
def test_artifact_states(tmp_path): 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) artifact_name = 'test_model' a1 = SklearnModelArtifact(artifact_name) # verify initial states assert not a1.loaded assert not a1.packed assert not a1.is_ready # verify that get will fail with pytest.raises(FailedPrecondition): a1.get() # verify that save will fail with pytest.raises(FailedPrecondition): a1.save('anywhere') # verify states after pack a1.pack(clf) assert not a1.loaded assert a1.packed assert a1.is_ready assert isinstance(a1.get(), svm.SVC) # Test save and load artifact # 1. save the packed artifact to tempdir a1.save(tmp_path) # 2. create a new artifact with same name a2 = SklearnModelArtifact(artifact_name) # 3. load a2 from tempdir a2.load(tmp_path) # verify states after load assert a2.loaded assert a2.is_ready assert a2.packed # this dependes on the artifact implementation, in the case of # Sklearn artifact, the `load` method invokes `pack` internally assert isinstance(a2.get(), svm.SVC) assert all(a1.get().predict(X) == a2.get().predict(X))