Skip to content

Commit 1b1f269

Browse files
askliarAndrii Skliarmgoin
authored andcommitted
[Attention] Fix FlashInfer SM12x prefill with sinks (vllm-project#52148)
Signed-off-by: Andrii Skliar <askliar@nvidia.com> Co-authored-by: Andrii Skliar <askliar@nvidia.com> Co-authored-by: Michael Goin <mgoin64@gmail.com> Signed-off-by: Wyett <wyettzeng@gmail.com>
1 parent 89dca0c commit 1b1f269

2 files changed

Lines changed: 66 additions & 24 deletions

File tree

tests/v1/attention/test_attention_backends.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ def test_flashinfer_attention_sinks_refreshed_after_reload(dtype):
848848
AttentionBackendEnum.FLASHINFER not in BACKENDS_TO_TEST,
849849
reason="FlashInfer is not available.",
850850
)
851-
def test_flashinfer_native_prefill_with_sinks():
851+
def test_flashinfer_native_prefill_with_sinks(default_vllm_config):
852852
if not (
853853
current_platform.is_cuda() and current_platform.is_device_capability_family(120)
854854
):

vllm/v1/attention/backends/flashinfer.py

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import numpy as np
1111
import torch
1212
from flashinfer import (
13+
BatchAttentionWithAttentionSinkWrapper,
1314
BatchDecodeWithPagedKVCacheWrapper,
1415
BatchPrefillWithPagedKVCacheWrapper,
1516
BatchPrefillWithRaggedKVCacheWrapper,
@@ -1113,11 +1114,27 @@ def _get_prefill_wrapper(
11131114
"NVFP4 KV cache."
11141115
)
11151116
if self._noncausal_prefill_wrapper is None:
1116-
self._noncausal_prefill_wrapper = BatchPrefillWithPagedKVCacheWrapper(
1117-
self._get_workspace_buffer(),
1118-
get_kv_cache_layout(),
1119-
backend="auto",
1120-
)
1117+
if self.has_sinks and current_platform.is_device_capability_family(120):
1118+
self._noncausal_prefill_wrapper = (
1119+
BatchAttentionWithAttentionSinkWrapper(
1120+
self._get_workspace_buffer(),
1121+
get_kv_cache_layout(),
1122+
backend="auto",
1123+
q_data_type=self.q_data_type_prefill,
1124+
kv_data_type=self.kv_cache_dtype,
1125+
head_dim_qk=self.head_dim,
1126+
head_dim_vo=self.head_dim,
1127+
window_left=self.window_left,
1128+
)
1129+
)
1130+
else:
1131+
self._noncausal_prefill_wrapper = (
1132+
BatchPrefillWithPagedKVCacheWrapper(
1133+
self._get_workspace_buffer(),
1134+
get_kv_cache_layout(),
1135+
backend="auto",
1136+
)
1137+
)
11211138
return self._noncausal_prefill_wrapper
11221139

11231140
if self._prefill_wrapper is None:
@@ -1127,14 +1144,27 @@ def _get_prefill_wrapper(
11271144
dcp_a2a=self.dcp_a2a,
11281145
)
11291146
else:
1130-
# NVFP4 KV cache requires the trtllm-gen backend inside
1131-
# the wrapper; fa2/fa3 do not support nvfp4.
1132-
backend = "trtllm-gen" if self.is_kvcache_nvfp4 else "auto"
1133-
self._prefill_wrapper = BatchPrefillWithPagedKVCacheWrapper(
1134-
self._get_workspace_buffer(),
1135-
get_kv_cache_layout(),
1136-
backend=backend,
1137-
)
1147+
if self.has_sinks and current_platform.is_device_capability_family(120):
1148+
assert not self.is_kvcache_nvfp4
1149+
self._prefill_wrapper = BatchAttentionWithAttentionSinkWrapper(
1150+
self._get_workspace_buffer(),
1151+
get_kv_cache_layout(),
1152+
backend="auto",
1153+
q_data_type=self.q_data_type_prefill,
1154+
kv_data_type=self.kv_cache_dtype,
1155+
head_dim_qk=self.head_dim,
1156+
head_dim_vo=self.head_dim,
1157+
window_left=self.window_left,
1158+
)
1159+
else:
1160+
# NVFP4 KV cache requires the trtllm-gen backend inside
1161+
# the wrapper; fa2/fa3 do not support nvfp4.
1162+
backend = "trtllm-gen" if self.is_kvcache_nvfp4 else "auto"
1163+
self._prefill_wrapper = BatchPrefillWithPagedKVCacheWrapper(
1164+
self._get_workspace_buffer(),
1165+
get_kv_cache_layout(),
1166+
backend=backend,
1167+
)
11381168
assert self._prefill_wrapper is not None
11391169
return self._prefill_wrapper
11401170

@@ -2086,16 +2116,28 @@ def forward(
20862116
else:
20872117
out_prefill = output[num_decode_tokens:]
20882118

2089-
prefill_wrapper.run(
2090-
prefill_query,
2091-
kv_cache_for_fi,
2092-
q_scale=layer._q_scale_float,
2093-
k_scale=layer._k_scale_float,
2094-
v_scale=layer._v_scale_float,
2095-
out=out_prefill,
2096-
kv_cache_sf=kv_cache_sf,
2097-
sinks=self.sinks,
2098-
)
2119+
if isinstance(
2120+
prefill_wrapper, BatchAttentionWithAttentionSinkWrapper
2121+
):
2122+
assert self.sinks is not None
2123+
prefill_wrapper.run(
2124+
prefill_query,
2125+
kv_cache_for_fi,
2126+
self.sinks,
2127+
self.scale * layer._q_scale_float * layer._k_scale_float,
2128+
v_scale=layer._v_scale_float,
2129+
out=out_prefill,
2130+
)
2131+
else:
2132+
prefill_wrapper.run(
2133+
prefill_query,
2134+
kv_cache_for_fi,
2135+
q_scale=layer._q_scale_float,
2136+
k_scale=layer._k_scale_float,
2137+
v_scale=layer._v_scale_float,
2138+
out=out_prefill,
2139+
kv_cache_sf=kv_cache_sf,
2140+
)
20992141

21002142
if needs_fp8_out_prefill:
21012143
output[

0 commit comments

Comments
 (0)