Files
vllm-omni/tests/diffusion/attention/test_sage_attn3.py
T
95a9311696 [CI] Select mirror_hardwares presets via MIRROR_HW (H100/B200) (#5543)
Signed-off-by: wangyu <410167048@qq.com>
Signed-off-by: lishunyang12 <lishunyang12@163.com>
Signed-off-by: [Your Name] <your.email@example.com>
Signed-off-by: wangyu <53896905+yenuo26@users.noreply.github.com>
Signed-off-by: Bo Li <22713281+bobboli@users.noreply.github.com>
Co-authored-by: lishunyang12 <lishunyang12@163.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Bo Li <22713281+bobboli@users.noreply.github.com>
2026-09-02 15:39:49 +00:00

208 lines
7.8 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
import importlib
import sys
import types
import pytest
import torch
from vllm.platforms import current_platform
from vllm_omni.diffusion.attention.backends.abstract import AttentionMetadata
pytestmark = [pytest.mark.core_model, pytest.mark.diffusion, pytest.mark.cpu]
SAGE_ATTN3_MODULE = "vllm_omni.diffusion.attention.backends.sage_attn3"
def load_sage_attn3_module(monkeypatch: pytest.MonkeyPatch, kernel_impl):
fake_module = types.ModuleType("sageattn3")
setattr(fake_module, "sageattn3_blackwell", kernel_impl)
monkeypatch.setitem(sys.modules, "sageattn3", fake_module)
sys.modules.pop(SAGE_ATTN3_MODULE, None)
return importlib.import_module(SAGE_ATTN3_MODULE)
def test_sage_attn3_forward_uses_blackwell_layout(monkeypatch: pytest.MonkeyPatch):
calls = {}
def fake_kernel(query, key, value, is_causal=False):
calls["query_shape"] = query.shape
calls["is_causal"] = is_causal
return query + key + value
backend_module = load_sage_attn3_module(monkeypatch, fake_kernel)
impl = backend_module.SageAttention3Impl(
num_heads=4,
head_size=64,
softmax_scale=1.0 / 8.0,
causal=False,
)
query = torch.randn(2, 8, 4, 64)
key = torch.randn(2, 8, 4, 64)
value = torch.randn(2, 8, 4, 64)
output = impl.forward_cuda(query, key, value)
assert calls["query_shape"] == (2, 4, 8, 64)
assert calls["is_causal"] is False
expected = (query.transpose(1, 2) + key.transpose(1, 2) + value.transpose(1, 2)).transpose(1, 2)
assert torch.allclose(output, expected)
def test_sage_attn3_rejects_gqa_instead_of_falling_back(monkeypatch: pytest.MonkeyPatch):
def fake_kernel(*args, **kwargs):
raise AssertionError("sageattn3_blackwell should not be used for GQA")
backend_module = load_sage_attn3_module(monkeypatch, fake_kernel)
impl = backend_module.SageAttention3Impl(
num_heads=4,
head_size=64,
softmax_scale=1.0 / 8.0,
causal=False,
)
query = torch.randn(2, 8, 4, 64)
key = torch.randn(2, 8, 2, 64)
value = torch.randn(2, 8, 2, 64)
with pytest.raises(NotImplementedError, match="does not support GQA/MQA"):
impl.forward_cuda(query, key, value)
def test_sage_attn3_rejects_mask_instead_of_ignoring_it(monkeypatch: pytest.MonkeyPatch):
def fake_kernel(*args, **kwargs):
raise AssertionError("sageattn3_blackwell should not run with an unsupported mask")
backend_module = load_sage_attn3_module(monkeypatch, fake_kernel)
impl = backend_module.SageAttention3Impl(
num_heads=4,
head_size=64,
softmax_scale=1.0 / 8.0,
causal=False,
)
query = torch.randn(2, 8, 4, 64)
metadata = AttentionMetadata(attn_mask=torch.ones(2, 8, dtype=torch.bool))
with pytest.raises(ValueError, match="does not support attn_mask"):
impl.forward_cuda(query, query, query, metadata)
def test_sage_attn3_rejects_custom_softmax_scale(monkeypatch: pytest.MonkeyPatch):
backend_module = load_sage_attn3_module(monkeypatch, lambda *args, **kwargs: None)
with pytest.raises(ValueError, match="does not expose a custom softmax scale"):
backend_module.SageAttention3Impl(
num_heads=4,
head_size=64,
softmax_scale=1.0,
causal=False,
)
@pytest.mark.skipif(not current_platform.is_cuda(), reason="sage_attn3 tests require CUDA platform")
def test_cuda_platform_selects_sage_attn3_alias(monkeypatch: pytest.MonkeyPatch):
from vllm.platforms.interface import DeviceCapability
from vllm_omni.diffusion.attention.backends.registry import DiffusionAttentionBackendEnum
from vllm_omni.diffusion.envs import PACKAGES_CHECKER
from vllm_omni.platforms.cuda import platform as cuda_platform_module
from vllm_omni.platforms.cuda.platform import CudaOmniPlatform
original_import_module = importlib.import_module
monkeypatch.setattr(
CudaOmniPlatform,
"get_device_capability",
classmethod(lambda cls, device_id=0: DeviceCapability(10, 0)),
)
monkeypatch.setattr(PACKAGES_CHECKER, "get_packages_info", lambda: {"has_flash_attn": False})
monkeypatch.setattr(
cuda_platform_module.importlib,
"import_module",
lambda module_name: object() if module_name == "sageattn3" else original_import_module(module_name),
)
backend_path = CudaOmniPlatform.get_diffusion_attn_backend_cls("SAGE_ATTN_3", head_size=64)
assert backend_path == DiffusionAttentionBackendEnum.SAGE_ATTN_3.get_path()
@pytest.mark.skipif(not current_platform.is_cuda(), reason="sage_attn3 tests require CUDA platform")
@pytest.mark.parametrize("head_size", [32, 320])
def test_cuda_platform_rejects_explicit_sage_attn3_unsupported_head_size(
monkeypatch: pytest.MonkeyPatch, head_size: int
):
from vllm.platforms.interface import DeviceCapability
from vllm_omni.diffusion.envs import PACKAGES_CHECKER
from vllm_omni.platforms.cuda import platform as cuda_platform_module
from vllm_omni.platforms.cuda.platform import CudaOmniPlatform
original_import_module = importlib.import_module
monkeypatch.setattr(
CudaOmniPlatform,
"get_device_capability",
classmethod(lambda cls, device_id=0: DeviceCapability(10, 0)),
)
monkeypatch.setattr(PACKAGES_CHECKER, "get_packages_info", lambda: {"has_flash_attn": False})
monkeypatch.setattr(
cuda_platform_module.importlib,
"import_module",
lambda module_name: object() if module_name == "sageattn3" else original_import_module(module_name),
)
load_sage_attn3_module(monkeypatch, lambda *args, **kwargs: None)
with pytest.raises(ValueError, match=f"head_size={head_size} is unsupported"):
CudaOmniPlatform.get_diffusion_attn_backend_cls("SAGE_ATTN_3", head_size=head_size)
@pytest.mark.skipif(not current_platform.is_cuda(), reason="sage_attn3 tests require CUDA platform")
def test_cuda_platform_rejects_explicit_sage_attn3_on_unsupported_gpu(monkeypatch: pytest.MonkeyPatch):
from vllm.platforms.interface import DeviceCapability
from vllm_omni.diffusion.envs import PACKAGES_CHECKER
from vllm_omni.platforms.cuda.platform import CudaOmniPlatform
monkeypatch.setattr(
CudaOmniPlatform,
"get_device_capability",
classmethod(lambda cls, device_id=0: DeviceCapability(9, 0)),
)
monkeypatch.setattr(PACKAGES_CHECKER, "get_packages_info", lambda: {"has_flash_attn": False})
with pytest.raises(ValueError, match="explicitly selected"):
CudaOmniPlatform.get_diffusion_attn_backend_cls("SAGE_ATTN_3", head_size=64)
@pytest.mark.skipif(not current_platform.is_cuda(), reason="sage_attn3 tests require CUDA platform")
def test_cuda_platform_rejects_missing_explicit_sage_attn3(monkeypatch: pytest.MonkeyPatch):
from vllm.platforms.interface import DeviceCapability
from vllm_omni.diffusion.envs import PACKAGES_CHECKER
from vllm_omni.platforms.cuda import platform as cuda_platform_module
from vllm_omni.platforms.cuda.platform import CudaOmniPlatform
original_import_module = importlib.import_module
monkeypatch.setattr(
CudaOmniPlatform,
"get_device_capability",
classmethod(lambda cls, device_id=0: DeviceCapability(10, 0)),
)
monkeypatch.setattr(PACKAGES_CHECKER, "get_packages_info", lambda: {"has_flash_attn": False})
def _missing_sageattn3(module_name):
if module_name == "sageattn3":
raise ImportError("sageattn3 not installed")
return original_import_module(module_name)
monkeypatch.setattr(cuda_platform_module.importlib, "import_module", _missing_sageattn3)
with pytest.raises(ImportError, match="explicitly selected"):
CudaOmniPlatform.get_diffusion_attn_backend_cls("SAGE_ATTN_3", head_size=64)