A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 14, 05:30 UTC
[ROCm] [VL] [Bugfix] Fix vit flash attn dispatcher logic for ROCm (#26104)
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
TJian committed
Oct 2, 2025 at 22:34 UTC
9c5ee91b2af834fb3221787d63ac025badbe0168
9 files changed
+154
-141
vllm/attention/layer.py
+49
-23
@@ -1,7 +1,7 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
"""Attention layer."""
4
-from typing import List, Optional
4
+from typing import Callable, List, Optional
5
6
import torch
7
import torch.nn as nn
@@ -68,9 +68,39 @@ def check_upstream_fa_availability(dtype: torch.dtype):
68
) and current_platform.has_device_capability(80):
69
from transformers.utils import is_flash_attn_2_available
70
return is_flash_attn_2_available()
71
+ if current_platform.is_rocm():
72
+ from importlib.util import find_spec
73
+ return find_spec("flash_attn") is not None
74
return False
75
76
77
+def maybe_get_vit_flash_attn_backend(
78
+ attn_backend: _Backend,
79
+ use_upstream_fa: bool) -> tuple[_Backend, Callable]:
80
+ if attn_backend != _Backend.FLASH_ATTN and \
81
+ attn_backend != _Backend.ROCM_AITER_FA and \
82
+ check_upstream_fa_availability(torch.get_default_dtype()):
83
+ attn_backend = _Backend.FLASH_ATTN
84
+ use_upstream_fa = True
85
+
86
+ if current_platform.is_rocm() and \
87
+ attn_backend == _Backend.FLASH_ATTN:
88
+ use_upstream_fa = True
89
+
90
+ if (attn_backend in {_Backend.FLASH_ATTN, _Backend.ROCM_AITER_FA}):
91
+ if attn_backend == _Backend.ROCM_AITER_FA:
92
+ from aiter import flash_attn_varlen_func
93
+ else:
94
+ if use_upstream_fa:
95
+ from flash_attn import flash_attn_varlen_func
96
+ else:
97
+ from vllm.vllm_flash_attn import flash_attn_varlen_func
98
+ else:
99
+ flash_attn_varlen_func = None
100
+
101
+ return attn_backend, flash_attn_varlen_func
102
+
103
+
104
class Attention(nn.Module, AttentionLayerBase):
105
"""Attention layer.
106
@@ -410,13 +440,9 @@ class MultiHeadAttention(nn.Module):
440
# to upstream flash attention if available.
441
# If vllm native fa is selected, we use it directly.
442
use_upstream_fa = False
413
- if backend != _Backend.FLASH_ATTN and check_upstream_fa_availability(
414
- dtype):
415
- backend = _Backend.FLASH_ATTN
416
- use_upstream_fa = True
443
418
- if current_platform.is_rocm() or current_platform.is_xpu():
419
- # currently, only torch_sdpa is supported on rocm/xpu
444
+ if current_platform.is_xpu():
445
+ # currently, only torch_sdpa is supported on xpu
446
self.attn_backend = _Backend.TORCH_SDPA
447
else:
448
@@ -428,17 +454,25 @@ class MultiHeadAttention(nn.Module):
454
_Backend.FLASH_ATTN,
455
} else _Backend.TORCH_SDPA
456
457
+ self.attn_backend, self._flash_attn_varlen_func \
458
+ = maybe_get_vit_flash_attn_backend(
459
+ self.attn_backend,
460
+ use_upstream_fa,
461
+ )
462
+
463
if (self.attn_backend == _Backend.XFORMERS
464
and not check_xformers_availability()):
465
self.attn_backend = _Backend.TORCH_SDPA
466
435
- if self.attn_backend == _Backend.FLASH_ATTN:
436
- if use_upstream_fa:
437
- from flash_attn import flash_attn_varlen_func
438
- self._flash_attn_varlen_func = flash_attn_varlen_func
439
- else:
440
- from vllm.vllm_flash_attn import flash_attn_varlen_func
441
- self._flash_attn_varlen_func = flash_attn_varlen_func
467
+ self.is_flash_attn_backend = self.attn_backend in {
468
+ _Backend.FLASH_ATTN, _Backend.ROCM_AITER_FA
469
+ }
470
+
471
+ # this condition is just to make sure that the
472
+ # use_upstream_fa in the log is correct
473
+ if current_platform.is_rocm() \
474
+ and self.attn_backend == _Backend.FLASH_ATTN:
475
+ use_upstream_fa = True
476
477
logger.info_once(
478
f"MultiHeadAttention attn_backend: {self.attn_backend}, "
@@ -466,7 +500,7 @@ class MultiHeadAttention(nn.Module):
500
key = torch.repeat_interleave(key, num_repeat, dim=2)
501
value = torch.repeat_interleave(value, num_repeat, dim=2)
502
469
- if self.attn_backend == _Backend.FLASH_ATTN:
503
+ if self.is_flash_attn_backend:
504
cu_seqlens_q = torch.arange(0, (bsz + 1) * q_len,
505
step=q_len,
506
dtype=torch.int32,
@@ -507,14 +541,6 @@ class MultiHeadAttention(nn.Module):
541
from torch_xla.experimental.custom_kernel import flash_attention
542
out = flash_attention(query, key, value, sm_scale=self.scale)
543
out = out.transpose(1, 2)
510
- elif self.attn_backend == _Backend.ROCM_AITER_FA:
511
- from aiter import flash_attn_varlen_func
512
-
513
- # ROCm Flash Attention expects (batch, seq, heads, head_dim)
514
- out = flash_attn_varlen_func(query,
515
- key,
516
- value,
517
- softmax_scale=self.scale)
544
else:
545
# ViT attention hasn't supported this backend yet
546
raise NotImplementedError(
vllm/model_executor/models/dots_ocr.py
+19
-22
@@ -10,7 +10,8 @@ from torch.nn import LayerNorm
10
from transformers.models.qwen2_vl import Qwen2VLProcessor
11
12
from vllm.attention.backends.registry import _Backend
13
-from vllm.attention.layer import check_upstream_fa_availability
13
+from vllm.attention.layer import (check_upstream_fa_availability,
14
+ maybe_get_vit_flash_attn_backend)
15
from vllm.config import VllmConfig
16
from vllm.distributed import utils as dist_utils
17
from vllm.distributed.parallel_state import (
@@ -267,10 +268,12 @@ class DotsVisionAttention(nn.Module):
268
self.attn_backend = get_vit_attn_backend(
269
self.hidden_size_per_attention_head, torch.get_default_dtype())
270
self.use_upstream_fa = False
270
- if self.attn_backend != _Backend.FLASH_ATTN and \
271
- check_upstream_fa_availability(torch.get_default_dtype()):
272
- self.attn_backend = _Backend.FLASH_ATTN
273
- self.use_upstream_fa = True
271
+
272
+ self.attn_backend, self.flash_attn_varlen_func \
273
+ = maybe_get_vit_flash_attn_backend(
274
+ self.attn_backend,
275
+ self.use_upstream_fa,
276
+ )
277
if self.attn_backend not in {
278
_Backend.FLASH_ATTN, _Backend.TORCH_SDPA, _Backend.XFORMERS,
279
_Backend.ROCM_AITER_FA
@@ -306,25 +309,18 @@ class DotsVisionAttention(nn.Module):
309
q, k = torch.chunk(qk_rotated, 2, dim=0)
310
311
if self.is_flash_attn_backend:
309
- if self.attn_backend == _Backend.ROCM_AITER_FA:
310
- from aiter import flash_attn_varlen_func
311
- else:
312
- if self.use_upstream_fa:
313
- from flash_attn import flash_attn_varlen_func
314
- else:
315
- from vllm.vllm_flash_attn import flash_attn_varlen_func
312
q_ = q.reshape(bs * q.shape[1], q.shape[2], q.shape[3])
313
k_ = k.reshape(bs * k.shape[1], k.shape[2], k.shape[3])
314
v_ = v.reshape(bs * v.shape[1], v.shape[2], v.shape[3])
319
- output = flash_attn_varlen_func(q_,
320
- k_,
321
- v_,
322
- cu_seqlens_q=cu_seqlens,
323
- cu_seqlens_k=cu_seqlens,
324
- max_seqlen_q=max_seqlen,
325
- max_seqlen_k=max_seqlen,
326
- dropout_p=0.0,
327
- causal=False)
315
+ output = self.flash_attn_varlen_func(q_,
316
+ k_,
317
+ v_,
318
+ cu_seqlens_q=cu_seqlens,
319
+ cu_seqlens_k=cu_seqlens,
320
+ max_seqlen_q=max_seqlen,
321
+ max_seqlen_k=max_seqlen,
322
+ dropout_p=0.0,
323
+ causal=False)
324
context_layer = output.view(bs, -1,
325
self.num_attention_heads_per_partition,
326
self.hidden_size_per_attention_head)
@@ -611,7 +607,8 @@ class DotsVisionTransformer(nn.Module):
607
self, cu_seqlens: torch.Tensor
608
) -> tuple[Optional[int], Optional[list[int]]]:
609
max_seqlen, seqlens = None, None
614
- if self.attn_backend == _Backend.FLASH_ATTN:
610
+ if (self.attn_backend == _Backend.FLASH_ATTN
611
+ or self.attn_backend == _Backend.ROCM_AITER_FA):
612
max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max().item()
613
elif self.attn_backend == _Backend.XFORMERS:
614
seqlens = (cu_seqlens[1:] - cu_seqlens[:-1]).tolist()
vllm/model_executor/models/ernie45_vl.py
+23
-26
@@ -35,7 +35,8 @@ from einops import rearrange, repeat
35
from transformers import BatchFeature
36
37
from vllm.attention.backends.registry import _Backend
38
-from vllm.attention.layer import check_upstream_fa_availability
38
+from vllm.attention.layer import (check_upstream_fa_availability,
39
+ maybe_get_vit_flash_attn_backend)
40
from vllm.config import VllmConfig
41
from vllm.distributed import parallel_state
42
from vllm.distributed import utils as dist_utils
@@ -176,14 +177,18 @@ class Ernie4_5_VisionAttention(nn.Module):
177
dtype=torch.get_default_dtype())
178
179
self.use_upstream_fa = False
179
- if self.attn_backend != _Backend.FLASH_ATTN and \
180
- check_upstream_fa_availability(torch.get_default_dtype()):
181
- self.attn_backend = _Backend.FLASH_ATTN
182
- self.use_upstream_fa = True
180
+
181
+ self.attn_backend, self.flash_attn_varlen_func \
182
+ = maybe_get_vit_flash_attn_backend(
183
+ self.attn_backend,
184
+ self.use_upstream_fa,
185
+ )
186
187
if self.attn_backend not in {
185
- _Backend.FLASH_ATTN, _Backend.TORCH_SDPA, _Backend.XFORMERS,
186
- _Backend.ROCM_AITER_FA
188
+ _Backend.FLASH_ATTN,
189
+ _Backend.TORCH_SDPA,
190
+ _Backend.XFORMERS,
191
+ _Backend.ROCM_AITER_FA,
192
}:
193
raise RuntimeError(
194
f"Ernie45-VL does not support {self.attn_backend} backend now."
@@ -239,27 +244,18 @@ class Ernie4_5_VisionAttention(nn.Module):
244
q, k = torch.chunk(qk_rotated, 2, dim=0)
245
246
if self.is_flash_attn_backend:
242
- # from vllm_flash_attn.flash_attn_interface import (
243
- # flash_attn_varlen_func)
244
- if self.attn_backend == _Backend.ROCM_AITER_FA:
245
- from aiter import flash_attn_varlen_func
246
- else:
247
- if self.use_upstream_fa:
248
- from flash_attn import flash_attn_varlen_func
249
- else:
250
- from vllm.vllm_flash_attn import flash_attn_varlen_func
247
248
q, k, v = (rearrange(x, "b s ... -> (b s) ...") for x in [q, k, v])
249
254
- output = flash_attn_varlen_func(q,
255
- k,
256
- v,
257
- cu_seqlens_q=cu_seqlens,
258
- cu_seqlens_k=cu_seqlens,
259
- max_seqlen_q=max_seqlen,
260
- max_seqlen_k=max_seqlen,
261
- dropout_p=0.0,
262
- causal=False)
250
+ output = self.flash_attn_varlen_func(q,
251
+ k,
252
+ v,
253
+ cu_seqlens_q=cu_seqlens,
254
+ cu_seqlens_k=cu_seqlens,
255
+ max_seqlen_q=max_seqlen,
256
+ max_seqlen_k=max_seqlen,
257
+ dropout_p=0.0,
258
+ causal=False)
259
260
context_layer = rearrange(output,
261
"(b s) h d -> s b (h d)",
@@ -516,7 +512,8 @@ class Ernie4_5_VisionTransformer(nn.Module):
512
self, cu_seqlens: torch.Tensor
513
) -> tuple[Optional[int], Optional[list[int]]]:
514
max_seqlen, seqlens = None, None
519
- if self.attn_backend == _Backend.FLASH_ATTN:
515
+ if (self.attn_backend == _Backend.FLASH_ATTN
516
+ or self.attn_backend == _Backend.ROCM_AITER_FA):
517
max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max().item()
518
elif self.attn_backend == _Backend.XFORMERS:
519
seqlens = (cu_seqlens[1:] - cu_seqlens[:-1]).tolist()
vllm/model_executor/models/glm4_1v.py
+17
-14
@@ -47,7 +47,8 @@ from transformers.models.glm4v.video_processing_glm4v import (
47
from transformers.video_utils import VideoMetadata
48
49
from vllm.attention.backends.registry import _Backend
50
-from vllm.attention.layer import check_upstream_fa_availability
50
+from vllm.attention.layer import (check_upstream_fa_availability,
51
+ maybe_get_vit_flash_attn_backend)
52
from vllm.config import VllmConfig
53
from vllm.distributed import (get_tensor_model_parallel_world_size,
54
parallel_state)
@@ -263,19 +264,26 @@ class Glm4vVisionAttention(nn.Module):
264
head_size=self.hidden_size_per_attention_head,
265
dtype=torch.get_default_dtype())
266
self.use_upstream_fa = False
266
- if self.attn_backend != _Backend.FLASH_ATTN and \
267
- check_upstream_fa_availability(torch.get_default_dtype()):
268
- self.attn_backend = _Backend.FLASH_ATTN
269
- self.use_upstream_fa = True
267
+
268
+ self.attn_backend, self.flash_attn_varlen_func \
269
+ = maybe_get_vit_flash_attn_backend(
270
+ self.attn_backend,
271
+ self.use_upstream_fa,
272
+ )
273
274
if self.attn_backend not in {
275
_Backend.FLASH_ATTN,
276
_Backend.TORCH_SDPA,
277
_Backend.XFORMERS,
278
+ _Backend.ROCM_AITER_FA,
279
}:
280
raise RuntimeError(
281
f"GLM-4V does not support {self.attn_backend} backend now.")
282
283
+ self.is_flash_attn_backend = self.attn_backend in {
284
+ _Backend.FLASH_ATTN, _Backend.ROCM_AITER_FA
285
+ }
286
+
287
def split_qkv(self, qkv: torch.Tensor) -> tuple[torch.Tensor, ...]:
288
# [s, b, 3 * head * head_dim]
289
seq_len, bs, _ = qkv.shape
@@ -316,17 +324,11 @@ class Glm4vVisionAttention(nn.Module):
324
qk_rotated = apply_rotary_pos_emb_vision(qk_concat, rotary_pos_emb)
325
q, k = torch.chunk(qk_rotated, 2, dim=0)
326
319
- if self.attn_backend == _Backend.FLASH_ATTN:
320
- # from vllm_flash_attn.flash_attn_interface import (
321
- # flash_attn_varlen_func)
322
- if self.use_upstream_fa:
323
- from flash_attn import flash_attn_varlen_func
324
- else:
325
- from vllm.vllm_flash_attn import flash_attn_varlen_func
327
+ if self.is_flash_attn_backend:
328
329
q, k, v = (rearrange(x, "b s ... -> (b s) ...") for x in [q, k, v])
330
329
- output = flash_attn_varlen_func(
331
+ output = self.flash_attn_varlen_func(
332
q,
333
k,
334
v,
@@ -774,7 +776,8 @@ class Glm4vVisionTransformer(nn.Module):
776
) -> tuple[Optional[int], Optional[list[int]]]:
777
max_seqlen, seqlens = None, None
778
seqlens = (cu_seqlens[1:] - cu_seqlens[:-1]).tolist()
777
- if self.attn_backend == _Backend.FLASH_ATTN:
779
+ if (self.attn_backend == _Backend.FLASH_ATTN
780
+ or self.attn_backend == _Backend.ROCM_AITER_FA):
781
max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max().item()
782
return max_seqlen, seqlens
783
vllm/model_executor/models/qwen2_5_vl.py
+17
-17
@@ -39,7 +39,8 @@ from transformers.models.qwen2_5_vl.configuration_qwen2_5_vl import (
39
Qwen2_5_VLConfig, Qwen2_5_VLVisionConfig)
40
41
from vllm.attention.backends.registry import _Backend
42
-from vllm.attention.layer import check_upstream_fa_availability
42
+from vllm.attention.layer import (check_upstream_fa_availability,
43
+ maybe_get_vit_flash_attn_backend)
44
from vllm.config import VllmConfig
45
from vllm.distributed import parallel_state
46
from vllm.distributed import utils as dist_utils
@@ -302,6 +303,11 @@ class Qwen2_5_VisionAttention(nn.Module):
303
disable_tp=use_data_parallel)
304
self.attn_backend = attn_backend
305
self.use_upstream_fa = use_upstream_fa
306
+ self.attn_backend, self.flash_attn_varlen_func \
307
+ = maybe_get_vit_flash_attn_backend(
308
+ self.attn_backend,
309
+ self.use_upstream_fa,
310
+ )
311
self.is_flash_attn_backend = self.attn_backend in {
312
_Backend.FLASH_ATTN, _Backend.ROCM_AITER_FA
313
}
@@ -354,25 +360,18 @@ class Qwen2_5_VisionAttention(nn.Module):
360
q, k = torch.chunk(qk_rotated, 2, dim=0)
361
362
if self.is_flash_attn_backend:
357
- if self.attn_backend == _Backend.ROCM_AITER_FA:
358
- from aiter import flash_attn_varlen_func
359
- else:
360
- if self.use_upstream_fa:
361
- from flash_attn import flash_attn_varlen_func
362
- else:
363
- from vllm.vllm_flash_attn import flash_attn_varlen_func
363
364
q, k, v = (rearrange(x, "b s ... -> (b s) ...") for x in [q, k, v])
365
367
- output = flash_attn_varlen_func(q,
368
- k,
369
- v,
370
- cu_seqlens_q=cu_seqlens,
371
- cu_seqlens_k=cu_seqlens,
372
- max_seqlen_q=max_seqlen,
373
- max_seqlen_k=max_seqlen,
374
- dropout_p=0.0,
375
- causal=False)
366
+ output = self.flash_attn_varlen_func(q,
367
+ k,
368
+ v,
369
+ cu_seqlens_q=cu_seqlens,
370
+ cu_seqlens_k=cu_seqlens,
371
+ max_seqlen_q=max_seqlen,
372
+ max_seqlen_k=max_seqlen,
373
+ dropout_p=0.0,
374
+ causal=False)
375
376
context_layer = rearrange(output,
377
"(b s) h d -> s b (h d)",
@@ -618,6 +617,7 @@ class Qwen2_5_VisionTransformer(nn.Module):
617
self.attn_backend = get_vit_attn_backend(
618
head_size=head_dim, dtype=torch.get_default_dtype())
619
if self.attn_backend != _Backend.FLASH_ATTN and \
620
+ self.attn_backend != _Backend.ROCM_AITER_FA and \
621
check_upstream_fa_availability(
622
torch.get_default_dtype()):
623
self.attn_backend = _Backend.FLASH_ATTN
vllm/model_executor/models/qwen2_vl.py
+18
-22
@@ -42,7 +42,8 @@ from transformers.models.qwen2_vl.video_processing_qwen2_vl import (
42
Qwen2VLVideoProcessor)
43
44
from vllm.attention.backends.registry import _Backend
45
-from vllm.attention.layer import check_upstream_fa_availability
45
+from vllm.attention.layer import (check_upstream_fa_availability,
46
+ maybe_get_vit_flash_attn_backend)
47
from vllm.config import VllmConfig
48
from vllm.distributed import parallel_state, tensor_model_parallel_all_gather
49
from vllm.distributed import utils as dist_utils
@@ -319,11 +320,12 @@ class Qwen2VisionAttention(nn.Module):
320
head_size=self.hidden_size_per_attention_head,
321
dtype=torch.get_default_dtype())
322
self.use_upstream_fa = False
322
- if self.attn_backend != _Backend.FLASH_ATTN and \
323
- check_upstream_fa_availability(
324
- torch.get_default_dtype()):
325
- self.attn_backend = _Backend.FLASH_ATTN
326
- self.use_upstream_fa = True
323
+
324
+ self.attn_backend, self.flash_attn_varlen_func \
325
+ = maybe_get_vit_flash_attn_backend(
326
+ self.attn_backend,
327
+ self.use_upstream_fa,
328
+ )
329
330
if self.attn_backend not in {
331
_Backend.FLASH_ATTN, _Backend.TORCH_SDPA, _Backend.XFORMERS,
@@ -331,6 +333,7 @@ class Qwen2VisionAttention(nn.Module):
333
}:
334
raise RuntimeError(
335
f"Qwen2-VL does not support {self.attn_backend} backend now.")
336
+
337
self.is_flash_attn_backend = self.attn_backend in {
338
_Backend.FLASH_ATTN, _Backend.ROCM_AITER_FA
339
}
@@ -383,25 +386,18 @@ class Qwen2VisionAttention(nn.Module):
386
q, k = torch.chunk(qk_rotated, 2, dim=0)
387
388
if self.is_flash_attn_backend:
386
- if self.attn_backend == _Backend.ROCM_AITER_FA:
387
- from aiter import flash_attn_varlen_func
388
- else:
389
- if self.use_upstream_fa:
390
- from flash_attn import flash_attn_varlen_func
391
- else:
392
- from vllm.vllm_flash_attn import flash_attn_varlen_func
389
390
q, k, v = (rearrange(x, "b s ... -> (b s) ...") for x in [q, k, v])
391
396
- output = flash_attn_varlen_func(q,
397
- k,
398
- v,
399
- cu_seqlens_q=cu_seqlens,
400
- cu_seqlens_k=cu_seqlens,
401
- max_seqlen_q=max_seqlen,
402
- max_seqlen_k=max_seqlen,
403
- dropout_p=0.0,
404
- causal=False)
392
+ output = self.flash_attn_varlen_func(q,
393
+ k,
394
+ v,
395
+ cu_seqlens_q=cu_seqlens,
396
+ cu_seqlens_k=cu_seqlens,
397
+ max_seqlen_q=max_seqlen,
398
+ max_seqlen_k=max_seqlen,
399
+ dropout_p=0.0,
400
+ causal=False)
401
402
context_layer = rearrange(output,
403
"(b s) h d -> s b (h d)",
vllm/model_executor/models/qwen3_vl.py
+3
-1
@@ -323,6 +323,7 @@ class Qwen3_VisionTransformer(nn.Module):
323
head_size=head_dim, dtype=torch.get_default_dtype())
324
use_upstream_fa = False
325
if self.attn_backend != _Backend.FLASH_ATTN and \
326
+ self.attn_backend != _Backend.ROCM_AITER_FA and \
327
check_upstream_fa_availability(
328
torch.get_default_dtype()):
329
self.attn_backend = _Backend.FLASH_ATTN
@@ -476,7 +477,8 @@ class Qwen3_VisionTransformer(nn.Module):
477
cu_seqlens: torch.Tensor,
478
) -> tuple[Optional[int], Optional[list[int]]]:
479
max_seqlen, seqlens = None, None
479
- if self.attn_backend == _Backend.FLASH_ATTN:
480
+ if (self.attn_backend == _Backend.FLASH_ATTN
481
+ or self.attn_backend == _Backend.ROCM_AITER_FA):
482
max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max().item()
483
elif self.attn_backend == _Backend.XFORMERS:
484
seqlens = (cu_seqlens[1:] - cu_seqlens[:-1]).tolist()
vllm/model_executor/models/siglip2navit.py
+8
-14
@@ -14,7 +14,7 @@ from transformers import Siglip2VisionConfig
14
from transformers.configuration_utils import PretrainedConfig
15
16
from vllm.attention.backends.registry import _Backend
17
-from vllm.attention.layer import check_upstream_fa_availability
17
+from vllm.attention.layer import maybe_get_vit_flash_attn_backend
18
from vllm.distributed import divide, get_tensor_model_parallel_world_size
19
from vllm.model_executor.layers.activation import get_act_fn
20
from vllm.model_executor.layers.linear import (ColumnParallelLinear,
@@ -240,11 +240,12 @@ class Siglip2Attention(nn.Module):
240
self.attn_backend = get_vit_attn_backend(
241
head_size=self.head_dim, dtype=torch.get_default_dtype())
242
self.use_upstream_fa = False
243
- if self.attn_backend != _Backend.FLASH_ATTN and \
244
- check_upstream_fa_availability(
245
- torch.get_default_dtype()):
246
- self.attn_backend = _Backend.FLASH_ATTN
247
- self.use_upstream_fa = True
243
+
244
+ self.attn_backend, self.flash_attn_varlen_func \
245
+ = maybe_get_vit_flash_attn_backend(
246
+ self.attn_backend,
247
+ self.use_upstream_fa,
248
+ )
249
250
if self.attn_backend not in {
251
_Backend.FLASH_ATTN, _Backend.TORCH_SDPA,
@@ -286,14 +287,7 @@ class Siglip2Attention(nn.Module):
287
288
max_seqlen = (cu_seqlens[1:] - cu_seqlens[:-1]).max().item()
289
if self.is_flash_attn_backend:
289
- if self.attn_backend == _Backend.ROCM_AITER_FA:
290
- from aiter import flash_attn_varlen_func
291
- else:
292
- if self.use_upstream_fa:
293
- from flash_attn import flash_attn_varlen_func
294
- else:
295
- from vllm.vllm_flash_attn import flash_attn_varlen_func
296
- attn_output = flash_attn_varlen_func(
290
+ attn_output = self.flash_attn_varlen_func(
291
queries, keys, values, cu_seqlens, cu_seqlens, max_seqlen,
292
max_seqlen).reshape(seq_length, -1)
293
elif self.attn_backend == _Backend.TORCH_SDPA:
vllm/platforms/rocm.py
-2
@@ -189,8 +189,6 @@ class RocmPlatform(Platform):
189
from vllm.attention.backends.registry import _Backend
190
if (envs.VLLM_ROCM_USE_AITER and envs.VLLM_ROCM_USE_AITER_MHA
191
and on_gfx9()):
192
- # Note: AITER FA is only supported for Qwen-VL models.
193
- # TODO: Add support for other VL models in their model class.
192
return _Backend.ROCM_AITER_FA
193
if on_gfx9():
194
return _Backend.FLASH_ATTN