mirror of
https://github.com/vllm-project/vllm.git
synced 2026-10-28 09:45:26 +08:00
[ROCm][aiter] officially supporting aiter Triton kernels+dsv4 on RDNA3 (#52970)
Signed-off-by: xawang <xawang@amd.com> Signed-off-by: skysnow2001 <skysnow9285@gmail.com> Co-authored-by: skysnow2001 <skysnow9285@gmail.com> Co-authored-by: keneoneth <keneoneth18@gmail.com> Co-authored-by: vllm-agent <claw@inferact.ai> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
8 files changed
+45
-33
No files matched your search
+23
-14
@@ -238,6 +238,15 @@ def is_aiter_found_and_supported_on_rdna4() -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def is_aiter_found_and_supported_on_rdna() -> bool:
|
||||
"""RDNA (gfx11 + gfx12) analog of `is_aiter_found_and_supported()`."""
|
||||
if current_platform.is_rocm() and IS_AITER_FOUND:
|
||||
from vllm.platforms.rocm import on_rdna
|
||||
|
||||
return on_rdna()
|
||||
return False
|
||||
|
||||
|
||||
def _triton_gemm_config_is_tuned(config_name: str, N: int, K: int) -> bool:
|
||||
from aiter.ops.triton.utils.gemm_config_utils import get_gemm_config
|
||||
|
||||
@@ -2290,20 +2299,20 @@ class rocm_aiter_ops:
|
||||
|
||||
@classmethod
|
||||
def is_rdna_aiter_enabled(cls) -> bool:
|
||||
"""AITER on RDNA4 (gfx12): library present, arch is rdna4, and the user
|
||||
enabled aiter. Only aiter's Triton kernels exist on gfx12 (no CK build),
|
||||
so this deliberately stays off the gfx9/CK `@if_aiter_supported` umbrella
|
||||
and gates only the Triton paths rdna4 uses. The gfx12 analog of
|
||||
"""AITER on RDNA: library present, arch is RDNA, and the user enabled
|
||||
aiter. Only aiter's Triton kernels exist on RDNA (no CK build), so this
|
||||
deliberately stays off the gfx9/CK `@if_aiter_supported` umbrella and
|
||||
gates only the Triton paths RDNA uses. The RDNA analog of
|
||||
`is_enabled()`."""
|
||||
if not current_platform.is_rocm() or not IS_AITER_FOUND:
|
||||
return False
|
||||
from vllm.platforms.rocm import on_rdna4
|
||||
from vllm.platforms.rocm import on_rdna
|
||||
|
||||
return on_rdna4() and cls._AITER_ENABLED
|
||||
return on_rdna() and cls._AITER_ENABLED
|
||||
|
||||
@classmethod
|
||||
def is_rdna_linear_enabled(cls) -> bool:
|
||||
"""RDNA4 (gfx12) analog of is_linear_enabled() (aiter Triton blockscale)."""
|
||||
"""RDNA analog of is_linear_enabled() (aiter Triton blockscale)."""
|
||||
return cls.is_rdna_aiter_enabled() and cls._LINEAR_ENABLED
|
||||
|
||||
@classmethod
|
||||
@@ -2840,8 +2849,8 @@ class rocm_aiter_ops:
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def is_rdna_gdn_triton_kernels_available(cls) -> bool:
|
||||
"""RDNA4 (gfx12) analog of are_gdn_triton_kernels_available()."""
|
||||
def are_rdna_gdn_triton_kernels_available(cls) -> bool:
|
||||
"""RDNA analog of are_gdn_triton_kernels_available()."""
|
||||
return cls.is_rdna_aiter_enabled() and cls._gdn_triton_kernels_importable()
|
||||
|
||||
@classmethod
|
||||
@@ -3024,16 +3033,16 @@ class rocm_aiter_ops:
|
||||
global _OPS_REGISTERED
|
||||
|
||||
if not (
|
||||
is_aiter_found_and_supported() or is_aiter_found_and_supported_on_rdna4()
|
||||
is_aiter_found_and_supported() or is_aiter_found_and_supported_on_rdna()
|
||||
):
|
||||
if not current_platform.is_rocm():
|
||||
return
|
||||
|
||||
from vllm.platforms.rocm import on_gfx11, on_gfx950
|
||||
from vllm.platforms.rocm import on_gfx950
|
||||
|
||||
# This op has self-contained Triton/C++ implementations on gfx11
|
||||
# and gfx950. Only its optional top-k fast path comes from aiter.
|
||||
if (on_gfx11() or on_gfx950()) and not _OPS_REGISTERED:
|
||||
# This op has self-contained Triton/C++ implementations on gfx950.
|
||||
# Only its optional top-k fast path comes from aiter.
|
||||
if on_gfx950() and not _OPS_REGISTERED:
|
||||
direct_register_custom_op(
|
||||
op_name="rocm_aiter_sparse_attn_indexer",
|
||||
op_func=rocm_aiter_sparse_attn_indexer,
|
||||
|
||||
@@ -733,7 +733,7 @@ class RocmAiterRMSNormQuantFusionPass(VllmPatternMatcherPass):
|
||||
|
||||
gated_norm_shapes.add((num_v_heads // layer.tp_size, head_v_dim))
|
||||
|
||||
# RDNA4 uses native quant ops and supports only Triton replacements.
|
||||
# RDNA uses native quant ops and supports only Triton replacements.
|
||||
match_aiter_quant_op = not rocm_aiter_ops.is_rdna_aiter_enabled()
|
||||
|
||||
# Make sure fused add patterns are before simple rms norm,
|
||||
@@ -804,7 +804,7 @@ class RocmAiterRMSNormQuantFusionPass(VllmPatternMatcherPass):
|
||||
# an aiter version that includes the GDN triton kernel renames.
|
||||
if gated_norm_shapes and (
|
||||
rocm_aiter_ops.are_gdn_triton_kernels_available()
|
||||
or rocm_aiter_ops.is_rdna_gdn_triton_kernels_available()
|
||||
or rocm_aiter_ops.are_rdna_gdn_triton_kernels_available()
|
||||
):
|
||||
for num_heads, head_dim in gated_norm_shapes:
|
||||
if head_dim != 128:
|
||||
|
||||
@@ -464,9 +464,9 @@ class AiterFp8BlockScaledMMKernel(Fp8BlockScaledMMLinearKernel):
|
||||
"quantization with group_shape=(1,128).",
|
||||
)
|
||||
|
||||
# RDNA4 (gfx12) only has the aiter Triton blockscale backend, which
|
||||
# needs a per-(N,K) tune. Reject untuned shapes so the dispatcher falls
|
||||
# through to the generic backend.
|
||||
# RDNA only has the aiter Triton blockscale backend, which needs a
|
||||
# per-(N,K) tune. Reject untuned shapes so the dispatcher falls through
|
||||
# to the generic backend.
|
||||
if rocm_aiter_ops.is_rdna_linear_enabled():
|
||||
n, k = config.weight_shape
|
||||
if not rocm_aiter_ops.is_triton_gemm_w8a8_tuned(n, k):
|
||||
|
||||
@@ -93,7 +93,7 @@ from vllm.v1.worker.workspace import current_workspace_manager
|
||||
# import overhead.
|
||||
GDN_AITER_TRITON_AVAILABLE = (
|
||||
rocm_aiter_ops.are_gdn_triton_kernels_available()
|
||||
or rocm_aiter_ops.is_rdna_gdn_triton_kernels_available()
|
||||
or rocm_aiter_ops.are_rdna_gdn_triton_kernels_available()
|
||||
)
|
||||
|
||||
if GDN_AITER_TRITON_AVAILABLE:
|
||||
|
||||
@@ -1171,12 +1171,11 @@ class SparseAttnIndexer(CustomOp):
|
||||
assert isinstance(q_quant, torch.Tensor), (
|
||||
"AMD sparse_attn_indexer expects a single FP8 q_quant tensor"
|
||||
)
|
||||
from vllm.platforms.rocm import on_gfx11, on_gfx950
|
||||
from vllm.platforms.rocm import on_gfx950
|
||||
|
||||
if (
|
||||
rocm_aiter_ops.is_enabled()
|
||||
or rocm_aiter_ops.is_rdna_aiter_enabled()
|
||||
or on_gfx11()
|
||||
# The so-called AITER sparse indexer op has a native gfx950 path:
|
||||
# its cache insert, MQA logits, and top-k fallbacks are implemented
|
||||
# by local Triton/C++ kernels and do not require the aiter package.
|
||||
@@ -1204,7 +1203,7 @@ class SparseAttnIndexer(CustomOp):
|
||||
)
|
||||
raise RuntimeError(
|
||||
"Sparse attention indexer ROCm path requires AITER or a supported "
|
||||
"native architecture (gfx950/gfx11)."
|
||||
"native architecture (gfx950)."
|
||||
)
|
||||
|
||||
def forward_cpu(
|
||||
|
||||
@@ -35,7 +35,7 @@ from vllm.models.deepseek_v4.sparse_mla import (
|
||||
DeepseekV4SparseMLAMetadataBuilder,
|
||||
)
|
||||
from vllm.platforms import current_platform
|
||||
from vllm.platforms.rocm import _ON_GFX950, on_gfx1250
|
||||
from vllm.platforms.rocm import _ON_GFX950, on_gfx1250, on_rdna
|
||||
from vllm.triton_utils import tl, triton
|
||||
from vllm.utils.multi_stream_utils import execute_in_parallel
|
||||
from vllm.v1.attention.backend import (
|
||||
@@ -1489,7 +1489,7 @@ class DeepseekV4ROCMAiterMLAAttention(DeepseekV4Attention):
|
||||
)
|
||||
rotated = 0
|
||||
if num_decodes > 0:
|
||||
fuse_decode_inv_rope = fuse_inv_rope and not on_gfx1250()
|
||||
fuse_decode_inv_rope = fuse_inv_rope and not on_gfx1250() and not on_rdna()
|
||||
rotated = self._forward_decode(
|
||||
q=q[:num_decode_tokens],
|
||||
positions=(
|
||||
|
||||
@@ -559,8 +559,11 @@ def _get_backend_priorities(
|
||||
backends.append(AttentionBackendEnum.ROCM_AITER_FA)
|
||||
if is_aiter_found_and_supported():
|
||||
backends.append(AttentionBackendEnum.ROCM_AITER_UNIFIED_ATTN)
|
||||
elif rocm_aiter_ops.is_rdna_aiter_enabled():
|
||||
backends.insert(0, AttentionBackendEnum.ROCM_AITER_UNIFIED_ATTN)
|
||||
if rocm_aiter_ops.is_rdna_aiter_enabled():
|
||||
if on_rdna4():
|
||||
backends.insert(0, AttentionBackendEnum.ROCM_AITER_UNIFIED_ATTN)
|
||||
else:
|
||||
backends.append(AttentionBackendEnum.ROCM_AITER_UNIFIED_ATTN)
|
||||
backends.append(AttentionBackendEnum.TRITON_ATTN)
|
||||
backends.append(AttentionBackendEnum.TURBOQUANT)
|
||||
backends.append(AttentionBackendEnum.ROCM_OCTAVE)
|
||||
@@ -1422,7 +1425,6 @@ class RocmPlatform(Platform):
|
||||
cc.cudagraph_mode != CUDAGraphMode.NONE
|
||||
and envs.VLLM_ROCM_USE_AITER
|
||||
and envs.VLLM_ROCM_USE_AITER_RMSNORM
|
||||
and not on_rdna4()
|
||||
and not on_gfx90a() # AITER not built for gfx90a, rmsnorm -> SEGV.
|
||||
):
|
||||
rms_norm = ["aiter"] + default
|
||||
|
||||
@@ -23,10 +23,12 @@ from vllm.v1.attention.ops.common import pack_seq_triton, unpack_seq_triton
|
||||
from vllm.v1.worker.workspace import current_workspace_manager
|
||||
|
||||
if current_platform.is_rocm():
|
||||
from vllm.platforms.rocm import _ON_GFX942, _ON_GFX950
|
||||
from vllm.platforms.rocm import _ON_GFX942, _ON_GFX950, _ON_GFX1151, _ON_RDNA
|
||||
else:
|
||||
_ON_GFX942 = False
|
||||
_ON_GFX950 = False
|
||||
_ON_GFX1151 = False
|
||||
_ON_RDNA = False
|
||||
|
||||
logger = init_logger(__name__)
|
||||
|
||||
@@ -709,7 +711,7 @@ def paged_mqa_logits_module():
|
||||
str(error),
|
||||
)
|
||||
return None
|
||||
if _ON_GFX942 or _ON_GFX950:
|
||||
if _ON_GFX942 or _ON_GFX950 or (_ON_RDNA and not _ON_GFX1151):
|
||||
function_name = "deepgemm_fp8_paged_mqa_logits"
|
||||
required_parameters = {
|
||||
"Preshuffle",
|
||||
@@ -812,7 +814,7 @@ def rocm_fp8_paged_mqa_logits(
|
||||
aiter_paged_mqa_logits_module = paged_mqa_logits_module()
|
||||
|
||||
if aiter_paged_mqa_logits_module is not None:
|
||||
if _ON_GFX942 or _ON_GFX950:
|
||||
if _ON_GFX942 or _ON_GFX950 or (_ON_RDNA and not _ON_GFX1151):
|
||||
logger.info_once(
|
||||
"Using AITER paged-MQA logits from %s.",
|
||||
aiter_paged_mqa_logits_module.__name__,
|
||||
@@ -833,7 +835,7 @@ def rocm_fp8_paged_mqa_logits(
|
||||
block_tables,
|
||||
max_model_len,
|
||||
ChunkK=256,
|
||||
Preshuffle=block_size > 1,
|
||||
Preshuffle=block_size > 1 and not _ON_RDNA,
|
||||
KVBlockSize=block_size,
|
||||
WavePerEU=2,
|
||||
)
|
||||
@@ -1339,7 +1341,7 @@ def rocm_aiter_sparse_attn_indexer(
|
||||
|
||||
# Decode logits buffer, used by rocm_fp8_paged_mqa_logits.
|
||||
decode_rows = _max_decode_logits_rows(hidden_states.shape[0])
|
||||
if _ON_GFX942 or _ON_GFX950:
|
||||
if _ON_GFX942 or _ON_GFX950 or _ON_RDNA:
|
||||
workspace_manager.get_simultaneous(
|
||||
((decode_rows, max_model_len), torch.float32),
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user