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, 01:15 UTC
[Model] use AutoWeightsLoader for DeepSeekV2 (#41706)
Signed-off-by: SoluMilken <ypiheyn.imm02g@g2.nctu.edu.tw>
SoluMilken committed
May 10, 2026 at 01:55 UTC
cd74911d92841102c1cbbc8ed6d544518bf68223
1 file changed
+186
-169
vllm/model_executor/models/deepseek_v2.py
+186
-169
@@ -83,6 +83,7 @@ from vllm.model_executor.model_loader.weight_utils import (
83
maybe_remap_kv_scale_name,
84
)
85
from vllm.model_executor.models.utils import (
86
+ AutoWeightsLoader,
87
extract_layer_index,
88
sequence_parallel_chunk,
89
)
@@ -1254,6 +1255,16 @@ class DeepseekV2Model(nn.Module):
1255
1256
self.aux_hidden_state_layers = tuple[int, ...]()
1257
1258
+ # Needed by load_weights
1259
+ qk_nope_head_dim = getattr(config, "qk_nope_head_dim", 0)
1260
+ qk_rope_head_dim = getattr(config, "qk_rope_head_dim", 0)
1261
+ self.use_mha = config.model_type == "deepseek" or all(
1262
+ dim == 0 for dim in (qk_nope_head_dim, qk_rope_head_dim)
1263
+ )
1264
+ self.num_redundant_experts = (
1265
+ vllm_config.parallel_config.eplb_config.num_redundant_experts
1266
+ )
1267
+
1268
def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
1269
return self.embed_tokens(input_ids)
1270
@@ -1315,174 +1326,6 @@ class DeepseekV2Model(nn.Module):
1326
return hidden_states, aux_hidden_states
1327
return hidden_states
1328
1318
-
1319
-class DeepseekV2MixtureOfExperts(MixtureOfExperts):
1320
- moe_mlp_layers: list[DeepseekV2MoE]
1321
- """
1322
- List of MoE MLP layers in the model.
1323
- """
1324
-
1325
- def extract_moe_parameters(self, example_moe: DeepseekV2MoE | None):
1326
- if example_moe is None:
1327
- self.num_moe_layers = 0
1328
- self.num_expert_groups = 0
1329
- self.num_logical_experts = 0
1330
- self.num_physical_experts = 0
1331
- self.num_local_physical_experts = 0
1332
- self.num_routed_experts = 0
1333
- self.num_shared_experts = 0
1334
- self.num_redundant_experts = 0
1335
- logger.warning("DeepSeekV2: No DeepseekV2MoE layer found in model.layers.")
1336
- else:
1337
- self.num_logical_experts = example_moe.n_logical_experts
1338
- self.num_physical_experts = example_moe.n_physical_experts
1339
- self.num_local_physical_experts = example_moe.n_local_physical_experts
1340
- self.num_routed_experts = example_moe.n_routed_experts
1341
- self.num_shared_experts = example_moe.n_shared_experts
1342
- self.num_redundant_experts = example_moe.n_redundant_experts
1343
-
1344
- def update_physical_experts_metadata(
1345
- self,
1346
- num_physical_experts: int,
1347
- num_local_physical_experts: int,
1348
- ) -> None:
1349
- assert self.num_local_physical_experts == num_local_physical_experts
1350
- self.num_physical_experts = num_physical_experts
1351
- self.num_local_physical_experts = num_local_physical_experts
1352
- self.num_redundant_experts = num_physical_experts - self.num_logical_experts
1353
- for moe in self.moe_mlp_layers:
1354
- moe.n_local_physical_experts = num_local_physical_experts
1355
- moe.n_physical_experts = num_physical_experts
1356
- moe.n_redundant_experts = self.num_redundant_experts
1357
- moe.experts.update_expert_map()
1358
-
1359
-
1360
-class DeepseekV2ForCausalLM(
1361
- nn.Module,
1362
- SupportsPP,
1363
- DeepseekV2MixtureOfExperts,
1364
- SupportsLoRA,
1365
- SupportsEagle,
1366
- SupportsEagle3,
1367
-):
1368
- packed_modules_mapping = {
1369
- "gate_up_proj": ["gate_proj", "up_proj"],
1370
- }
1371
- model_cls = DeepseekV2Model
1372
-
1373
- def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
1374
- super().__init__()
1375
- config = vllm_config.model_config.hf_config
1376
- quant_config = vllm_config.quant_config
1377
- self.config = config
1378
- self.quant_config = quant_config
1379
-
1380
- qk_nope_head_dim = getattr(config, "qk_nope_head_dim", 0)
1381
- qk_rope_head_dim = getattr(config, "qk_rope_head_dim", 0)
1382
- self.use_mha = config.model_type == "deepseek" or all(
1383
- dim == 0 for dim in (qk_nope_head_dim, qk_rope_head_dim)
1384
- )
1385
-
1386
- if self.use_mha:
1387
- self.packed_modules_mapping["qkv_proj"] = ["q_proj", "k_proj", "v_proj"]
1388
-
1389
- # `packed_modules_mapping` needs to be modified before
1390
- # initializing DeepseekV2Model, as it is passed inplace to
1391
- # quantization config init and may be used to select the
1392
- # quant_method for relevant layers during initialization.
1393
- self.fuse_qkv_a_proj = (
1394
- hasattr(config, "q_lora_rank") and config.q_lora_rank is not None
1395
- )
1396
- if self.fuse_qkv_a_proj:
1397
- self.packed_modules_mapping["fused_qkv_a_proj"] = [
1398
- "q_a_proj",
1399
- "kv_a_proj_with_mqa",
1400
- ]
1401
-
1402
- self.model = self.model_cls(
1403
- vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
1404
- )
1405
- if get_pp_group().is_last_rank:
1406
- self.lm_head = ParallelLMHead(
1407
- config.vocab_size,
1408
- config.hidden_size,
1409
- quant_config=quant_config,
1410
- prefix=maybe_prefix(prefix, "lm_head"),
1411
- )
1412
- else:
1413
- self.lm_head = PPMissingLayer()
1414
- self.logits_processor = LogitsProcessor(config.vocab_size)
1415
- self.make_empty_intermediate_tensors = (
1416
- self.model.make_empty_intermediate_tensors
1417
- )
1418
- # Set MoE hyperparameters
1419
- self.num_moe_layers = (
1420
- self.config.num_hidden_layers - self.config.first_k_dense_replace
1421
- )
1422
- self.set_moe_parameters()
1423
-
1424
- def set_moe_parameters(self):
1425
- self.expert_weights = []
1426
-
1427
- self.num_expert_groups = getattr(self.config, "n_group", 1)
1428
-
1429
- self.moe_layers = []
1430
- self.moe_mlp_layers = []
1431
- example_moe = None
1432
- for layer in self.model.layers:
1433
- if isinstance(layer, PPMissingLayer):
1434
- continue
1435
-
1436
- assert isinstance(layer, DeepseekV2DecoderLayer)
1437
- if isinstance(layer.mlp, DeepseekV2MoE):
1438
- # Pick last one layer since the first ones may be dense layers.
1439
- example_moe = layer.mlp
1440
- self.moe_mlp_layers.append(layer.mlp)
1441
- self.moe_layers.append(layer.mlp.experts)
1442
-
1443
- self.extract_moe_parameters(example_moe)
1444
-
1445
- def set_aux_hidden_state_layers(self, layers: tuple[int, ...]) -> None:
1446
- self.model.aux_hidden_state_layers = layers
1447
-
1448
- def get_eagle3_aux_hidden_state_layers(self) -> tuple[int, ...]:
1449
- num_layers = len(self.model.layers)
1450
- return (2, num_layers // 2, num_layers - 3)
1451
-
1452
- def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
1453
- return self.model.embed_input_ids(input_ids)
1454
-
1455
- def forward(
1456
- self,
1457
- input_ids: torch.Tensor | None,
1458
- positions: torch.Tensor,
1459
- intermediate_tensors: IntermediateTensors | None = None,
1460
- inputs_embeds: torch.Tensor | None = None,
1461
- ) -> torch.Tensor | IntermediateTensors:
1462
- hidden_states = self.model(
1463
- input_ids, positions, intermediate_tensors, inputs_embeds
1464
- )
1465
- return hidden_states
1466
-
1467
- def compute_logits(
1468
- self,
1469
- hidden_states: torch.Tensor,
1470
- ) -> torch.Tensor | None:
1471
- logits = self.logits_processor(self.lm_head, hidden_states)
1472
- return logits
1473
-
1474
- def get_expert_mapping(self) -> list[tuple[str, str, int, str]]:
1475
- # Params for weights, fp8 weight scales, fp8 activation scales
1476
- # (param_name, weight_name, expert_id, shard_id)
1477
- return fused_moe_make_expert_params_mapping(
1478
- self,
1479
- ckpt_gate_proj_name="gate_proj",
1480
- ckpt_down_proj_name="down_proj",
1481
- ckpt_up_proj_name="up_proj",
1482
- num_experts=self.config.n_routed_experts,
1483
- num_redundant_experts=0,
1484
- )
1485
-
1329
def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
1330
rocm_aiter_moe_shared_expert_enabled = (
1331
rocm_aiter_ops.is_fusion_moe_shared_experts_enabled()
@@ -1703,6 +1546,178 @@ class DeepseekV2ForCausalLM(
1546
return loaded_params
1547
1548
1549
+class DeepseekV2MixtureOfExperts(MixtureOfExperts):
1550
+ moe_mlp_layers: list[DeepseekV2MoE]
1551
+ """
1552
+ List of MoE MLP layers in the model.
1553
+ """
1554
+
1555
+ def extract_moe_parameters(self, example_moe: DeepseekV2MoE | None):
1556
+ if example_moe is None:
1557
+ self.num_moe_layers = 0
1558
+ self.num_expert_groups = 0
1559
+ self.num_logical_experts = 0
1560
+ self.num_physical_experts = 0
1561
+ self.num_local_physical_experts = 0
1562
+ self.num_routed_experts = 0
1563
+ self.num_shared_experts = 0
1564
+ self.num_redundant_experts = 0
1565
+ logger.warning("DeepSeekV2: No DeepseekV2MoE layer found in model.layers.")
1566
+ else:
1567
+ self.num_logical_experts = example_moe.n_logical_experts
1568
+ self.num_physical_experts = example_moe.n_physical_experts
1569
+ self.num_local_physical_experts = example_moe.n_local_physical_experts
1570
+ self.num_routed_experts = example_moe.n_routed_experts
1571
+ self.num_shared_experts = example_moe.n_shared_experts
1572
+ self.num_redundant_experts = example_moe.n_redundant_experts
1573
+
1574
+ def update_physical_experts_metadata(
1575
+ self,
1576
+ num_physical_experts: int,
1577
+ num_local_physical_experts: int,
1578
+ ) -> None:
1579
+ assert self.num_local_physical_experts == num_local_physical_experts
1580
+ self.num_physical_experts = num_physical_experts
1581
+ self.num_local_physical_experts = num_local_physical_experts
1582
+ self.num_redundant_experts = num_physical_experts - self.num_logical_experts
1583
+ for moe in self.moe_mlp_layers:
1584
+ moe.n_local_physical_experts = num_local_physical_experts
1585
+ moe.n_physical_experts = num_physical_experts
1586
+ moe.n_redundant_experts = self.num_redundant_experts
1587
+ moe.experts.update_expert_map()
1588
+
1589
+
1590
+class DeepseekV2ForCausalLM(
1591
+ nn.Module,
1592
+ SupportsPP,
1593
+ DeepseekV2MixtureOfExperts,
1594
+ SupportsLoRA,
1595
+ SupportsEagle,
1596
+ SupportsEagle3,
1597
+):
1598
+ packed_modules_mapping = {
1599
+ "gate_up_proj": ["gate_proj", "up_proj"],
1600
+ }
1601
+ model_cls = DeepseekV2Model
1602
+
1603
+ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
1604
+ super().__init__()
1605
+ config = vllm_config.model_config.hf_config
1606
+ quant_config = vllm_config.quant_config
1607
+ self.config = config
1608
+ self.quant_config = quant_config
1609
+
1610
+ qk_nope_head_dim = getattr(config, "qk_nope_head_dim", 0)
1611
+ qk_rope_head_dim = getattr(config, "qk_rope_head_dim", 0)
1612
+ self.use_mha = config.model_type == "deepseek" or all(
1613
+ dim == 0 for dim in (qk_nope_head_dim, qk_rope_head_dim)
1614
+ )
1615
+
1616
+ if self.use_mha:
1617
+ self.packed_modules_mapping["qkv_proj"] = ["q_proj", "k_proj", "v_proj"]
1618
+
1619
+ # `packed_modules_mapping` needs to be modified before
1620
+ # initializing DeepseekV2Model, as it is passed inplace to
1621
+ # quantization config init and may be used to select the
1622
+ # quant_method for relevant layers during initialization.
1623
+ self.fuse_qkv_a_proj = (
1624
+ hasattr(config, "q_lora_rank") and config.q_lora_rank is not None
1625
+ )
1626
+ if self.fuse_qkv_a_proj:
1627
+ self.packed_modules_mapping["fused_qkv_a_proj"] = [
1628
+ "q_a_proj",
1629
+ "kv_a_proj_with_mqa",
1630
+ ]
1631
+
1632
+ self.model = self.model_cls(
1633
+ vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model")
1634
+ )
1635
+ if get_pp_group().is_last_rank:
1636
+ self.lm_head = ParallelLMHead(
1637
+ config.vocab_size,
1638
+ config.hidden_size,
1639
+ quant_config=quant_config,
1640
+ prefix=maybe_prefix(prefix, "lm_head"),
1641
+ )
1642
+ else:
1643
+ self.lm_head = PPMissingLayer()
1644
+ self.logits_processor = LogitsProcessor(config.vocab_size)
1645
+ self.make_empty_intermediate_tensors = (
1646
+ self.model.make_empty_intermediate_tensors
1647
+ )
1648
+ # Set MoE hyperparameters
1649
+ self.num_moe_layers = (
1650
+ self.config.num_hidden_layers - self.config.first_k_dense_replace
1651
+ )
1652
+ self.set_moe_parameters()
1653
+
1654
+ def set_moe_parameters(self):
1655
+ self.expert_weights = []
1656
+
1657
+ self.num_expert_groups = getattr(self.config, "n_group", 1)
1658
+
1659
+ self.moe_layers = []
1660
+ self.moe_mlp_layers = []
1661
+ example_moe = None
1662
+ for layer in self.model.layers:
1663
+ if isinstance(layer, PPMissingLayer):
1664
+ continue
1665
+
1666
+ assert isinstance(layer, DeepseekV2DecoderLayer)
1667
+ if isinstance(layer.mlp, DeepseekV2MoE):
1668
+ # Pick last one layer since the first ones may be dense layers.
1669
+ example_moe = layer.mlp
1670
+ self.moe_mlp_layers.append(layer.mlp)
1671
+ self.moe_layers.append(layer.mlp.experts)
1672
+
1673
+ self.extract_moe_parameters(example_moe)
1674
+
1675
+ def set_aux_hidden_state_layers(self, layers: tuple[int, ...]) -> None:
1676
+ self.model.aux_hidden_state_layers = layers
1677
+
1678
+ def get_eagle3_aux_hidden_state_layers(self) -> tuple[int, ...]:
1679
+ num_layers = len(self.model.layers)
1680
+ return (2, num_layers // 2, num_layers - 3)
1681
+
1682
+ def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
1683
+ return self.model.embed_input_ids(input_ids)
1684
+
1685
+ def forward(
1686
+ self,
1687
+ input_ids: torch.Tensor | None,
1688
+ positions: torch.Tensor,
1689
+ intermediate_tensors: IntermediateTensors | None = None,
1690
+ inputs_embeds: torch.Tensor | None = None,
1691
+ ) -> torch.Tensor | IntermediateTensors:
1692
+ hidden_states = self.model(
1693
+ input_ids, positions, intermediate_tensors, inputs_embeds
1694
+ )
1695
+ return hidden_states
1696
+
1697
+ def compute_logits(
1698
+ self,
1699
+ hidden_states: torch.Tensor,
1700
+ ) -> torch.Tensor | None:
1701
+ logits = self.logits_processor(self.lm_head, hidden_states)
1702
+ return logits
1703
+
1704
+ def get_expert_mapping(self) -> list[tuple[str, str, int, str]]:
1705
+ # Params for weights, fp8 weight scales, fp8 activation scales
1706
+ # (param_name, weight_name, expert_id, shard_id)
1707
+ return fused_moe_make_expert_params_mapping(
1708
+ self,
1709
+ ckpt_gate_proj_name="gate_proj",
1710
+ ckpt_down_proj_name="down_proj",
1711
+ ckpt_up_proj_name="up_proj",
1712
+ num_experts=self.config.n_routed_experts,
1713
+ num_redundant_experts=0,
1714
+ )
1715
+
1716
+ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
1717
+ loader = AutoWeightsLoader(self)
1718
+ return loader.load_weights(weights)
1719
+
1720
+
1721
class DeepseekForCausalLM(DeepseekV2ForCausalLM):
1722
pass
1723
@@ -1726,6 +1741,8 @@ def get_spec_layer_idx_from_weight_name(
1741
):
1742
layer_idx = config.num_hidden_layers
1743
for i in range(config.num_nextn_predict_layers):
1729
- if weight_name.startswith(f"model.layers.{layer_idx + i}."):
1744
+ if weight_name.startswith(
1745
+ f"model.layers.{layer_idx + i}."
1746
+ ) or weight_name.startswith(f"layers.{layer_idx + i}."):
1747
return layer_idx + i
1748
return None