e93507a09c
Lockfile supply-chain audit / lockfile supply-chain audit (push) Has been cancelled
Windows Studio GGUF CI / GPU prebuilt resolves without Visual Studio (push) Has been cancelled
Windows Studio GGUF CI / setup.ps1 unit tests (VS 2026 / CMake guard) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2022) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-2025-vs2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-latest) (push) Has been cancelled
Windows Studio Update CI / Studio Updating Tests (push) Has been cancelled
Wheel CI / Wheel build + content sanity + import smoke (push) Has been cancelled
Lint CI / Source lint (Python + shell + YAML + JSON + safety nets) (push) Has been cancelled
MLX CI on Mac M1 / dispatch (push) Has been cancelled
Security audit / advisory audit (pip + npm + cargo) (push) Has been cancelled
Security audit / pip scan-packages :: extras (push) Has been cancelled
Security audit / pip scan-packages :: studio (push) Has been cancelled
Security audit / pip scan-packages :: hf-stack (push) Has been cancelled
Security audit / npm scan-packages (Studio frontend tarballs) (push) Has been cancelled
Security audit / workflow-trigger lint (pull_request_target / cache-poisoning) (push) Has been cancelled
Security audit / pytest tests/security (push) Has been cancelled
Security audit / npm provenance + new install-script diff (push) Has been cancelled
Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Backend CI / (Python 3.10) (push) Has been cancelled
Backend CI / (Python 3.11) (push) Has been cancelled
Backend CI / (Python 3.12) (push) Has been cancelled
Backend CI / (Python 3.13) (push) Has been cancelled
Backend CI / Repo tests (CPU) (push) Has been cancelled
Frontend CI / Frontend build + bundle sanity (push) Has been cancelled
Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Mac Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Mac Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-14) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15-intel) (push) Has been cancelled
Mac Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26-intel) (push) Has been cancelled
Mac Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Tauri CI / Tauri Linux debug build (no codesign) (push) Has been cancelled
Mac Studio Update CI / Studio Updating Tests (push) Has been cancelled
Studio UI CI / Chat UI Tests (push) Has been cancelled
Windows Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Windows Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Update CI / Studio Updating Tests (push) Has been cancelled
Core / Core (HF=default + TRL=default) (push) Has been cancelled
Core / Core (HF=4.57.6 + TRL<1) (push) Has been cancelled
Core / Core (HF=latest + TRL=latest) (push) Has been cancelled
Core / llama.cpp build + smoke (push) Has been cancelled
Windows Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Windows Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Windows Studio GGUF CI / JSON, images (push) Has been cancelled
Windows Studio GGUF CI / Studio install + inference without Visual Studio (push) Has been cancelled
Studio export capability / capability (macos-latest) (push) Has been cancelled
Studio export capability / capability (ubuntu-latest) (push) Has been cancelled
Studio export capability / capability (windows-latest) (push) Has been cancelled
Cross-platform parity / parity (macos-latest) (push) Has been cancelled
Cross-platform parity / parity (windows-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Studio load-orchestrator CI / test (push) Has been cancelled
157 lines
5.9 KiB
Python
157 lines
5.9 KiB
Python
# SPDX-License-Identifier: GNU Affero General Public License v3.0
|
|
# Copyright 2023-present the Unsloth team. All rights reserved.
|
|
|
|
import torch
|
|
from transformers.models.qwen3_moe.configuration_qwen3_moe import Qwen3MoeConfig
|
|
from transformers.models.qwen3_moe.modeling_qwen3_moe import Qwen3MoeSparseMoeBlock
|
|
|
|
from ..interface import grouped_gemm
|
|
from ..kernels.tuning import (
|
|
KernelConfigBackward_dW,
|
|
KernelConfigBackward_dX,
|
|
KernelConfigForward,
|
|
)
|
|
from .moe_ops import (
|
|
Qwen3MoeGroupedGEMMBlock,
|
|
permute,
|
|
unpermute,
|
|
)
|
|
|
|
"""
|
|
Reference implementation of MoE block using grouped gemm.
|
|
|
|
This is the same as the Qwen3MoeGroupedGEMMBlock but with triton grouped gemm in place of torch-native grouped gemm implementation.
|
|
|
|
NOTE: This is NOT to be used for production as it contains many extra checks and saves all intermediate results for debugging.
|
|
"""
|
|
|
|
|
|
class Qwen3MoeFusedGroupedGEMMBlock(Qwen3MoeGroupedGEMMBlock):
|
|
def __init__(
|
|
self,
|
|
config: Qwen3MoeConfig,
|
|
gate: torch.Tensor,
|
|
gate_up_proj: torch.Tensor,
|
|
down_proj: torch.Tensor,
|
|
permute_x: bool = True,
|
|
permute_y: bool = True,
|
|
autotune: bool = True,
|
|
kernel_config_fwd: KernelConfigForward = None,
|
|
kernel_config_bwd_dW: KernelConfigBackward_dW = None,
|
|
kernel_config_bwd_dX: KernelConfigBackward_dX = None,
|
|
dW_only: bool = False,
|
|
dX_only: bool = False,
|
|
):
|
|
super().__init__(config, gate, gate_up_proj, down_proj)
|
|
self.permute_x = permute_x
|
|
self.permute_y = permute_y
|
|
self.autotune = autotune
|
|
if not autotune:
|
|
assert (
|
|
kernel_config_fwd is not None
|
|
and kernel_config_bwd_dW is not None
|
|
and kernel_config_bwd_dX is not None
|
|
), "Kernel configs must be provided if autotune is False"
|
|
self.kernel_config_fwd = kernel_config_fwd
|
|
self.kernel_config_bwd_dW = kernel_config_bwd_dW
|
|
self.kernel_config_bwd_dX = kernel_config_bwd_dX
|
|
self.dW_only = dW_only
|
|
self.dX_only = dX_only
|
|
|
|
@classmethod
|
|
def from_hf(
|
|
cls,
|
|
moe_block: Qwen3MoeSparseMoeBlock,
|
|
permute_x: bool = True,
|
|
permute_y: bool = True,
|
|
autotune: bool = True,
|
|
kernel_config_fwd: KernelConfigForward = None,
|
|
kernel_config_bwd_dW: KernelConfigBackward_dW = None,
|
|
kernel_config_bwd_dX: KernelConfigBackward_dX = None,
|
|
dW_only: bool = False,
|
|
dX_only: bool = False,
|
|
):
|
|
config: Qwen3MoeConfig = moe_block.experts[0].config
|
|
gate, gate_up_proj, down_proj = Qwen3MoeGroupedGEMMBlock.extract_hf_weights(moe_block)
|
|
return cls(
|
|
config,
|
|
gate,
|
|
gate_up_proj,
|
|
down_proj,
|
|
permute_x = permute_x,
|
|
permute_y = permute_y,
|
|
autotune = autotune,
|
|
kernel_config_fwd = kernel_config_fwd,
|
|
kernel_config_bwd_dW = kernel_config_bwd_dW,
|
|
kernel_config_bwd_dX = kernel_config_bwd_dX,
|
|
dW_only = dW_only,
|
|
dX_only = dX_only,
|
|
)
|
|
|
|
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
|
batch_size, sequence_length, hidden_dim = hidden_states.shape
|
|
num_tokens = batch_size * sequence_length
|
|
total_tokens = num_tokens * self.top_k
|
|
|
|
hidden_states = hidden_states.view(-1, hidden_dim)
|
|
|
|
router_logits, routing_weights, selected_experts = self.run_router(hidden_states)
|
|
# Pre-processing
|
|
# 1. Compute tokens per expert and indices for gathering tokes from token order to expert order
|
|
# NOTE: these are auxiliary data structs which don't need to be recorded in autograd graph
|
|
token_counts_by_expert, gather_indices = self.get_token_counts_and_gather_indices(
|
|
selected_experts
|
|
)
|
|
|
|
# 2. permute_x -> permutation will be fused in prologue of first grouped gemm
|
|
if not self.permute_x:
|
|
hidden_states = permute(hidden_states, gather_indices, self.top_k)
|
|
# Start expert computation
|
|
hidden_states = grouped_gemm(
|
|
X = hidden_states,
|
|
W = self.gate_up_proj,
|
|
m_sizes = token_counts_by_expert,
|
|
gather_indices = gather_indices,
|
|
topk = self.top_k,
|
|
permute_x = self.permute_x,
|
|
permute_y = False, # output of first grouped gemm should never be permuted
|
|
autotune = self.autotune,
|
|
kernel_config_fwd = self.kernel_config_fwd,
|
|
kernel_config_bwd_dW = self.kernel_config_bwd_dW,
|
|
kernel_config_bwd_dX = self.kernel_config_bwd_dX,
|
|
is_first_gemm = True,
|
|
dW_only = self.dW_only,
|
|
dX_only = self.dX_only,
|
|
)
|
|
hidden_states = self.act_and_mul(hidden_states)
|
|
hidden_states = grouped_gemm(
|
|
X = hidden_states,
|
|
W = self.down_proj,
|
|
m_sizes = token_counts_by_expert,
|
|
gather_indices = gather_indices,
|
|
topk = self.top_k,
|
|
permute_x = False,
|
|
permute_y = self.permute_y,
|
|
autotune = self.autotune,
|
|
kernel_config_fwd = self.kernel_config_fwd,
|
|
kernel_config_bwd_dW = self.kernel_config_bwd_dW,
|
|
kernel_config_bwd_dX = self.kernel_config_bwd_dX,
|
|
is_first_gemm = False,
|
|
dW_only = self.dW_only,
|
|
dX_only = self.dX_only,
|
|
)
|
|
|
|
# Post-processing
|
|
# 1. Unpermute from expert order to token order
|
|
if not self.permute_y:
|
|
hidden_states = unpermute(hidden_states, gather_indices)
|
|
|
|
# 2. Merge topk weights
|
|
hidden_states = (
|
|
hidden_states.view(num_tokens, self.top_k, hidden_dim) * routing_weights[..., None]
|
|
)
|
|
hidden_states = hidden_states.sum(dim = 1)
|
|
|
|
hidden_states = hidden_states.view(batch_size, sequence_length, hidden_dim)
|
|
return hidden_states, router_logits
|