| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| from typing import Tuple |
|
|
| import torch |
| import triton |
| import triton.language as tl |
|
|
|
|
| |
| @triton.jit |
| def _fp8_per_block_quant_kernel(x_ptr, y_ptr, s_ptr, M, N, BLOCK_SIZE: tl.constexpr): |
| """Quantizes FP32 tensor to FP8 format using block-wise quantization.""" |
| pid_m = tl.program_id(axis=0) |
| pid_n = tl.program_id(axis=1) |
| n = tl.cdiv(N, BLOCK_SIZE) |
|
|
| offs_m = pid_m * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) |
| offs_n = pid_n * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) |
| offs = offs_m[:, None] * N + offs_n[None, :] |
|
|
| mask = (offs_m[:, None] < M) & (offs_n[None, :] < N) |
| x = tl.load(x_ptr + offs, mask=mask).to(tl.float32) |
| max_val = tl.max(tl.abs(x)) |
| scale = max_val / 448.0 |
| scale = tl.where(max_val == 0.0, 1.0, scale) |
| y = x / scale |
| y = y.to(y_ptr.dtype.element_ty) |
|
|
| tl.store(y_ptr + offs, y, mask=mask) |
| tl.store(s_ptr + pid_m * n + pid_n, scale) |
|
|
|
|
| |
| |
| def fp8_per_block_quant_triton( |
| x: torch.Tensor, block_size: int = 128 |
| ) -> Tuple[torch.Tensor, torch.Tensor]: |
| """ |
| Quantizes a FP32 2D tensor to FP8 (E4M3FN) using block-wise quantization. |
| For each (block_size x block_size) block: |
| - scale = max(abs(block)) / 448.0 (FP8 E4M3FN max magnitude) |
| - if block is all zeros, use scale = 1.0 to avoid div-by-zero |
| - scale, clamp and cast to FP8 |
| Returns: |
| y: Quantized FP8 tensor, same shape as input |
| s: Per-block scales, shape (num_blocks_M, num_blocks_N) |
| """ |
| assert x.is_contiguous() |
| assert x.dim() == 2 |
|
|
| M, N = x.size() |
| y = torch.empty_like(x, dtype=torch.float8_e4m3fn) |
| m_blocks = triton.cdiv(M, block_size) |
| n_blocks = triton.cdiv(N, block_size) |
| s = torch.empty((m_blocks, n_blocks), dtype=torch.float32, device=x.device) |
|
|
| def grid(meta): |
| return ( |
| triton.cdiv(M, meta["BLOCK_SIZE"]), |
| triton.cdiv(N, meta["BLOCK_SIZE"]), |
| ) |
|
|
| _fp8_per_block_quant_kernel[grid](x, y, s, M, N, BLOCK_SIZE=block_size) |
|
|
| return y, s |
|
|