In a previous post I asked about saving and loading models with custom myflow.pyfunc objects and received an excellent answer from Daniel Schneider explaining the difference between mlflow.pyfunc.PythonModel and mlflow.pyfunc.PyFuncModel.

Here, I extend the question, as the proposed solution doesn't work for me when also trying to save and retrieve model artifacts.

I have a class with a 'fit' function that calculates some values that are saved to a dict, and a 'predict' function that uses the values. The predict function works before saving to ML flow, but not on subsequent re-loading.

Initially creating the class and running it outside MLFlow (using the solution proposed by Daniel Schneider of passing None into the predict function) works fine.

# dummy data data = {'col1': [1, 2], 'col2': [3, 4]} df = pd.DataFrame(data=data) # create class class PredictSpeciality(mlflow.pyfunc.PythonModel): def fit(self): print('fit') d = {'mult': 2} return d def predict(self, context, X, d, y=None): print('predict') X['pred'] = X['col1'] * d['mult'] return X # create instance of model, return weights dict and pass weights into predict function m = PredictSpeciality() d = m.fit() m.predict(None, df, d) 

However, saving and re-loading from MLFlow:

mlflow.pyfunc.save_model(path="temp_model", python_model=m) m2 = mlflow.pyfunc.load_model("temp_model") m2.predict(None, df, d) 

Returns the following error:

predict() takes 2 positional arguments but 4 were given

I'm assuming this is again due to the differences outlined before between mlflow.pyfunc.PythonModel and mlflow.pyfunc.PyFuncModel but I'm not sure how to handle it.

1 Answer

The solution is to pass all the model_input data including the artefacts into the model as one argument. This now correctly calls and returns output from the predict method.

# dummy data data = {'col1': [1, 2], 'col2': [3, 4]} df = pd.DataFrame(data=data) # create class class PredictSpeciality(mlflow.pyfunc.PythonModel): def fit(self): print('fit') d = {'mult': 2} return d def predict(self, context, X, y=None): print('predict') df, d = X df['pred'] = df['col1'] * d['mult'] return df # create instance of model, return weights dict m = PredictSpeciality() d = m.fit() # create model input for predict function as tuple model_input = ([df, d]) m.predict(None, model_input) # save and re-load from ML flow mlflow.pyfunc.save_model(path="temp_model", python_model=m) m2 = mlflow.pyfunc.load_model("temp_model") m2.predict(model_input) 
1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.