Fix DeepSeek V4 loading with RunAI Model Streamer. (#30240)
This commit is contained in:
@@ -119,7 +119,10 @@ from sglang.srt.model_executor.runner_backend_utils.tc_piecewise_cuda_graph impo
|
||||
get_tc_piecewise_forward_context,
|
||||
)
|
||||
from sglang.srt.model_loader.utils import maybe_executor_submit, should_async_load
|
||||
from sglang.srt.model_loader.weight_utils import default_weight_loader
|
||||
from sglang.srt.model_loader.weight_utils import (
|
||||
RUNAI_STREAMER_TENSOR_ATTR,
|
||||
default_weight_loader,
|
||||
)
|
||||
from sglang.srt.models.dbrx import ReplicatedLinear
|
||||
from sglang.srt.models.deepseek_common.amd.deepseek_v4_fused_mhc import (
|
||||
try_fused_hc_post_pre,
|
||||
@@ -2814,13 +2817,7 @@ class DeepseekV4ForCausalLM(nn.Module):
|
||||
raise ValueError("num_nextn_predict_layers is not in the config")
|
||||
|
||||
if not envs.SGLANG_OPT_FP8_WO_A_GEMM.get():
|
||||
weights = list(weights)
|
||||
exists_wo_a_scale = any(n.endswith(".wo_a.scale") for n, t in weights)
|
||||
if exists_wo_a_scale:
|
||||
logger.info("Execute dequant fp8 wo_a")
|
||||
weights = _dequant_fp8_wo_a(weights)
|
||||
else:
|
||||
logger.info("Skip dequant fp8 wo_a")
|
||||
weights = _dequant_fp8_wo_a_streaming(weights)
|
||||
|
||||
stacked_params_mapping = DEEPSEEK_V4_STACKED_PARAMS_MAPPING
|
||||
|
||||
@@ -3026,7 +3023,7 @@ class DeepseekV4ForCausalLM(nn.Module):
|
||||
if key not in cache_compressor_weight:
|
||||
cache_compressor_weight[key] = (
|
||||
is_kv,
|
||||
loaded_weight,
|
||||
_clone_if_runai_streamed_tensor(loaded_weight),
|
||||
)
|
||||
else:
|
||||
assert key in cache_compressor_weight
|
||||
@@ -3064,7 +3061,9 @@ class DeepseekV4ForCausalLM(nn.Module):
|
||||
assert (
|
||||
shard_key not in bucket
|
||||
), f"duplicate shard {shard_key} for {param_name}"
|
||||
bucket[shard_key] = loaded_weight
|
||||
bucket[shard_key] = _clone_if_runai_streamed_tensor(
|
||||
loaded_weight
|
||||
)
|
||||
if len(bucket) == 2:
|
||||
fused_weight = torch.cat(
|
||||
[bucket["q"], bucket["kv"]], dim=0
|
||||
@@ -3194,6 +3193,57 @@ def _dequant_fp8(weight: torch.Tensor, scale: torch.Tensor) -> torch.Tensor:
|
||||
return result.to(torch.bfloat16)
|
||||
|
||||
|
||||
def _clone_if_runai_streamed_tensor(tensor: torch.Tensor) -> torch.Tensor:
|
||||
if getattr(tensor, RUNAI_STREAMER_TENSOR_ATTR, False):
|
||||
return tensor.clone().detach()
|
||||
return tensor
|
||||
|
||||
|
||||
def _dequant_fp8_wo_a_streaming(
|
||||
weights: Iterable[Tuple[str, torch.Tensor]],
|
||||
) -> Iterable[Tuple[str, torch.Tensor]]:
|
||||
pending: dict[str, dict[str, torch.Tensor]] = {}
|
||||
saw_wo_a_scale = False
|
||||
emitted = False
|
||||
|
||||
for name, tensor in weights:
|
||||
if name.endswith(".wo_a.weight"):
|
||||
prefix = name[: -len(".weight")]
|
||||
bucket = pending.setdefault(prefix, {})
|
||||
scale = bucket.pop("scale", None)
|
||||
if scale is not None:
|
||||
pending.pop(prefix, None)
|
||||
emitted = True
|
||||
yield name, _dequant_fp8(tensor, scale)
|
||||
else:
|
||||
bucket["weight"] = _clone_if_runai_streamed_tensor(tensor)
|
||||
continue
|
||||
|
||||
if name.endswith(".wo_a.scale"):
|
||||
saw_wo_a_scale = True
|
||||
prefix = name[: -len(".scale")]
|
||||
bucket = pending.setdefault(prefix, {})
|
||||
weight = bucket.pop("weight", None)
|
||||
if weight is not None:
|
||||
pending.pop(prefix, None)
|
||||
emitted = True
|
||||
yield prefix + ".weight", _dequant_fp8(weight, tensor)
|
||||
else:
|
||||
bucket["scale"] = _clone_if_runai_streamed_tensor(tensor)
|
||||
continue
|
||||
|
||||
yield name, tensor
|
||||
|
||||
if emitted:
|
||||
logger.info("Finished streaming dequant fp8 wo_a")
|
||||
for prefix, bucket in pending.items():
|
||||
if "weight" in bucket:
|
||||
assert not saw_wo_a_scale, f"{prefix}.scale is missing"
|
||||
yield prefix + ".weight", bucket["weight"]
|
||||
if "scale" in bucket:
|
||||
yield prefix + ".scale", bucket["scale"]
|
||||
|
||||
|
||||
def _dequant_fp8_wo_a(
|
||||
weights: Iterable[Tuple[str, torch.Tensor]],
|
||||
) -> Iterable[Tuple[str, torch.Tensor]]:
|
||||
|
||||
@@ -30,7 +30,7 @@ from sglang.srt.models.deepseek_v4 import (
|
||||
DEEPSEEK_V4_STACKED_PARAMS_MAPPING,
|
||||
DeepseekV4DecoderLayer,
|
||||
MqaAttentionBase,
|
||||
_dequant_fp8_wo_a,
|
||||
_dequant_fp8_wo_a_streaming,
|
||||
hc_head_torch,
|
||||
make_hc_head_params,
|
||||
)
|
||||
@@ -761,9 +761,7 @@ class DeepseekV4ForCausalLMDSpark(nn.Module):
|
||||
params_dict = dict(self.named_parameters())
|
||||
loaded_params = set()
|
||||
|
||||
weights = list(weights)
|
||||
if any(name.endswith(".wo_a.scale") for name, _ in weights):
|
||||
weights = list(_dequant_fp8_wo_a(weights))
|
||||
weights = _dequant_fp8_wo_a_streaming(weights)
|
||||
|
||||
stacked_params_mapping = DEEPSEEK_V4_STACKED_PARAMS_MAPPING
|
||||
from sglang.srt.layers.moe.fused_moe_triton import FusedMoE
|
||||
|
||||
Reference in New Issue
Block a user