[ModelOPT] Support Qwen 3 Next Coder NVFP4 (#18224)
Signed-off-by: vincentzed <207368749+vincentzed@users.noreply.github.com>
This commit is contained in:
@@ -665,6 +665,7 @@ class Qwen3HybridAttentionDecoderLayer(nn.Module):
|
||||
self.scaling,
|
||||
num_kv_heads=self.num_kv_heads,
|
||||
layer_id=layer_id,
|
||||
quant_config=quant_config,
|
||||
prefix=f"{prefix}.attn",
|
||||
)
|
||||
|
||||
@@ -921,6 +922,15 @@ class HybridLayerType(enum.Enum):
|
||||
class Qwen3NextForCausalLM(nn.Module):
|
||||
fall_back_to_pt_during_load = False
|
||||
|
||||
# Map fused module names to their checkpoint (unfused) counterparts.
|
||||
# This is needed so the quantization exclusion logic can match
|
||||
# checkpoint-style names (e.g. "q_proj") against the fused sglang
|
||||
# module names (e.g. "qkv_proj").
|
||||
packed_modules_mapping = {
|
||||
"qkv_proj": ["q_proj", "k_proj", "v_proj"],
|
||||
"gate_up_proj": ["gate_proj", "up_proj"],
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: Qwen3NextConfig,
|
||||
@@ -931,6 +941,14 @@ class Qwen3NextForCausalLM(nn.Module):
|
||||
self.config = config
|
||||
self.pp_group = get_pp_group()
|
||||
assert self.pp_group.is_first_rank and self.pp_group.is_last_rank
|
||||
|
||||
# The quant config's packed_modules_mapping may be None if it wasn't
|
||||
# in the checkpoint config. The base class (QuantizationConfig) intends
|
||||
# for models to set this. We need it so is_layer_skipped can unfuse
|
||||
# "qkv_proj" into ["q_proj","k_proj","v_proj"] when checking exclusions.
|
||||
if quant_config is not None and hasattr(quant_config, "packed_modules_mapping"):
|
||||
quant_config.packed_modules_mapping = self.packed_modules_mapping
|
||||
|
||||
self.quant_config = quant_config
|
||||
self.model = Qwen3NextModel(
|
||||
config, quant_config, prefix=add_prefix("model", prefix)
|
||||
@@ -1052,6 +1070,14 @@ class Qwen3NextForCausalLM(nn.Module):
|
||||
if ".self_attn." in name:
|
||||
name = name.replace(".self_attn", "")
|
||||
|
||||
# Remap modelopt FP8 KV cache scale names:
|
||||
# checkpoint: k_proj.k_scale / v_proj.v_scale
|
||||
# model: attn.k_scale / attn.v_scale
|
||||
if name.endswith(".k_proj.k_scale"):
|
||||
name = name.replace(".k_proj.k_scale", ".attn.k_scale")
|
||||
elif name.endswith(".v_proj.v_scale"):
|
||||
name = name.replace(".v_proj.v_scale", ".attn.v_scale")
|
||||
|
||||
for param_name, weight_name, shard_id in stacked_params_mapping:
|
||||
if weight_name not in name:
|
||||
continue
|
||||
@@ -1060,15 +1086,16 @@ class Qwen3NextForCausalLM(nn.Module):
|
||||
if "mlp.experts" in name:
|
||||
continue
|
||||
|
||||
name = name.replace(weight_name, param_name)
|
||||
replaced_name = name.replace(weight_name, param_name)
|
||||
# Skip loading extra bias for GPTQ models.
|
||||
if name.endswith(".bias") and name not in params_dict:
|
||||
if replaced_name.endswith(".bias") and replaced_name not in params_dict:
|
||||
continue
|
||||
# Skip layers on other devices.
|
||||
# if is_pp_missing_parameter(name, self):
|
||||
# continue
|
||||
if name not in params_dict:
|
||||
if replaced_name not in params_dict:
|
||||
continue
|
||||
name = replaced_name
|
||||
param = params_dict[name]
|
||||
weight_loader = getattr(param, "weight_loader")
|
||||
weight_loader(param, loaded_weight, shard_id)
|
||||
@@ -1078,15 +1105,17 @@ class Qwen3NextForCausalLM(nn.Module):
|
||||
param_name, weight_name, expert_id, shard_id = mapping
|
||||
if weight_name not in name:
|
||||
continue
|
||||
name = name.replace(weight_name, param_name)
|
||||
replaced_name = name.replace(weight_name, param_name)
|
||||
# Skip layers on other devices.
|
||||
# if is_pp_missing_parameter(name, self):
|
||||
# continue
|
||||
# Skip loading extra bias for GPTQ models.
|
||||
if (
|
||||
name.endswith(".bias") or name.endswith("_bias")
|
||||
) and name not in params_dict:
|
||||
replaced_name.endswith(".bias")
|
||||
or replaced_name.endswith("_bias")
|
||||
) and replaced_name not in params_dict:
|
||||
continue
|
||||
name = replaced_name
|
||||
param = params_dict[name]
|
||||
|
||||
weight_loader = getattr(param, "weight_loader")
|
||||
|
||||
Reference in New Issue
Block a user