[XPU] Support softmax_lse in sgl_kernel::fwd API - #33840
Conversation
|
@sunjiweiswift @mingfeima Please help review, thanks. |
|
@Valentine233 SGLang framework expects 3D shape (batch_size, nheads, seqlen) But XPU kernel is returning 2D shape. So some alignment is required in xpu_backend.py |
@rahulvijayaraghavan Thanks to point out this. The LSE shape is not explicitly assumed in |
|
@Valentine233 @ckvermaAI tested the kernel PR for Wan model in SP mode which uses this feature. He added a reshape for for a specific varlenc call. Similar alignment is required for all calls in xpu_backend.py if kernel returns 2D shape. @ckvermaAI |
diff --git a/python/sglang/multimodal_gen/runtime/layers/attention/backends/xpu_backend.py b/python/sglang/multimodal_gen/runtime/layers/attention/backends/xpu_backend.py
index 613f2df661..0b92ef5893 100644
--- a/python/sglang/multimodal_gen/runtime/layers/attention/backends/xpu_backend.py
+++ b/python/sglang/multimodal_gen/runtime/layers/attention/backends/xpu_backend.py
@@ -116,6 +125,12 @@ class XPUAttentionImpl(AttentionImpl):
if return_softmax_lse:
out_tensor, softmax_lse = out[:2]
result = out_tensor.reshape(bsz, seqlen_q, nheads_q, d)
+ # The varlen kernel returns the LSE packed as [num_heads, total_q];
+ # total_q is the row-major flattening of (batch, seq) built by
+ # _get_cu_seqlens. Consumers (ring attention's per-hop merge,
+ # _merge_attention_partials) expect the dense-FA layout [B, H, S],
+ # which is what FlashAttentionImpl produces on its non-varlen path.
+ softmax_lse = softmax_lse.reshape(nheads_q, bsz, seqlen_q).transpose(0, 1)
return result, softmax_lse
result = out.reshape(bsz, seqlen_q, nheads_q, d) |
|
@rahulvijayaraghavan @ckvermaAI According to your input, 3D LSE is required for multimodal gen models, but it's not necessary to modify all the calls in |
|
@Valentine233 this change should be only related to api change from sgl-kernel-xpu? not related to torch version? |
The change is xpu only, and the API |
| # that index into the list do not fail shape propagation. | ||
| out_accum = q.new_empty(0) | ||
| softmax_lse_accum = q.new_empty(0, dtype=torch.float32) | ||
| return (out, softmax_lse, out_accum, softmax_lse_accum) |
There was a problem hiding this comment.
How to determine whether LSE-Softmax is needed?
There was a problem hiding this comment.
In the definition of mha_fwd https://github.com/sgl-project/sgl-kernel-xpu/pull/330/changes#diff-0c0fb34a127ec671cce962e4f85e9d124264131f65016cc0299651b724ccefd8L49-R81, the input softmax_lse is an optional tensor, so we can tell from softmax_lse.has_value().
No. It is not specific to multimodal. We expect same shape in all cases if return_softmax_lse=True. We have shape differences with CUDA flash_attn API definition which needs to be handled in xpu_backend.py CUDA (returns 3D softmax_lse) sglang/python/sglang/kernels/aot/python/sgl_kernel/flash_attn.py Lines 156 to 160 in 256981c XPU returns 2D softmax_lse |
|
@rahulvijayaraghavan The comment for CUDA is not complete here: sglang/python/sglang/kernels/aot/python/sgl_kernel/flash_attn.py Lines 156 to 160 in 256981c In the CUDA implementation, varlen path uses 2D LSE and dense path uses 3D LSE. Please check this https://github.com/sgl-project/sgl-flash-attn/blob/main/hopper/flash_api.cpp#L887-L892. |

Motivation
sgl-project/sgl-kernel-xpu#330 supports
softmax_lsein XPU attention now, sosgl_kernel::fwdneeds to know ifsoftmax_lseis required.Modifications
outandsoftmax_lse.softmax_lseisNoneif it isn't required.None.Accuracy Tests
Speed Tests and Profiling
Checklist
Review and Merge Process
/tag-and-rerun-ci,/tag-run-ci-label,/rerun-failed-ciCI States
Latest PR Test (Base): ❌ Run #32465198483
Latest PR Test (Extra): ❌ Run #32465198031
Latest PR Test (AMD ROCm 7.2): ❌ Run #32465198154