MarianMTModel performance regression due to Bidirectional masks
Author: jiqing-feng
Pull request: no
Labels: name: bug

### System Info

torch 2.10.0.dev20251008+cpu

### Who can help?

@vasqu 

### Information

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

### Tasks

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

### Reproduction

`numactl -C 0-3 --membind 0 python test.py`

```python
import time
import torch
from transformers import pipeline, AutoTokenizer

model_id = "Helsinki-NLP/opus-mt-mul-en"
tokenizer = AutoTokenizer.from_pretrained(model_id)
generator = pipeline("translation_fr_to_en", model=model_id, dtype=torch.float16, tokenizer=tokenizer)
generation_config = generator.model.generation_config
generation_config.max_new_tokens = 128
generation_config.min_new_tokens = 128
generation_config.do_sample = False
generation_config.temperature = 1.0
generation_config.num_beams = 1
generation_config.cache_implementation="static"
input_sentence = "C'est fait et soumis. Vous pouvez jouer à « Survival of the Tastiest » sur Android, et sur le web. Le jeu sur le web fonctionne, mais vous devez simuler plusieurs touches pour déplacer les tables, ce qui peut être un peu déroutant. Il y a beaucoup de choses dont j'aimerais parler. Je vais passer en revue chaque sujet, au lieu de faire la liste habituelle de ce qui s'est bien passé et de ce qui s'est mal passé. Concept Travailler sur le thème a probablement été l'une des tâches les plus difficiles auxquelles j'ai dû faire face. A l'origine, j'avais une idée du type de jeu que je voulais développer, du point de vue du gameplay - quelque chose avec beaucoup d'ennemis/acteurs"
for _ in range(5):
    output = generator(input_sentence, generation_config=generation_config)
for _ in range(5):
    start = time.time()
    output = generator(input_sentence, generation_config=generation_config)
    end = time.time()
    print(f"pipeline latency: {(end-start)*1000} ms")
```

### Expected behavior

The performance has 40% regression after PR [41265](https://github.com/huggingface/transformers/pull/41265).

Same issue as #41566 . But the fix PR #41586 only fixes the Bert model regression, and didn't fix MarianMTModel performance regression.

Comments:
Oops that's my bad . I'll look into it and try to fix it .

I updated the script a bit to force "cpu":
```python
import time
import torch
from transformers import pipeline, AutoTokenizer

model_id = "Helsinki-NLP/opus-mt-mul-en"
tokenizer = AutoTokenizer.from_pretrained(model_id)
generator = pipeline("translation_fr_to_en", model=model_id, dtype=torch.float16, tokenizer=tokenizer, device="cpu")
generation_config = generator.model.generation_config
generation_config.max_new_tokens = 128
generation_config.min_new_tokens = 128
generation_config.do_sample = False
generation_config.temperature = 1.0
generation_config.num_beams = 1
generation_config.cache_implementation="static"
input_sentence = "C'est fait et soumis. Vous pouvez jouer à « Survival of the Tastiest » sur Android, et sur le web. Le jeu sur le web fonctionne, mais vous devez simuler plusieurs touches pour déplacer les tables, ce qui peut être un peu déroutant. Il y a beaucoup de choses dont j'aimerais parler. Je vais passer en revue chaque sujet, au lieu de faire la liste habituelle de ce qui s'est bien passé et de ce qui s'est mal passé. Concept Travailler sur le thème a probablement été l'une des tâches les plus difficiles auxquelles j'ai dû faire face. A l'origine, j'avais une idée du type de jeu que je voulais développer, du point de vue du gameplay - quelque chose avec beaucoup d'ennemis/acteurs"
for _ in range(10):
    output = generator(input_sentence, generation_config=generation_config)
for _ in range(10):
    torch.cuda.synchronize()
    start = time.time()
    output = generator(input_sentence, generation_config=generation_config)
    end = time.time()
    print(f"pipeline latency: {(end-start)*1000} ms")
```
The issue stems from the causal mask this time tho, not the bidirectional mask - checked on commit before mask intro (~1050ms), main with no change (~1650ms), main with only changing the causal mask (~1050ms). The diff becomes less extensive on local cuda (~5ms around 170ms). We have already talked a bit about this @Cyrilvallez: Do we want to change the implementations to be default non-vmap and only opt for it for more powerful patterns (packed sequences, and/or masks, etc).

So I don't think it's an issue with your PR @i3hz