Prhub

#27868 fix(qwen3.5): keep CUDA dual-stream overlap (regressed by #25885)

原始 PR 作者 YAMY1234 合并时间 2026-06-15 21:44 文件变更 1 提交数 5 评论 8 代码增减 +12 / -4

执行摘要

修复 #25885 引入的 CUDA dual-stream overlap 性能回退

25885 为 AMD 平台增加 alt_stream 支持,但门控条件使用 _is_hip 且未保留 _is_cuda,导致原先对 CUDA 启用的 dual-stream overlap 被静默禁用。git bisect 定位 #25885 为性能回退首次坏提交,H200 上 Qwen3.5 decode 吞吐从 434 tok/s 降至 377 tok/s(-15%)。

值得精读,尤其适合需要处理跨平台条件分支的开发者。PR 简洁地演示了如何修复因平台特定门控引入的回归,以及 Review 中建议的代码简化。

讨论亮点

Reviewer ispobock 建议将 _is_cuda 直接折叠到 flag 定义中,而不是在方法内分散使用 _is_cuda or,以提高代码简洁性。作者接受建议并更新了变量定义,同时移除了方法内显式的 _is_cuda or 检查(因为 flag 已包含该逻辑)。

实现拆解

该 PR 在 python/sglang/srt/models/qwen3_5.py 中做了两处核心修改:

  1. 将模块级别的全局标志 _gdn_use_alt_stream_qknorm_use_alt_stream 的定义从原来仅依赖环境变量与 _is_hip,改为 _is_cuda or (环境变量 and _hip_use_alt_stream)。这样在 CUDA 上这两个标志始终为 True,恢复原有行为;AMD 上仍通过环境变量控制。
  2. Qwen3_5AttentionDecoderLayer.__init__Qwen3_5DecoderLayer.__init__ 中,传递给 Qwen2MoeSparseMoeBlockalt_stream 参数判断,从 alt_stream if _disable_shared_experts_fusion() else None 改为 alt_stream if (_is_cuda or _disable_shared_experts_fusion()) else None,保证 CUDA 上始终传入 alt_stream 参数,即使 shared experts fusion 未禁用。
文件 模块 状态 重要度
python/sglang/srt/models/qwen3_5.py 模型层 modified 6.27

关键符号

Qwen3_5GatedDeltaNet._forward_input_proj Qwen3_5AttentionDecoderLayer._apply_qk_norm Qwen3_5AttentionDecoderLayer.__init__ Qwen3_5DecoderLayer.__init__

关键源码片段

python/sglang/srt/models/qwen3_5.py core-logic

唯一的修改文件,包含了全部三处逻辑变更:变量定义、MLP 参数传递、方法内条件(变量定义折叠后自动修复)。

# 在模块顶部:CUDA 上始终启用 alt_stream,AMD 上需显式设置环境变量
_gdn_use_alt_stream = _is_cuda or (
    get_bool_env_var("SGLANG_GDN_QKVZ_BA_ALT_STREAM", "False") and _hip_use_alt_stream
)
_qknorm_use_alt_stream = _is_cuda or (
    get_bool_env_var("SGLANG_QK_NORM_ALT_STREAM", "False") and _hip_use_alt_stream
)# 在 Qwen3_5AttentionDecoderLayer.__init__ 中传递 alt_stream 给共享专家模块
# 确保 CUDA 上始终使用 alt_stream,无论 shared experts fusion 是否禁用
self.mlp = Qwen2MoeSparseMoeBlock(
    ...
    alt_stream=(
        alt_stream
        if (_is_cuda or _disable_shared_experts_fusion())
        else None
    ),
    ...
)

评论区精华

将 _is_cuda 折叠到 flag 定义中简化代码 设计

Reviewer ispobock 建议在定义 _gdn_use_alt_stream 和 _qknorm_use_alt_stream 时直接包含 _is_cuda,避免方法内重复检查 `_is_cuda or`。

结论:作者采纳建议,在最新提交中将 _is_cuda 折叠到 flag 定义中,并移除了方法内的显式检查。 · 已解决

风险与影响

风险较低,因为变更仅恢复之前已存在的行为,未引入新逻辑。但需要注意:

1) 没有测试覆盖该修复,未来改动可能再次回退;
2) 如果 is_cuda() 函数判断逻辑发生变化,可能导致预期外行为;
3) 对 AMD 平台无影响(环境变量仍可控制)。

影响所有使用 Qwen3.5 模型的 CUDA 用户(如 H200、Blackwell、Ampere 等),恢复 decode 吞吐约 15%(434 vs 377 tok/s)。仅修改一个文件,影响范围明确,无 breaking change。

核心路径变更 缺少测试覆盖

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论