YoungHun Jo
06/03/2024, 8:25 AMclass interface formatYoungHun Jo
06/03/2024, 8:25 AMimport bentoml
import os
from <http://bentoml.io|bentoml.io> import NumpyNdarray
from numpy import ndarray
bento_svc_name = os.getenv("BENTOML_SVC_NAME")
bento_model_name = os.getenv("BENTOML_MODEL_NAME")
bento_model = bentoml.mlflow.get(f"{bento_model_name}:latest")
bento_runner = bento_model.to_runner()
svc = bentoml.Service(
name=bento_svc_name,
runners=[bento_runner]
)
def preprocess(x: ndarray) -> ndarray:
return x
@svc.api(input=NumpyNdarray(), output=NumpyNdarray())
def predict(x: ndarray) -> ndarray:
x = preprocess(x)
y = bento_runner.predict.run(x)
return y
But, I defined the same server using class interface format of api. this code is below.
import bentoml
import os
from pydantic import BaseModel, Field
bento_svc_name = os.getenv("BENTOML_SVC_NAME", "tabular-diabetes-regressor-v1-bento-svc")
bento_model_name = os.getenv("BENTOML_MODEL_NAME", "tabular-diabetes-regressor-v1-bento-model")
bento_model = bentoml.mlflow.get(f"{bento_model_name}:latest")
bento_runner = bento_model.to_runner()
class InputRequest(BaseModel):
instances: list[float] = Field(example=[0,1,2,3,4,5,6,7,8,9])
class OutputResponse(BaseModel):
y: float
@bentoml.service(runners=[bento_runner])
class ZeddTest:
def __init__(self) -> None:
self.bento_runner = bento_runner
@bentoml.api(input_spec=InputRequest, output_spec=OutputResponse)
def predict(self, instances):
y = self.bento_runner.predict.run(instances)
return y
And I command bentoml serve service:ZeddTest and when on swagger-ui I request to server and encountered this error.
Traceback (most recent call last):
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/_bentoml_impl/server/app.py", line 418, in api_endpoint_wrapper
resp = await self.api_endpoint(name, request)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/_bentoml_impl/server/app.py", line 508, in api_endpoint
output = await self._to_thread(func, *input_args, **input_params)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/_bentoml_impl/server/app.py", line 363, in _to_thread
output = await anyio.to_thread.run_sync(func, limiter=self._limiter)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/anyio/to_thread.py", line 56, in run_sync
return await get_async_backend().run_sync_in_worker_thread(
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 2144, in run_sync_in_worker_thread
return await future
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 851, in run
result = context.run(func, *args)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/_bentoml_sdk/method.py", line 131, in wrapped
return self.func(instance, *args, **kwargs)
File "/Users/zedd.ai/home-mlops/serving/tabular-diabetes-regressor/bento-ml/service.py", line 28, in predict
y = self.bento_runner.predict.run(instances)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/bentoml/_internal/runner/runner.py", line 53, in run
return self.runner._runner_handle.run_method(self, *args, **kwargs)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/bentoml/_internal/runner/runner_handle/__init__.py", line 71, in run_method
raise StateException(
bentoml.exceptions.StateException: Runner is not initialized. Make sure to include '<bentoml._internal.runner.runner_handle.DummyRunnerHandle object at 0x16e256440>' to your service definition.
What is the reason of this error? I asked ChatGPT and googling but I can't fix it.. plz advise me!Jian Shen Yap
06/03/2024, 10:23 AMto_runner() you will have to do a runner_service()
conversion instead.
https://docs.bentoml.com/en/latest/guides/services.html#convert-legacy-runners-to-a-service
If you want to use the runner method, you will have to use the legacy API, 1.1 where you can see the documentation here.
https://docs.bentoml.com/en/v1.1.11/concepts/service.htmlYoungHun Jo
06/03/2024, 1:19 PMrunner component is no longer supported and using runner_service() is only for migration for legacy code.
So, I wonder the official code when making BentoML with model trained by MLflow. Is guideline exist?YoungHun Jo
06/05/2024, 11:58 AMdiabetes toy-dataset
• Based on docs
import bentoml
import os
from numpy import ndarray
bento_svc_name = os.getenv("BENTOML_SVC_NAME", "tabular-diabetes-regressor-v1-bento-svc")
bento_model_name = os.getenv("BENTOML_MODEL_NAME", "tabular-diabetes-regressor-v1-bento-model")
bento_model = bentoml.mlflow.get(f"{bento_model_name}:latest")
bento_legacy_runner = bento_model.to_runner()
bento_runner_svc = bentoml.runner_service(runner=bento_legacy_runner)
@bentoml.service(
traffic={"timeout": 10},
resources={"cpu": "2"},
name=bento_svc_name
)
class DiabetesRegressor:
runner = bentoml.depends(bento_runner_svc)
@bentoml.api
def predict(self, x: ndarray) -> ndarray:
x = self.preprocess(x)
# print(type(self.runner.predict), dir(self.runner.predict))
y = self.runner.predict.run(x)
return y
def preprocess(self, x: ndarray) -> ndarray:
return x
and run command bentoml serve service:DiabetesRegressor and call /predict API, below error occured.
Traceback (most recent call last):
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/_bentoml_impl/server/app.py", line 418, in api_endpoint_wrapper
resp = await self.api_endpoint(name, request)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/_bentoml_impl/server/app.py", line 508, in api_endpoint
output = await self._to_thread(func, *input_args, **input_params)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/_bentoml_impl/server/app.py", line 363, in _to_thread
output = await anyio.to_thread.run_sync(func, limiter=self._limiter)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/anyio/to_thread.py", line 56, in run_sync
return await get_async_backend().run_sync_in_worker_thread(
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 2144, in run_sync_in_worker_thread
return await future
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 851, in run
result = context.run(func, *args)
File "/Users/zedd.ai/.pyenv/versions/home-mlops/lib/python3.10/site-packages/_bentoml_sdk/method.py", line 131, in wrapped
return self.func(instance, *args, **kwargs)
File "/Users/zedd.ai/home-mlops/serving/tabular-diabetes-regressor/bento-ml/service.py", line 26, in predict
y = self.runner.predict.run(x)
AttributeError: 'function' object has no attribute 'run'
So, I verbose type and dir of self.runner.predict and I check it is just function and has a callable method (___call___) So, I changed my code removing run
• Changed code
import bentoml
import os
from numpy import ndarray
bento_svc_name = os.getenv("BENTOML_SVC_NAME", "tabular-diabetes-regressor-v1-bento-svc")
bento_model_name = os.getenv("BENTOML_MODEL_NAME", "tabular-diabetes-regressor-v1-bento-model")
bento_model = bentoml.mlflow.get(f"{bento_model_name}:latest")
bento_legacy_runner = bento_model.to_runner()
bento_runner_svc = bentoml.runner_service(runner=bento_legacy_runner)
@bentoml.service(
traffic={"timeout": 10},
resources={"cpu": "2"},
name=bento_svc_name
)
class DiabetesRegressor:
runner = bentoml.depends(bento_runner_svc)
@bentoml.api
def predict(self, x: ndarray) -> ndarray:
x = self.preprocess(x)
print(type(self.runner.predict), dir(self.runner.predict))
y = self.runner.predict(x) # it is changed!
return y
def preprocess(self, x: ndarray) -> ndarray:
return x
and run bentoml serve service:DiabetesRegressor and call /predict API, I got a 200 status.
please modify content of docs for anyone who has trouble with this problem. Thanks!