Skip to content

Conversation

@oliverholworthy
Copy link
Contributor

Follow up to #554

Implementation Details 🚧

In #554 ,among other things, we changed the way features are stored and passed around to layers that need the context of the inputs. e.g. the ItemRetrievalScorer.

After #554 tests using the RetrievalModel.evaluate method started breaking with tensorflow version 2.8.0. (The tests pass with the newer release 2.9.1.)

The error message is:

>       metrics = model.evaluate(
            ecommerce_data, batch_size=10, item_corpus=ecommerce_data, return_dict=True
        )

tests/unit/tf/models/test_retrieval.py:244:

merlin/models/tf/models/base.py:878: in evaluate                                                                                                                                                                           
    self.pre_eval_topk = TopKIndexBlock.from_block(
merlin/models/tf/core/index.py:208: in from_block
    return super().from_block(block=block, data=data, id_column=id_column, k=k, **kwargs)  
merlin/models/tf/core/index.py:81: in from_block                                                                                                                                                                            
    embedding_df = cls.get_candidates_dataset(block, data, id_column)
merlin/models/tf/core/index.py:112: in get_candidates_dataset
    model_encode = TFModelEncode(model=block, output_concat_func=np.concatenate)
merlin/models/tf/utils/batch_utils.py:80: in __init__                                                                                                                                                                       
    model.save(save_path)

[...]

>         raise e.ag_error_metadata.to_exception(e)
E         TypeError: in user code:
E
E             File "/usr/local/lib/python3.8/dist-packages/keras/saving/saving_utils.py", line 138, in _wrapped_model  *
E                 outputs = model(*args, **kwargs)
E             File "/workspace/dev/merlin/models/merlin/models/config/schema.py", line 58, in __call__  *
E                 return super().__call__(*args, **kwargs)
E
E             TypeError: tf__call() takes 2 positional arguments but 3 were given

The issue is that the model object. In this case the item_block of a two tower model thinks it accepts 2 arguments when actually it only wants one.

We can check this with the helper function model_call_inputs and a breakpoint in the RetrievalModel.evaluate method. which reports that the item_block has 2 arguments. (The error "2 positional arguments but 3 were given" is not 1 vs 2 because of the additional self argument.)

from keras.saving.saving_utils import model_call_inputs

len(model_call_inputs(item_block)[0])  # => 2

By wrapping the features in a class, somehow this results in the model helper correctly returning 1 instead of 2.

class Features:
    def __init__(self, values: Dict[str, TensorLike]):
        self.values = values

    def __getitem__(self, key: str) -> TensorLike:
        return self.values[key]

This is not necessary in tensorflow 2.9.0 and 2.9.1.

Testing Details 🔍

Tested on 2.8.0 and 2.9.0 locally

PR #573 extends our testing matrix to check both these versions

@oliverholworthy oliverholworthy added bug Something isn't working skip-changelog Exclude from change log labels Jul 14, 2022
@oliverholworthy oliverholworthy self-assigned this Jul 14, 2022
@nvidia-merlin-bot
Copy link

Click to view CI Results
GitHub pull request #574 of commit 93aceb1a0616db222cf526acacf50dba5e8ccd80, no merge conflicts.
Running as SYSTEM
Setting status of 93aceb1a0616db222cf526acacf50dba5e8ccd80 to PENDING with url https://10.20.13.93:8080/job/merlin_models/695/console and message: 'Pending'
Using context: Jenkins
Building on master in workspace /var/jenkins_home/workspace/merlin_models
using credential nvidia-merlin-bot
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url https://github.com/NVIDIA-Merlin/models/ # timeout=10
Fetching upstream changes from https://github.com/NVIDIA-Merlin/models/
 > git --version # timeout=10
using GIT_ASKPASS to set credentials This is the bot credentials for our CI/CD
 > git fetch --tags --force --progress -- https://github.com/NVIDIA-Merlin/models/ +refs/pull/574/*:refs/remotes/origin/pr/574/* # timeout=10
 > git rev-parse 93aceb1a0616db222cf526acacf50dba5e8ccd80^{commit} # timeout=10
Checking out Revision 93aceb1a0616db222cf526acacf50dba5e8ccd80 (detached)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 93aceb1a0616db222cf526acacf50dba5e8ccd80 # timeout=10
Commit message: "Wrap features in class"
 > git rev-list --no-walk 1df1e026e2265ec9a75b14c030f076604ac6ca6e # timeout=10
[merlin_models] $ /bin/bash /tmp/jenkins3608752064310319777.sh
Looking in indexes: https://pypi.org/simple, https://pypi.ngc.nvidia.com
Requirement already satisfied: testbook in /usr/local/lib/python3.8/dist-packages (0.4.2)
Requirement already satisfied: nbformat>=5.0.4 in /usr/local/lib/python3.8/dist-packages (from testbook) (5.4.0)
Requirement already satisfied: nbclient>=0.4.0 in /usr/local/lib/python3.8/dist-packages (from testbook) (0.6.5)
Requirement already satisfied: traitlets>=5.1 in /usr/local/lib/python3.8/dist-packages (from nbformat>=5.0.4->testbook) (5.3.0)
Requirement already satisfied: jsonschema>=2.6 in /usr/local/lib/python3.8/dist-packages (from nbformat>=5.0.4->testbook) (4.6.1)
Requirement already satisfied: jupyter-core in /usr/local/lib/python3.8/dist-packages (from nbformat>=5.0.4->testbook) (4.10.0)
Requirement already satisfied: fastjsonschema in /usr/local/lib/python3.8/dist-packages (from nbformat>=5.0.4->testbook) (2.15.3)
Requirement already satisfied: jupyter-client>=6.1.5 in /usr/local/lib/python3.8/dist-packages (from nbclient>=0.4.0->testbook) (7.3.4)
Requirement already satisfied: nest-asyncio in /usr/local/lib/python3.8/dist-packages (from nbclient>=0.4.0->testbook) (1.5.5)
Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.8/dist-packages (from jsonschema>=2.6->nbformat>=5.0.4->testbook) (21.4.0)
Requirement already satisfied: importlib-resources>=1.4.0; python_version < "3.9" in /usr/local/lib/python3.8/dist-packages (from jsonschema>=2.6->nbformat>=5.0.4->testbook) (5.8.0)
Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /usr/local/lib/python3.8/dist-packages (from jsonschema>=2.6->nbformat>=5.0.4->testbook) (0.18.1)
Requirement already satisfied: entrypoints in /usr/local/lib/python3.8/dist-packages (from jupyter-client>=6.1.5->nbclient>=0.4.0->testbook) (0.4)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.8/dist-packages (from jupyter-client>=6.1.5->nbclient>=0.4.0->testbook) (2.8.2)
Requirement already satisfied: pyzmq>=23.0 in /usr/local/lib/python3.8/dist-packages (from jupyter-client>=6.1.5->nbclient>=0.4.0->testbook) (23.2.0)
Requirement already satisfied: tornado>=6.0 in /usr/local/lib/python3.8/dist-packages (from jupyter-client>=6.1.5->nbclient>=0.4.0->testbook) (6.1)
Requirement already satisfied: zipp>=3.1.0; python_version < "3.10" in /usr/local/lib/python3.8/dist-packages (from importlib-resources>=1.4.0; python_version < "3.9"->jsonschema>=2.6->nbformat>=5.0.4->testbook) (3.8.0)
Requirement already satisfied: six>=1.5 in /var/jenkins_home/.local/lib/python3.8/site-packages (from python-dateutil>=2.8.2->jupyter-client>=6.1.5->nbclient>=0.4.0->testbook) (1.15.0)
============================= test session starts ==============================
platform linux -- Python 3.8.10, pytest-7.1.2, pluggy-1.0.0
rootdir: /var/jenkins_home/workspace/merlin_models/models, configfile: pyproject.toml
plugins: anyio-3.6.1, xdist-2.5.0, forked-1.4.0, cov-3.0.0
collected 475 items / 2 skipped

tests/unit/config/test_schema.py .... [ 0%]
tests/unit/datasets/test_advertising.py .s [ 1%]
tests/unit/datasets/test_ecommerce.py ..sss [ 2%]
tests/unit/datasets/test_entertainment.py ....sss. [ 4%]
tests/unit/datasets/test_social.py . [ 4%]
tests/unit/datasets/test_synthetic.py ..... [ 5%]
tests/unit/tf/test_core.py ...... [ 6%]
tests/unit/tf/test_dataset.py ............... [ 9%]
tests/unit/tf/test_public_api.py . [ 9%]
tests/unit/tf/blocks/test_cross.py ........... [ 12%]
tests/unit/tf/blocks/test_dlrm.py ........ [ 13%]
tests/unit/tf/blocks/test_interactions.py . [ 14%]
tests/unit/tf/blocks/test_mlp.py ................................. [ 21%]
tests/unit/tf/blocks/retrieval/test_matrix_factorization.py .. [ 21%]
tests/unit/tf/blocks/retrieval/test_two_tower.py ........... [ 23%]
tests/unit/tf/core/test_aggregation.py ......... [ 25%]
tests/unit/tf/core/test_base.py .. [ 26%]
tests/unit/tf/core/test_combinators.py ............... [ 29%]
tests/unit/tf/core/test_index.py ... [ 29%]
tests/unit/tf/core/test_prediction.py .. [ 30%]
tests/unit/tf/core/test_tabular.py .... [ 31%]
tests/unit/tf/core/test_transformations.py ...... [ 32%]
tests/unit/tf/data_augmentation/test_misc.py . [ 32%]
tests/unit/tf/data_augmentation/test_negative_sampling.py ...... [ 33%]
tests/unit/tf/data_augmentation/test_noise.py ..... [ 34%]
tests/unit/tf/examples/test_01_getting_started.py . [ 35%]
tests/unit/tf/examples/test_02_dataschema.py . [ 35%]
tests/unit/tf/examples/test_03_exploring_different_models.py . [ 35%]
tests/unit/tf/examples/test_04_export_ranking_models.py . [ 35%]
tests/unit/tf/examples/test_05_export_retrieval_model.py . [ 36%]
tests/unit/tf/examples/test_06_advanced_own_architecture.py . [ 36%]
tests/unit/tf/examples/test_usecase_pretrained_embeddings.py . [ 36%]
tests/unit/tf/inputs/test_continuous.py ..... [ 37%]
tests/unit/tf/inputs/test_embedding.py .......................... [ 42%]
tests/unit/tf/inputs/test_tabular.py ....... [ 44%]
tests/unit/tf/layers/test_queue.py .............. [ 47%]
tests/unit/tf/losses/test_losses.py ....................... [ 52%]
tests/unit/tf/metrics/test_metrics_popularity.py ..... [ 53%]
tests/unit/tf/metrics/test_metrics_topk.py .................. [ 57%]
tests/unit/tf/models/test_base.py ........... [ 59%]
tests/unit/tf/models/test_benchmark.py .. [ 59%]
tests/unit/tf/models/test_ranking.py ................ [ 63%]
tests/unit/tf/models/test_retrieval.py ............................... [ 69%]
tests/unit/tf/prediction_tasks/test_classification.py .. [ 70%]
tests/unit/tf/prediction_tasks/test_multi_task.py ....... [ 71%]
tests/unit/tf/prediction_tasks/test_next_item.py ..... [ 72%]
tests/unit/tf/prediction_tasks/test_regression.py .. [ 73%]
tests/unit/tf/prediction_tasks/test_sampling.py ...... [ 74%]
tests/unit/tf/utils/test_batch.py .... [ 75%]
tests/unit/tf/utils/test_tf_utils.py .. [ 75%]
tests/unit/torch/test_dataset.py ......... [ 77%]
tests/unit/torch/test_public_api.py . [ 77%]
tests/unit/torch/block/test_base.py .... [ 78%]
tests/unit/torch/block/test_mlp.py . [ 78%]
tests/unit/torch/features/test_continuous.py .. [ 79%]
tests/unit/torch/features/test_embedding.py ..........F... [ 82%]
tests/unit/torch/features/test_tabular.py .... [ 82%]
tests/unit/torch/model/test_head.py ............ [ 85%]
tests/unit/torch/model/test_model.py .. [ 85%]
tests/unit/torch/tabular/test_aggregation.py ........ [ 87%]
tests/unit/torch/tabular/test_tabular.py ... [ 88%]
tests/unit/torch/tabular/test_transformations.py ....... [ 89%]
tests/unit/utils/test_schema_utils.py ................................ [ 96%]
tests/unit/xgb/test_xgboost.py ................. [100%]

=================================== FAILURES ===================================
_____________________________ test_soft_embedding ______________________________

def test_soft_embedding():
    embeddings_dim = 16
    num_embeddings = 64

    soft_embedding = ml.SoftEmbedding(num_embeddings, embeddings_dim)
    assert soft_embedding.embedding_table.weight.shape == torch.Size(
        [num_embeddings, embeddings_dim]
    ), "Internal soft embedding table does not have the expected shape"

    batch_size = 10
    seq_length = 20
    cont_feature_inputs = torch.rand((batch_size, seq_length))
    output = soft_embedding(cont_feature_inputs)

    assert output.shape == torch.Size(
        [batch_size, seq_length, embeddings_dim]
    ), "Soft embedding output has not the expected shape"

    # Checking the default embedding initialization
  assert output.detach().numpy().mean() == pytest.approx(0.0, abs=0.1)

E assert 0.10143307 == 0.0 ± 1.0e-01
E comparison failed
E Obtained: 0.10143306851387024
E Expected: 0.0 ± 1.0e-01

tests/unit/torch/features/test_embedding.py:182: AssertionError
=============================== warnings summary ===============================
../../../../../usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:36
/usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:36: DeprecationWarning: NEAREST is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.NEAREST or Dither.NONE instead.
'nearest': pil_image.NEAREST,

../../../../../usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:37
/usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:37: DeprecationWarning: BILINEAR is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BILINEAR instead.
'bilinear': pil_image.BILINEAR,

../../../../../usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:38
/usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:38: DeprecationWarning: BICUBIC is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BICUBIC instead.
'bicubic': pil_image.BICUBIC,

../../../../../usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:39
/usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:39: DeprecationWarning: HAMMING is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.HAMMING instead.
'hamming': pil_image.HAMMING,

../../../../../usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:40
/usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:40: DeprecationWarning: BOX is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BOX instead.
'box': pil_image.BOX,

../../../../../usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:41
/usr/local/lib/python3.8/dist-packages/keras/utils/image_utils.py:41: DeprecationWarning: LANCZOS is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.LANCZOS instead.
'lanczos': pil_image.LANCZOS,

tests/unit/datasets/test_ecommerce.py::test_synthetic_aliccp_raw_data
tests/unit/tf/test_dataset.py::test_tf_drp_reset[100-True-10]
tests/unit/tf/test_dataset.py::test_tf_drp_reset[100-True-9]
tests/unit/tf/test_dataset.py::test_tf_drp_reset[100-True-8]
tests/unit/tf/test_dataset.py::test_tf_drp_reset[100-False-10]
tests/unit/tf/test_dataset.py::test_tf_drp_reset[100-False-9]
tests/unit/tf/test_dataset.py::test_tf_drp_reset[100-False-8]
tests/unit/tf/test_dataset.py::test_tf_catname_ordering
tests/unit/tf/test_dataset.py::test_tf_map
/usr/local/lib/python3.8/dist-packages/cudf/core/frame.py:384: UserWarning: The deep parameter is ignored and is only included for pandas compatibility.
warnings.warn(

tests/unit/tf/blocks/retrieval/test_matrix_factorization.py::test_matrix_factorization_embedding_export
tests/unit/tf/blocks/retrieval/test_matrix_factorization.py::test_matrix_factorization_embedding_export
tests/unit/tf/blocks/retrieval/test_two_tower.py::test_matrix_factorization_embedding_export
tests/unit/tf/blocks/retrieval/test_two_tower.py::test_matrix_factorization_embedding_export
tests/unit/tf/inputs/test_embedding.py::test_embedding_features_exporting_and_loading_pretrained_initializer
/var/jenkins_home/workspace/merlin_models/models/merlin/models/tf/inputs/embedding.py:566: DeprecationWarning: This function is deprecated in favor of cupy.from_dlpack
embeddings_cupy = cupy.fromDlpack(to_dlpack(tf.convert_to_tensor(embeddings)))

tests/unit/tf/core/test_index.py: 7 warnings
tests/unit/tf/models/test_retrieval.py: 317 warnings
tests/unit/tf/prediction_tasks/test_next_item.py: 3 warnings
tests/unit/tf/utils/test_batch.py: 4 warnings
/tmp/autograph_generated_filexxpaxobk.py:8: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead
ag
.converted_call(ag__.ld(warnings).warn, ("The 'warn' method is deprecated, use 'warning' instead", ag__.ld(DeprecationWarning), 2), None, fscope)

tests/unit/tf/data_augmentation/test_noise.py: 4 warnings
tests/unit/tf/models/test_base.py: 6 warnings
/usr/local/lib/python3.8/dist-packages/tensorflow/python/util/dispatch.py:1082: UserWarning: tf.keras.backend.random_binomial is deprecated, and will be removed in a future version.Please use tf.keras.backend.random_bernoulli instead.
return dispatch_target(*args, **kwargs)

tests/unit/tf/models/test_ranking.py::test_dlrm_model_multi_task[True]
tests/unit/tf/models/test_ranking.py::test_dlrm_model_multi_task[True]
tests/unit/tf/models/test_ranking.py::test_dlrm_model_multi_task[False]
tests/unit/tf/models/test_ranking.py::test_dlrm_model_multi_task[False]
/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py:2446: DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
return bool(asarray(a1 == a2).all())

tests/unit/torch/block/test_mlp.py::test_mlp_block
/var/jenkins_home/workspace/merlin_models/models/tests/unit/torch/_conftest.py:151: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ../torch/csrc/utils/tensor_new.cpp:201.)
return {key: torch.tensor(value) for key, value in data.items()}

tests/unit/xgb/test_xgboost.py::test_without_dask_client
tests/unit/xgb/test_xgboost.py::TestXGBoost::test_music_regression
tests/unit/xgb/test_xgboost.py::test_gpu_hist_dmatrix[fit_kwargs0-DaskDeviceQuantileDMatrix]
tests/unit/xgb/test_xgboost.py::test_gpu_hist_dmatrix[fit_kwargs1-DaskDMatrix]
tests/unit/xgb/test_xgboost.py::TestEvals::test_multiple
tests/unit/xgb/test_xgboost.py::TestEvals::test_default
tests/unit/xgb/test_xgboost.py::TestEvals::test_train_and_valid
tests/unit/xgb/test_xgboost.py::TestEvals::test_invalid_data
/var/jenkins_home/workspace/merlin_models/models/merlin/models/xgb/init.py:266: UserWarning: Ignoring list columns as inputs to XGBoost model: ['item_genres', 'user_genres'].
warnings.warn(f"Ignoring list columns as inputs to XGBoost model: {list_column_names}.")

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
SKIPPED [1] tests/unit/implicit/init.py:18: could not import 'implicit': No module named 'implicit'
SKIPPED [1] tests/unit/lightfm/init.py:18: could not import 'lightfm': No module named 'lightfm'
SKIPPED [1] tests/unit/datasets/test_advertising.py:20: No data-dir available, pass it through env variable $INPUT_DATA_DIR
SKIPPED [1] tests/unit/datasets/test_ecommerce.py:62: ALI-CCP data is not available, pass it through env variable $DATA_PATH_ALICCP
SKIPPED [1] tests/unit/datasets/test_ecommerce.py:78: ALI-CCP data is not available, pass it through env variable $DATA_PATH_ALICCP
SKIPPED [1] tests/unit/datasets/test_ecommerce.py:92: ALI-CCP data is not available, pass it through env variable $DATA_PATH_ALICCP
SKIPPED [3] tests/unit/datasets/test_entertainment.py:44: No data-dir available, pass it through env variable $INPUT_DATA_DIR
===== 1 failed, 467 passed, 9 skipped, 374 warnings in 1578.07s (0:26:18) ======
Build step 'Execute shell' marked build as failure
Performing Post build task...
Match found for : : True
Logical operation result is TRUE
Running script : #!/bin/bash
cd /var/jenkins_home/
CUDA_VISIBLE_DEVICES=1 python test_res_push.py "https://api.GitHub.com/repos/NVIDIA-Merlin/models/issues/$ghprbPullId/comments" "/var/jenkins_home/jobs/$JOB_NAME/builds/$BUILD_NUMBER/log"
[merlin_models] $ /bin/bash /tmp/jenkins403355694350629220.sh

@github-actions
Copy link

Documentation preview

https://nvidia-merlin.github.io/models/review/pr-574

@oliverholworthy
Copy link
Contributor Author

We have tracked down the underlying reason for this in the way the save model spec is computed. And have adopted a different solution in #582

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working skip-changelog Exclude from change log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants