@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / ffee741626
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 4, 03:45 UTC

[Model] Use AutoWeightsLoader for AXK1 (#41901)

Signed-off-by: liwenyi <lwy.lwy@163.com> Co-authored-by: Claude <noreply@anthropic.com>

wenyili committed May 7, 2026 at 20:40 UTC ffee74162609612c3aae3113b8fa3cbca5eeb1b9
1 file changed +167 -153
vllm/model_executor/models/AXK1.py
+167 -153
@@ -77,6 +77,7 @@ from vllm.transformers_utils.configs.AXK1 import AXK1Config
77
78 from .interfaces import MixtureOfExperts, SupportsEagle, SupportsLoRA, SupportsPP
79 from .utils import (
80 + AutoWeightsLoader,
81 PPMissingLayer,
82 is_pp_missing_parameter,
83 make_empty_intermediate_tensors_factory,
@@ -727,6 +728,13 @@ class AXK1Model(nn.Module):
728 self.make_empty_intermediate_tensors = make_empty_intermediate_tensors_factory(
729 ["hidden_states", "residual"], config.hidden_size
730 )
731 + self.use_mha = all(
732 + dim == 0 for dim in (config.qk_nope_head_dim, config.qk_rope_head_dim)
733 + )
734 + self.fuse_qkv_a_proj = config.q_lora_rank is not None
735 + self.num_redundant_experts = (
736 + vllm_config.parallel_config.eplb_config.num_redundant_experts
737 + )
738
739 def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
740 return self.embed_tokens(input_ids)
@@ -776,158 +784,6 @@ class AXK1Model(nn.Module):
784 hidden_states, _ = self.norm(hidden_states, residual)
785 return hidden_states
786
779 -
780 -class AXK1MixtureOfExperts(MixtureOfExperts):
781 - moe_mlp_layers: list[AXK1MoE]
782 - """
783 - List of MoE MLP layers in the model.
784 - """
785 -
786 - def extract_moe_parameters(self, example_moe: AXK1MoE | None):
787 - if example_moe is None:
788 - self.num_moe_layers = 0
789 - self.num_expert_groups = 0
790 - self.num_logical_experts = 0
791 - self.num_physical_experts = 0
792 - self.num_local_physical_experts = 0
793 - self.num_routed_experts = 0
794 - self.num_shared_experts = 0
795 - self.num_redundant_experts = 0
796 - logger.warning("AXK1: No AXK1MoE layer found in model.layers.")
797 - else:
798 - self.num_logical_experts = example_moe.n_logical_experts
799 - self.num_physical_experts = example_moe.n_physical_experts
800 - self.num_local_physical_experts = example_moe.n_local_physical_experts
801 - self.num_routed_experts = example_moe.n_routed_experts
802 - self.num_shared_experts = example_moe.n_shared_experts
803 - self.num_redundant_experts = example_moe.n_redundant_experts
804 -
805 - def update_physical_experts_metadata(
806 - self,
807 - num_physical_experts: int,
808 - num_local_physical_experts: int,
809 - ) -> None:
810 - assert self.num_local_physical_experts == num_local_physical_experts
811 - self.num_physical_experts = num_physical_experts
812 - self.num_local_physical_experts = num_local_physical_experts
813 - self.num_redundant_experts = num_physical_experts - self.num_logical_experts
814 - for moe in self.moe_mlp_layers:
815 - moe.n_local_physical_experts = num_local_physical_experts
816 - moe.n_physical_experts = num_physical_experts
817 - moe.n_redundant_experts = self.num_redundant_experts
818 - moe.experts.update_expert_map()
819 -
820 -
821 -class AXK1ForCausalLM(
822 - nn.Module, SupportsPP, AXK1MixtureOfExperts, SupportsLoRA, SupportsEagle
823 -):
824 - packed_modules_mapping = {
825 - "gate_up_proj": ["gate_proj", "up_proj"],
826 - }
827 - model_cls = AXK1Model
828 -
829 - def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
830 - super().__init__()
831 - config: AXK1Config = vllm_config.model_config.hf_config
832 - quant_config = vllm_config.quant_config
833 - self.config = config
834 - self.quant_config = quant_config
835 -
836 - qk_nope_head_dim = config.qk_nope_head_dim
837 - qk_rope_head_dim = config.qk_rope_head_dim
838 - self.use_mha = all(dim == 0 for dim in (qk_nope_head_dim, qk_rope_head_dim))
839 -
840 - if self.use_mha:
841 - self.packed_modules_mapping["qkv_proj"] = ["q_proj", "k_proj", "v_proj"]
842 -
843 - # `packed_modules_mapping` needs to be modified before
844 - # initializing AXK1Model, as it is passed inplace to
845 - # quantization config init and may be used to select the
846 - # quant_method for relevant layers during initialization.
847 - self.fuse_qkv_a_proj = config.q_lora_rank is not None
848 - if self.fuse_qkv_a_proj:
849 - self.packed_modules_mapping["fused_qkv_a_proj"] = [
850 - "q_a_proj",
851 - "kv_a_proj_with_mqa",
852 - ]
853 -
854 - self.model = self.model_cls(
855 - vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
856 - )
857 - if get_pp_group().is_last_rank:
858 - self.lm_head = ParallelLMHead(
859 - config.vocab_size,
860 - config.hidden_size,
861 - quant_config=quant_config,
862 - prefix=maybe_prefix(prefix, "lm_head"),
863 - )
864 - else:
865 - self.lm_head = PPMissingLayer()
866 - self.logits_processor = LogitsProcessor(config.vocab_size)
867 - self.make_empty_intermediate_tensors = (
868 - self.model.make_empty_intermediate_tensors
869 - )
870 - # Set MoE hyperparameters
871 - self.num_moe_layers = (
872 - self.config.num_hidden_layers - self.config.first_k_dense_replace
873 - )
874 - self.set_moe_parameters()
875 -
876 - def set_moe_parameters(self):
877 - self.expert_weights = []
878 -
879 - self.num_expert_groups = getattr(self.config, "n_group", 1)
880 -
881 - self.moe_layers = []
882 - self.moe_mlp_layers = []
883 - example_moe = None
884 - for layer in self.model.layers:
885 - if isinstance(layer, PPMissingLayer):
886 - continue
887 -
888 - assert isinstance(layer, AXK1DecoderLayer)
889 - if isinstance(layer.mlp, AXK1MoE):
890 - # Pick last one layer since the first ones may be dense layers.
891 - example_moe = layer.mlp
892 - self.moe_mlp_layers.append(layer.mlp)
893 - self.moe_layers.append(layer.mlp.experts)
894 -
895 - self.extract_moe_parameters(example_moe)
896 -
897 - def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
898 - return self.model.embed_input_ids(input_ids)
899 -
900 - def forward(
901 - self,
902 - input_ids: torch.Tensor | None,
903 - positions: torch.Tensor,
904 - intermediate_tensors: IntermediateTensors | None = None,
905 - inputs_embeds: torch.Tensor | None = None,
906 - ) -> torch.Tensor | IntermediateTensors:
907 - hidden_states = self.model(
908 - input_ids, positions, intermediate_tensors, inputs_embeds
909 - )
910 - return hidden_states
911 -
912 - def compute_logits(
913 - self,
914 - hidden_states: torch.Tensor,
915 - ) -> torch.Tensor | None:
916 - logits = self.logits_processor(self.lm_head, hidden_states)
917 - return logits
918 -
919 - def get_expert_mapping(self) -> list[tuple[str, str, int, str]]:
920 - # Params for weights, fp8 weight scales, fp8 activation scales
921 - # (param_name, weight_name, expert_id, shard_id)
922 - return fused_moe_make_expert_params_mapping(
923 - self,
924 - ckpt_gate_proj_name="gate_proj",
925 - ckpt_down_proj_name="down_proj",
926 - ckpt_up_proj_name="up_proj",
927 - num_experts=self.config.n_routed_experts,
928 - num_redundant_experts=0,
929 - )
930 -
787 def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
788 rocm_aiter_moe_shared_expert_enabled = (
789 rocm_aiter_ops.is_fusion_moe_shared_experts_enabled()
@@ -1135,12 +991,170 @@ class AXK1ForCausalLM(
991 return loaded_params
992
993
994 +class AXK1MixtureOfExperts(MixtureOfExperts):
995 + moe_mlp_layers: list[AXK1MoE]
996 + """
997 + List of MoE MLP layers in the model.
998 + """
999 +
1000 + def extract_moe_parameters(self, example_moe: AXK1MoE | None):
1001 + if example_moe is None:
1002 + self.num_moe_layers = 0
1003 + self.num_expert_groups = 0
1004 + self.num_logical_experts = 0
1005 + self.num_physical_experts = 0
1006 + self.num_local_physical_experts = 0
1007 + self.num_routed_experts = 0
1008 + self.num_shared_experts = 0
1009 + self.num_redundant_experts = 0
1010 + logger.warning("AXK1: No AXK1MoE layer found in model.layers.")
1011 + else:
1012 + self.num_logical_experts = example_moe.n_logical_experts
1013 + self.num_physical_experts = example_moe.n_physical_experts
1014 + self.num_local_physical_experts = example_moe.n_local_physical_experts
1015 + self.num_routed_experts = example_moe.n_routed_experts
1016 + self.num_shared_experts = example_moe.n_shared_experts
1017 + self.num_redundant_experts = example_moe.n_redundant_experts
1018 +
1019 + def update_physical_experts_metadata(
1020 + self,
1021 + num_physical_experts: int,
1022 + num_local_physical_experts: int,
1023 + ) -> None:
1024 + assert self.num_local_physical_experts == num_local_physical_experts
1025 + self.num_physical_experts = num_physical_experts
1026 + self.num_local_physical_experts = num_local_physical_experts
1027 + self.num_redundant_experts = num_physical_experts - self.num_logical_experts
1028 + for moe in self.moe_mlp_layers:
1029 + moe.n_local_physical_experts = num_local_physical_experts
1030 + moe.n_physical_experts = num_physical_experts
1031 + moe.n_redundant_experts = self.num_redundant_experts
1032 + moe.experts.update_expert_map()
1033 +
1034 +
1035 +class AXK1ForCausalLM(
1036 + nn.Module, SupportsPP, AXK1MixtureOfExperts, SupportsLoRA, SupportsEagle
1037 +):
1038 + packed_modules_mapping = {
1039 + "gate_up_proj": ["gate_proj", "up_proj"],
1040 + }
1041 + model_cls = AXK1Model
1042 +
1043 + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
1044 + super().__init__()
1045 + config: AXK1Config = vllm_config.model_config.hf_config
1046 + quant_config = vllm_config.quant_config
1047 + self.config = config
1048 + self.quant_config = quant_config
1049 +
1050 + qk_nope_head_dim = config.qk_nope_head_dim
1051 + qk_rope_head_dim = config.qk_rope_head_dim
1052 + self.use_mha = all(dim == 0 for dim in (qk_nope_head_dim, qk_rope_head_dim))
1053 +
1054 + if self.use_mha:
1055 + self.packed_modules_mapping["qkv_proj"] = ["q_proj", "k_proj", "v_proj"]
1056 +
1057 + # `packed_modules_mapping` needs to be modified before
1058 + # initializing AXK1Model, as it is passed inplace to
1059 + # quantization config init and may be used to select the
1060 + # quant_method for relevant layers during initialization.
1061 + self.fuse_qkv_a_proj = config.q_lora_rank is not None
1062 + if self.fuse_qkv_a_proj:
1063 + self.packed_modules_mapping["fused_qkv_a_proj"] = [
1064 + "q_a_proj",
1065 + "kv_a_proj_with_mqa",
1066 + ]
1067 +
1068 + self.model = self.model_cls(
1069 + vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
1070 + )
1071 + if get_pp_group().is_last_rank:
1072 + self.lm_head = ParallelLMHead(
1073 + config.vocab_size,
1074 + config.hidden_size,
1075 + quant_config=quant_config,
1076 + prefix=maybe_prefix(prefix, "lm_head"),
1077 + )
1078 + else:
1079 + self.lm_head = PPMissingLayer()
1080 + self.logits_processor = LogitsProcessor(config.vocab_size)
1081 + self.make_empty_intermediate_tensors = (
1082 + self.model.make_empty_intermediate_tensors
1083 + )
1084 + # Set MoE hyperparameters
1085 + self.num_moe_layers = (
1086 + self.config.num_hidden_layers - self.config.first_k_dense_replace
1087 + )
1088 + self.set_moe_parameters()
1089 +
1090 + def set_moe_parameters(self):
1091 + self.expert_weights = []
1092 +
1093 + self.num_expert_groups = getattr(self.config, "n_group", 1)
1094 +
1095 + self.moe_layers = []
1096 + self.moe_mlp_layers = []
1097 + example_moe = None
1098 + for layer in self.model.layers:
1099 + if isinstance(layer, PPMissingLayer):
1100 + continue
1101 +
1102 + assert isinstance(layer, AXK1DecoderLayer)
1103 + if isinstance(layer.mlp, AXK1MoE):
1104 + # Pick last one layer since the first ones may be dense layers.
1105 + example_moe = layer.mlp
1106 + self.moe_mlp_layers.append(layer.mlp)
1107 + self.moe_layers.append(layer.mlp.experts)
1108 +
1109 + self.extract_moe_parameters(example_moe)
1110 +
1111 + def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
1112 + return self.model.embed_input_ids(input_ids)
1113 +
1114 + def forward(
1115 + self,
1116 + input_ids: torch.Tensor | None,
1117 + positions: torch.Tensor,
1118 + intermediate_tensors: IntermediateTensors | None = None,
1119 + inputs_embeds: torch.Tensor | None = None,
1120 + ) -> torch.Tensor | IntermediateTensors:
1121 + hidden_states = self.model(
1122 + input_ids, positions, intermediate_tensors, inputs_embeds
1123 + )
1124 + return hidden_states
1125 +
1126 + def compute_logits(
1127 + self,
1128 + hidden_states: torch.Tensor,
1129 + ) -> torch.Tensor | None:
1130 + logits = self.logits_processor(self.lm_head, hidden_states)
1131 + return logits
1132 +
1133 + def get_expert_mapping(self) -> list[tuple[str, str, int, str]]:
1134 + # Params for weights, fp8 weight scales, fp8 activation scales
1135 + # (param_name, weight_name, expert_id, shard_id)
1136 + return fused_moe_make_expert_params_mapping(
1137 + self,
1138 + ckpt_gate_proj_name="gate_proj",
1139 + ckpt_down_proj_name="down_proj",
1140 + ckpt_up_proj_name="up_proj",
1141 + num_experts=self.config.n_routed_experts,
1142 + num_redundant_experts=0,
1143 + )
1144 +
1145 + def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
1146 + loader = AutoWeightsLoader(self)
1147 + return loader.load_weights(weights)
1148 +
1149 +
1150 def get_spec_layer_idx_from_weight_name(
1151 config: AXK1Config, weight_name: str
1152 ) -> int | None:
1153 if config.num_nextn_predict_layers and config.num_nextn_predict_layers > 0:
1154 layer_idx = config.num_hidden_layers
1155 for i in range(config.num_nextn_predict_layers):
1144 - if weight_name.startswith(f"model.layers.{layer_idx + i}."):
1156 + if weight_name.startswith(
1157 + f"model.layers.{layer_idx + i}."
1158 + ) or weight_name.startswith(f"layers.{layer_idx + i}."):
1159 return layer_idx + i
1160 return None