From f05a3ae3e9205f0cfbc5547169bcc02d9c3e73bd Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Sat, 11 Jul 2026 09:18:16 +0100 Subject: [PATCH] fix(sdnq): skip compiled dequant for fp8 weights without hardware support Triton has no e4m3 conversions before sm_89, so any compiled graph touching fp8 storage weights fails with an InductorError on Ampere. Select the eager dequant and re-quantize paths for e4m3 weights when the hardware cannot compile them; other dtypes keep compiled dequant. SDNQ_ALLOW_FP8_COMPILE overrides the detection. --- modules/sdnq/common.py | 8 ++++++++ modules/sdnq/dequantizer.py | 11 ++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/modules/sdnq/common.py b/modules/sdnq/common.py index 88e5b0482..490ebe89e 100644 --- a/modules/sdnq/common.py +++ b/modules/sdnq/common.py @@ -358,6 +358,14 @@ if os.environ.get("SDNQ_ALLOW_FP8_MM", None) is None: else: is_fp8_mm_supported = os.environ.get("SDNQ_ALLOW_FP8_MM", "0").lower() not in {"0", "false", "no"} +if os.environ.get("SDNQ_ALLOW_FP8_COMPILE", None) is None: + if devices.backend == "cuda": + is_fp8_compile_supported = bool(torch.cuda.get_device_capability(devices.device) >= (8,9)) # triton has no e4m3 conversions before sm_89 + else: + is_fp8_compile_supported = True +else: + is_fp8_compile_supported = os.environ.get("SDNQ_ALLOW_FP8_COMPILE", "0").lower() not in {"0", "false", "no"} + if os.environ.get("SDNQ_USE_OPENVINO_MM", None) is None: use_openvino_mm = bool(devices.backend in {"cpu", "openvino"}) else: diff --git a/modules/sdnq/dequantizer.py b/modules/sdnq/dequantizer.py index b2d2bb0c6..637574168 100644 --- a/modules/sdnq/dequantizer.py +++ b/modules/sdnq/dequantizer.py @@ -5,13 +5,17 @@ from dataclasses import dataclass import torch from modules import devices -from .common import dtype_dict, compile_func, use_contiguous_int8_mm, use_contiguous_fp16_mm, use_tensorwise_fp8_matmul +from .common import dtype_dict, compile_func, use_contiguous_int8_mm, use_contiguous_fp16_mm, use_tensorwise_fp8_matmul, is_fp8_compile_supported from .quant_utils import quantize_int_mm, quantize_uint_mm, quantize_fp_mm, rotate_hadamard, get_hadamard from .packed_int import unpack_int from .packed_float import unpack_float from .layers import SDNQLayer +def skip_fp8_compile(weights_dtype: str) -> bool: # triton has no e4m3 conversions before sm_89, compiled dequant would crash + return not is_fp8_compile_supported and dtype_dict[weights_dtype]["storage_dtype"] == torch.float8_e4m3fn + + @devices.inference_context() def dequantize_asymmetric( weight: torch.Tensor, @@ -290,7 +294,8 @@ class SDNQDequantizer: ) -> tuple[torch.Tensor, torch.FloatTensor]: # pylint: disable=unused-argument if hadamard is None and self.use_hadamard and not non_hadamard: hadamard = get_hadamard(self.hadamard_group_size, dtype=self.result_dtype, device=weight.device) - return re_quantize_matmul_compiled( + re_quantize_matmul_func = re_quantize_matmul if skip_fp8_compile(self.weights_dtype) else re_quantize_matmul_compiled + return re_quantize_matmul_func( self.weights_dtype, weight, scale, @@ -322,7 +327,7 @@ class SDNQDequantizer: if hadamard is None and self.use_hadamard and not non_hadamard: hadamard = get_hadamard(self.hadamard_group_size, dtype=dtype, device=weight.device) re_quantize_for_matmul = self.re_quantize_for_matmul or self.is_packed - dequantize_weight_func = dequantize_weight if skip_compile else dequantize_weight_compiled + dequantize_weight_func = dequantize_weight if skip_compile or skip_fp8_compile(self.weights_dtype) else dequantize_weight_compiled return dequantize_weight_func( self.weights_dtype, weight,