Repository navigation
SonicMoe #45433
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SonicMoe #45433
Changes from 6 commits
c82c2ef
ebf3bdc
f132b45
7dd8cd0
0a7b8c0
a8c882a
71d7e90
174a3a4
b078cb1
134cf63
a4c8934
09910a1
76abdc2
2007f78
1669103
998a8a3
30b915b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| # Copyright 2026 The HuggingFace Team. All rights reserved. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| """SonicMoE integration: fused MoE using CuteDSL kernels from `kernels-community/sonic-moe`. | ||
|
|
||
| Provides `sonicmoe_experts_forward` registered as "sonicmoe" in the ExpertsInterface. | ||
| Requirements: CUDA, `kernels`, `nvidia-cutlass-dsl`, has_gate=True, is_transposed=False. | ||
|
vasqu marked this conversation as resolved.
Resolved
|
||
| """ | ||
|
|
||
| import torch | ||
|
|
||
| from ..utils import logging | ||
| from .hub_kernels import lazy_load_kernel | ||
|
|
||
|
|
||
| logger = logging.get_logger(__name__) | ||
|
|
||
| # Map activation function names from HF config to SonicMoE epilogue names | ||
| ACT_MAP = {"silu": "swiglu", "gelu": "geglu", "relu": "reglu"} | ||
|
|
||
|
|
||
| def sonicmoe_experts_forward( | ||
| self: torch.nn.Module, | ||
| hidden_states: torch.Tensor, | ||
| top_k_index: torch.Tensor, | ||
| top_k_weights: torch.Tensor, | ||
| ) -> torch.Tensor: | ||
| if self.is_transposed: | ||
| raise ValueError("sonicmoe requires non-transposed weights (is_transposed=False)") | ||
| if not self.has_gate: | ||
| raise ValueError("sonicmoe requires gated experts (has_gate=True)") | ||
| if hidden_states.device.type != "cuda": | ||
| raise ValueError("sonicmoe requires CUDA device") | ||
|
|
||
| sonic_moe = lazy_load_kernel("sonic-moe") | ||
| moe_general_routing = getattr(sonic_moe, "moe_general_routing_inputs", None) | ||
| ActivationType = getattr(getattr(sonic_moe, "enums", None), "ActivationType", None) | ||
| if moe_general_routing is None or ActivationType is None: | ||
| raise ImportError( | ||
| "moe_general_routing_inputs function or ActivationType enum not found in kernels-community/sonic-moe. " | ||
| "Make sure you have the `kernels` package and `nvidia-cutlass-dsl` installed." | ||
| ) | ||
|
IlyasMoutawwakil marked this conversation as resolved.
Resolved
|
||
|
|
||
| device = hidden_states.device | ||
| num_experts = self.num_experts | ||
| num_top_k = top_k_index.size(-1) | ||
| num_tokens = hidden_states.size(0) | ||
| grad_enabled = torch.is_grad_enabled() | ||
| stream_id = torch.cuda.current_stream(device).cuda_stream | ||
|
|
||
| # Flatten — token_indices must be int32, sorted ascending (required by sonic-moe) | ||
| token_idx = torch.arange(num_tokens, device=device).unsqueeze(1).expand(-1, num_top_k).reshape(-1).int() | ||
| router_scores = top_k_weights.reshape(-1).to(hidden_states.dtype) | ||
| expert_ids = top_k_index.reshape(-1).int() | ||
|
|
||
| # Map activation function | ||
| act_name = getattr(self.config, "hidden_act", "silu").lower() | ||
| activation_type = getattr(ActivationType, ACT_MAP.get(act_name, "swiglu").upper(), ActivationType.SWIGLU) | ||
|
|
||
| # Permute weights to (E, H, I) as expected by sonic-moe (E=num_experts, H=hidden_size, I=intermediate_size) | ||
| w1 = self.gate_up_proj.permute(1, 2, 0) # (2*I, H, E) | ||
| w2 = self.down_proj.permute(1, 2, 0) # (I, H, E) | ||
| b1 = self.gate_up_proj_bias if self.has_bias else None | ||
| b2 = self.down_proj_bias if self.has_bias else None | ||
|
|
||
| output, _ = moe_general_routing( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just curious: Is this compatible with torch compile? My hunch says no because they seldomly register the fake types upstream without external contributions lol
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's actually not 😭 well supposedly works on torch 2.9 or smth but my tests failed because of torch dynamo issues with cuda streams Dao-AILab/sonic-moe#21
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess torch 2.12 will fix it if I followed correctly pytorch/pytorch#177610
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should i link it in a comment ? |
||
| hidden_states, | ||
| router_scores, | ||
| token_idx, | ||
| expert_ids, | ||
| w1, | ||
| b1, | ||
| w2, | ||
| b2, | ||
| E=num_experts, | ||
| stream_id=stream_id, | ||
| activation_type=activation_type, | ||
| is_inference_mode_enabled=not grad_enabled, | ||
| is_concatenated_gate_up=True, | ||
| ) | ||
|
|
||
| return output | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imo, this is so small that we can also move this under moe directly - it's essentially the one forward wrapper :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be nice to also not even have this here but on kernels!
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes it's simple now but my guess is that it might get more complicated (fp8/fp4 support for example).
i made it into a separate file to avoid what we have in finegrained_fp8 with deepgemm for example 🤔 my understanding is that we want to move deepgemm integration to a separate file as well
it's very transformers and experts impl specific (which changes from time to time), for example if we were to move it in kernels, we will have to add many more inputs in the function (has_gate, has_bias, is_transposed, is_concatenated..) which will ultimately just be moe_general_routing with the weight axis permutation baked into it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha, fair assesment, I only thought about the current version which is shortsighted
kernels should really only act as thin wrapper and we handle the specifics here imo - otherwise kernels maintainer will always have to do additional work from version change to version change (if things break)