DFLASH support added for XPU (#32798)
Co-authored-by: Ma Mingfei <mingfei.ma@intel.com>
This commit is contained in:
co-authored by
Ma Mingfei
parent
690428b470
commit
0fadad8933
@@ -111,6 +111,7 @@ DRAFT_ATTENTION_BACKEND_CHOICES = [
|
||||
"triton",
|
||||
"ascend",
|
||||
"trtllm_mha",
|
||||
"intel_xpu",
|
||||
]
|
||||
|
||||
DETERMINISTIC_ATTENTION_BACKEND_CHOICES = [
|
||||
|
||||
@@ -5,6 +5,7 @@ import logging
|
||||
import os
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from sglang.srt.arg_groups.choices import DRAFT_ATTENTION_BACKEND_CHOICES
|
||||
from sglang.srt.arg_groups.overrides import (
|
||||
_speculative_moe_runner_default,
|
||||
attention_backends_of,
|
||||
@@ -198,9 +199,11 @@ def handle_speculative_decoding(server_args: ServerArgs) -> None:
|
||||
def _handle_dflash(server_args: ServerArgs) -> None:
|
||||
cfg = resolving_view(server_args)
|
||||
|
||||
if not (cfg.device.startswith("cuda") or cfg.device == "npu"):
|
||||
if not (
|
||||
cfg.device.startswith("cuda") or cfg.device == "npu" or cfg.device == "xpu"
|
||||
):
|
||||
raise ValueError(
|
||||
"DFLASH speculative decoding only supports CUDA and NPU devices."
|
||||
"DFLASH speculative decoding only supports CUDA, NPU and XPU devices."
|
||||
)
|
||||
|
||||
if resolved_view(server_args).enable_dp_attention:
|
||||
@@ -722,16 +725,11 @@ def _resolve_dflash_draft_attention_backend(server_args: ServerArgs) -> None:
|
||||
"""
|
||||
cfg = resolving_view(server_args)
|
||||
|
||||
supported_draft_backends = (
|
||||
"flashinfer",
|
||||
"fa3",
|
||||
"fa4",
|
||||
"triton",
|
||||
"trtllm_mha",
|
||||
"ascend",
|
||||
supported_draft_backends = DRAFT_ATTENTION_BACKEND_CHOICES
|
||||
# FlashInfer is CUDA-only; fall back to triton on XPU and ROCm.
|
||||
fallback_backend = (
|
||||
"triton" if (get_platform().is_xpu or get_platform().is_hip) else "flashinfer"
|
||||
)
|
||||
# Use triton on ROCm (no FlashInfer), flashinfer on CUDA.
|
||||
fallback_backend = "triton" if get_platform().is_hip else "flashinfer"
|
||||
|
||||
draft_backend = cfg.speculative_draft_attention_backend
|
||||
if draft_backend is None:
|
||||
|
||||
@@ -12,6 +12,7 @@ from sglang.srt.layers.attention.flashattention_backend import (
|
||||
merge_state_v2_wrapper,
|
||||
prepare_swa_spec_page_table_triton,
|
||||
)
|
||||
from sglang.srt.layers.radix_attention import AttentionType
|
||||
from sglang.srt.mem_cache.memory_pool import KVWriteLoc
|
||||
from sglang.srt.mem_cache.swa_memory_pool import SWAKVPool
|
||||
from sglang.srt.model_executor.forward_batch_info import ForwardBatch, ForwardMode
|
||||
@@ -553,7 +554,13 @@ class XPUAttentionBackend(AttentionBackend):
|
||||
# q = q.to(self.kv_cache_dtype)
|
||||
# q_rope = q_rope.to(self.kv_cache_dtype) if q_rope is not None else None
|
||||
# k_rope = k_rope.to(self.kv_cache_dtype) if k_rope is not None else None
|
||||
causal = not layer.is_cross_attention
|
||||
# Mirror FlashAttentionBackend: ENCODER_ONLY / bidirectional layers
|
||||
# (DFLASH draft full_attention) are non-causal, not just cross-attention.
|
||||
causal = not (
|
||||
layer.is_cross_attention
|
||||
or layer.attn_type
|
||||
in (AttentionType.ENCODER_ONLY, AttentionType.DECODER_BIDIRECTIONAL)
|
||||
)
|
||||
|
||||
# Check if we should use local attention
|
||||
use_local_attn = (
|
||||
@@ -974,7 +981,13 @@ class XPUAttentionBackend(AttentionBackend):
|
||||
if layer.sliding_window_size is not None and layer.sliding_window_size > -1
|
||||
else (-1, -1)
|
||||
)
|
||||
causal = not layer.is_cross_attention
|
||||
# Mirror FlashAttentionBackend: ENCODER_ONLY / bidirectional layers
|
||||
# (DFLASH draft full_attention) are non-causal, not just cross-attention.
|
||||
causal = not (
|
||||
layer.is_cross_attention
|
||||
or layer.attn_type
|
||||
in (AttentionType.ENCODER_ONLY, AttentionType.DECODER_BIDIRECTIONAL)
|
||||
)
|
||||
|
||||
# For fa3 interface version compatibility, we put new fields into conditional keyword args
|
||||
kwargs = {}
|
||||
|
||||
@@ -36,6 +36,7 @@ _DFLASH_VERIFY_SKIP_CUSTOM_MASK_BACKENDS = frozenset(
|
||||
"TritonAttnBackend",
|
||||
"TRTLLMHAAttnBackend",
|
||||
"TRTLLMMLABackend",
|
||||
"XPUAttentionBackend",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ from sglang.srt.speculative.spec_utils import (
|
||||
assign_req_to_token_pool_func,
|
||||
build_grammar_vocab_mask,
|
||||
)
|
||||
from sglang.srt.utils import is_cuda, is_hip, is_npu
|
||||
from sglang.srt.utils import is_cuda, is_hip, is_npu, is_xpu
|
||||
|
||||
_is_npu = is_npu()
|
||||
|
||||
@@ -503,12 +503,12 @@ class DFlashWorkerV2(BaseSpecWorker):
|
||||
self._draft_greedy_rank_index_buf: Optional[torch.Tensor] = None
|
||||
self._draft_greedy_selected_ids_buf: Optional[torch.Tensor] = None
|
||||
self._draft_greedy_index_cap: int = 0
|
||||
self._use_fused_kv_materialize = is_cuda() or is_hip()
|
||||
self._use_fused_kv_materialize = is_cuda() or is_hip() or is_xpu()
|
||||
self._fused_kv_helper: Optional[object] = None
|
||||
if self._use_fused_kv_materialize:
|
||||
self._init_fused_kv_helper()
|
||||
|
||||
supports_gpu_triton = is_cuda() or is_hip()
|
||||
supports_gpu_triton = is_cuda() or is_hip() or is_xpu()
|
||||
self._use_triton_prepare_block = supports_gpu_triton
|
||||
self._use_triton_accept_bonus = supports_gpu_triton
|
||||
# The legacy compact-rebuild path host-syncs twice per step (masked
|
||||
|
||||
@@ -9,7 +9,7 @@ import torch
|
||||
from sglang.srt.layers.logits_processor import LogitsProcessorOutput
|
||||
from sglang.srt.managers.tp_worker import TpModelWorker
|
||||
from sglang.srt.model_executor.forward_batch_info import CaptureHiddenMode
|
||||
from sglang.srt.runtime_context import attention_backends, get_spec
|
||||
from sglang.srt.runtime_context import attention_backends, get_platform, get_spec
|
||||
from sglang.srt.server_args import DRAFT_ATTENTION_BACKEND_CHOICES, ServerArgs
|
||||
from sglang.srt.speculative.dflash_info import DFlashVerifyInput
|
||||
from sglang.srt.speculative.dflash_info_v2 import DFlashDraftInputV2
|
||||
@@ -36,13 +36,17 @@ def _resolve_draft_attention_backend_fallback(*, algo_label: str) -> str:
|
||||
otherwise the process's prefill backend. Both are resolution's answers, so
|
||||
they come from the bags.
|
||||
"""
|
||||
# FlashInfer is CUDA-only; fall back to triton on XPU and ROCm.
|
||||
platform_fallback = (
|
||||
"triton" if (get_platform().is_xpu or torch.version.hip) else "flashinfer"
|
||||
)
|
||||
draft_backend = get_spec().speculative_draft_attention_backend
|
||||
if draft_backend is None:
|
||||
draft_backend, _ = attention_backends()
|
||||
if draft_backend is None:
|
||||
return "triton" if torch.version.hip else "flashinfer"
|
||||
return platform_fallback
|
||||
if draft_backend not in DRAFT_ATTENTION_BACKEND_CHOICES:
|
||||
fallback = "triton" if torch.version.hip else "flashinfer"
|
||||
fallback = platform_fallback
|
||||
logger.warning(
|
||||
"%s draft worker only supports attention_backend in %s for now, "
|
||||
"but got %r. Falling back to '%s'.",
|
||||
|
||||
Reference in New Issue
Block a user