Files
wehub-resource-sync 94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:38:16 +08:00

519 lines
19 KiB
Python

from __future__ import annotations
import torch
from sglang.srt.layers.quantization.marlin_utils import (
USE_FP32_REDUCE_DEFAULT,
marlin_make_workspace,
marlin_permute_bias,
marlin_permute_scales,
should_use_atomic_add_reduce,
)
from sglang.srt.layers.quantization.utils import get_scalar_types
from sglang.srt.utils import is_cuda
from sglang.srt.utils.custom_op import register_custom_op
_is_cuda = is_cuda()
if _is_cuda:
from sglang.jit_kernel.gptq_marlin import gptq_marlin_gemm
from sglang.jit_kernel.gptq_marlin_repack import gptq_marlin_repack
ScalarType, scalar_types = get_scalar_types()
def nvfp4_marlin_process_scales(marlin_scales: torch.Tensor) -> torch.Tensor:
if not (marlin_scales >= 0).all():
# NVFP4 ModelOpt scales are expected to be non-negative. Keep this as
# a warning so unusual checkpoints can still load for diagnosis.
import logging
logging.getLogger(__name__).warning_once(
"NVFP4 Marlin assumes non-negative scales, but negative scales "
"were found. Accuracy may be degraded."
)
marlin_scales = marlin_scales.to(torch.half)
marlin_scales = marlin_scales.view(-1, 4)[:, [0, 2, 1, 3]].view(
marlin_scales.size(0), -1
)
marlin_scales = (marlin_scales * (2**7)).view(torch.int16) << 1
marlin_scales = marlin_scales.view(torch.float8_e4m3fn)
return marlin_scales[:, 1::2].contiguous()
def nvfp4_marlin_process_global_scale(global_scale: torch.Tensor) -> torch.Tensor:
assert global_scale.dtype in [torch.half, torch.bfloat16]
global_scale_shape = global_scale.shape
fp4_exponent = 2
if global_scale.dtype == torch.half:
target_exponent = 5
elif global_scale.dtype == torch.bfloat16:
target_exponent = 8
exponent_bias = 2 ** (target_exponent - 1) - 2 ** (fp4_exponent - 1)
global_scale = global_scale * (2.0 ** (exponent_bias - 7))
if global_scale_shape == torch.Size([]):
global_scale = global_scale.reshape(1)
return global_scale
def fake_apply_fp4_marlin_linear(
input: torch.Tensor,
weight: torch.Tensor,
weight_scale: torch.Tensor,
weight_global_scale: torch.Tensor,
workspace: torch.Tensor,
size_n: int,
size_k: int,
bias: torch.Tensor | None = None,
use_fp32_reduce: bool = USE_FP32_REDUCE_DEFAULT,
) -> torch.Tensor:
del weight, weight_scale, weight_global_scale, workspace, size_k, bias
out_shape = input.shape[:-1] + (size_n,)
return input.new_empty(out_shape)
@register_custom_op(fake_impl=fake_apply_fp4_marlin_linear)
def apply_fp4_marlin_linear(
input: torch.Tensor,
weight: torch.Tensor,
weight_scale: torch.Tensor,
weight_global_scale: torch.Tensor,
workspace: torch.Tensor,
size_n: int,
size_k: int,
bias: torch.Tensor | None = None,
use_fp32_reduce: bool = USE_FP32_REDUCE_DEFAULT,
) -> torch.Tensor:
if input.dtype not in (torch.float16, torch.bfloat16):
raise RuntimeError("NVFP4 Marlin requires FP16 or BF16 activations.")
reshaped_x = input.reshape(-1, input.shape[-1])
out_shape = input.shape[:-1] + (size_n,)
use_atomic_add = should_use_atomic_add_reduce(
m=reshaped_x.size(0),
n=size_n,
k=size_k,
device=input.device,
dtype=input.dtype,
)
output = gptq_marlin_gemm(
a=reshaped_x,
c=None,
b_q_weight=weight,
b_scales=weight_scale,
global_scale=weight_global_scale,
b_zeros=None,
g_idx=None,
perm=None,
workspace=workspace,
b_q_type=scalar_types.float4_e2m1f,
size_m=reshaped_x.size(0),
size_n=size_n,
size_k=size_k,
is_k_full=True,
use_atomic_add=use_atomic_add,
use_fp32_reduce=use_fp32_reduce,
)
if bias is not None:
output.add_(bias)
return output.reshape(out_shape)
def prepare_nvfp4_layer_for_marlin(layer: torch.nn.Module) -> None:
if getattr(layer, "quant_config", None) is not None:
group_size = layer.quant_config.group_size
if group_size != 16:
raise ValueError(f"NVFP4 Marlin requires group_size=16, got {group_size}.")
part_size_n = layer.output_size_per_partition
part_size_k = layer.input_size_per_partition
param_dtype = getattr(layer, "params_dtype", getattr(layer, "orig_dtype", None))
if param_dtype not in (torch.float16, torch.bfloat16):
raise RuntimeError("NVFP4 Marlin requires FP16 or BF16 activation dtype.")
assert layer.weight.shape == (part_size_n, part_size_k // 2)
if part_size_n % 64 != 0:
raise ValueError(
f"NVFP4 Marlin requires output_size_per_partition to be a multiple of 64, "
f"got {part_size_n}."
)
device = layer.weight.device
layer.workspace = marlin_make_workspace(device)
perm = torch.empty(0, dtype=torch.int, device=device)
qweight = layer.weight.view(torch.int32).T.contiguous()
marlin_qweight = gptq_marlin_repack(
b_q_weight=qweight,
perm=perm,
size_k=part_size_k,
size_n=part_size_n,
num_bits=4,
)
layer.weight = torch.nn.Parameter(marlin_qweight, requires_grad=False)
weight_scale = layer.weight_scale.T.contiguous().to(param_dtype)
weight_scale = marlin_permute_scales(
s=weight_scale,
size_k=part_size_k,
size_n=part_size_n,
group_size=16,
)
weight_scale = nvfp4_marlin_process_scales(weight_scale)
layer.weight_scale = torch.nn.Parameter(weight_scale, requires_grad=False)
weight_global_scale = layer.weight_global_scale.to(param_dtype)
weight_global_scale = nvfp4_marlin_process_global_scale(weight_global_scale)
layer.weight_global_scale = torch.nn.Parameter(
weight_global_scale, requires_grad=False
)
if hasattr(layer, "bias") and layer.bias is not None:
assert layer.bias.shape == (part_size_n,)
bias = marlin_permute_bias(layer.bias)
layer.bias = torch.nn.Parameter(bias, requires_grad=False)
def mxfp4_marlin_process_scales(
marlin_scales: torch.Tensor,
input_dtype: torch.dtype | None = None,
) -> torch.Tensor:
if input_dtype is None or input_dtype.itemsize == 2:
marlin_scales = marlin_scales.view(-1, 4)[:, [0, 2, 1, 3]].view(
marlin_scales.size(0), -1
)
marlin_scales = marlin_scales.to(torch.float8_e8m0fnu)
if input_dtype == torch.float8_e4m3fn:
marlin_scales = marlin_scales.view(torch.uint8)
assert marlin_scales.max() <= 249
# exponent_bias (fp4->fp8) = 2 ** 3 - 2 ** 1 = 6
marlin_scales = marlin_scales + 6
marlin_scales = marlin_scales.view(torch.float8_e8m0fnu)
return marlin_scales
def _normalize_scale_tensor(
scales: torch.Tensor, target_dtype: torch.dtype
) -> torch.Tensor:
# The kernel consumes E8M0 exponents. Regardless of the placeholder dtype
# the loader used, we want the *numerical* value 2**e in ``target_dtype``.
# float32/bfloat16/float16 containers hold the numerical 2**e directly
# (they were filled via a dtype-promoting copy from uint8/e8m0).
# uint8/int8 containers hold the raw E8M0 byte and must be reinterpreted.
if scales.dtype == torch.float8_e8m0fnu:
return scales.to(target_dtype)
if scales.dtype == torch.uint8:
return scales.view(torch.float8_e8m0fnu).to(target_dtype)
if scales.dtype == torch.int8:
return scales.view(torch.uint8).view(torch.float8_e8m0fnu).to(target_dtype)
if scales.dtype in (torch.float32, torch.bfloat16, torch.float16):
return scales.to(target_dtype)
raise TypeError(f"Unsupported MXFP4 scale dtype for Marlin: {scales.dtype}")
def _get_optional_param(layer: torch.nn.Module, *names: str) -> torch.Tensor | None:
for name in names:
value = getattr(layer, name, None)
if value is not None:
return value
return None
def deinterleave_moe_mxfp4_w13_for_marlin(layer: torch.nn.Module) -> None:
"""Convert GPT-OSS interleaved w13 rows to Marlin's contiguous halves.
GPT-OSS stores gate/up rows as [gate0, up0, gate1, up1, ...]. The Marlin
fused activation consumes [all_gate_rows, all_up_rows].
"""
w13 = layer.w13_weight.data
w13_scale = _get_optional_param(layer, "w13_weight_scale", "w13_weight_scale_inv")
w13_bias = _get_optional_param(layer, "w13_weight_bias", "w13_bias")
if w13.shape[1] % 2 != 0:
raise ValueError(f"Expected even w13 row dimension, got {w13.shape}.")
e, n, k = w13.shape
layer.w13_weight.data = (
w13.view(e, n // 2, 2, k).permute(0, 2, 1, 3).contiguous().view(e, n, k)
)
if w13_scale is not None:
scale = w13_scale.data
if scale.shape[1] != n:
raise ValueError(
f"Expected w13 scale row dimension {n}, got {scale.shape}."
)
w13_scale.data = (
scale.view(e, n // 2, 2, scale.shape[-1])
.permute(0, 2, 1, 3)
.contiguous()
.view(e, n, scale.shape[-1])
)
if w13_bias is not None:
bias = w13_bias.data
if bias.shape[1] != n:
raise ValueError(f"Expected w13 bias row dimension {n}, got {bias.shape}.")
w13_bias.data = bias.view(e, n // 2, 2).permute(0, 2, 1).contiguous().view(e, n)
def prepare_moe_mxfp4_layer_for_marlin(layer: torch.nn.Module) -> None:
group_size = 32
w13 = layer.w13_weight.data
w2 = layer.w2_weight.data
w13_scale = _get_optional_param(layer, "w13_weight_scale", "w13_weight_scale_inv")
w2_scale = _get_optional_param(layer, "w2_weight_scale", "w2_weight_scale_inv")
w13_bias = _get_optional_param(layer, "w13_weight_bias", "w13_bias")
w2_bias = _get_optional_param(layer, "w2_weight_bias", "w2_bias")
if w13_scale is None or w2_scale is None:
raise ValueError("MXFP4 Marlin requires w13/w2 weight scales.")
w13_scale_data = w13_scale.data if hasattr(w13_scale, "data") else w13_scale
w2_scale_data = w2_scale.data if hasattr(w2_scale, "data") else w2_scale
w13_bias_data = w13_bias.data if hasattr(w13_bias, "data") else w13_bias
w2_bias_data = w2_bias.data if hasattr(w2_bias, "data") else w2_bias
num_experts = w13.shape[0]
intermediate_size = w13.shape[1] // 2
hidden_size = w13.shape[2] * 2
if hidden_size % 128 == 0:
padded_intermediate_size = ((intermediate_size + 63) // 64) * 64
else:
if hidden_size % 64 != 0:
raise ValueError(
f"MXFP4 Marlin requires hidden_size to be divisible by 64, "
f"got {hidden_size}."
)
padded_intermediate_size = ((intermediate_size + 127) // 128) * 128
param_dtype = getattr(
layer,
"orig_dtype",
w13_bias_data.dtype if w13_bias_data is not None else torch.bfloat16,
)
device = w13.device
layer.workspace = marlin_make_workspace(device, 4)
perm = torch.empty(0, dtype=torch.int, device=device)
def _pad_w13(x: torch.Tensor) -> torch.Tensor:
if padded_intermediate_size == intermediate_size:
return x
x = x.view(num_experts, 2, intermediate_size, x.shape[-1])
x = torch.nn.functional.pad(
x, (0, 0, 0, padded_intermediate_size - intermediate_size)
)
return x.reshape(num_experts, 2 * padded_intermediate_size, -1)
def _pad_w2(x: torch.Tensor, packing: int) -> torch.Tensor:
if padded_intermediate_size == intermediate_size:
return x
return torch.nn.functional.pad(
x, (0, (padded_intermediate_size - intermediate_size) // packing)
)
w13 = _pad_w13(w13)
w2 = _pad_w2(w2, packing=2)
w13_scale_data = _pad_w13(_normalize_scale_tensor(w13_scale_data, param_dtype))
w2_scale_data = _pad_w2(
_normalize_scale_tensor(w2_scale_data, param_dtype),
packing=group_size,
)
if w13_bias_data is not None:
w13_bias_data = _pad_w13(w13_bias_data.unsqueeze(-1)).squeeze(-1)
def _repack_weight(weight: torch.Tensor, is_w13: bool) -> torch.Tensor:
if is_w13:
size_n, size_k = padded_intermediate_size * 2, hidden_size
else:
size_n, size_k = hidden_size, padded_intermediate_size
assert weight.shape == (num_experts, size_n, size_k // 2)
tensor_list = []
for i in range(num_experts):
qweight = weight[i].view(torch.int32).T.contiguous()
marlin_qweight = gptq_marlin_repack(
b_q_weight=qweight,
perm=perm,
size_k=size_k,
size_n=size_n,
num_bits=4,
)
tensor_list.append(marlin_qweight)
return torch.stack(tensor_list)
def _permute_scales(scales: torch.Tensor, is_w13: bool) -> torch.Tensor:
if is_w13:
size_n, size_k = padded_intermediate_size * 2, hidden_size
else:
size_n, size_k = hidden_size, padded_intermediate_size
tensor_list = []
for i in range(num_experts):
scale = scales[i].T.contiguous()
marlin_scales = marlin_permute_scales(
s=scale,
size_k=size_k,
size_n=size_n,
group_size=group_size,
)
tensor_list.append(
mxfp4_marlin_process_scales(
marlin_scales,
input_dtype=param_dtype,
)
)
return torch.stack(tensor_list)
def _permute_bias(bias: torch.Tensor | None) -> torch.Tensor | None:
if bias is None:
return None
tensor_list = []
for i in range(num_experts):
tensor_list.append(marlin_permute_bias(bias[i].to(param_dtype)))
return torch.stack(tensor_list)
w13_marlin = _repack_weight(w13, True)
w2_marlin = _repack_weight(w2, False)
w13_scale_marlin = _permute_scales(w13_scale_data, True)
w2_scale_marlin = _permute_scales(w2_scale_data, False)
layer.w13_weight = torch.nn.Parameter(w13_marlin, requires_grad=False)
layer.w2_weight = torch.nn.Parameter(w2_marlin, requires_grad=False)
layer.w13_weight_scale = torch.nn.Parameter(w13_scale_marlin, requires_grad=False)
layer.w2_weight_scale = torch.nn.Parameter(w2_scale_marlin, requires_grad=False)
if w13_bias_data is not None:
layer.w13_weight_bias = torch.nn.Parameter(
_permute_bias(w13_bias_data), requires_grad=False
)
if w2_bias_data is not None:
layer.w2_weight_bias = torch.nn.Parameter(
_permute_bias(w2_bias_data), requires_grad=False
)
def prepare_moe_nvfp4_layer_for_marlin(layer: torch.nn.Module) -> None:
if layer.quant_config.group_size != 16:
raise ValueError(
f"NVFP4 Marlin MoE requires group_size=16, got {layer.quant_config.group_size}."
)
w13 = layer.w13_weight.data
w2 = layer.w2_weight.data
w13_scale = layer.w13_weight_scale.data
w2_scale = layer.w2_weight_scale.data
w13_global_scale = layer.w13_weight_scale_2.data
w2_global_scale = layer.w2_weight_scale_2.data
w13_bias = getattr(layer, "w13_bias", None)
w2_bias = getattr(layer, "w2_bias", None)
num_experts = w13.shape[0]
num_shards = 2 if layer.moe_runner_config.is_gated else 1
intermediate_size = layer.intermediate_size_per_partition
hidden_size = w13.shape[2] * 2
param_dtype = layer.params_dtype
if param_dtype not in (torch.float16, torch.bfloat16):
raise RuntimeError("NVFP4 Marlin MoE requires FP16 or BF16 activations.")
device = w13.device
layer.workspace = marlin_make_workspace(device, 4)
perm = torch.empty(0, dtype=torch.int, device=device)
if not layer.moe_runner_config.is_gated:
padded_intermediate_size = ((intermediate_size + 127) // 128) * 128
intermediate_size_pad = padded_intermediate_size - intermediate_size
if intermediate_size_pad:
w13 = torch.nn.functional.pad(w13, (0, 0, 0, intermediate_size_pad))
w13_scale = torch.nn.functional.pad(
w13_scale, (0, 0, 0, intermediate_size_pad)
)
w2 = torch.nn.functional.pad(w2, (0, intermediate_size_pad // 2, 0, 0))
w2_scale = torch.nn.functional.pad(
w2_scale, (0, intermediate_size_pad // 16)
)
if w13_bias is not None:
w13_bias = torch.nn.functional.pad(w13_bias, (0, intermediate_size_pad))
intermediate_size = padded_intermediate_size
def _repack_weight(weight: torch.Tensor, is_w13: bool) -> torch.Tensor:
if is_w13:
size_n, size_k = intermediate_size * num_shards, hidden_size
else:
size_n, size_k = hidden_size, intermediate_size
assert weight.shape == (num_experts, size_n, size_k // 2)
tensor_list = []
for i in range(num_experts):
qweight = weight[i].view(torch.int32).T.contiguous()
marlin_qweight = gptq_marlin_repack(
b_q_weight=qweight,
perm=perm,
size_k=size_k,
size_n=size_n,
num_bits=4,
)
tensor_list.append(marlin_qweight)
return torch.stack(tensor_list)
def _permute_scales(scales: torch.Tensor, is_w13: bool) -> torch.Tensor:
scales = scales.to(param_dtype)
if is_w13:
size_n, size_k = intermediate_size * num_shards, hidden_size
else:
size_n, size_k = hidden_size, intermediate_size
tensor_list = []
for i in range(num_experts):
scale = scales[i].T.contiguous()
marlin_scales = marlin_permute_scales(
s=scale,
size_k=size_k,
size_n=size_n,
group_size=16,
)
tensor_list.append(nvfp4_marlin_process_scales(marlin_scales))
return torch.stack(tensor_list)
def _process_global_scale(global_scale: torch.Tensor) -> torch.Tensor:
return nvfp4_marlin_process_global_scale(global_scale.to(param_dtype))
def _permute_bias(bias: torch.Tensor | None) -> torch.Tensor | None:
if bias is None:
return None
tensor_list = []
for i in range(num_experts):
tensor_list.append(marlin_permute_bias(bias[i].to(param_dtype)))
return torch.stack(tensor_list)
layer.w13_weight = torch.nn.Parameter(
_repack_weight(w13, True), requires_grad=False
)
layer.w2_weight = torch.nn.Parameter(_repack_weight(w2, False), requires_grad=False)
layer.w13_weight_scale = torch.nn.Parameter(
_permute_scales(w13_scale, True), requires_grad=False
)
layer.w2_weight_scale = torch.nn.Parameter(
_permute_scales(w2_scale, False), requires_grad=False
)
layer.w13_weight_scale_2 = torch.nn.Parameter(
_process_global_scale(w13_global_scale), requires_grad=False
)
layer.w2_weight_scale_2 = torch.nn.Parameter(
_process_global_scale(w2_global_scale), requires_grad=False
)
if w13_bias is not None:
layer.w13_bias = torch.nn.Parameter(
_permute_bias(w13_bias), requires_grad=False
)
if w2_bias is not None:
layer.w2_bias = torch.nn.Parameter(_permute_bias(w2_bias), requires_grad=False)