[Bugfix][NPU] Skip FRACTAL_NZ format for MoE weights with unaligned dimensions (#21209)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: ronnie_zheng <zl19940307@163.com>
This commit is contained in:
Aditya Sharma
2026-03-30 23:22:17 +03:00
committed by GitHub
co-authored by gemini-code-assist[bot] ronnie_zheng
parent 4a9ffc3ab6
commit d6029de6ad
2 changed files with 37 additions and 5 deletions
@@ -107,6 +107,28 @@ def init_npu_backend():
torch_npu.npu.set_compile_mode(jit_compile=False)
def _is_nz_aligned(tensor: torch.Tensor) -> bool:
"""Check whether the last two dims satisfy FRACTAL_NZ alignment rules.
Ascend FRACTAL_NZ requires:
BF16 / FP16 : both dims divisible by 16
INT8 : k % 16 == 0 and n % 32 == 0
INT4 : k % 16 == 0 and n % 64 == 0
FP4 : both dims divisible by 64
"""
if tensor.dim() < 2:
return False
k, n = tensor.shape[-2], tensor.shape[-1]
if tensor.dtype in (torch.bfloat16, torch.float16):
return k % 16 == 0 and n % 16 == 0
if tensor.dtype == torch.int8:
return k % 16 == 0 and n % 32 == 0
if tensor.dtype in (torch.uint8, torch.int32):
# INT4 is typically packed into uint8/int32; be conservative
return k % 16 == 0 and n % 64 == 0
return True
def npu_format_cast(
tensor: torch.Tensor,
acl_format: NPUACLFormat = NPUACLFormat.ACL_FORMAT_FRACTAL_NZ,
@@ -135,8 +157,20 @@ def npu_format_cast(
"significantly reduced."
)
return tensor
else:
return torch.ops.npu.npu_format_cast(tensor, acl_format.value)
if acl_format == NPUACLFormat.ACL_FORMAT_FRACTAL_NZ and not _is_nz_aligned(tensor):
k, n = tensor.shape[-2], tensor.shape[-1]
logger.warning_once(
"Skipping FRACTAL_NZ format cast: tensor shape (%d, %d) dtype %s "
"is not aligned to NZ requirements. Falling back to 'ND' format, "
"which may reduce NPU performance.",
k,
n,
tensor.dtype,
)
return tensor
return torch.ops.npu.npu_format_cast(tensor, acl_format.value)
def get_indexer_weight_stream():
@@ -317,9 +317,7 @@ class UnquantizedFusedMoEMethod(FusedMoEMethodBase, MultiPlatformOp):
for weight_name in ["w13_weight", "w2_weight"]:
weight = getattr(layer, weight_name)
weight.data = weight.data.transpose(1, 2)
weight.data = npu_format_cast(
weight.data,
)
weight.data = npu_format_cast(weight.data)
return