Skip to content

replace enable_gpa with repeat_interleave for krea2 - #14523

Merged
yiyixuxu merged 4 commits into
mainfrom
gqa-mask-no-math
Aug 18, 2026
Merged

replace enable_gpa with repeat_interleave for krea2#14523
yiyixuxu merged 4 commits into
mainfrom
gqa-mask-no-math

Conversation

@yiyixuxu

Copy link
Copy Markdown
Collaborator

fix #14518

yiyixuxu and others added 3 commits August 18, 2026 02:54
Krea 2 always attends with a text padding mask, and no fused SDPA kernel takes
a mask together with mismatched query/key head counts — flash rejects the mask,
the memory-efficient kernel rejects the mismatch. Attention therefore fell back
to the math backend, which materializes the full
[batch_size, num_heads, seq_len, seq_len] score matrix with no error or warning.

Repeating the key/value heads in the processor computes the same thing and keeps
the memory-efficient kernel eligible: at 1024x1024 (48/12 heads, 4608 tokens) one
attention call goes from 9.02 GiB / 26.7 ms to 0.16 GiB / 4.1 ms.

It also unpins the model from the native backend, since cuDNN, flash, FA3, sage
and the hub kernels all raise on `enable_gqa`.

Fixes #14518

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added fixes-issue models size/S PR with diff < 50 LOC labels Aug 18, 2026
@yiyixuxu
yiyixuxu requested review from asomoza and sayakpaul August 18, 2026 03:00
@yiyixuxu yiyixuxu changed the title replace enable_gpa with repeat_interleave replace enable_gpa with repeat_interleave for krea2 Aug 18, 2026
@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@sayakpaul sayakpaul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Just flagging the following table:

Image

Claude derived it by using the following code and running it against this branch and main:

from diffusers import Krea2Transformer2DModel

device, dtype = "cuda", torch.bfloat16

model = Krea2Transformer2DModel.from_pretrained(
    "krea/Krea-2-Raw", subfolder="transformer", torch_dtype=dtype
).to(device)
model.eval()

# 1024x1024 image -> 128x128 latents -> 64x64 grid of patch-2 tokens;
# 512 text positions with only the first 77 valid (padding mask exercised).
torch.manual_seed(0)
batch, text_seq_len, grid = 1, 512, 64
image_seq_len = grid * grid

hidden_states = torch.randn(batch, image_seq_len, 64, device=device, dtype=dtype)
encoder_hidden_states = torch.randn(batch, text_seq_len, 12, 2560, device=device, dtype=dtype)
timestep = torch.tensor([0.7], device=device)
encoder_attention_mask = torch.zeros(batch, text_seq_len, dtype=torch.bool, device=device)
encoder_attention_mask[:, :77] = True

text_ids = torch.zeros(text_seq_len, 3, device=device)
image_ids = torch.zeros(grid, grid, 3, device=device)
image_ids[..., 1] = torch.arange(grid, device=device)[:, None]
image_ids[..., 2] = torch.arange(grid, device=device)[None, :]
position_ids = torch.cat([text_ids, image_ids.reshape(-1, 3)], dim=0)

with torch.no_grad():
    out = model(
        hidden_states=hidden_states,
        encoder_hidden_states=encoder_hidden_states,
        timestep=timestep,
        position_ids=position_ids,
        encoder_attention_mask=encoder_attention_mask,
    ).sample

I think this is acceptable because now the kernel invocations internally have changed.

Comment thread .ai/models.md Outdated

### Grouped-query attention

Fewer key/value heads than query heads can be spelled two ways. Either pass `enable_gqa=True` to `dispatch_attention_fn` and let the backend broadcast, or repeat the key/value heads in the processor after RoPE and pass no flag (`transformer_krea2.py`, `transformer_nucleusmoe_image.py`):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either pass enable_gqa=True to dispatch_attention_fn

Can we also supplement a model file here for the reference?

Comment thread .ai/models.md Outdated

- **Compatibility.** Most backends do not implement `enable_gqa` yet — flash, FA3, sage, cuDNN and the hub kernels raise on it, as does the context-parallel path. Grep `enable_gqa` in `attention_dispatch.py` for the current list rather than trusting this one; it changes as support lands. The flag limits the model to whichever backends still accept it, while repeating works on all of them.

- **Performance.** Turns on whether the model passes a mask. With a mask, no fused kernel takes a mask *and* mismatched head counts, so SDPA falls back to math and materializes the full `[batch_size, num_heads, seq_len_q, seq_len_kv]` score matrix — no error, no warning, only memory. Without a mask, flash broadcasts inside the kernel and the flag saves the key/value copy. Both effects scale with sequence length and head count, so measure at the model's real shape; `torch.backends.cuda.can_use_flash_attention(params, debug=True)` and `can_use_efficient_attention` print why a kernel was rejected, which is the fastest way to see which one you actually got.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns on whether the model passes a mask.

Do we mean performance is turned on?

@asomoza asomoza left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! this fixes the issue.

Not sure if it's worth to mention, but this changes the resulting image a little:

main PR
Image Image

But still, it doesn't make it worse or better, and the change is minimal and mostly imperceptible if you're not comparing both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yiyixuxu
yiyixuxu merged commit 11a82a1 into main Aug 18, 2026
14 of 16 checks passed
@yiyixuxu
yiyixuxu deleted the gqa-mask-no-math branch August 18, 2026 20:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fixes-issue models size/S PR with diff < 50 LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Krea-2] enable_gqa + attn_mask produces high usage of VRAM

4 participants