NVIDIA-Merlin / NVIDIA-Merlin/Transformers4Rec

[BUG] `Model.load` raises TypeError on Python 3.9+ (parameterized generic in isinstance)

Open Beginner friendly
#810 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.3k
Forks
165
Avg merge
1m
Merged PRs (30d)
2

Description

Bug description

After PR #809 (commit 8bf122f5), transformers4rec.torch.model.base.Model.load() uses a parameterized generic as the second argument to isinstance:

https://github.com/NVIDIA-Merlin/Transformers4Rec/blob/8bf122f5dcb39feecfc6dabde734d79c2d1c4380/transformers4rec/torch/model/base.py#L917

if isinstance(state_dict, Dict[str, torch.Tensor]):
    model.load_state_dict(state_dict, strict=strict)
else:
    raise ValueError("`state_dict` must be a dictionary of parameter (torch) tensors.")

On Python 3.9+ this raises TypeError: Subscripted generics cannot be used with class and instance checks before any of the load logic runs. Net effect: Model.load() is completely unusable on current main.

The regression is not caught by the existing test tests/unit/torch/model/test_model.py::test_save_next_item_prediction_model, which is the only place in the test suite that reaches this line. CI does not appear to exercise it on a clean env (likely the copy-pr-bot runners are currently blocked, see #798).

Steps/Code to reproduce bug

Pure-Python repro (no T4Rec install needed):

from typing import Dict
import torch

isinstance({"a": torch.zeros(1)}, Dict[str, torch.Tensor])
# TypeError: Subscripted generics cannot be used with class and instance checks

Library-level repro:

import torch
from transformers4rec.torch.model.base import Model

Model.load({"a": torch.zeros(1)}, heads=[])   # raises TypeError before anything else
Expected behavior

Model.load() should accept a plain dict (as returned by state_dict() or torch.load) and load the weights into the provided heads.

Environment details
  • Transformers4Rec: main @ 8bf122f5
  • Python: any 3.9+ (documented semantics; all modern installs affected)
  • PyTorch: any
Additional context

Minimal fix — replace the parameterized generic with a plain dict:

if isinstance(state_dict, dict):
    model.load_state_dict(state_dict, strict=strict)
else:
    raise TypeError("`state_dict` must be a dict of torch.Tensor.")

The tighter "dict of strtorch.Tensor" check cannot be done in a single isinstance call; if such validation is desired it has to be a loop over items. In practice load_state_dict itself will surface incompatible entries, so the bare dict check is sufficient.

Happy to send a one-line PR.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in transformers4rec/torch/model/base.py at Model.load(), around the isinstance check introduced in commit 8bf122f5. Run tests/unit/torch/model/test_model.py::test_save_next_item_prediction_model and reproduce the Python 3.9+ TypeError from the issue. Done means Model.load() accepts a plain state_dict and loads weights without raising that TypeError.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, pytorch
Domain
machine-learning
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.