Skip to content

[WebGPU]: Add Intel subgroup prefill flash-attention kernel - #32702

Open
Jianhui Dai (daijh) wants to merge 7 commits into
microsoft:mainfrom
daijh:pr/flash-attn-prefill
Open

Jianhui Dai (daijh) wants to merge 7 commits into
microsoft:mainfrom
daijh:pr/flash-attn-prefill

Conversation

@daijh

@daijh Jianhui Dai (daijh) commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Description

Add FlashAttentionPrefillProgram, a simplified variant of
FlashAttentionProgram used for dense prefill on Intel GPUs.

Kernel design (and key differences from FlashAttentionProgram):

  • One query row per thread.
  • The full-head K tile is staged before the QK^T + online-softmax
    stage. V is staged just before the PV matmul, in slices of up to 16
    vec4 values, so global-memory latency overlaps with softmax compute
    and V needs less workgroup memory. The default kernel stages both K
    and V at full head size.
  • K and V tiles use a transposed layout ([head_size_vec][kv_step]),
    so adjacent lanes hit adjacent shared-memory addresses and avoid bank
    conflicts. The default kernel uses [kv_step][head_size_vec].
  • Subgroup shuffle is a static code path chosen on the host from the
    adapter's guaranteed minimum subgroup size (shuffle_chunk = min(kv_step, subgroup_min_size)). Below 8, the kernel reads K/V
    directly from shared memory, which also covers adapters without
    subgroups.
  • The workgroup size and KV step are chosen per adapter and shapes.
  • No quantized KV cache, TurboQuant LUT, or compressed K/V decoding
    paths.

Configuration (host-selected per adapter):

  • Default: 64 threads, 16 KV rows per step.
  • Xe2: 128 threads / 64 KV rows for query length <= 128, otherwise
    256 threads / 32 KV rows.
  • Xe3: 128 threads / 64 KV rows.
  • If the K tile and V slice would exceed
    maxComputeWorkgroupStorageSize, fall back to the default
    configuration.

Integration:

  • Adds CanApplyFlashAttentionPrefill and ApplyFlashAttentionPrefill.
    ApplyDensePrefill selects this kernel when the adapter is Intel and
    the KV cache is not quantized. Otherwise it uses the existing
    FlashAttentionProgram.
  • Quantized KV cache (int8 / TurboQuant) is not supported by this
    kernel yet.

Tests:

  • Parameterize RunFp16HighMagnitudeAttention by head size and add
    head_size 80 and 96 cases, whose head_size / 4 is not a multiple of
    the V slice width.

Performance (Phi-4-mini, Intel Panther Lake):

Metric Baseline Prefill TPS Optimized Prefill TPS Improve
Prefill-128 1961.46 1945.12 -0.83%
Prefill-256 2481.54 2502.52 0.85%
Prefill-512 2577.39 2774.83 7.66%
Prefill-1024 2505.69 2751.47 9.81%
Prefill-2048 2346.94 2673.69 13.92%
Prefill-4096 1668.55 1985.91 19.02%

TODO (follow-up PRs):

  • Support quantized KV cache (int8 / TurboQuant).
  • Merge back into FlashAttentionProgram.

Motivation and Context

See above.

Copilot AI balanced review requested due to automatic review settings September 20, 2026 06:44
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@daijh

Copy link
Copy Markdown
Contributor Author

Prerequisite: #32605

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.

Copilot review overview

🟡 Changes recommended

The kernel has out-of-bounds subgroup accesses, incorrect long-context fp16 accumulation, and no automated Intel execution coverage.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 High severity · 1 Medium severity · 1 Low severity

Open (3)
What changed in this PR

Adds an Intel-optimized WebGPU flash-attention prefill path using subgroup shuffles and deferred V loading.

Changes:

  • Adds the simplified WGSL prefill kernel.
  • Adds host-side configuration and Intel-specific dispatch.
  • Retains the existing kernel as fallback.
File Description
flash_attention.h Declares the new program and helpers.
flash_attention.cc Configures and selects the Intel kernel.
flash_attention_prefill_simple.wgsl.template Implements tiled attention and online softmax.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread onnxruntime/contrib_ops/webgpu/bert/flash_attention_prefill_simple.wgsl.template Outdated
Comment thread onnxruntime/contrib_ops/webgpu/bert/flash_attention.cc Outdated
Comment thread onnxruntime/contrib_ops/webgpu/bert/flash_attention.cc Outdated
@daijh
Jianhui Dai (daijh) marked this pull request as draft September 22, 2026 05:15
@daijh
Jianhui Dai (daijh) force-pushed the pr/flash-attn-prefill branch 2 times, most recently from 5e758ee to 1402c7b Compare October 19, 2026 05:41
Introduce FlashAttentionPrefillSimpleProgram and its template
(flash_attention_prefill_simple.wgsl.template). This is a simplified
version of the FlashAttentionProgram kernel. (TODO: Merge back into
the original FlashAttentionProgram)

Key implementation details:
- Latency Hiding: Only K is loaded before the QK^T + online-softmax
  stage. V is fetched just before the PV matmul, allowing global-memory
  latency to overlap with softmax compute.
- Avoids Bank Conflicts: K and V tiles are stored in transposed layout
  ([head_size_vec][kv_step]), ensuring the subgroup column is the inner/
  fastest dimension. Adjacent lanes hit adjacent shared-memory
  addresses.
- Static Shuffle Codepath: Unconditionally uses a subgroup-shuffle path
  based on the host-configured minimum subgroup size. This avoids
  dynamic runtime SubgroupSize detection inside the WGSL kernel.
- Configurations: The host determines kv_step (8 or 16) based on the
  adapter's guaranteed minimum subgroup size (needs minimum of 8).
  Workgroup size is 128 for causal and 256 for non-causal prefill.
- Unsupported Features: Does not support quantized KV cache (int8/
  TurboQuant) or the shared-memory fallback path (to be supported).

Integration & Selection:
- Adds CanApplyFlashAttentionPrefillSimple and
  ApplyFlashAttentionPrefillSimple, mirroring the MatMulNBits pattern.
- ApplyFlashAttention selects this kernel only if 'is_intel' is true,
  subgroup_min_size >= 8, and the KV cache is unquantized. Otherwise,
  it falls back to the existing FlashAttentionProgram.

**Test on Phi-4-mini, EdgeLLMOnDeviceModel\2026.5.8.1, Panther Lake:**

| Metric | Baseline Prefill TPS | Optimized Prefill TPS | Improve |
|---|---|---|---|
| Prefill-128 | 1289.89 | 1264.72 | -1.95% |
| Prefill-256 | 1647.14 | 1631.21 | -0.97% |
| Prefill-512 | 1915.64 | 2012.29 | 5.05% |
| Prefill-1024 | 1834.62 | 1935.33 | 5.49% |
| Prefill-2048 | 1745.07 | 1947.23 | 11.58% |
| Prefill-4096 | 1508.13 | 1812.86 | 20.21% |
@daijh
Jianhui Dai (daijh) marked this pull request as ready for review October 27, 2026 03:52
@daijh

Copy link
Copy Markdown
Contributor Author

This branch has not been deployed

No deployments
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