Skip to content

[webgpu] support smooth softmax for non-FA GQA implementation - #25285

Merged
fs-eire merged 5 commits into
mainfrom
fs-eire/webgpu-smooth-softmax
Jul 7, 2025
Merged

[webgpu] support smooth softmax for non-FA GQA implementation#25285
fs-eire merged 5 commits into
mainfrom
fs-eire/webgpu-smooth-softmax

Conversation

@fs-eire

@fs-eire fs-eire commented Jul 4, 2025

Copy link
Copy Markdown
Contributor

Description

support smooth softmax for non-FA GQA implementation

This change depends on:

Work items:

  • support smooth softmax
  • support bias
  • support head sink (per-head smooth softmax)

The following will not be included in this PR:

  • support for FlashAttention
  • support sliding window

@fs-eire
fs-eire marked this pull request as draft July 4, 2025 02:01
@fs-eire fs-eire changed the title [webgpu] support smooth softmax for non-FA GQA implementation [WIP][webgpu] support smooth softmax for non-FA GQA implementation Jul 4, 2025
@fs-eire
fs-eire force-pushed the fs-eire/webgpu-smooth-softmax branch 5 times, most recently from c201d49 to 5845d0e Compare July 5, 2025 19:11
@fs-eire fs-eire changed the title [WIP][webgpu] support smooth softmax for non-FA GQA implementation [webgpu] support smooth softmax for non-FA GQA implementation Jul 5, 2025
@fs-eire
fs-eire marked this pull request as ready for review July 5, 2025 19:11
@fs-eire
fs-eire force-pushed the fs-eire/webgpu-smooth-softmax branch from 5845d0e to 3a7b54f Compare July 5, 2025 19:13
@fs-eire
fs-eire requested a review from Copilot July 5, 2025 19:13

Copilot AI 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.

Pull Request Overview

Adds support for smooth softmax, attention bias, and a per-head “sink” value in the non-FlashAttention path of GroupQueryAttention.

  • Introduce three new optional inputs (position_ids, attention_bias, head_sink) in both WebGPU and CPU GQA kernels
  • Wire attention_bias and head_sink through ComputeInternal, ApplyAttention, and the softmax shader
  • Update program constructors and shader generation to respect use_smooth_softmax, has_seqlen_k, and has_head_sink flags

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
onnxruntime/contrib_ops/webgpu/bert/group_query_attention.cc Added new inputs and custom‐input checks; passed attention_bias & head_sink into ComputeInternal and ApplyAttention
onnxruntime/contrib_ops/webgpu/bert/flash_attention.cc Noted TODO for smooth softmax/head_sink support in FlashAttention
onnxruntime/contrib_ops/webgpu/bert/attention_common.h Extended ApplyAttention signature to include head_sink
onnxruntime/contrib_ops/webgpu/bert/attention.h Modified program constructors to take use_smooth_softmax, has_seqlen_k, has_head_sink flags
onnxruntime/contrib_ops/webgpu/bert/attention.cc Enhanced InPlaceSoftmaxProgram generation to handle the new flags in the shader
onnxruntime/contrib_ops/cpu/bert/group_query_attention_helper.h Added validation logic for the new head_sink tensor
onnxruntime/contrib_ops/cpu/bert/group_query_attention.cc Loaded head_sink input and invoked validation in the CPU kernel
Comments suppressed due to low confidence (3)

onnxruntime/contrib_ops/webgpu/bert/attention.cc:226

  • The new smooth_softmax and head_sink branches in the shader code introduce distinct behavior; please add unit or integration tests to cover both code paths in WebGPU and CPU implementations.
