Fix Evolla eager attention for the GQA text decoder
Author: jiqing-feng
Pull request: yes

## Summary

Evolla's text decoder (`EvollaAttention`, based on `LlamaAttention`) uses
grouped-query attention (`num_attention_heads=32`, `num_key_value_heads=8`,
so `num_key_value_groups=4`). However, the module-level `eager_attention_forward`
in `modeling_evolla.py` is inherited from the SaProt/ESM encoder, which is
multi-head attention and therefore never repeats the key/value heads.

As a result, running Evolla with `attn_implementation="eager"` crashes in the
text decoder:

```
RuntimeError: The size of tensor a (32) must match the size of tensor b (8)
at non-singleton dimension 1
```

`sdpa` works because it repeats KV heads internally; `eager` does not, so the
bug only surfaces on the eager path (and on hardware without FA2/SDPA fast paths).

## Fix

Add the missing `repeat_kv` step to Evolla's `eager_attention_forward`. The number
of repeats is read defensively via `getattr(module, "num_key_value_groups", 1)`,
so it is a no-op for the SaProt encoder (which has no `num_key_value_groups`) and
correctly expands KV heads for the GQA text decoder.

The change is made in the source-of-truth `modular_evolla.py` (which now defines
`eager_attention_forward` explicitly and imports `repeat_kv` from Llama), and the
generated `modeling_evolla.py` is regenerated with:

```bash
python utils/modular_model_converter.py \
  --files_to_parse src/transformers/models/evolla/modular_evolla.py
```

Generated diff in `modeling_evolla.py`:

```python
def eager_attention_forward(module, query, key, value, attention_mask, scaling=None, dropout=0.0, **kwargs):
    if scaling is None:
        scaling = query.size(-1) ** -0.5

    # Repeat key/value heads to match the number of query heads for grouped-query attention
    # (the text decoder uses GQA). For the SaProt encoder there is no `num_key_value_groups`,
    # so `n_rep` defaults to 1 and this is a no-op.
    n_rep = getattr(module, "num_key_value_groups", 1)
    key = repeat_kv(key, n_rep)
    value = repeat_kv(value, n_rep)

    attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
    ...
```

## Reproduction

```python
import torch
from transformers import EvollaForProteinText2Text, AutoProcessor

mid = "westlake-repl/Evolla-10B-hf"
processor = AutoProcessor.from_pretrained(mid)

aa = "MALWMRLLPLLALLALWGPDPAAA"
protein = {"aa_seq": aa, "foldseek": "#" * len(aa)}
messages = [
    {"role": "system", "content": "You are an AI expert that can answer any questions about protein."},
    {"role": "user", "content": "What is the function of this protein?"},
]

model = EvollaForProteinText2Text.from_pretrained(
    mid, dtype=torch.bfloat16, attn_implementation="eager", device_map="auto"
).eval()

inputs = processor(
    proteins=[protein],
    messages_list=[messages],
    return_tensors="pt",
    text_max_length=512,
    protein_max_length=1024,
).to(model.device)

# Before the fix: RuntimeError: The size of tensor a (32) must match the size of tensor b (8)
# After the fix: generates normally.
out = model.generate(**inputs, max_new_tokens=12)
print(processor.batch_decode(out, skip_special_tokens=True)[0])
```


Comments:
**[For maintainers]** Suggested jobs to run (before merge)

run-slow: evolla

**CI Dashboard:** [View test results in Grafana](https://transformers-ci.lor-e.huggingface.cool/d/pytest-observability-by-pr/pytest-observability-branch?var-pr=46860)

The docs for this PR live [here](https://moon-ci-docs.huggingface.co/docs/transformers/pr_46860). All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.