164 lines
5.3 KiB
Python
164 lines
5.3 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
|
|
|
from abc import abstractmethod
|
|
|
|
import torch
|
|
|
|
import vllm.model_executor.layers.fused_moe.modular_kernel as mk
|
|
from vllm.model_executor.layers.fused_moe import (
|
|
FusedMoEMethodBase,
|
|
RoutedExperts,
|
|
SharedExperts,
|
|
)
|
|
from vllm.model_executor.model_loader.reload.layerwise import (
|
|
initialize_online_processing,
|
|
)
|
|
from vllm.model_executor.utils import set_weight_attrs
|
|
|
|
|
|
class OnlineMoEMethodBase(FusedMoEMethodBase):
|
|
"""Base for MoE methods that load full-precision weights on meta device
|
|
and quantize them after loading via the QeRL layerwise processing system.
|
|
"""
|
|
|
|
uses_meta_device: bool = True
|
|
|
|
def create_weights(
|
|
self,
|
|
layer: torch.nn.Module,
|
|
num_experts: int,
|
|
hidden_size: int,
|
|
intermediate_size_per_partition: int,
|
|
params_dtype: torch.dtype,
|
|
**extra_weight_attrs,
|
|
):
|
|
layer.num_experts = num_experts
|
|
layer.orig_dtype = params_dtype
|
|
layer.weight_block_size = None
|
|
|
|
# Fused gate_up_proj (column parallel) — full precision on meta device
|
|
w13_weight = torch.nn.Parameter(
|
|
torch.empty(
|
|
num_experts,
|
|
2 * intermediate_size_per_partition,
|
|
hidden_size,
|
|
device="meta",
|
|
dtype=params_dtype,
|
|
),
|
|
requires_grad=False,
|
|
)
|
|
layer.register_parameter("w13_weight", w13_weight)
|
|
set_weight_attrs(w13_weight, extra_weight_attrs)
|
|
|
|
# down_proj (row parallel) — full precision on meta device
|
|
w2_weight = torch.nn.Parameter(
|
|
torch.empty(
|
|
num_experts,
|
|
hidden_size,
|
|
intermediate_size_per_partition,
|
|
device="meta",
|
|
dtype=params_dtype,
|
|
),
|
|
requires_grad=False,
|
|
)
|
|
layer.register_parameter("w2_weight", w2_weight)
|
|
set_weight_attrs(w2_weight, extra_weight_attrs)
|
|
|
|
# BIASES (for models like GPT-OSS that have biased MoE)
|
|
if self.moe.has_bias:
|
|
w13_bias = torch.nn.Parameter(
|
|
torch.zeros(
|
|
num_experts,
|
|
2 * intermediate_size_per_partition,
|
|
device="meta",
|
|
dtype=layer.orig_dtype,
|
|
),
|
|
requires_grad=False,
|
|
)
|
|
layer.register_parameter("w13_bias", w13_bias)
|
|
set_weight_attrs(w13_bias, extra_weight_attrs)
|
|
|
|
w2_bias = torch.nn.Parameter(
|
|
torch.zeros(
|
|
num_experts,
|
|
hidden_size,
|
|
device="meta",
|
|
dtype=layer.orig_dtype,
|
|
),
|
|
requires_grad=False,
|
|
)
|
|
layer.register_parameter("w2_bias", w2_bias)
|
|
set_weight_attrs(w2_bias, extra_weight_attrs)
|
|
|
|
layer.w13_input_scale = None
|
|
layer.w2_input_scale = None
|
|
|
|
initialize_online_processing(layer)
|
|
|
|
@abstractmethod
|
|
def process_weights_after_loading(self, layer: torch.nn.Module) -> None:
|
|
pass
|
|
|
|
def maybe_make_prepare_finalize(
|
|
self,
|
|
routing_tables: tuple[torch.Tensor, torch.Tensor, torch.Tensor] | None = None,
|
|
) -> mk.FusedMoEPrepareAndFinalizeModular | None:
|
|
raise ValueError(
|
|
f"{self.__class__.__name__} uses the new modular kernel "
|
|
"initialization logic. This function should not be called."
|
|
)
|
|
|
|
@property
|
|
def supports_eplb(self) -> bool:
|
|
return True
|
|
|
|
def apply_monolithic(
|
|
self,
|
|
layer: RoutedExperts,
|
|
x: torch.Tensor,
|
|
router_logits: torch.Tensor,
|
|
input_ids: torch.Tensor | None = None,
|
|
) -> torch.Tensor:
|
|
assert self.is_monolithic
|
|
assert self.moe_kernel is not None
|
|
return self.moe_kernel.apply_monolithic(
|
|
x,
|
|
layer.w13_weight,
|
|
layer.w2_weight,
|
|
router_logits,
|
|
activation=layer.activation,
|
|
global_num_experts=layer.global_num_experts,
|
|
expert_map=layer.expert_map,
|
|
apply_router_weight_on_input=layer.apply_router_weight_on_input,
|
|
num_expert_group=layer.num_expert_group,
|
|
topk_group=layer.topk_group,
|
|
e_score_correction_bias=layer.e_score_correction_bias,
|
|
routed_scaling_factor=layer.routed_scaling_factor,
|
|
)
|
|
|
|
def apply(
|
|
self,
|
|
layer: RoutedExperts,
|
|
x: torch.Tensor,
|
|
topk_weights: torch.Tensor,
|
|
topk_ids: torch.Tensor,
|
|
shared_experts: SharedExperts | None,
|
|
shared_experts_input: torch.Tensor | None,
|
|
) -> torch.Tensor:
|
|
assert not self.is_monolithic
|
|
assert self.moe_kernel is not None
|
|
return self.moe_kernel.apply(
|
|
x,
|
|
layer.w13_weight,
|
|
layer.w2_weight,
|
|
topk_weights,
|
|
topk_ids,
|
|
activation=layer.activation,
|
|
global_num_experts=layer.global_num_experts,
|
|
expert_map=layer.expert_map,
|
|
apply_router_weight_on_input=layer.apply_router_weight_on_input,
|
|
shared_experts=shared_experts,
|
|
shared_experts_input=shared_experts_input,
|
|
)
|