Repository: pykeen/pykeen
Issue: Error while inferencing transformer interaction
Root cause: Validation Gap

### Describe the bug

Running prediction for transformer interaction produces grad error

### How to reproduce

```python

training_inverse = TriplesFactory.from_path('../graphs/train_plus_msk_new_only_sh.tsv', create_inverse_triples=True)
testing_inverse = TriplesFactory.from_path('../graphs/test_sh.tsv',                        
                                   entity_to_id=training_inverse.entity_to_id, 
                                   relation_to_id=training_inverse.relation_to_id
                                  )

results_other = pipeline(
    training=training_inverse,
    testing=testing_inverse,
    model='CompGCN',
    training_loop='sLCWA',
    negative_sampler='basic',
    stopper='early',
    validation=testing_inverse,
    training_kwargs = dict(num_epochs=1, batch_size=720, drop_last=False),
    model_kwargs = dict(
        embedding_dim=512,
        interaction='transformer',
    ),     
    stopper_kwargs=dict(frequency=3, patience=3, relative_delta=0.0001),
    lr_scheduler=torch.optim.lr_scheduler.ConstantLR,
    negative_sampler_kwargs=dict(
        filtered=True,
        filterer='python-set',  
        num_negs_per_pos=3, 
        corruption_scheme=(0)
    ),
    optimizer='adamax',
    optimizer_kwargs=dict(lr=0.01),
    loss='softplus',
    random_seed=42,
    device='cuda'
)

predict.get_head_prediction_df(
        model=results_other.model, 
        relation_label='what ancestor?', 
        tail_label="cow", 
        triples_factory=results_other.training
    )
```

