Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trouble in saving the Keras model to the Bentoml model store #4631

Open
rxiaogit opened this issue Apr 1, 2024 · 3 comments
Open

Trouble in saving the Keras model to the Bentoml model store #4631

rxiaogit opened this issue Apr 1, 2024 · 3 comments

Comments

@rxiaogit
Copy link

rxiaogit commented Apr 1, 2024

Versions installed on Windows 11 desktop:
bentoml 1.2.9
keras 3.1.1
tensorflow 2.16.1

The Issue:
After training a Keras model of CNN with the MNIST dataset, need to save the trained Keras model
to the Bentoml model store, but always got the ValueError complaining about the arguments of ['signatures', 'options']
not supported, though those were never passed as arguments in the save_model() call.

See the python codes below:

def main():

import bentoml
import tensorflow as tf
from tensorflow import keras

"""Trains a model for classifying digits using the MNIST dataset."""
train_images, train_labels, test_images, test_labels = prepare_mnist_training_data()

model = build_convnet_model(INPUT_SHAPE, NUM_CLASSES)

model = train_model(
    model, train_images, train_labels, test_images, test_labels, NUM_EPOCHS
)

# save the model to bento model store 
# model.save("cnn_model.keras")

bentoml.keras.save_model("keras_cnn", model)

if name == "main":
main()

And the error messages when running above codes:

Traceback (most recent call last):
File "C:\Users\rxiao\Tensorflow-Tutorial\mldeployment\mldeployment\training.py", line 138, in
main()
File "C:\Users\rxiao\Tensorflow-Tutorial\mldeployment\mldeployment\training.py", line 134, in main
bentoml.keras.save_model("keras_cnn", model)
File "C:\Users\rxiao\anaconda3\envs\tf\Lib\site-packages\bentoml_internal\frameworks\keras.py", line 267, in save_model
model.save(
File "C:\Users\rxiao\AppData\Roaming\Python\Python311\site-packages\keras\src\utils\traceback_utils.py", line 123, in error_handler
raise e.with_traceback(filtered_tb) from None
File "C:\Users\rxiao\AppData\Roaming\Python\Python311\site-packages\keras\src\models\model.py", line 309, in save
raise ValueError(
ValueError: The following argument(s) are not supported: ['signatures', 'options']

Is there a bug in the bentoml._internal.frameworks.keras library?
Or What else do I miss here?

Thanks in advance for your help!!

@dhj-git
Copy link

dhj-git commented May 27, 2024

i have the same problem

@kascesar
Copy link

same here!

@kascesar
Copy link

kascesar commented May 30, 2024

@rxiaogit @dhj-git Hello, i solved the problem. but you need to use bentoml.mlflow instead of bentoml.keras:

  1. Instantiate a server of mlflow
  2. save your model keras model into mlflow -lots of tutorials in web, just googleit-

My code

from datetime import datetime

import mlflow
import pandas as pd
import tensorflow as tf
from hydra import compose, initialize
from hydra.utils import instantiate
from mlflow.models.signature import infer_signature
from tensorflow.keras.callbacks import CSVLogger
from tensorflow.keras.optimizers import Adam

from src.utils import parse_dataset


def main():
    with initialize(version_base=None, config_path="config", job_name="test_app"):
        cfg = compose(config_name="main")
        mlflow.set_tracking_uri(cfg.mlflow.uri)
        mlflow.set_experiment("anomaly-det")
        # mlflow.keras.autolog()
        with mlflow.start_run(run_name="anomaly-csv2d-lstm-autoenconder"):
            model = instantiate(cfg.model)

            dataset = tf.data.TFRecordDataset(cfg.dataset.train)
            dataset = dataset.map(parse_dataset)
            dataset = dataset.batch(cfg.train.batch_size)
            opt = Adam(
                learning_rate=1e-4,
                epsilon=1e-6,
            )
            model.compile(loss="mse", optimizer=opt)
            csv_logger = CSVLogger("training.csv")
            model.fit(
                dataset,
                epochs=cfg.train.epocs,
                callbacks=[csv_logger],
            )
            # Login mlflow
            now = datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
            model_name = f"Conv2D_LSTM_Anomlay_Fatigue_Model_{now}"
            registered_model_name = f"Conv2D_LSTM_Anomaly_Fatigue_Model_{now}"

            df_loger = pd.read_csv("training.csv")

            # crea el signature para el modelo
            example_input = tf.random.normal((1, 1, 5, 4, 4))
            example_output = model.predict(example_input)
            signature = infer_signature(example_input.numpy(), example_output)

            mlflow.keras.log_model(
                model,
                artifact_path=model_name,
                registered_model_name=registered_model_name,
                signature=signature,
            )
            mlflow.log_table(data=df_loger, artifact_file="train-log.csv")
            mlflow.log_param("train-date", now.replace("_", " "))


if __name__ == "__main__":
    main()
  1. create a bento model
import bentoml
import mlflow
from hydra import compose, initialize

from anomaly_x_builder import XBuilderAnomaly, anomaly_mesure


initialize(version_base=None, config_path="../../config", job_name="bento-create-model")
cfg = compose(config_name="main")
mlflow.set_tracking_uri(cfg.mlflow.uri)


bentoml.mlflow.import_model(
    "fatiguelog-anomaly-detector",
    model_uri=cfg.model.mlflow_uri,
    signatures={"predict": {"batchable": False, "batch_dim": 0}},
    custom_objects={
        "x_builder": XBuilderAnomaly(),
        "anomaly_mesure": anomaly_mesure,
    },
)
  1. build a bento

My code for serve

from io import StringIO
import bentoml
import pandas as pd
from bentoml.io import JSON, Text

model_ref = bentoml.mlflow.get("fatiguelog-anomaly-detector:latest")
runner = model_ref.to_runner()
xbuilder = model_ref.custom_objects["x_builder"]
mesure = model_ref.custom_objects["anomaly_mesure"]
sample_input = pd.read_csv(
    "sample_input.csv",
    parse_dates=["shift_start_timestamp_utc", "fatigue_log_timestamp_utc"],
)

svc = bentoml.Service(
    name="fatiguelog-anomaly-detector",
    runners=[runner],
)


@svc.api(input=Text.from_sample(sample_input.to_csv(index=False)), output=JSON())
async def predict(data):
    data = pd.read_csv(StringIO(data), engine="pyarrow")
    X, dts = xbuilder(data)
    result = await runner.async_run(X)
    return {"anomaly-score": [f"{i}" for i in mesure(X, result)], "timestamp": dts}
bentoml build fatiguelog-anomaly-detector:latest
  1. serve the model
    run the following code in the folder where are the serve.py
bentoml serve .

Previously i had a problem with deplyment to AWS sagemaker , the version of bentoml thaths works for that is the 1.1.11, y don't know why.

Enjoy!
Hope this help! :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants