Add intel_xpu to DETERMINISTIC_ATTENTION_BACKEND_CHOICES (#29143)
Co-authored-by: vshekhawat-hlab <vshekhawat@habana.ai>
This commit is contained in:
co-authored by
vshekhawat-hlab
parent
fee00a41db
commit
4c02584773
@@ -99,6 +99,15 @@ class XPUAttentionBackend(AttentionBackend):
|
||||
self.has_swa = (
|
||||
self.sliding_window_size is not None and self.sliding_window_size > -1
|
||||
)
|
||||
|
||||
# If num_splits == 0, the kernel uses a heuristic to automatically
|
||||
# determine the number of splits. Split-KV reduces across a
|
||||
# non-deterministic number of partitions, so we pin num_splits to 1
|
||||
# when deterministic inference is enabled to keep attention reduction
|
||||
# order fixed. This mirrors the flash-attention (fa3) backend.
|
||||
self.num_splits = (
|
||||
1 if model_runner.server_args.enable_deterministic_inference else 0
|
||||
)
|
||||
self.is_encoder_decoder = model_runner.model_config.is_encoder_decoder
|
||||
|
||||
def init_forward_metadata(self, forward_batch: ForwardBatch):
|
||||
@@ -553,6 +562,10 @@ class XPUAttentionBackend(AttentionBackend):
|
||||
# Use Flash Attention for prefill
|
||||
if not self.use_mla:
|
||||
# Do multi-head attention
|
||||
# The MLA branch passes num_splits explicitly per call site, since the
|
||||
# chunked-prefix varlen kernels there keep their own default.
|
||||
kwargs["num_splits"] = self.num_splits
|
||||
|
||||
key_cache, value_cache = self.token_to_kv_pool.get_kv_buffer(layer.layer_id)
|
||||
key_cache = key_cache.view(
|
||||
-1, self.page_size, layer.tp_k_head_num, layer.head_dim
|
||||
@@ -716,6 +729,7 @@ class XPUAttentionBackend(AttentionBackend):
|
||||
k_descale=k_descale,
|
||||
v_descale=v_descale,
|
||||
return_softmax_lse=use_cascade_attn,
|
||||
num_splits=self.num_splits,
|
||||
)
|
||||
if use_cascade_attn:
|
||||
o, softmax_lse, *rest = result
|
||||
@@ -737,6 +751,7 @@ class XPUAttentionBackend(AttentionBackend):
|
||||
k_descale=k_descale,
|
||||
v_descale=v_descale,
|
||||
return_softmax_lse=True,
|
||||
num_splits=self.num_splits,
|
||||
)
|
||||
)
|
||||
o, _ = merge_state_v2_wrapper(
|
||||
@@ -843,6 +858,11 @@ class XPUAttentionBackend(AttentionBackend):
|
||||
if not self.use_mla:
|
||||
# Do multi-head attention
|
||||
|
||||
# Only the MHA kernels below take num_splits. The MLA path calls
|
||||
# flash_mla_decode, whose own num_kv_splits already defaults to 1
|
||||
# (no split-KV), so it needs no deterministic override here.
|
||||
kwargs["num_splits"] = self.num_splits
|
||||
|
||||
key_cache, value_cache = self.token_to_kv_pool.get_kv_buffer(layer.layer_id)
|
||||
key_cache = key_cache.view(
|
||||
-1, self.page_size, layer.tp_k_head_num, layer.head_dim
|
||||
@@ -987,6 +1007,12 @@ class XPUAttentionBackend(AttentionBackend):
|
||||
metadata.page_table,
|
||||
self.workspace,
|
||||
layer.scaling,
|
||||
# flash_mla_decode's heuristic only kicks in when num_kv_splits
|
||||
# < 1, and it derives the split count from batch * num_heads and
|
||||
# seq_len_kv, which is not batch-invariant. Pin it to 1 (the
|
||||
# kernel's current default) so the reduction order stays fixed
|
||||
# regardless of upstream default changes.
|
||||
num_kv_splits=1,
|
||||
)
|
||||
|
||||
out = o.view(-1, layer.tp_q_head_num * layer.v_head_dim)
|
||||
|
||||
@@ -241,6 +241,7 @@ DETERMINISTIC_ATTENTION_BACKEND_CHOICES = [
|
||||
"fa3",
|
||||
"fa4",
|
||||
"flashinfer",
|
||||
"intel_xpu",
|
||||
"triton",
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user