Status InPlaceSoftmaxProgram::GenerateShaderCode(ShaderHelper& shader) const {

onnxruntime/contrib_ops/webgpu/bert/group_query_attention.cc:155

  • The operator schema and user‐facing documentation need updating to expose the new optional inputs (position_ids, attention_bias, and head_sink) and explain their semantics.
  const Tensor* position_ids = context.Input<Tensor>(9);  // TODO: support sliding window

onnxruntime/contrib_ops/webgpu/bert/attention.h:72

  • [nitpick] The term head_sink may be unfamiliar to new readers; consider renaming it to something more descriptive or adding a comment in the header to clarify its intended effect on the softmax.
  InPlaceSoftmaxProgram(int work_group_size, int components, bool use_smooth_softmax, bool has_seqlen_k, bool has_head_sink)

Comment thread onnxruntime/contrib_ops/webgpu/bert/group_query_attention.cc Outdated
Comment thread onnxruntime/contrib_ops/cpu/bert/group_query_attention_helper.h
Comment thread onnxruntime/contrib_ops/webgpu/bert/group_query_attention.cc Outdated
@guschmue guschmue added the ep:WebGPU ort-web webgpu provider label Jul 7, 2025
@fs-eire
fs-eire merged commit 6d28e2d into main Jul 7, 2025
91 checks passed
@fs-eire
fs-eire deleted the fs-eire/webgpu-smooth-softmax branch July 7, 2025 23:59
daijh pushed a commit to daijh/onnxruntime that referenced this pull request Jul 10, 2025
…oft#25285)

### Description



support smooth softmax for non-FA GQA implementation


This change depends on:
- microsoft#25269



Work items:

- [x] support smooth softmax
- [x] support bias
- [x] support head sink (per-head smooth softmax)

The following will not be included in this PR:
- support for FlashAttention
- support sliding window
qti-yuduo pushed a commit to CodeLinaro/onnxruntime that referenced this pull request Aug 8, 2025
…oft#25285)

### Description



support smooth softmax for non-FA GQA implementation


This change depends on:
- microsoft#25269



Work items:

- [x] support smooth softmax
- [x] support bias
- [x] support head sink (per-head smooth softmax)

The following will not be included in this PR:
- support for FlashAttention
- support sliding window
sanketkaleoss pushed a commit to sanketkaleoss/onnxruntime that referenced this pull request Aug 11, 2025
…oft#25285)

### Description



support smooth softmax for non-FA GQA implementation


This change depends on:
- microsoft#25269



Work items:

- [x] support smooth softmax
- [x] support bias
- [x] support head sink (per-head smooth softmax)

The following will not be included in this PR:
- support for FlashAttention
- support sliding window
tianleiwu pushed a commit that referenced this pull request Jul 8, 2026
…path (#29525)

### Description

`com.microsoft.GroupQueryAttention`'s optional `attention_bias` input
(input #10) is implemented by the CPU EP (#23944) and the WebGPU EP
(#25285, #26769), but the CUDA EP rejects it at runtime. This PR wires
it through.

No new kernel is needed: the unfused GQA fallback added for #28195 calls
`LaunchUnfusedAttention`, whose kernel already implements an additive
bias with dim-0/dim-1 broadcast, per-batch `seqlens_k`,
causal/sliding-window masking and softcap — the op just passed
`attn_bias=nullptr`. The change is dispatch plumbing:

- **`group_query_attention.cc`** — remove the blanket rejection;
validate the bias element type; set `broadcast_attn_bias_dim_0/1` from
the bias shape (the fields already exist on `AttentionParameters`); add
`!has_attention_bias` to the XQA / cuDNN SDPA / flash /
flash-fast-decode / MEA eligibility so bias-carrying nodes dispatch to
the unfused fallback; set `data.attention_bias`.
- **`attention_data.h`** — add the `attention_bias` pointer to
`GroupQueryAttentionData`.
- **`group_query_attention_impl.cu`** — pass the real pointer and
broadcast flags in `UnfusedGqaAttention` (previously hardcoded
`nullptr`/`false`).

Why each fused path stays disqualified with a bias:
- flash / flash fast-decode: `flash_api.h` has no bias parameter (same
exclusion as MHA and the ONNX `Attention`-op CUDA kernel).
- XQA: no bias parameter.
- cuDNN SDPA: GQA's cuDNN path is bottom-right causal, which cuDNN
documents as incompatible with a bias (`multihead_attention.cc` has the
same restriction).
- cutlass MEA: the wrapper computes the bias row stride from
`kv_sequence_length`, which GQA sets to the KV-cache capacity
(`seqlen_present_kv_cache`) rather than `total_sequence_length`, so rows
would be misaligned under past/present buffer sharing. Left for a
follow-up (needs an explicit `attn_bias_strideM` in
`MemoryEfficientAttentionParams`).

Kept `NOT_IMPLEMENTED` (explicit, clear errors instead of the previous
blanket rejection): bias × quantized KV cache (unfused requires `T ==
U`), bias × smooth-softmax/head_sink.

### Tests

New `TestGQAAttentionBias` in `test_gqa.py`: prompt and past/decode
parity across packed/unpacked QKV, shared/separate KV buffer, rotary,
odd head sizes (40/80), and a subsequent multi-token prompt. The bias is
**non-zero random** so a kernel that silently ignores the input fails
parity (the harness previously modeled a zeros bias). Also fixes the
test graph builder declaring the bias input's last dim as the KV-cache
capacity instead of `total_sequence_length` (the shape the op
validates).

Full `test_gqa.py` suite: 476 tests pass, no regressions (SM89, CUDA
12.8).

### Motivation and Context

Fixes #29506.

Transformers.js-exported speech models carry non-causal attention
patterns as `attention_bias` and currently cannot run on the CUDA EP at
all, while running fine on WebGPU and CPU:
-
[`onnx-community/Voxtral-Mini-4B-Realtime-2602-ONNX`](https://huggingface.co/onnx-community/Voxtral-Mini-4B-Realtime-2602-ONNX)
(streaming ASR)
-
[`onnx-community/cohere-transcribe-03-2026-ONNX`](https://huggingface.co/onnx-community/cohere-transcribe-03-2026-ONNX)

End-to-end validation with this patch on an RTX 4070 SUPER: the full
Voxtral-Mini-4B-Realtime streaming pipeline (q4f16) transcribes
correctly at **RTF 0.23** (31 s clip, 25.6 tok/s sustained decode, 6.4
GB VRAM) — on this workload the unfused-attention path outperforms the
same model on the WebGPU EP (RTF 0.26).

(While validating, an unrelated pre-existing issue surfaced:
`GroupQueryAttentionFusion` breaks graphs whose GQA nodes carry >9
inputs — filed as #29524.)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ep:WebGPU ort-web webgpu provider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants