Skip to content

Commit af52f6d

Browse files
authored
feat: support sparse attention (#81)
Support sparse attention for vllm-plugin-fl.
1 parent 1cc3947 commit af52f6d

8 files changed

Lines changed: 33 additions & 9 deletions

File tree

vllm_fl/dispatch/backends/flaggems/flaggems.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,13 @@ def rotary_embedding(
118118
inplace=inplace,
119119
)
120120

121-
def attention_backend(self, use_mla: bool = False) -> str:
121+
def attention_backend(self, use_mla: bool = False, use_sparse: bool = False) -> str:
122122
"""
123123
Get the attention backend class path for FlagGems.
124124
125125
Args:
126126
use_mla: Whether to use Multi-head Latent Attention (MLA)
127+
use_sparse: Whether to use Deepseek Sparse Attention (DSA)
127128
128129
Returns:
129130
Fully qualified class path string
@@ -140,4 +141,7 @@ def attention_backend(self, use_mla: bool = False) -> str:
140141
if use_mla:
141142
raise NotImplementedError("NOT support mla now!")
142143

144+
if use_sparse:
145+
raise ValueError("use_sparse=True requires use_mla=True.")
146+
143147
return AttentionBackendEnum.TRITON_ATTN.get_path()

vllm_fl/dispatch/backends/reference/reference.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def rotary_embedding(
120120
inplace=inplace,
121121
)
122122

123-
def attention_backend(self, use_mla: bool = False) -> str:
123+
def attention_backend(self, use_mla: bool = False, use_sparse: bool = False) -> str:
124124
"""
125125
Get the attention backend class path for reference (vLLM native).
126126
@@ -129,6 +129,7 @@ def attention_backend(self, use_mla: bool = False) -> str:
129129
130130
Args:
131131
use_mla: Whether to use Multi-head Latent Attention (MLA)
132+
use_sparse: Whether to use Deepseek Sparse Attention (DSA)
132133
133134
Returns:
134135
Fully qualified class path string (vLLM native backend)
@@ -138,5 +139,7 @@ def attention_backend(self, use_mla: bool = False) -> str:
138139

139140
if use_mla:
140141
# vLLM native MLA backend
142+
if use_sparse:
143+
return AttentionBackendEnum.FLASHMLA_SPARSE.get_path()
141144
return AttentionBackendEnum.FLASHMLA.get_path()
142145
return AttentionBackendEnum.FLASH_ATTN.get_path()

vllm_fl/dispatch/backends/vendor/ascend/ascend.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def rotary_embedding(
127127
inplace=inplace,
128128
)
129129

130-
def attention_backend(self, use_mla: bool = False) -> str:
130+
def attention_backend(self, use_mla: bool = False, use_sparse: bool = False) -> str:
131131
"""
132132
Get the attention backend class path for Ascend NPU.
133133
@@ -140,10 +140,13 @@ def attention_backend(self, use_mla: bool = False) -> str:
140140
141141
Args:
142142
use_mla: Whether to use Multi-head Latent Attention (MLA)
143+
use_sparse: Whether to use Deepseek Sparse Attention (DSA)
143144
144145
Returns:
145146
Fully qualified class path string
146147
"""
147148
if use_mla:
149+
if use_sparse:
150+
raise NotImplementedError("MLA with sparse attention is not implemented for Ascend yet.")
148151
return "vllm_fl.dispatch.backends.vendor.ascend.impl.attention.AscendMLABackend"
149152
return "vllm_fl.dispatch.backends.vendor.ascend.impl.attention.AscendAttentionBackend"

vllm_fl/dispatch/backends/vendor/cuda/cuda.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,18 @@ def rotary_embedding(
137137
inplace=inplace,
138138
)
139139

140-
def attention_backend(self, use_mla: bool = False) -> str:
140+
def attention_backend(self, use_mla: bool = False, use_sparse: bool = False) -> str:
141141
"""
142142
Get the attention backend class path for CUDA.
143143
144144
Supports:
145145
- FLASH_ATTN (default)
146146
- TRITON_ATTN (when use_flaggems_op("triton_attn") is True)
147+
- FLASHMLA_SPARSE (when use_mla and use_sparse are both True)
147148
148149
Args:
149150
use_mla: Whether to use Multi-head Latent Attention (MLA)
151+
use_sparse: Whether to use Deepseek Sparse Attention (DSA)
150152
151153
Returns:
152154
Fully qualified class path string
@@ -155,6 +157,8 @@ def attention_backend(self, use_mla: bool = False) -> str:
155157
from vllm_fl.utils import use_flaggems_op
156158

157159
if use_mla:
160+
if use_sparse:
161+
return AttentionBackendEnum.FLASHMLA_SPARSE.get_path()
158162
return AttentionBackendEnum.FLASHMLA.get_path()
159163

160164
# Default to FLASH_ATTN

vllm_fl/dispatch/backends/vendor/iluvatar/iluvatar.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,19 +143,22 @@ def rotary_embedding(
143143
inplace=inplace,
144144
)
145145

146-
def attention_backend(self, use_mla: bool = False) -> str:
146+
def attention_backend(self, use_mla: bool = False, use_sparse: bool = False) -> str:
147147
"""
148148
Get the attention backend class path for Iluvatar.
149149
150150
Args:
151151
use_mla: Whether to use Multi-head Latent Attention (MLA)
152+
use_sparse: Whether to use Deepseek Sparse Attention (DSA)
152153
153154
Returns:
154155
Fully qualified class path string
155156
"""
156157
from vllm.attention.backends.registry import AttentionBackendEnum
157158

158159
if use_mla:
160+
if use_sparse:
161+
return AttentionBackendEnum.FLASHMLA_SPARSE.get_path()
159162
return AttentionBackendEnum.FLASHMLA.get_path()
160163

161164
return AttentionBackendEnum.FLASH_ATTN.get_path()

vllm_fl/dispatch/backends/vendor/metax/metax.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,19 +131,23 @@ def rotary_embedding(
131131
inplace=inplace,
132132
)
133133

134-
def attention_backend(self, use_mla: bool = False) -> str:
134+
def attention_backend(self, use_mla: bool = False, use_sparse: bool = False) -> str:
135135
"""
136136
Get the attention backend class path for METAX.
137137
138138
Args:
139139
use_mla: Whether to use Multi-head Latent Attention (MLA)
140+
use_sparse: Whether to use Deepseek Sparse Attention (DSA)
140141
141142
Returns:
142143
Fully qualified class path string
143144
"""
144145
from vllm.attention.backends.registry import AttentionBackendEnum
145146

146147
if use_mla:
148+
if use_sparse:
149+
# TODO: Implement METAX MLA Sparse backend
150+
return AttentionBackendEnum.FLASHMLA_SPARSE.get_path()
147151
# TODO: Implement METAX MLA backend
148152
return AttentionBackendEnum.FLASHMLA.get_path()
149153

vllm_fl/dispatch/ops.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def rotary_embedding(
129129
# ==================== Attention Backend ====================
130130

131131
@abstractmethod
132-
def attention_backend(self, use_mla: bool = False) -> str:
132+
def attention_backend(self, use_mla: bool = False, use_sparse: bool = False) -> str:
133133
"""
134134
Get the attention backend class path for this platform.
135135
@@ -138,6 +138,7 @@ def attention_backend(self, use_mla: bool = False) -> str:
138138
139139
Args:
140140
use_mla: Whether to use Multi-head Latent Attention (MLA)
141+
use_sparse: Whether to use sparse attention
141142
142143
Returns:
143144
Fully qualified class path string, e.g.:

vllm_fl/platform.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,14 @@ def get_attn_backend_cls(
170170
from vllm_fl.dispatch import call_op
171171

172172
use_mla = attn_selector_config.use_mla
173+
use_sparse = attn_selector_config.use_sparse
173174

174-
backend_path = call_op("attention_backend", use_mla=use_mla)
175+
backend_path = call_op("attention_backend", use_mla=use_mla, use_sparse=use_sparse)
175176

176177
logger.info_once(
177-
"Using attention backend via dispatch (use_mla=%s): %s",
178+
"Using attention backend via dispatch (use_mla=%s, use_sparse=%s): %s",
178179
use_mla,
180+
use_sparse,
179181
backend_path,
180182
scope="local",
181183
)

0 commit comments

Comments
 (0)