fa_utils.py 3.75 KB
Newer Older
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4

from vllm.logger import init_logger
5
from vllm.platforms import current_platform
6
7
8

logger = init_logger(__name__)

9
if current_platform.is_cuda():
10
    from vllm import _custom_ops
11

12
    ops = _custom_ops
13
    reshape_and_cache_flash = ops.reshape_and_cache_flash
14
15
16
17
18
    from vllm.vllm_flash_attn import (  # type: ignore[attr-defined]
        flash_attn_varlen_func,
        get_scheduler_metadata,
    )

19
elif current_platform.is_xpu():
20
    from vllm._ipex_ops import ipex_ops
21

22
    ops = ipex_ops
23
24
25
    reshape_and_cache_flash = ops.reshape_and_cache_flash
    flash_attn_varlen_func = ops.flash_attn_varlen_func
    get_scheduler_metadata = ops.get_scheduler_metadata
26

27
28
29
30
31
32
33
34
elif current_platform.is_rocm():
    try:
        from flash_attn import flash_attn_varlen_func  # noqa: F401
    except ImportError as e:
        raise ImportError(
            "Rocm platform requires upstream flash-attn "
            "to be installed. Please install flash-attn first."
        ) from e
35

36

37
def get_flash_attn_version(requires_alibi: bool = False) -> int | None:
38
39
    # import here to avoid circular dependencies
    from vllm.platforms import current_platform
40

41
42
    if current_platform.is_xpu():
        return 2
43
44
    try:
        from vllm.vllm_flash_attn.flash_attn_interface import (
45
46
47
48
            fa_version_unsupported_reason,
            is_fa_version_supported,
        )

49
50
51
52
53
        device_capability = current_platform.get_device_capability()

        assert device_capability is not None

        # 1. default version depending on platform
54
55
56
        fa_version = (
            3 if (device_capability.major == 9 and is_fa_version_supported(3)) else 2
        )
57

58
59
60
61
62
63
        # 2. override if passed by environment or config
        from vllm.config import get_current_vllm_config

        vllm_config = get_current_vllm_config()
        if vllm_config.attention_config.flash_attn_version is not None:
            fa_version = vllm_config.attention_config.flash_attn_version
64
65
66

        # 3. fallback for unsupported combinations
        if device_capability.major == 10 and fa_version == 3:
67
68
            logger.warning_once(
                "Cannot use FA version 3 on Blackwell platform "
69
70
                "defaulting to FA version 2."
            )
71
72
73
            fa_version = 2

        if requires_alibi and fa_version == 3:
74
75
76
            logger.warning_once(
                "Cannot use FA version 3 with ALiBi, defaulting to FA version 2."
            )
77
78
79
            fa_version = 2

        if not is_fa_version_supported(fa_version):
80
81
82
83
84
            logger.error(
                "Cannot use FA version %d is not supported due to %s",
                fa_version,
                fa_version_unsupported_reason(fa_version),
            )
85
86
87
88
89

        assert is_fa_version_supported(fa_version)
        return fa_version
    except (ImportError, AssertionError):
        return None
90
91
92


def flash_attn_supports_fp8() -> bool:
93
94
    return (
        get_flash_attn_version() == 3
95
        and current_platform.is_device_capability_family(90)
96
    )
97
98


99
100
101
102
103
104
105
def flash_attn_supports_sinks() -> bool:
    if current_platform.is_xpu():
        return True
    else:
        return get_flash_attn_version() == 3


106
107
def flash_attn_supports_mla():
    from vllm.platforms import current_platform
108

109
110
111
    if current_platform.is_cuda():
        try:
            from vllm.vllm_flash_attn.flash_attn_interface import (
112
113
114
                is_fa_version_supported,
            )

115
116
117
            return is_fa_version_supported(
                3
            ) and current_platform.is_device_capability_family(90)
118
119
120
121
122
        except (ImportError, AssertionError):
            pass
    return False


123
124
def is_flash_attn_varlen_func_available() -> bool:
    return current_platform.is_cuda() or current_platform.is_xpu()