初始化项目,由ModelHub XC社区提供模型
Model: ayh015/myLightningOPD Source: Original Platform
This commit is contained in:
3
slime/backends/fsdp_utils/models/__init__.py
Normal file
3
slime/backends/fsdp_utils/models/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
128
slime/backends/fsdp_utils/models/qwen3_moe.py
Normal file
128
slime/backends/fsdp_utils/models/qwen3_moe.py
Normal file
@@ -0,0 +1,128 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
from transformers.models.qwen3_moe.modeling_qwen3_moe import Qwen3MoeMLP
|
||||
|
||||
from slime.backends.fsdp_utils.kernels.fused_experts import (
|
||||
DownProjFunction,
|
||||
GateUpProjFunction,
|
||||
MoeSumReduceFunction,
|
||||
SiluAndMulFunction,
|
||||
)
|
||||
|
||||
|
||||
def fused_experts_impl(
|
||||
hidden_states: torch.Tensor,
|
||||
w1: torch.Tensor,
|
||||
w2: torch.Tensor,
|
||||
topk_weights: torch.Tensor,
|
||||
topk_ids: torch.Tensor,
|
||||
):
|
||||
assert hidden_states.shape[1] == w1.shape[2], "Hidden size mismatch"
|
||||
assert topk_weights.shape == topk_ids.shape, "topk shape mismatch"
|
||||
assert hidden_states.is_contiguous(), "Hidden_states must be contiguous"
|
||||
assert w1.is_contiguous(), "Expert weights1 must be contiguous"
|
||||
assert w2.is_contiguous(), "Expert weights2 must be contiguous"
|
||||
assert hidden_states.dtype in [torch.bfloat16]
|
||||
|
||||
intermediate_cache1 = GateUpProjFunction.apply(
|
||||
hidden_states,
|
||||
w1,
|
||||
topk_weights,
|
||||
topk_ids,
|
||||
)
|
||||
intermediate_cache2 = SiluAndMulFunction.apply(intermediate_cache1)
|
||||
intermediate_cache3 = DownProjFunction.apply(
|
||||
intermediate_cache2,
|
||||
w2,
|
||||
topk_weights,
|
||||
topk_ids,
|
||||
)
|
||||
output_hidden_states = MoeSumReduceFunction.apply(
|
||||
intermediate_cache3,
|
||||
hidden_states.shape,
|
||||
)
|
||||
return output_hidden_states
|
||||
|
||||
|
||||
class StandardDispatcher:
|
||||
def __init__(self, num_experts: int, num_local_experts: int):
|
||||
self.moe_ep_size = 1
|
||||
self.num_experts = num_experts
|
||||
self.num_local_experts = num_local_experts
|
||||
self.moe_ep_rank = 0
|
||||
self.local_expert_mapping = None
|
||||
|
||||
if self.moe_ep_size > 1:
|
||||
self.local_expert_mapping = torch.full((self.num_experts,), -1, dtype=torch.int32, device="cuda")
|
||||
self.local_expert_mapping[
|
||||
self.moe_ep_rank * self.num_local_experts : (self.moe_ep_rank + 1) * self.num_local_experts
|
||||
] = torch.arange(0, self.num_local_experts, dtype=torch.int32, device="cuda")
|
||||
|
||||
def dispatch(self, topk_ids) -> torch.Tensor:
|
||||
if self.local_expert_mapping is not None:
|
||||
return self.local_expert_mapping[topk_ids]
|
||||
return topk_ids
|
||||
|
||||
|
||||
class Qwen3MoeSparseMoeBlock(nn.Module):
|
||||
dispatcher = None
|
||||
runner = None
|
||||
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
self.num_experts = config.num_experts
|
||||
self.top_k = config.num_experts_per_tok
|
||||
self.norm_topk_prob = config.norm_topk_prob
|
||||
|
||||
# gating
|
||||
self.gate = nn.Linear(config.hidden_size, config.num_experts, bias=False)
|
||||
|
||||
self.experts = nn.ModuleList(
|
||||
[Qwen3MoeMLP(config, intermediate_size=config.moe_intermediate_size) for _ in range(self.num_experts)]
|
||||
)
|
||||
|
||||
if Qwen3MoeSparseMoeBlock.dispatcher is None:
|
||||
Qwen3MoeSparseMoeBlock.dispatcher = StandardDispatcher(
|
||||
num_experts=config.num_experts, num_local_experts=config.num_experts
|
||||
)
|
||||
|
||||
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
||||
batch_size, sequence_length, hidden_dim = hidden_states.shape
|
||||
hidden_states = hidden_states.view(-1, hidden_dim)
|
||||
# router_logits: (batch * sequence_length, n_experts)
|
||||
router_logits = self.gate(hidden_states)
|
||||
|
||||
routing_weights = F.softmax(router_logits, dim=1, dtype=torch.float)
|
||||
routing_weights, selected_experts = torch.topk(routing_weights, self.top_k, dim=-1)
|
||||
|
||||
if self.norm_topk_prob: # only diff with mixtral sparse moe block!
|
||||
routing_weights /= routing_weights.sum(dim=-1, keepdim=True)
|
||||
# we cast back to the input dtype
|
||||
routing_weights = routing_weights.to(hidden_states.dtype)
|
||||
|
||||
selected_experts = Qwen3MoeSparseMoeBlock.dispatcher.dispatch(selected_experts)
|
||||
|
||||
w13_weight = torch.stack(
|
||||
[torch.cat([layer.gate_proj.weight, layer.up_proj.weight], dim=0) for layer in self.experts]
|
||||
)
|
||||
w2_weight = torch.stack([layer.down_proj.weight for layer in self.experts], dim=0)
|
||||
|
||||
final_hidden_states = fused_experts_impl(
|
||||
hidden_states.to(torch.bfloat16),
|
||||
w13_weight,
|
||||
w2_weight,
|
||||
routing_weights,
|
||||
selected_experts,
|
||||
)
|
||||
|
||||
return final_hidden_states, router_logits
|
||||
|
||||
|
||||
def apply_true_on_policy_patch_for_qwen3_moe():
|
||||
from transformers.models.qwen3_moe import modeling_qwen3_moe
|
||||
|
||||
modeling_qwen3_moe.Qwen3MoeSparseMoeBlock = Qwen3MoeSparseMoeBlock
|
||||
46
slime/backends/fsdp_utils/models/qwen3_moe_hf.py
Normal file
46
slime/backends/fsdp_utils/models/qwen3_moe_hf.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
|
||||
|
||||
def apply_fsdp_moe_patch():
|
||||
|
||||
from transformers.models.qwen3_moe import modeling_qwen3_moe
|
||||
|
||||
def _forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
||||
batch_size, sequence_length, hidden_dim = hidden_states.shape
|
||||
hidden_states = hidden_states.view(-1, hidden_dim)
|
||||
router_logits = self.gate(hidden_states)
|
||||
|
||||
routing_weights = F.softmax(router_logits, dim=1, dtype=torch.float)
|
||||
routing_weights, selected_experts = torch.topk(routing_weights, self.top_k, dim=-1)
|
||||
if self.norm_topk_prob:
|
||||
routing_weights /= routing_weights.sum(dim=-1, keepdim=True)
|
||||
routing_weights = routing_weights.to(hidden_states.dtype)
|
||||
|
||||
final_hidden_states = torch.zeros(
|
||||
(batch_size * sequence_length, hidden_dim), dtype=hidden_states.dtype, device=hidden_states.device
|
||||
)
|
||||
|
||||
expert_mask = torch.nn.functional.one_hot(selected_experts, num_classes=self.num_experts).permute(2, 1, 0)
|
||||
|
||||
# Loop over all experts
|
||||
for expert_idx in range(self.num_experts):
|
||||
expert_layer = self.experts[expert_idx]
|
||||
idx, top_x = torch.where(expert_mask[expert_idx])
|
||||
|
||||
if top_x.numel() > 0:
|
||||
current_state = hidden_states[None, top_x].reshape(-1, hidden_dim)
|
||||
current_hidden_states = expert_layer(current_state) * routing_weights[top_x, idx, None]
|
||||
final_hidden_states.index_add_(0, top_x, current_hidden_states.to(hidden_states.dtype))
|
||||
else:
|
||||
# force experts to participate in computation graph
|
||||
dummy_output = expert_layer(hidden_states[:1]) * 0.0
|
||||
final_hidden_states[:1] = final_hidden_states[:1] + dummy_output
|
||||
|
||||
final_hidden_states = final_hidden_states.reshape(batch_size, sequence_length, hidden_dim)
|
||||
return final_hidden_states, router_logits
|
||||
|
||||
modeling_qwen3_moe.Qwen3MoeSparseMoeBlock.forward = _forward
|
||||
Reference in New Issue
Block a user