perf: overlap Qwen shared expert with DeepEP routed experts (#34938)

This commit is contained in:
YAMY
2026-08-21 15:39:44 -07:00
committed by GitHub
parent 7d893255c3
commit 834400705f
3 changed files with 28 additions and 0 deletions
@@ -331,6 +331,11 @@ SGLang supports various environment variables that can be used to configure its
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Run shared experts on an alternate stream when single batch overlap is enabled on GB200. When not setting this flag, shared experts and down gemm will be overlapped with DeepEP combine together.</td> <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Run shared experts on an alternate stream when single batch overlap is enabled on GB200. When not setting this flag, shared experts and down gemm will be overlapped with DeepEP combine together.</td>
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>`"false"`</td> <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>`"false"`</td>
</tr> </tr>
<tr>
<td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}>`SGLANG_ENABLE_QWEN_DEEPEP_SHARED_OVERLAP`</td>
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Run the Qwen shared expert on an alternate CUDA stream while DeepEP executes the routed experts.</td>
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>`"true"`</td>
</tr>
<tr> <tr>
<td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}><code>SGLANG_DISABLED_MODEL_ARCHS</code></td> <td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}><code>SGLANG_DISABLED_MODEL_ARCHS</code></td>
<td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Comma-separated list of model architectures to disable from auto-registration.</td> <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Comma-separated list of model architectures to disable from auto-registration.</td>
+1
View File
@@ -1028,6 +1028,7 @@ class Envs:
SGLANG_DEEPEP_NUM_MAX_DISPATCH_TOKENS_PER_RANK = EnvInt(128) SGLANG_DEEPEP_NUM_MAX_DISPATCH_TOKENS_PER_RANK = EnvInt(128)
SGLANG_DEEPEP_LL_COMBINE_SEND_NUM_SMS = EnvInt(32) SGLANG_DEEPEP_LL_COMBINE_SEND_NUM_SMS = EnvInt(32)
SGLANG_BLACKWELL_OVERLAP_SHARED_EXPERTS_OUTSIDE_SBO = EnvBool(False) SGLANG_BLACKWELL_OVERLAP_SHARED_EXPERTS_OUTSIDE_SBO = EnvBool(False)
SGLANG_ENABLE_QWEN_DEEPEP_SHARED_OVERLAP = EnvBool(True)
# Force dynamic Waterfill with runtime EP all-reduce instead of the default # Force dynamic Waterfill with runtime EP all-reduce instead of the default
# static local-batch path. # static local-batch path.
SGLANG_DISABLE_STATIC_WATERFILL = EnvBool(False) SGLANG_DISABLE_STATIC_WATERFILL = EnvBool(False)
+22
View File
@@ -91,6 +91,9 @@ from sglang.srt.model_executor.cuda_graph_config import (
) )
from sglang.srt.model_executor.forward_batch_info import ForwardBatch, PPProxyTensors from sglang.srt.model_executor.forward_batch_info import ForwardBatch, PPProxyTensors
from sglang.srt.model_executor.runner import get_is_capture_mode from sglang.srt.model_executor.runner import get_is_capture_mode
from sglang.srt.model_executor.runner_backend_utils.breakable_cuda_graph.context import (
is_in_breakable_cuda_graph,
)
from sglang.srt.model_loader.weight_utils import default_weight_loader from sglang.srt.model_loader.weight_utils import default_weight_loader
from sglang.srt.runtime_context import get_exec, get_forward, get_parallel from sglang.srt.runtime_context import get_exec, get_forward, get_parallel
from sglang.srt.utils import ( from sglang.srt.utils import (
@@ -533,6 +536,16 @@ class Qwen2MoeSparseMoeBlock(nn.Module):
and envs.SGLANG_NPU_USE_MULTI_STREAM.get() and envs.SGLANG_NPU_USE_MULTI_STREAM.get()
and forward_batch.forward_mode.is_cuda_graph() and forward_batch.forward_mode.is_cuda_graph()
) )
enable_cuda_shared_overlap = (
_is_cuda
and envs.SGLANG_ENABLE_QWEN_DEEPEP_SHARED_OVERLAP.get()
# Breakable CUDA graph joins side streams before the eager DeepEP
# break, so this path cannot overlap the two expert computations.
and not is_in_breakable_cuda_graph()
and self.alt_stream is not None
and self.shared_expert is not None
and hidden_states.shape[0] > 0
)
shared_output = None shared_output = None
if hidden_states.shape[0] > 0: if hidden_states.shape[0] > 0:
# router_logits: (num_tokens, n_experts) # router_logits: (num_tokens, n_experts)
@@ -541,6 +554,13 @@ class Qwen2MoeSparseMoeBlock(nn.Module):
shared_output = shared_expert_on_independent_stream( shared_output = shared_expert_on_independent_stream(
hidden_states.clone(), self._forward_shared_experts hidden_states.clone(), self._forward_shared_experts
) )
elif enable_cuda_shared_overlap:
current_stream = torch.cuda.current_stream()
self.alt_stream.wait_stream(current_stream)
with torch.cuda.stream(self.alt_stream):
shared_output = self._forward_shared_experts(hidden_states)
shared_output.record_stream(self.alt_stream)
shared_event = self.alt_stream.record_event()
else: else:
shared_output = self._forward_shared_experts(hidden_states) shared_output = self._forward_shared_experts(hidden_states)
topk_output = self.topk( topk_output = self.topk(
@@ -563,6 +583,8 @@ class Qwen2MoeSparseMoeBlock(nn.Module):
) )
if enable_dual_stream: if enable_dual_stream:
wait_share_stream() wait_share_stream()
elif enable_cuda_shared_overlap:
torch.cuda.current_stream().wait_event(shared_event)
if shared_output is not None: if shared_output is not None:
final_hidden_states.add_(shared_output) final_hidden_states.add_(shared_output)