Support inverse transform ue8m0 scale (#13285)

This commit is contained in:
fzyzcjy
2025-11-15 16:34:32 +08:00
committed by GitHub
parent 2fbc78a083
commit 8e6083bfcf
3 changed files with 84 additions and 0 deletions

View File

@@ -504,6 +504,45 @@ def _transform_scale_ue8m0(sf, mn):
return sf
def inverse_transform_scale_ue8m0(sf_packed, mn):
sf_fp32 = _inverse_transform_scale_ue8m0_impl(sf_packed)
# Can call consistency check every time since this is only called on startup
sf_packed_recreated = _transform_scale_ue8m0(sf_fp32, mn=mn)
assert torch.all(
sf_packed == sf_packed_recreated
), f"{sf_packed=} {sf_packed_recreated}"
return sf_fp32
# Inverse impl can refer to DeepGEMM's torch impl in get_mn_major_tma_aligned_packed_ue8m0_tensor_torch_impl
def _inverse_transform_scale_ue8m0_impl(sf_packed):
"""
NOTE: We assume k is aligned
:param sf_packed: (scale_mn, scale_k/4) int32
:return: (scale_mn, scale_k), float32
"""
block_size = 128
assert len(sf_packed.shape) == 2
assert sf_packed.dtype == torch.int32
mn_repeat_128, k_div_4 = sf_packed.shape
mn = mn_repeat_128 // block_size
k = k_div_4 * 4
# packed u8 -> fp32
sf_u8 = sf_packed.contiguous().flatten().view(torch.uint8).view(mn_repeat_128, k)
sf_fp32 = (sf_u8.to(torch.int32) << 23).view(torch.float32)
# remove repeat
sf_reshaped = sf_fp32.view(mn, block_size, k)
sf_unrepeated = sf_reshaped[:, 0:1, :]
assert torch.all(sf_unrepeated == sf_reshaped)
sf_unrepeated = sf_unrepeated.squeeze(1).contiguous()
assert sf_unrepeated.shape == (mn, k)
return sf_unrepeated
# COPIED FROM DeepGEMM
def per_block_cast_to_fp8(x: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
assert x.dim() == 2