Repository navigation
Description
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
nadiaya commentedon Jul 9, 2020
Your script is using a dependency that is not installed in the container:
Also the error is coming from
Failure_Pred.pyuser script but it looks likeMy_script.pywas supposed to be used. Is it the correct stack trace?Federicofkt commentedon Jul 9, 2020
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
nadiaya commentedon Jul 9, 2020
you should be able to add it using requirement.txt file
just put in the same direction with the user script file:
Federicofkt commentedon Jul 9, 2020
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?
chuyang-deng commentedon Jul 17, 2020
Hi,
If you want to use
b3fsin your script, you can simply add the stringb3fsto 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)