GPT-2 Forward w/ and w/o caching of past values gives different results
Author: rajcscw
Pull request: no
Labels: name: bug

### System Info

```shell
- `transformers` version: 4.18.0
- Platform: Linux-3.10.0-1160.45.1.el7.x86_64-x86_64-with-debian-buster-sid
- Python version: 3.7.13
- Huggingface_hub version: 0.5.1
- PyTorch version (GPU?): 1.11.0 (True)
- Tensorflow version (GPU?): 2.9.0 (False)
- Flax version (CPU?/GPU?/TPU?): not installed (NA)
- Jax version: not installed
- JaxLib version: not installed
- Using GPU in script?: no
- Using distributed or parallel set-up in script?: no
```


### Who can help?

@patrickvonplaten 

### Information

- [ ] The official example scripts
- [X] My own modified scripts

### Tasks

- [ ] An officially supported task in the `examples` folder (such as GLUE/SQuAD, ...)
- [X] My own task or dataset (give details below)

### Reproduction

Hey, I am trying to do a forward() pass of the GPT-2 model with and without caching of past values and observed that the logits are slightly different. Is this to be expected or I am missing something?  I highly appreciate it if someone could help me with this.

Code snippet for an MWE below (Check the last assert statement which fails)

```python
from transformers import GPT2LMHeadModel
import torch

model = GPT2LMHeadModel.from_pretrained('gpt2')
model.eval()

with torch.no_grad():
    #########################################################################
    # with forward and no caching of past
    # left padded to size of 5
    # step 0
    input_ids = torch.tensor([50256, 50256, 50256, 50256, 2]).reshape(1, -1)
    attention_mask = torch.tensor([0, 0, 0, 0, 1]).reshape(1, -1)
    position_ids = torch.tensor([1, 1, 1, 1, 0]).reshape(1, -1)

    gen_outputs = model(input_ids=input_ids,
                        attention_mask=attention_mask,
                        position_ids=position_ids,
                        return_dict=True)
    no_cache_0_next_token_logits = gen_outputs.logits[0, -1, :].clone()

    # step 1 - input grown by 1
    input_ids = torch.tensor([50256, 50256, 50256, 50256, 2, 5]).reshape(1, -1)
    attention_mask = torch.tensor([0, 0, 0, 0, 1, 1]).reshape(1, -1)
    position_ids = torch.tensor([1, 1, 1, 1, 0, 1]).reshape(1, -1)
    gen_outputs = model(input_ids=input_ids,
                        attention_mask=attention_mask,
                        position_ids=position_ids,
                        return_dict=True)
    no_cache_1_next_token_logits = gen_outputs.logits[0, -1, :].clone()

    ########################################################################
    # with forward with caching
    # left padded to size of 5
    # step 0
    input_ids = torch.tensor([50256, 50256, 50256, 50256, 2]).reshape(1, -1)
    model_kwargs = {
        "attention_mask": torch.tensor([0, 0, 0, 0, 1]).reshape(1, -1)
    }

    model_inputs = model.prepare_inputs_for_generation(
        input_ids, **model_kwargs)
    gen_outputs = model(**model_inputs,
                        return_dict=True)
    cache_0_next_token_logits = gen_outputs.logits[0, -1, :].clone()
    assert torch.equal(cache_0_next_token_logits,
                       no_cache_0_next_token_logits) == True
    model_kwargs = model._update_model_kwargs_for_generation(
        gen_outputs, model_kwargs, is_encoder_decoder=model.config.is_encoder_decoder
    )

    # step 1 - input grown by 1
    input_ids = torch.tensor([50256, 50256, 50256, 50256, 2, 5]).reshape(1, -1)
    model_inputs = model.prepare_inputs_for_generation(
        input_ids, **model_kwargs)
    gen_outputs = model(**model_inputs,
                        return_dict=True)
    cache_1_next_token_logits = gen_outputs.logits[0, -1, :].clone()
    assert torch.equal(cache_1_next_token_logits,
                       no_cache_1_next_token_logits) == True

```

### Expected behavior

```shell
Expected behavior: Caching does not affect the logits and only speeds up the computation.
```


Comments:
Hey @rajcscw,

I'm not 100% sure what your codesnippet is doing there exactly (note that I wouldn't try to pass the position_ids, but instead let GPT2 handle that).

We have exactly that test in transformers which you can find here: https://github.com/huggingface/transformers/blob/975dd2bbbcd4e8bdaf07c275c090d218d88c7c12/tests/models/gpt2/test_modeling_gpt2.py#L288

Could you take a look here and see whether you can use this code?

Also cc @patil-suraj @ArthurZucker just FYI


Not sure either but the inputs fed to the network might be different as : 
1. the `position_ids` are specified with : 
```python
attention_mask = torch.tensor([0, 0, 0, 0, 1, 1]).reshape(1, -1)
position_ids = torch.tensor([1, 1, 1, 1, 0, 1]).reshape(1, -1)
```  
in the first case 
2. in the second case they are not specified and should be automatically created. 

Check if you still have an issue when you use the same position ids vectors, or just don't input them. 



@patrickvonplaten  I will check that test case and adapt my example. @ArthurZucker In both cases, the position IDs should be identical; in the first case, it is created explicitly and in the other, it is generated automatically. I will test it without passing any position IDs.

This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the [contributing guidelines](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md) are likely to be ignored.