Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds optional Log-Sum-Exp (LSE) output plumbing for XPU attention kernels (SDPA + SAGEV1) to support sequence-parallel / Ring Attention merges, plus Python API exposure and unit tests. Also sets an Intel IGC environment variable to stabilize performance across driver/compiler changes.
Changes:
- Thread an optional
float* lseoutput pointer through SYCL-TLA wrapper options, kernel arguments, and epilogues. - Extend the Python-facing API with
return_lseto optionally return(O, LSE)for SDPA/SAGEV1 paths and add unit tests validating merge correctness. - Set
IGC_RemoveUnusedIdImplicitLocalIDs=0at import time to avoid performance regressions tied to IGC behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| auto_round_extension/ark/test/test_lse.py | New XPU unit tests covering return_lse contract and split-KV merge via LSE rescaling. |
| auto_round_extension/ark/auto_round_kernel/wrapper/include/xpu_wrapper.hpp | Threads optional lse pointer through XPU wrapper entry points into ARK SDPA/SAGE dispatchers. |
| auto_round_extension/ark/auto_round_kernel/wrapper/include/sycl_tla_sdpa.hpp | Adds Options::lse and forwards it into SDPA/SAGE kernel runner arguments. |
| auto_round_extension/ark/auto_round_kernel/wrapper/include/sycl_tla_common.hpp | Updates forward declarations to accept an optional float* lse. |
| auto_round_extension/ark/auto_round_kernel/wrapper/include/stla/xe_sage_fwd_kernel.hpp | Forwards LSE metadata into the epilogue and passes (head_q, idx_b) for correct LSE layout indexing. |
| auto_round_extension/ark/auto_round_kernel/sdpa.cpp | Propagates lse into option structs and dispatcher calls for prefill/decode and varlen paths. |
| auto_round_extension/ark/auto_round_kernel/ark.cpp | Extends pybind bridge function signatures to accept an optional LSE pointer. |
| auto_round_extension/ark/auto_round_kernel/init.py | Python API: adds return_lse, allocates LSE buffers, passes pointers into native bindings, and sets IGC env var. |
Comments suppressed due to low confidence (2)
auto_round_extension/ark/auto_round_kernel/init.py:635
sdpa_varlen()can return eitherOor(O, LSE)but the return type annotation and docstring still describe onlyO. This makes the public Python API contract unclear/inaccurate, especially for the LSE shape in varlen mode.
return_lse: bool = False,
) -> torch.Tensor:
"""Scaled dot-product attention (SDPA) prefill+decode with variable-length sequences.
Q, K, V use a flat 3-D layout where tokens from all sequences in the batch
are concatenated along dim-0 (the *total* dimension). Per-sequence
auto_round_extension/ark/auto_round_kernel/init.py:1235
sageattn_varlen()can return eitherOor(O, LSE), but the return type annotation/docstring still indicate onlyO. This makes it easy to misuse the returned LSE (shape/domain) in sequence-parallel merges.
return_lse: bool = False,
**kwargs,
) -> torch.Tensor:
"""SAGE attention with variable-length sequences (no padding).
Q/K/V are flat 3-D tensors: [total_tokens, num_heads, head_dim].
Per-sequence boundaries given by ``cu_seqlens_q`` / ``cu_seqlens_k``.
Contributor
|
/azp run Unit-Test-CUDA-AutoRound |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Collaborator
|
/azp run Unit-Test-CUDA-AutoRound |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
- Modified kernel functions to accept an optional LSE output buffer. - Updated the Options struct to include a pointer for LSE. - Enhanced the XeSageFwdKernel class to handle LSE in the epilogue. - Implemented tests to verify the correctness of LSE outputs and ensure backward compatibility. - Added unit tests for LSE functionality, including merging outputs from split-KV attention.
for more information, see https://pre-commit.ci
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…and error messages
for more information, see https://pre-commit.ci
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add optional
return_lse(Log-Sum-Exp) support to the ARK FMHA and SAGEV1 kernels, enabling correct sequence-parallel / Ring Attention merge via LSE rescaling. Whenreturn_lse=False(default), behavior is identical to the previous code — zero performance regression verified by benchmark.Changes
1. Kernel layer (
sycl-tla/stla)xe_fmha_fwd_epilogue.hpp: Epilogue now writes LSE =max + log₂(sum)to an optional float32 output buffer. The kernel already computes running max and sum internally for online softmax — this change only stores already-available values.xe_fmha_fwd_kernel.hpp:KernelArgumentsgainsfloat* Lsefield;to_underlying_argumentsforwards LSE pointer to epilogueArguments. Epilogueoperator()receiveshead_qandidx_bfor correct LSE output layout indexing.2. Wrapper layer (ARK)
sycl_tla_sdpa.hpp:Optionsstruct and bothKernelRunner::runinstantiations threadlsepointer through.sdpa.cpp: All dispatchers (sdpa_impl,sdpa_impl_qks8_pvhalf,sdpa_impl_qks8_pvi8,sage_prefill,sage_prefill_varlen,sdpa_varlen_impl,flash_attn_prefill,flash_attn_decode) accept optionalfloat* lse = nullptr.xpu_wrapper.hpp:sagev1_impl,sagev1,sagev1_pvi8,sagev1_varlen_implthread LSE pointer through.sycl_tla_common.hpp: Forward declarations updated.ark.cpp: All pybind wrappers accepttorch_ptr lse = 0.3. Python API
sdpa(),sdpa_varlen(),sagev1(),sagev1_pvi8(),sageattn(),sageattn_varlen()— all gainreturn_lse: bool = Falseparameter.True, returns(O, LSE)tuple with LSE shape[batch, num_heads, seq_len](float32).False, returnsOonly — backward compatible, zero overhead.4. Environment variable
IGC_RemoveUnusedIdImplicitLocalIDs=0to__init__.pyto prevent driver-upgrade-induced performance regressions. Reference: IGC Register-Allocation Regression on Xe2 (BMG) intel-graphics-compiler#412LSE Formula
The attention kernel uses
exp2-based softmax internally:lse[q] = max_j(score_{q,j}) + log₂(sum_j exp₂(score_{q,j} - max_j))
LSE merge for split-KV (Ring Attention):
lse_max = max(lse₁, lse₂)
w_k = 2^(lse_k - lse_max)
O_merged = (O₁·w₁ + O₂·w₂) / (w₁ + w₂)
Verification
Benchmark (no performance regression with
return_lse=False)Max diff +0.12% — well within measurement noise.
Benchmark (no performance regression with
return_lse=False|True)Unit tests (21/21 passed)
return_lse=False→ Tensor,return_lse=True→ (O, LSE), O from both paths identical (atol=0)