fix: stop folding global scale into float8 block scales
The fold block_sf (float8) * global_sf (float32) -> float8 loses ~25% precision. Product of ~56-448 block_sf * ~4.65e-05 global_sf lands in float8 low-precision zone where step size is 25%. This makes model output garbage despite finite values. Fix: keep block scales as original float8, return global scales separately as float32 per-expert vectors. Apply global scale as per-expert GEMM alpha in cutlass_grouped_nvfp4_gemm (already iterates per-expert). For L1 with separate gate/up global scales, use gate_gs as alpha and apply up_correction ratio to the up half post-GEMM. weight_transform.py: no more _fold_global_scale, returns (w, sf, global_sf) nvfp4_mega_moe.py: per-expert alpha = activation_gs * weight_gs kernel.py: per_expert_alpha parameter in grouped GEMM deepseek_v4.py: updated type hints and comments
This commit is contained in:
@@ -346,8 +346,8 @@ class DeepseekV4MegaMoEExperts(nn.Module):
|
||||
)
|
||||
set_weight_attrs(self.w2_input_scale, weight_attrs)
|
||||
|
||||
self._transformed_l1_weights: tuple[torch.Tensor, torch.Tensor] | None = None
|
||||
self._transformed_l2_weights: tuple[torch.Tensor, torch.Tensor] | None = None
|
||||
self._transformed_l1_weights: tuple[torch.Tensor, torch.Tensor, torch.Tensor] | None = None
|
||||
self._transformed_l2_weights: tuple[torch.Tensor, torch.Tensor, torch.Tensor] | None = None
|
||||
|
||||
# Register in the static forward context so the custom-op wrapper
|
||||
# can look up this module by name from within a torch.compile graph.
|
||||
@@ -437,13 +437,15 @@ class DeepseekV4MegaMoEExperts(nn.Module):
|
||||
from nvfp4_megamoe_kernel import transform_nvfp4_weights_for_mega_moe
|
||||
|
||||
# === Native NVFP4 path ===
|
||||
# The DeepGEMM nvfp4 mega_moe kernel consumes NVFP4 directly:
|
||||
# - E2M1 packed uint8 (same as checkpoint)
|
||||
# The CUTLASS nvfp4 mega_moe kernel consumes NVFP4 directly:
|
||||
# - E2M1 packed int8 (same as checkpoint)
|
||||
# - UE4M3 block scales (float8_e4m3fn), group_size=16
|
||||
# - float32 global scale folded into block scales
|
||||
# No conversion to MXFP4. Experts stay NVFP4.
|
||||
# - float32 global scales returned SEPARATELY (NOT folded into float8)
|
||||
# Previous versions folded global scales into block scales via float8
|
||||
# round-trip, which caused ~25% precision loss. Now, global scales
|
||||
# are applied as per-expert GEMM alpha in float32 (exact).
|
||||
|
||||
# Fold global scales into block scales and transform for the kernel
|
||||
# Transform weights — returns (w, sf, global_sf) tuples
|
||||
self._transformed_l1_weights, self._transformed_l2_weights = (
|
||||
transform_nvfp4_weights_for_mega_moe(
|
||||
(self.w13_weight.data.contiguous(),
|
||||
|
||||
Reference in New Issue
Block a user