| import torch |
|
|
| from kernels.benchmark import Benchmark |
|
|
|
|
| _original_allclose = torch.allclose |
|
|
|
|
| def _fp8_dtype() -> torch.dtype: |
| if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"): |
| return torch.float8_e4m3fnuz |
| return torch.float8_e4m3fn |
|
|
|
|
| def _fp8_max() -> float: |
| return 240.0 if torch.version.hip is not None else 448.0 |
|
|
|
|
| def _is_fp8_dtype(dtype: torch.dtype) -> bool: |
| return dtype == torch.float8_e4m3fn or ( |
| hasattr(torch, "float8_e4m3fnuz") and dtype == torch.float8_e4m3fnuz |
| ) |
|
|
|
|
| def _flashrt_allclose(input, other, rtol=1e-05, atol=1e-08, equal_nan=False): |
| if _is_fp8_dtype(input.dtype) or _is_fp8_dtype(other.dtype): |
| return _original_allclose( |
| input.float(), |
| other.float(), |
| rtol=0, |
| atol=0, |
| equal_nan=equal_nan, |
| ) |
| return _original_allclose(input, other, rtol=rtol, atol=atol, equal_nan=equal_nan) |
|
|
|
|
| torch.allclose = _flashrt_allclose |
|
|
|
|
| QUANT_SHAPES = [ |
| ("decode_m1", 1, 4096), |
| ("decode_m2", 2, 4096), |
| ("decode_m4", 4, 4096), |
| ("decode_m8", 8, 4096), |
| ("small_m16", 16, 4096), |
| ("small_m32", 32, 4096), |
| ("prefill_m64", 64, 4096), |
| ("prefill_m128", 128, 4096), |
| ("prefill_m256", 256, 4096), |
| ("wide_n8192_m16", 16, 8192), |
| ("wide_n8192_m128", 128, 8192), |
| ("vla_n12288_m16", 16, 12288), |
| ("vla_n12288_m64", 64, 12288), |
| ("vla_n16384_m16", 16, 16384), |
| ("vla_n16384_m64", 64, 16384), |
| ] |
|
|
|
|
| class BiasGeluFp8QuantizeBenchmark(Benchmark): |
| seed = 1 |
|
|
| def _setup_shape(self, m: int, n: int) -> None: |
| self.input = torch.randn((m, n), device=self.device, dtype=torch.bfloat16) |
| self.bias = torch.randn((n,), device=self.device, dtype=torch.bfloat16) |
| self.scale = torch.tensor([0.25], device=self.device, dtype=torch.float32) |
| self.out = torch.empty_like(self.input, dtype=_fp8_dtype()) |
|
|
| def _reference(self) -> torch.Tensor: |
| y = self.input.float() + self.bias.float() |
| y = torch.nn.functional.gelu(y, approximate="tanh") |
| limit = _fp8_max() |
| y = torch.clamp(y / self.scale.float(), -limit, limit) |
| return y.to(_fp8_dtype()) |
|
|
| def setup_decode_m1(self) -> None: |
| self._setup_shape(1, 4096) |
|
|
| def benchmark_decode_m1(self) -> None: |
| self.kernel.bias_gelu_quantize_fp8_static_bf16( |
| self.input, self.bias, self.scale, out=self.out |
| ) |
|
|
| def verify_decode_m1(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_decode_m8(self) -> None: |
| self._setup_shape(8, 4096) |
|
|
| def benchmark_decode_m8(self) -> None: |
| self.kernel.bias_gelu_quantize_fp8_static_bf16( |
| self.input, self.bias, self.scale, out=self.out |
| ) |
|
|
| def verify_decode_m8(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_small_m16(self) -> None: |
| self._setup_shape(16, 4096) |
|
|
| def benchmark_small_m16(self) -> None: |
| self.kernel.bias_gelu_quantize_fp8_static_bf16( |
| self.input, self.bias, self.scale, out=self.out |
| ) |
|
|
| def verify_small_m16(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_prefill_m64(self) -> None: |
| self._setup_shape(64, 4096) |
|
|
| def benchmark_prefill_m64(self) -> None: |
| self.kernel.bias_gelu_quantize_fp8_static_bf16( |
| self.input, self.bias, self.scale, out=self.out |
| ) |
|
|
| def verify_prefill_m64(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_prefill_m128(self) -> None: |
| self._setup_shape(128, 4096) |
|
|
| def benchmark_prefill_m128(self) -> None: |
| self.kernel.bias_gelu_quantize_fp8_static_bf16( |
| self.input, self.bias, self.scale, out=self.out |
| ) |
|
|
| def verify_prefill_m128(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_wide_n8192_m16(self) -> None: |
| self._setup_shape(16, 8192) |
|
|
| def benchmark_wide_n8192_m16(self) -> None: |
| self.kernel.bias_gelu_quantize_fp8_static_bf16( |
| self.input, self.bias, self.scale, out=self.out |
| ) |
|
|
| def verify_wide_n8192_m16(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_wide_n8192_m128(self) -> None: |
| self._setup_shape(128, 8192) |
|
|
| def benchmark_wide_n8192_m128(self) -> None: |
| self.kernel.bias_gelu_quantize_fp8_static_bf16( |
| self.input, self.bias, self.scale, out=self.out |
| ) |
|
|
| def verify_wide_n8192_m128(self) -> torch.Tensor: |
| return self._reference() |
|
|
|
|
| def _register_bias_gelu_shapes() -> None: |
| for label, m, n in QUANT_SHAPES: |
|
|
| def setup(self, m=m, n=n) -> None: |
| self._setup_shape(m, n) |
|
|
| def benchmark(self) -> None: |
| self.kernel.bias_gelu_quantize_fp8_static_bf16( |
| self.input, self.bias, self.scale, out=self.out |
| ) |
|
|
| def verify(self) -> torch.Tensor: |
| return self._reference() |
|
|
| setattr(BiasGeluFp8QuantizeBenchmark, f"setup_{label}", setup) |
| setattr(BiasGeluFp8QuantizeBenchmark, f"benchmark_{label}", benchmark) |
| setattr(BiasGeluFp8QuantizeBenchmark, f"verify_{label}", verify) |
|
|
|
|
| class GeluFp8QuantizeBenchmark(Benchmark): |
| seed = 3 |
|
|
| def _setup_shape(self, m: int, n: int) -> None: |
| self.input = torch.randn((m, n), device=self.device, dtype=torch.bfloat16) |
| self.scale = torch.tensor([0.25], device=self.device, dtype=torch.float32) |
| self.out = torch.empty_like(self.input, dtype=_fp8_dtype()) |
|
|
| def _reference(self) -> torch.Tensor: |
| y = torch.nn.functional.gelu(self.input.float(), approximate="tanh") |
| limit = _fp8_max() |
| y = torch.clamp(y / self.scale.float(), -limit, limit) |
| return y.to(_fp8_dtype()) |
|
|
| def setup_decode_m1(self) -> None: |
| self._setup_shape(1, 4096) |
|
|
| def benchmark_decode_m1(self) -> None: |
| self.kernel.gelu_quantize_fp8_static_bf16( |
| self.input, self.scale, out=self.out |
| ) |
|
|
| def verify_decode_m1(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_decode_m8(self) -> None: |
| self._setup_shape(8, 4096) |
|
|
| def benchmark_decode_m8(self) -> None: |
| self.kernel.gelu_quantize_fp8_static_bf16( |
| self.input, self.scale, out=self.out |
| ) |
|
|
| def verify_decode_m8(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_small_m16(self) -> None: |
| self._setup_shape(16, 4096) |
|
|
| def benchmark_small_m16(self) -> None: |
| self.kernel.gelu_quantize_fp8_static_bf16( |
| self.input, self.scale, out=self.out |
| ) |
|
|
| def verify_small_m16(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_prefill_m64(self) -> None: |
| self._setup_shape(64, 4096) |
|
|
| def benchmark_prefill_m64(self) -> None: |
| self.kernel.gelu_quantize_fp8_static_bf16( |
| self.input, self.scale, out=self.out |
| ) |
|
|
| def verify_prefill_m64(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_prefill_m128(self) -> None: |
| self._setup_shape(128, 4096) |
|
|
| def benchmark_prefill_m128(self) -> None: |
| self.kernel.gelu_quantize_fp8_static_bf16( |
| self.input, self.scale, out=self.out |
| ) |
|
|
| def verify_prefill_m128(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_wide_n8192_m16(self) -> None: |
| self._setup_shape(16, 8192) |
|
|
| def benchmark_wide_n8192_m16(self) -> None: |
| self.kernel.gelu_quantize_fp8_static_bf16( |
| self.input, self.scale, out=self.out |
| ) |
|
|
| def verify_wide_n8192_m16(self) -> torch.Tensor: |
| return self._reference() |
|
|
| def setup_wide_n8192_m128(self) -> None: |
| self._setup_shape(128, 8192) |
|
|
| def benchmark_wide_n8192_m128(self) -> None: |
| self.kernel.gelu_quantize_fp8_static_bf16( |
| self.input, self.scale, out=self.out |
| ) |
|
|
| def verify_wide_n8192_m128(self) -> torch.Tensor: |
| return self._reference() |
|
|
|
|
| def _register_gelu_shapes() -> None: |
| for label, m, n in QUANT_SHAPES: |
|
|
| def setup(self, m=m, n=n) -> None: |
| self._setup_shape(m, n) |
|
|
| def benchmark(self) -> None: |
| self.kernel.gelu_quantize_fp8_static_bf16( |
| self.input, self.scale, out=self.out |
| ) |
|
|
| def verify(self) -> torch.Tensor: |
| return self._reference() |
|
|
| setattr(GeluFp8QuantizeBenchmark, f"setup_{label}", setup) |
| setattr(GeluFp8QuantizeBenchmark, f"benchmark_{label}", benchmark) |
| setattr(GeluFp8QuantizeBenchmark, f"verify_{label}", verify) |
|
|
|
|
| _register_bias_gelu_shapes() |
| _register_gelu_shapes() |
|
|