```
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Input In [15], in <cell line: 1>()
----> 1 predict.get_head_prediction_df(
      2         model=results_other.model, 
      3         relation_label='what detail?', 
      4         tail_label=vin, 
      5         triples_factory=results_other.training
      6     )

File ~/pykeen/src/pykeen/models/predict.py:242, in get_head_prediction_df(model, triples_factory, relation_label, tail_label, heads, **kwargs)
    211 """Predict heads for the given relation and tail (given by label).
    212 
    213 :param model:
   (...)
    239 >>> df = get_head_prediction_df(result.model, 'accusation', 'brazil', triples_factory=result.training)
    240 """
    241 warnings.warn("Please directly use `pykeen.models.predict.get_prediction_df`", DeprecationWarning)
--> 242 return get_prediction_df(
    243     model=model,
    244     triples_factory=triples_factory,
    245     relation_label=relation_label,
    246     tail_label=tail_label,
    247     targets=heads,
    248     **kwargs,
    249 )

File ~/pykeen/src/pykeen/models/predict.py:182, in get_prediction_df(model, triples_factory, head_label, relation_label, tail_label, targets, add_novelties, remove_known, testing, mode)
    177 label_ids, targets = _get_targets(
    178     ids=targets, triples_factory=triples_factory, device=model.device, entity=relation_label is not None
    179 )
    181 # get scores
--> 182 scores = model.predict(batch, full_batch=False, mode=mode, ids=targets, target=target).squeeze(dim=0).tolist()
    184 # create raw dataframe
    185 rv = pd.DataFrame(
    186     [(target_id, target_label, score) for (target_label, target_id), score in zip(label_ids, scores)],
    187     columns=[f"{target}_id", f"{target}_label", "score"],
    188 ).sort_values("score", ascending=False)

File ~/pykeen/src/pykeen/models/base.py:475, in Model.predict(self, hrt_batch, target, full_batch, ids, **kwargs)
    473     if full_batch:
    474         hrt_batch = hrt_batch[:, 1:3]
--> 475     return self.predict_h(hrt_batch, **kwargs, heads=ids)
    477 raise ValueError(f"Unknown target={target}")

File ~/pykeen/src/pykeen/models/base.py:366, in Model.predict_h(self, rt_batch, **kwargs)
    364 rt_batch = self._prepare_batch(batch=rt_batch, index_relation=0)
    365 if self.use_inverse_triples:
--> 366     scores = self.score_h_inverse(rt_batch=rt_batch, **kwargs)
    367 else:
    368     scores = self.score_h(rt_batch, **kwargs)

File ~/pykeen/src/pykeen/models/base.py:645, in Model.score_h_inverse(self, rt_batch, heads, **kwargs)
    643 """Score all heads for a batch of (r,t)-pairs using the tail predictions for the inverses $(t,r_{inv},*)$."""
    644 t_r_inv = self._prepare_inverse_batch(batch=rt_batch, index_relation=0)
--> 645 return self.score_t(hr_batch=t_r_inv, tails=heads, **kwargs)

File ~/pykeen/src/pykeen/models/nbase.py:471, in ERModel.score_t(self, hr_batch, slice_size, mode, tails)
    468 if tails is None or tails.ndimension() == 1:
    469     t = parallel_unsqueeze(t, dim=0)
    470 return repeat_if_necessary(
--> 471     scores=self.interaction.score(h=h, r=r, t=t, slice_size=slice_size, slice_dim=1),
    472     representations=self.entity_representations,
    473     num=self._get_entity_len(mode=mode) if tails is None else tails.shape[-1],
    474 )

File ~/pykeen/src/pykeen/nn/modules.py:255, in Interaction.score(self, h, r, t, slice_size, slice_dim)
    233 """Compute broadcasted triple scores with optional slicing.
    234 
    235 .. note ::
   (...)
    252     The scores.
    253 """
    254 if slice_size is None:
--> 255     return self(h=h, r=r, t=t)
    257 return torch.cat(
    258     [
    259         self(h=h_batch, r=r_batch, t=t_batch)
   (...)
    262     dim=slice_dim,
    263 )

File /home/user/conda/envs/test_env/lib/python3.8/site-packages/torch/nn/modules/module.py:1102, in Module._call_impl(self, *input, **kwargs)
   1098 # If we don't have any hooks, we want to skip the rest of the logic in
   1099 # this function, and just call forward.
   1100 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1101         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1102     return forward_call(*input, **kwargs)
   1103 # Do not call functions when jit is used
   1104 full_backward_hooks, non_full_backward_hooks = [], []

File ~/pykeen/src/pykeen/nn/modules.py:402, in FunctionalInteraction.forward(self, h, r, t)
    384 def forward(
    385     self,
    386     h: HeadRepresentation,
    387     r: RelationRepresentation,
    388     t: TailRepresentation,
    389 ) -> torch.FloatTensor:
    390     """Compute broadcasted triple scores given broadcasted representations for head, relation and tails.
    391 
    392     :param h: shape: (`*batch_dims`, `*dims`)
   (...)
    400         The scores.
    401     """
--> 402     return self.__class__.func(**self._prepare_for_functional(h=h, r=r, t=t))

File ~/pykeen/src/pykeen/nn/functional.py:1453, in transformer_interaction(h, r, t, transformer, position_embeddings, final)
   1450 # reshape
   1451 x = x.view(*hr_shape[1:-1], x.shape[-1])
-> 1453 return (x * t).sum(dim=-1)

RuntimeError: Inference tensors cannot be saved for backward. To work around you can make a clone to get a normal tensor and use it in autograd.

```

### Environment

| Key             | Value                    |
|-----------------|--------------------------|
| OS              | posix                    |
| Platform        | Linux                    |
| Release         | 5.4.0-58-generic         |
| Time            | Wed Jul  6 10:28:00 2022 |
| Python          | 3.8.13                   |
| PyKEEN          | 1.8.3-dev                |
| PyKEEN Hash     | b0a9abd9                 |
| PyKEEN Branch   |                          |
| PyTorch         | 1.10.1+cu111             |
| CUDA Available? | true                     |
| CUDA Version    | 11.1                     |
| cuDNN Version   | 8005                     |

### Additional information

_No response_

### Issue Template Checks

- [X] This is not a feature request (use a different issue template if it is)
- [X] This is not a question (use the [discussions](https://github.com/pykeen/pykeen/discussions/new) forum instead)
- [X] I've read the text explaining why including environment information is important and understand if I omit this information that my issue will be dismissed