Skip to content

Add bool mask vs float additive bias guidance to debugging-memcpy skill - #272

Merged
justinchuby merged 6 commits into
mainfrom
skill-attn-mask-guidance
May 6, 2026
Merged

Add bool mask vs float additive bias guidance to debugging-memcpy skill#272
justinchuby merged 6 commits into
mainfrom
skill-attn-mask-guidance

Conversation

@justinchuby

Copy link
Copy Markdown
Member

Add a section to the debugging-memcpy skill documenting when to use float additive bias vs bool mask for attention.

Key points

  • Float additive bias recommended for complex patterns (sliding window, KV-shared layers, dual head_dim, padding)
  • Bool mask only for simple causal-only patterns where is_causal=1 suffices
  • Common misconception: Bool masks do NOT enable Flash Attention — Flash requires attn_mask=nullptr
  • Includes decision table and create_attention_bias() recommendation

Learned from Gemma4 debugging where bool mask construction for mixed sliding-window + KV-shared + dual head_dim was error-prone.

@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

Performance Comparison

Comparing e5eb9669b4463b

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

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@titaiwangms titaiwangms left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Test from CLI

@titaiwangms

Copy link
Copy Markdown
Contributor

LGTM with three small suggestions. Verified the technical claims against core/providers/cuda/llm/attention.cc (ConvertAttnMaskToBias, Flash mask rejection at line 1354, MEA bias-alignment guard at 1402). Tried to leave inline suggestion blocks but the GitHub Reviews API keeps 422'ing — pasting them here.


1. Scope the section to the ONNX Attention op (suggested replacement for the section header on line 332):

## Bool mask vs float additive bias for attention

> Applies to the ONNX-domain `Attention` op (opset 23/24) that mobius emits.
> Contrib `MultiHeadAttention` takes a pre-built float `attention_bias`;
> contrib `GroupQueryAttention` does not accept any bias.

The bool-mask + ConvertAttnMaskToBias claims are ONNX-Attention-specific. Mobius emits ONNX Attention so the audience is right, but stating it avoids confusion when this skill is read during contrib-op debugging.


2. Wording nit on the "double-applies" bullet (lines 358–359):

- **`is_causal=1` + bool mask** is redundant and easy to get out of sync —
  the `is_causal` flag adds its own causal mask on top of the explicit one,
  so any off-by-one between them silently changes results

In practice MEA (attention.cc:799) and Unfused (:1186) apply both p.causal and the converted bias, which is idempotent if the bool mask is itself causal — output stays correct, just redundant. "Double-applies constraints" reads as if correctness breaks. The real footgun is an off-by-one between the two, or a non-causal bool pattern silently overridden by is_causal=1.


3. Flash prerequisites + nonpad_kv_seqlen (suggested replacement for lines 374–377):

Bool masks do **NOT** enable Flash Attention. Flash Attention requires
`attn_mask=nullptr` (no mask at all). Both bool and float masks route
to Memory-Efficient Attention (MEA) or unfused attention. If you need
Flash Attention, use `is_causal=1` with no explicit mask. Note that
Flash also requires fp16/bf16, `head_size == v_head_size` (≤ 256),
and SM ≥ 8.0 (Ampere+); otherwise the op falls to MEA or unfused
regardless of how the mask is expressed. For variable-length padding,
prefer `nonpad_kv_seqlen` (opset 24) over a mask — it preserves Flash
eligibility, while a mask hard-disables Flash.

is_causal=1 is necessary but not sufficient for Flash. And it's worth distinguishing padding (express via nonpad_kv_seqlen → Flash-eligible) from attention pattern (sliding window / KV-shared / dual head_dim → float bias → MEA/unfused). Without that split, "use float bias" might lead users to express padding via bias too, and silently lose Flash on causal LM workloads.

justinchuby and others added 2 commits May 6, 2026 17:08
…py skill

Document when to use float additive bias vs bool mask for attention:
- Float bias recommended for complex patterns (sliding window,
  KV-shared, dual head_dim, padding)
- Bool mask only for simple causal-only patterns
- Common misconception: bool masks do NOT enable Flash Attention
- Decision table and code example using create_attention_bias()

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>
Add 5 dispatch reference tables to debugging-memcpy skill:
- Contrib MultiHeadAttention cascade (7 kernels)
- Contrib GroupQueryAttention cascade (4 kernels, rejects bias)
- ONNX Attention MHA cascade (3 kernels)
- ONNX Attention GQA cascade (3 kernels)
- GQA + float mask conditions (MEA vs unfused)

Explains why Gemma4 KV-shared layers fall to unfused (asymmetric
head_size) and key rules (Flash requires nullptr mask, SM>=8.0).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>
@justinchuby
justinchuby force-pushed the skill-attn-mask-guidance branch from 9c9790d to 9f73366 Compare May 6, 2026 17:09
justinchuby and others added 4 commits May 6, 2026 17:28
…ng-memcpy

Extract attention content from debugging-memcpy into a new standalone
attention-optimization skill covering:
- Bool mask vs float additive bias (when to use each)
- Flash Attention requirements and nonpad_kv_seqlens
- 5 ORT CUDA attention kernel dispatch tables
- GQA vs ONNX Attention tradeoffs
- Key takeaways for model builders

debugging-memcpy now focuses purely on memcpy debugging with a
cross-reference to the new skill.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>
Add top-level decision table mapping scenarios (causal, padding,
sliding window, complex, custom) to recommended mask types with
rationale.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>
- nonpad_kv_seqlens is best for padding (enables Flash + shared buffer)
- Flash primarily helps prefill, not decode (memory-bandwidth bound)
- Gemma4 can't use Flash for any layer (sliding needs mask, full has
  head_dim=512) — MEA is the effective best kernel
- Bool and float masks have identical dispatch (bool→float internally)
- Updated decision table with rationale

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>
Bool mask is equally precise as float for sliding window. We chose
float for Gemma4 because of a bug in our bool mask construction for
complex multi-constraint patterns (KV-shared + sliding + dual
head_dim), not a fundamental limitation. For simpler models, bool
is fine and uses less memory.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>
@justinchuby
justinchuby merged commit fe23d7b into main May 6, 2026
22 checks passed
@justinchuby
justinchuby deleted the skill-attn-mask-guidance branch May 6, 2026 21:21
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