Skip to content

Gemma4 CUDA EP: float additive bias + hybrid GQA/Attention dispatch - #269

Merged
justinchuby merged 2 commits into
mainfrom
gemma4-cuda-attention-fix
May 6, 2026
Merged

Gemma4 CUDA EP: float additive bias + hybrid GQA/Attention dispatch#269
justinchuby merged 2 commits into
mainfrom
gemma4-cuda-attention-fix

Conversation

@justinchuby

Copy link
Copy Markdown
Member

Summary

Two changes for Gemma4 CUDA EP support:

1. Float additive bias for all fallback Attention layers

All KV-shared layers (and all layers on default EP) now use create_attention_bias() which encodes causal + sliding window + padding constraints as a float additive bias. This:

  • Handles batch > 1 correctly (padding mask included)
  • Works with both unfused and MEA (CUTLASS FMHA) kernel paths on CUDA EP
  • Replaces the previous bool mask approach (which caused incorrect output on CUDA)

Removes unused create_padding_mask and create_sliding_window_mask imports.

2. Hybrid GQA/Attention dispatch with feature flag

Adds MOBIUS_USE_GQA_FOR_KV_SHARED flag (_flags.py, default False):

Flag value Normal layers (0-14) KV-shared layers (15-34)
False (default) GQA (fused RoPE + attention + KV cache) ONNX Attention (float additive bias)
True GQA GQA (requires ORT new_kv_length=0 support)

KV-shared layers cannot use GQA today because they pass the full KV cache as K input with no past_key — the CUTLASS MEA aligned kernel crashes (tracked in microsoft/onnxruntime#28376). Set MOBIUS_USE_GQA_FOR_KV_SHARED=1 when ORT GQA supports this pattern.

Testing

  • All 13 Gemma4 L1 tests pass
  • Lint clean
  • Pure ORT decoder test: all seq lengths 1-64 pass on CUDA EP

Three changes for Gemma4 CUDA EP support:

1. Use float additive bias for all fallback Attention layers (both
   sliding-window and full-attention). Encodes causal + sliding window
   + padding constraints. Required for batch>1 correctness.

2. Add feature flag MOBIUS_USE_GQA_FOR_KV_SHARED (default False).
   When False: normal layers use GQA, KV-shared layers use Attention.
   When True: all layers use GQA (requires ORT new_kv_length=0).

3. Remove unused create_padding_mask/create_sliding_window_mask imports.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>
@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

🏗️ Architecture Diff

Comparing a0b7ce18700af6

Model Sub-model Changes Status
bert (feature-extraction) model 0
falcon model 0
gemma2 model 0
gemma4 (gemma4) decoder 0
gemma4 (gemma4) embedding 0
gemma4 (gemma4) vision_encoder 0
gemma4_text model 0
gpt2 model 0
llama model 0
llama (static-cache) model 0
mamba (ssm-text-generation) model 0
phi3 model 0
phi3 (static-cache) model 0
qwen model 0
qwen (static-cache) model 0
qwen2 model 0
qwen2 (static-cache) model 0
qwen2_moe model 0
qwen2_moe (static-cache) model 0
qwen3 model 0
qwen3 (static-cache) model 0
qwen3_5_moe (hybrid-text-generation) model 0
qwen3_5_text (hybrid-text-generation) model 0
qwen3_5_vl (hybrid-qwen-vl) decoder 0
qwen3_5_vl (hybrid-qwen-vl) embedding 0
qwen3_5_vl (hybrid-qwen-vl) vision_encoder 0
qwen3_moe model 0
qwen3_moe (static-cache) model 0
qwen3_next (hybrid-text-generation) model 0
t5 (seq2seq) decoder 0
t5 (seq2seq) encoder 0
whisper (speech-to-text) decoder 0
whisper (speech-to-text) encoder 0

No architecture changes detected.


Legend: ⚪ No change · 🔵 Minor (attrs/inits) · 🟡 Moderate (nodes added/removed) · 🔴 Major (interface changed)

@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

Performance Comparison

Comparing a0b7ce18700af6

Model Metric Baseline Current Delta
bert (feature-extraction) model_size_bytes 359 KB 359 KB +0.0%
bert (feature-extraction) num_nodes 60 60 +0.0%
falcon model_size_bytes 364 KB 364 KB +0.0%
falcon num_nodes 66 66 +0.0%
gemma2 model_size_bytes 428 KB 428 KB +0.0%
gemma2 num_nodes 107 107 +0.0%
gpt2 model_size_bytes 388 KB 388 KB +0.0%
gpt2 num_nodes 53 53 +0.0%
llama model_size_bytes 425 KB 425 KB +0.0%
llama num_nodes 61 61 +0.0%
llama (static-cache) model_size_bytes 425 KB 425 KB +0.0%
llama (static-cache) num_nodes 58 58 +0.0%
mamba (ssm-text-generation) model_size_bytes 296 KB 296 KB +0.0%
mamba (ssm-text-generation) num_nodes 98 98 +0.0%
phi3 model_size_bytes 421 KB 421 KB +0.0%
phi3 num_nodes 59 59 +0.0%
phi3 (static-cache) model_size_bytes 421 KB 421 KB +0.0%
phi3 (static-cache) num_nodes 56 56 +0.0%
qwen2 model_size_bytes 425 KB 425 KB +0.0%
qwen2 num_nodes 61 61 +0.0%
qwen2 (static-cache) model_size_bytes 425 KB 425 KB +0.0%
qwen2 (static-cache) num_nodes 58 58 +0.0%
qwen3_5_moe (hybrid-text-generation) model_size_bytes 506 KB 506 KB +0.0%
qwen3_5_moe (hybrid-text-generation) num_nodes 275 275 +0.0%
qwen3_5_text (hybrid-text-generation) model_size_bytes 458 KB 458 KB +0.0%
qwen3_5_text (hybrid-text-generation) num_nodes 129 129 +0.0%
qwen3_5_vl (hybrid-qwen-vl) model_size_bytes 977 KB 977 KB +0.0%
qwen3_5_vl (hybrid-qwen-vl) num_nodes 408 408 +0.0%
t5 (seq2seq) model_size_bytes 836 KB 836 KB +0.0%
t5 (seq2seq) num_nodes 166 166 +0.0%
whisper (speech-to-text) model_size_bytes 1008 KB 1008 KB +0.0%
whisper (speech-to-text) num_nodes 128 128 +0.0%

No performance regressions.

@codecov

codecov Bot commented May 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/mobius/models/gemma4.py 85.71% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

ORT fuses Add(output_proj.bias) + RMSNormalization into
SkipSimplifiedLayerNormalization, placing the 1D bias as the 'skip'
input. ORT's CUDA kernel rejects 1D skip (requires 2D+), while the
CPU kernel accepts it.

This fusion was enabled by PR #253 which changed _Gemma4ScaleFreeRMSNorm
from manual primitive ops to op.RMSNormalization(stash_type=1). The
RMSNormalization op is recognized by ORT's SkipLayerNorm fusion pattern.

Fix: inline manual RMSNorm ops in _Gemma4AudioEncoderModel.forward()
for the pre_projection_norm, preventing ORT from recognizing the fusion
pattern. This preserves the FP32 accumulation for numerical stability.

Tested: audio encoder runs on CUDA with correct output (standalone ORT
and GenAI at 117 tok/s).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>
@justinchuby
justinchuby merged commit e2631ab into main May 6, 2026
20 of 23 checks passed
@justinchuby
justinchuby deleted the gemma4-cuda-attention-fix branch May 6, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants