fix: NVFP4 global scale bug — gsb=weight_scale_2 (not input_scale*ws2), gsa=input_scale
This commit is contained in:
@@ -141,9 +141,19 @@ def make_nvfp4_linear(in_features, out_features, device, all_w, pfx, proj_name):
|
||||
actual_in = weight.shape[1] * 2 # K_packed * 2 = BF16 input dim (for buffer allocation)
|
||||
lin = Nvfp4Linear(actual_in, actual_out, max_num_tokens=8192, device=d)
|
||||
lin.fp4 = [weight.to(d)]; lin.sf = [ws.to(d)]
|
||||
lin.ws2 = [ws2.to(d) if ws2 is not None else None] # weight_scale_2
|
||||
gs = isc.float().item() if isc is not None else 1.0 / (6.0 * 448.0)
|
||||
lin.gs = [gs]; lin.finalize_weights(); return lin
|
||||
# Global scales for NVFP4 GEMM:
|
||||
# gsb (weight global scale) = weight_scale_2 (NOT input_scale * weight_scale_2)
|
||||
# gsa (activation global scale) = input_scale from checkpoint
|
||||
# Dequant: w = lut[w_packed] * weight_scale * weight_scale_2
|
||||
# GEMM: y = (x * scale_a * gsa) @ (w * scale_b * gsb)
|
||||
# Nvfp4Linear.finalize_weights does: gsb = gs * ws2_val
|
||||
# So to get gsb = ws2_val, set gs = 1.0 and let ws2 do its job
|
||||
lin.gs = [1.0] # base gs — finalize_weights will multiply by ws2
|
||||
lin.ws2 = [ws2.to(d) if ws2 is not None else None]
|
||||
# Set activation global scale from checkpoint input_scale
|
||||
isc_val = isc.float().item() if isc is not None else 1.0 / (6.0 * 448.0)
|
||||
lin._activation_global_scale = isc_val # gsa = input_scale
|
||||
lin.finalize_weights(); return lin
|
||||
|
||||
# =====================================================================
|
||||
# Compressor — CSA (ratio=4) and HCA (ratio=128) [PyTorch ref]
|
||||
|
||||
Reference in New Issue
Block a user