Skip to content

Deploying ML model #1692

Closed
Closed

Description

@Federicofkt

Hi, I've locally implemented an ML model that I need to deploy on S3 and then creating a Lambda in order to invoke it.

The problem is that I'm facing tons of errors. I've tried to read the documentation and follow some notebooks, but I can't figure how to make my model working out.

Here is the code:

from sagemaker import get_execution_role
import sagemaker
import argparse
import numpy as np
import os
import pandas as pd
from sklearn.externals import joblib
pd.options.mode.chained_assignment = None
import datetime as dt
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
import io
from sagemaker.sklearn.estimator import SKLearn
import s3fs


prefix = 'FP'
sagemaker_session = sagemaker.Session()
role = get_execution_role()

data = pd.read_csv("df.csv", header = 0, usecols = ["col1", "col2"])


os.makedirs('./data_DM', exist_ok=True)
data.to_csv('./data_DM/orders.csv')

WORK_DIRECTORY = 'data_DM'

train_input = sagemaker_session.upload_data(WORK_DIRECTORY, key_prefix="{}/{}".format(prefix, WORK_DIRECTORY) )


script_path = './data_DM/My_script.py'

sklearn = SKLearn(
    entry_point=script_path,
    train_instance_type="ml.m5.2xlarge",
    role=role,
    sagemaker_session=sagemaker_session)

sklearn.fit({'train': train_input})

predictor = sklearn.deploy(initial_instance_count=1, instance_type="ml.m4.xlarge")

And here the My_script.py:

import argparse
import numpy as np
import os
import pandas as pd
from sklearn.externals import joblib
pd.options.mode.chained_assignment = None
import datetime as dt
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
import io
from sklearn import tree
import boto3, re, sys, math, json, urllib.request

def cleaning(data):
     lots of cleaning
     return cleaned data


if __name__ =='__main__':
    
    bucket_name = 'ciao'
    file_name = 'df.csv 


    data_location = 's3://{}/{}'.format(bucket_name, file_name)

    parser = argparse.ArgumentParser()

    parser.add_argument('--output-data-dir', type=str, default=os.environ['SM_OUTPUT_DATA_DIR'])
    parser.add_argument('--model-dir', type=str, default=os.environ['SM_MODEL_DIR'])
    parser.add_argument('--train', type=str, default=os.environ['SM_CHANNEL_TRAIN'])

    args = parser.parse_args()

    data = pd.read_csv(data_location, header = 0, usecols = ["col1", "col2"])

    data_ml = cleaning(data) 

    y = data_ml.loc[:,"event"]
    X = data_ml.loc[:, data_ml.columns != 'event']

    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
    
    

    model =  tree.DecisionTreeClassifier(n_estimators=600, class_weight = "balanced", random_state=42)
    model.fit(X_train, y_train)

    #Save the model to the location specified by args.model_dir
    joblib.dump(model, os.path.join(args.model_dir, "model.joblib"))



def model_fn(model_dir):
    model = joblib.load(os.path.join(model_dir, "model.joblib"))
    return model


def input_fn(request_body, request_content_type):
    if request_content_type == 'text/csv':
        samples = []
        for r in request_body.split('|'):
            samples.append(list(map(float,r.split(','))))
        return np.array(samples)
    else:
        raise ValueError("Thie model only supports text/csv input")

def predict_fn(input_data, model):
    return model.predict_proba(cleaning(input_data))

def output_fn(prediction, content_type):
    return ' | '.join([INDEX_TO_LABEL[t] for t in prediction])

Now the error is the following:
/miniconda3/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
Traceback (most recent call last):
File "/miniconda3/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"main", mod_spec)
File "/miniconda3/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/opt/ml/code/Failure_Pred.py", line 206, in
"weight", "userPrice", "amount", "nParcel"])
File "/miniconda3/lib/python3.7/site-packages/pandas/io/parsers.py", line 685, in parser_f
return _read(filepath_or_buffer, kwds)
File "/miniconda3/lib/python3.7/site-packages/pandas/io/parsers.py", line 440, in _read
filepath_or_buffer, encoding, compression
File "/miniconda3/lib/python3.7/site-packages/pandas/io/common.py", line 206, in get_filepath_or_buffer
from pandas.io import s3
File "/miniconda3/lib/python3.7/site-packages/pandas/io/s3.py", line 10, in
"s3fs", extra="The s3fs package is required to handle s3 files."
File "/miniconda3/lib/python3.7/site-packages/pandas/compat/_optional.py", line 93, in import_optional_dependency
raise ImportError(message.format(name=name, extra=extra)) from None
ImportError: Missing optional dependency 's3fs'. The s3fs package is required to handle s3 files. Use pip or conda to install s3fs.
2020-07-09 12:13:27,645 sagemaker-containers ERROR ExecuteUserScriptError:
Command "/miniconda3/bin/python -m Failure_Pred"

2020-07-09 12:13:36 Uploading - Uploading generated training model
2020-07-09 12:13:36 Failed - Training job failed

Error for Training job sagemaker-scikit-learn-2020-07-09-12-10-17-446: Failed. Reason: AlgorithmError: ExecuteUserScriptError:
Command "/miniconda3/bin/python -m Failure_Pred"

How can I fix this?

Thanks!

Activity

  1. nadiaya commented on Jul 9, 2020

    @nadiaya
    Contributor

    Your script is using a dependency that is not installed in the container:

    raise ImportError(message.format(name=name, extra=extra)) from None
    ImportError: Missing optional dependency 's3fs'. The s3fs package is required to handle s3 files. Use pip or conda to install s3fs.
    

    Also the error is coming from Failure_Pred.py user script but it looks like My_script.py was supposed to be used. Is it the correct stack trace?

  2. Federicofkt commented on Jul 9, 2020

    @Federicofkt
    Author

    Hi Nadiaya, thanks for the reply!

    How do I fix the s3fs error? I’ve tried with pip install and conda install, and the s3fs is both in pip list and conda list.

    My_script.py is actually Failure_pred.py, I just renamed here for the purpose of this question, but in my code is everywhere Failure_pred.py

  3. nadiaya commented on Jul 9, 2020

    @nadiaya
    Contributor

    you should be able to add it using requirement.txt file

    just put in the same direction with the user script file:

    script_dir = './data_DM/'
    
    sklearn = SKLearn(
        entry_point='My_script.py',
        source_dir=script_dir,
        train_instance_type="ml.m5.2xlarge",
        role=role,
        sagemaker_session=sagemaker_session)
    
  4. Federicofkt commented on Jul 9, 2020

    @Federicofkt
    Author

    Uhm I’ve read some documentation about this requirement.txt but I don’t exactly understand how can I write it, is like a .txt file with only b3fs written in it? And the uploaded into the data_DM folder?

  5. chuyang-deng commented on Jul 17, 2020

    @chuyang-deng
    Contributor

    Hi,

    If you want to use b3fs in your script, you can simply add the string b3fs to the requirements.txt, and put the requirements.txt under the same directory of your script.

    An example of requirements.txt is like this: https://github.com/aws/sagemaker-tensorflow-serving-container/blob/master/test/resources/examples/test3/requirements.txt (you do not have to specify the version of the library)

  6. locked and limited conversation to collaborators on May 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions