|
23 | 23 | from vllm.logger import logger |
24 | 24 |
|
25 | 25 | from vllm_ascend.ascend_config import get_ascend_config |
26 | | -from vllm_ascend.quantization.methods.base import QuantType |
| 26 | +from vllm_ascend.quantization.quant_type import QuantType |
| 27 | + |
| 28 | +EPLB_EXPERT_WEIGHT_NAMES = { |
| 29 | + (QuantType.NONE, False): ("w13_weight", "w2_weight"), |
| 30 | + (QuantType.NONE, True): ("w13_weight", "w2_weight"), |
| 31 | + (QuantType.W8A8, False): ( |
| 32 | + "w13_weight_list", |
| 33 | + "w2_weight_list", |
| 34 | + "w13_weight_scale_fp32_list", |
| 35 | + "w2_weight_scale_list", |
| 36 | + ), |
| 37 | + (QuantType.W8A8, True): ( |
| 38 | + "w13_weight_list", |
| 39 | + "w2_weight_list", |
| 40 | + "w13_weight_scale_fp32_list", |
| 41 | + "w2_weight_scale_list", |
| 42 | + "fused_w1_scale_list", |
| 43 | + "fused_w2_scale_list", |
| 44 | + ), |
| 45 | + (QuantType.W4A8, True): ( |
| 46 | + "w13_weight_list", |
| 47 | + "w2_weight_list", |
| 48 | + "w13_weight_scale_list", |
| 49 | + "w2_weight_scale_list", |
| 50 | + "w13_scale_bias_list", |
| 51 | + "w2_scale_bias_list", |
| 52 | + ), |
| 53 | + (QuantType.MXFP4, False): ("w13_weight", "w2_weight", "w13_weight_scale", "w2_weight_scale"), |
| 54 | + (QuantType.MXFP4, True): ("w13_weight", "w2_weight", "w13_weight_scale", "w2_weight_scale"), |
| 55 | + (QuantType.MXFP8, False): ("w13_weight", "w2_weight", "w13_weight_scale", "w2_weight_scale"), |
| 56 | + (QuantType.MXFP8, True): ("w13_weight", "w2_weight", "w13_weight_scale", "w2_weight_scale"), |
| 57 | +} |
27 | 58 |
|
28 | 59 |
|
29 | 60 | class VllmEplbAdaptor: |
@@ -61,73 +92,54 @@ def __init__(self, model, **args): |
61 | 92 | self.ep_rank = first_layer.ep_rank |
62 | 93 |
|
63 | 94 | self.expert_param_per_layer = dict() |
| 95 | + self.expert_weight_key_per_layer = dict() |
64 | 96 | self.init_expert_param_per_layer() |
65 | 97 |
|
66 | 98 | num_buffer_tensor = self.num_local_experts |
67 | | - self.buffer_tensor_list: list[list[Any]] = [[] for _ in range(num_buffer_tensor)] |
| 99 | + self.buffer_tensor_list: dict[Any, list[list[Any]]] = dict() |
68 | 100 | self.init_buffer_tensor(num_buffer_tensor) |
69 | 101 |
|
70 | 102 | self.log2phy_map_per_layer = dict() |
71 | 103 | for local_idx, layer in enumerate(self.moe_layers): |
72 | 104 | self.log2phy_map_per_layer[local_idx] = layer.get_log2phy_map() |
73 | 105 |
|
74 | 106 | def init_buffer_tensor(self, num_buffer_tensor): |
75 | | - for buffer_id in range(num_buffer_tensor): |
76 | | - for name in self.expert_weight_names: |
77 | | - expert_tensor = self.param_dict[f"0.{name}"][0] |
78 | | - buffer_tensor = torch.empty_like(expert_tensor) |
79 | | - self.buffer_tensor_list[buffer_id].append(buffer_tensor) |
| 107 | + buffer_tensor_shapes: dict[Any, list[torch.Size]] = dict() |
| 108 | + for local_idx, _ in enumerate(self.moe_layers): |
| 109 | + expert_weight_key = self.expert_weight_key_per_layer[local_idx] |
| 110 | + expert_weight_names = EPLB_EXPERT_WEIGHT_NAMES[expert_weight_key] |
| 111 | + expert_tensors = [self.param_dict[f"{local_idx}.{name}"][0] for name in expert_weight_names] |
| 112 | + expert_tensor_shapes = [tensor.shape for tensor in expert_tensors] |
| 113 | + if expert_weight_key in self.buffer_tensor_list: |
| 114 | + assert expert_tensor_shapes == buffer_tensor_shapes[expert_weight_key], ( |
| 115 | + f"EPLB expert weight shapes mismatch for {expert_weight_key}: " |
| 116 | + f"expected {buffer_tensor_shapes[expert_weight_key]}, got {expert_tensor_shapes}" |
| 117 | + ) |
| 118 | + continue |
| 119 | + buffer_tensor_shapes[expert_weight_key] = expert_tensor_shapes |
| 120 | + self.buffer_tensor_list[expert_weight_key] = [[] for _ in range(num_buffer_tensor)] |
| 121 | + for buffer_id in range(num_buffer_tensor): |
| 122 | + for expert_tensor in expert_tensors: |
| 123 | + buffer_tensor = torch.empty_like(expert_tensor) |
| 124 | + self.buffer_tensor_list[expert_weight_key][buffer_id].append(buffer_tensor) |
80 | 125 |
|
81 | 126 | def init_expert_param_per_layer(self): |
82 | 127 | self.param_dict = dict() |
83 | 128 |
|
84 | | - first_layer = self.moe_layers[0] |
85 | | - |
86 | | - if self.model.quant_config is not None: |
87 | | - quant_type = first_layer.quant_type |
88 | | - if quant_type == QuantType.W8A8: |
89 | | - self.expert_weight_names = [ |
90 | | - "w13_weight_list", |
91 | | - "w2_weight_list", |
92 | | - "w13_weight_scale_fp32_list", |
93 | | - "w2_weight_scale_list", |
94 | | - ] |
95 | | - if get_ascend_config().enable_fused_mc2 == 1: |
96 | | - self.expert_weight_names.append("fused_w1_scale_list") |
97 | | - self.expert_weight_names.append("fused_w2_scale_list") |
98 | | - |
99 | | - elif quant_type == QuantType.W4A8: |
100 | | - if get_ascend_config().enable_fused_mc2 != 1: |
101 | | - raise ValueError("EPLB not support W4A8 with fused MC2 disabled") |
102 | | - self.expert_weight_names = [ |
103 | | - "w13_weight_list", |
104 | | - "w2_weight_list", |
105 | | - "w13_weight_scale_list", |
106 | | - "w2_weight_scale_list", |
107 | | - "w13_scale_bias_list", |
108 | | - "w2_scale_bias_list", |
109 | | - ] |
110 | | - |
111 | | - elif quant_type in (QuantType.MXFP4, QuantType.MXFP8): |
112 | | - self.expert_weight_names = [ |
113 | | - "w13_weight", |
114 | | - "w2_weight", |
115 | | - "w13_weight_scale", |
116 | | - "w2_weight_scale", |
117 | | - ] |
118 | | - else: |
119 | | - raise ValueError(f"EPLB not support {quant_type}") |
120 | | - else: |
121 | | - self.expert_weight_names = ["w13_weight", "w2_weight"] |
122 | | - |
123 | 129 | for local_idx, layer in enumerate(self.moe_layers): |
| 130 | + quant_type = QuantType.NONE if self.model.quant_config is None else layer.quant_type |
| 131 | + expert_weight_key = (quant_type, get_ascend_config().enable_fused_mc2 == 1) |
| 132 | + if expert_weight_key not in EPLB_EXPERT_WEIGHT_NAMES: |
| 133 | + raise ValueError(f"EPLB not support {quant_type} with fused MC2 {expert_weight_key[1]}") |
| 134 | + expert_weight_names = EPLB_EXPERT_WEIGHT_NAMES[expert_weight_key] |
| 135 | + self.expert_weight_key_per_layer[local_idx] = expert_weight_key |
124 | 136 | self.expert_param_per_layer[local_idx] = list() |
125 | | - for name in self.expert_weight_names: |
| 137 | + for name in expert_weight_names: |
126 | 138 | param_key = f"{local_idx}.{name}" |
127 | 139 | self.param_dict[param_key] = getattr(layer, name) |
128 | 140 | for local_expert_id in range(self.num_local_experts): |
129 | 141 | per_expert_param = list() |
130 | | - for name in self.expert_weight_names: |
| 142 | + for name in expert_weight_names: |
131 | 143 | per_expert_param.append(self.param_dict[f"{local_idx}.{name}"][local_expert_id]) |
132 | 144 | self.expert_param_per_layer[local_idx].append(per_expert_param) |
133 | 145 |
|
@@ -168,8 +180,10 @@ def do_update_expert_map(self, layer_id, updated_expert_map): |
168 | 180 | self.expert_map_per_layer_cpu[layer_id].copy_(updated_expert_map) |
169 | 181 |
|
170 | 182 | def do_update_expert_weight(self, layer_id, local_expert_to_replace, buffer_tensor_id): |
| 183 | + expert_weight_key = self.expert_weight_key_per_layer[layer_id] |
171 | 184 | for expert_tensor, buffer_tensor in zip( |
172 | | - self.expert_param_per_layer[layer_id][local_expert_to_replace], self.buffer_tensor_list[buffer_tensor_id] |
| 185 | + self.expert_param_per_layer[layer_id][local_expert_to_replace], |
| 186 | + self.buffer_tensor_list[expert_weight_key][buffer_tensor_id], |
173 | 187 | ): |
174 | 188 | expert_tensor.copy_(buffer_tensor) |
175 | 189 | logger.debug("Expert tensor shape is :%s", expert_tensor.shape) |
|
0 commit comments