Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions fastvideo/platforms/cuda.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,12 @@ def get_attn_backend_cls(cls, selected_backend: AttentionBackendEnum | None, hea
if is_attn_qat_infer_available():
logger.info("Using Attn-QAT inference backend (%s).", attn_qat_infer_receipt())
return "fastvideo.attention.backends.attn_qat_infer.AttnQatInferBackend"
# Keep the trailing sentence stable: downstream receipts grep for it.
logger.info("Attn-QAT inference kernel is not built (%s). Fall back to Flash Attention.",
attn_qat_infer_receipt())
raise ImportError(
f"ATTN_QAT_INFER selected but the inference kernel is not usable ({attn_qat_infer_receipt()}). "
"Silent fallback would run plain FlashAttention while the caller believes it is measuring "
"FP4-QAT attention — an A/B comparison would silently benchmark bf16 against bf16; "
"refusing to proceed. Build the fastvideo-kernel attn_qat_infer target for this arch "
"or pick a different FASTVIDEO_ATTENTION_BACKEND.")
elif selected_backend == AttentionBackendEnum.ATTN_QAT_TRAIN:
from fastvideo.attention.backends.attn_qat_train import ( # noqa: F401
AttnQatTrainBackend, is_attn_qat_train_available)
Expand Down
20 changes: 19 additions & 1 deletion fastvideo/tests/attention/test_attn_qat_infer_arch_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
The capability sets route:
* sm_120a/sm_121a -> fastvideo-kernel CUTLASS extension,
* sm_100a/sm_103a -> FP4 FA4 (flash-attention-fp4, #1221 plumbing),
* anything else -> unavailable (honest FlashAttention fallback upstream).
* anything else -> unavailable (hard ImportError upstream: an explicitly
selected QAT-inference backend must never silently degrade to plain
FlashAttention, or A/B benchmarks measure bf16 against bf16).

All device/import probes are monkeypatched; no GPU or kernel install needed.
"""
Expand Down Expand Up @@ -71,6 +73,22 @@ def test_unsupported_arch_receipt_lists_support_matrix(monkeypatch) -> None:
assert "sm_100a/sm_103a" in receipt


def test_selecting_unavailable_backend_raises_instead_of_falling_back(monkeypatch) -> None:
"""Explicit ATTN_QAT_INFER on an arch without the kernel must hard-fail.

The old behavior logged "Fall back to Flash Attention" and continued,
which let FP4 A/B benchmarks silently measure bf16 against bf16.
"""
import torch

from fastvideo.platforms.cuda import CudaPlatform
from fastvideo.platforms.interface import AttentionBackendEnum

_patch(monkeypatch, cap=(9, 0), cutlass=False, fa4=False)
with pytest.raises(ImportError, match="ATTN_QAT_INFER selected but"):
CudaPlatform.get_attn_backend_cls(AttentionBackendEnum.ATTN_QAT_INFER, 128, torch.bfloat16)


def test_unsupported_arch_forward_never_calls_bundled_extension(monkeypatch) -> None:
"""An unsupported GPU (e.g. sm_90) carrying an importable sm_12x wheel
must fail cleanly at forward — never dispatch into the wrong binary."""
Expand Down
Loading