Repository: Giskard-AI/giskard-oss
Issue: tensorflow_text_classification.upload_model_and_df fails on Amazon Sagemaker Python 3.7
Root cause: Environment Incompatibility

[GSK-367](https://giskard.youtrack.cloud/issue/GSK-367)



Note: upload_df works. It is the upload model method which fails.

Stack trace

```
INFO:tensorflow:Assets written to: ram://d02c459f-8947-407f-857f-349ca950aed6/assets
2022-11-15 22:11:39,956 pid:22826 MainThread tensorflow   INFO     Assets written to: ram://d02c459f-8947-407f-857f-349ca950aed6/assets
Hint: "Your target variable values are numeric. It is recommended to have Human readable string as your target values to make results more understandable in Giskard."
1/1 [==============================] - 0s 98ms/step
196/196 [==============================] - 1s 4ms/step
1/1 [==============================] - 0s 43ms/step
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_22826/3728236702.py in <module>
      8     classification_labels=[0,1],  # List of the classification labels of your prediction
      9     model_name='Tensorflow', # Name of the model
---> 10     dataset_name='test_data' # Name of the dataset
     11 )

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/site-packages/giskard/client/project.py in upload_model_and_df(self, prediction_function, model_type, df, column_types, feature_names, target, model_name, dataset_name, classification_threshold, classification_labels)
    377             prediction_function,
    378             target,
--> 379             df,
    380         )
    381         data_res = self._post_data(column_types, data, dataset_name, raw_column_types, target)

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/site-packages/giskard/client/project.py in _validate_model(self, classification_labels, classification_threshold, feature_names, model_type, prediction_function, target, validate_df)
    251                 )
    252 
--> 253         model = self._serialize(transformed_pred_func)
    254         return classification_labels, model
    255 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/site-packages/giskard/client/project.py in _serialize(prediction_function)
     34             ]
     35     ) -> bytes:
---> 36         compressed_pickle: bytes = compress(pickle_dumps(prediction_function))
     37         return compressed_pickle
     38 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/site-packages/giskard/client/io_utils.py in pickle_dumps(variable)
     14 
     15 def pickle_dumps(variable: object) -> bytes:
---> 16     pickle: bytes = cloudpickle.dumps(variable)
     17     return pickle
     18 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/site-packages/cloudpickle/cloudpickle_fast.py in dumps(obj, protocol)
    100         with io.BytesIO() as file:
    101             cp = CloudPickler(file, protocol=protocol)
--> 102             cp.dump(obj)
    103             return file.getvalue()
    104 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/site-packages/cloudpickle/cloudpickle_fast.py in dump(self, obj)
    630     def dump(self, obj):
    631         try:
--> 632             return Pickler.dump(self, obj)
    633         except RuntimeError as e:
    634             if "recursion" in e.args[0]:

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/pickle.py in dump(self, obj)
    435         if self.proto >= 4:
    436             self.framer.start_framing()
--> 437         self.save(obj)
    438         self.write(STOP)
    439         self.framer.end_framing()

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/pickle.py in save(self, obj, save_persistent_id)
    502         f = self.dispatch.get(t)
    503         if f is not None:
--> 504             f(self, obj) # Call unbound method with explicit self
    505             return
    506 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/site-packages/cloudpickle/cloudpickle_fast.py in save_function(self, obj, name)
    817             else:
    818                 return self._save_reduce_pickle5(
--> 819                     *self._dynamic_function_reduce(obj), obj=obj
    820                 )
    821 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/site-packages/cloudpickle/cloudpickle_fast.py in _save_reduce_pickle5(self, func, args, state, listitems, dictitems, state_setter, obj)
    754             self.save_reduce(
    755                 func, args, state=None, listitems=listitems,
--> 756                 dictitems=dictitems, obj=obj
    757             )
    758             # backport of the Python 3.8 state_setter pickle operations

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
    636         else:
    637             save(func)
--> 638             save(args)
    639             write(REDUCE)
    640 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/pickle.py in save(self, obj, save_persistent_id)
    502         f = self.dispatch.get(t)
    503         if f is not None:
--> 504             f(self, obj) # Call unbound method with explicit self
    505             return
    506 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/pickle.py in save_tuple(self, obj)
    787         write(MARK)
    788         for element in obj:
--> 789             save(element)
    790 
    791         if id(obj) in memo:

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/pickle.py in save(self, obj, save_persistent_id)
    502         f = self.dispatch.get(t)
    503         if f is not None:
--> 504             f(self, obj) # Call unbound method with explicit self
    505             return
    506 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/pickle.py in save_tuple(self, obj)
    772         if n <= 3 and self.proto >= 2:
    773             for element in obj:
--> 774                 save(element)
    775             # Subtle.  Same as in the big comment below.
    776             if id(obj) in memo:

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/pickle.py in save(self, obj, save_persistent_id)
    502         f = self.dispatch.get(t)
    503         if f is not None:
--> 504             f(self, obj) # Call unbound method with explicit self
    505             return
    506 

~/anaconda3/envs/amazonei_pytorch_latest_p37/lib/python3.7/site-packages/dill/_dill.py in save_cell(pickler, obj)
   1224 def save_cell(pickler, obj):
   1225     log.info("Ce: %s" % obj)
-> 1226     f = obj.cell_contents
   1227     pickler.save_reduce(_create_cell, (f,), obj=obj)
   1228     log.info("# Ce")

ValueError: Cell is empty
```



Project: Giskard
Reporter: alex
Created: 2022-11-15