Prhub

#19329 Bugfix: fix symm not enabled due to incorrect registration of comm

原始 PR 作者 wangfakang 合并时间 2026-05-13 10:01 文件变更 4 提交数 14 评论 15 代码增减 +24 / -15

执行摘要

修复对称内存因通信组不一致未启用

PR body 明确指出:get_local_dp_buffer 默认使用 get_tp_group() 注册对称内存,但 attn_cp_all_gather_into_tensor 使用 get_attention_cp_group 执行 allgather,导致 symm 因组不一致而无法启用。此 PR 通过暴露通信组参数来保证注册操作与后续集合通信使用同一组。

建议阅读此 PR,尤其是讨论线程中关于强制参数 vs 可选默认值的设计决策,反映了对关键通信组一致性的严格态度。同时,提醒关注 nvcastet 指出的内存池复用问题,并检查是否已在后续 PR 中修复。对于需要多组通信的场景,建议在合并此 PR 后验证 symm 是否真正生效。

讨论亮点
  • 默认参数 vs 显式参数:ShangmingCai 建议使用 Optional[GroupCoordinator] = None 并兼容旧版。wangfakang 回应:“使用默认值容易导致组不一致”,坚持显式传入。最终采用强制参数,体现对关键通信组一致性的严格设计。
  • 内存池复用问题:nvcastet 指出即使传入正确组,若内存池已有 inactive memory,返回的 block 可能仍是之前注册的旧组,导致 symm 仍可能不生效。wangfakang 认为这是独立问题,先合并此 PR。nvcastet 最终批准但强调需后续修复。

实现拆解

  1. 核心函数签名变更dp_attention.py):将 get_global_dp_bufferget_local_dp_buffer 的签名从无参改为接收 group: GroupCoordinator 参数,在类方法中将 use_symmetric_memory 的上下文组从硬编码的 get_tp_group() 替换为传入的 group
  2. 调用点适配communicator.py):在 _scattered_to_tp_attn_full_gather_hidden_states_and_residual_scatter_hidden_states_gather 等方法中,根据语义传入正确的通信组(如 get_attention_tp_group()get_tp_group()),并新增 get_attention_tp_group 的导入。
  3. NSA CP 路径适配communicator_nsa_cp.py):在 _gather_hidden_states_and_residual 中调用 get_local_dp_buffer(get_attention_cp_group()),确保 NSA 上下文预填充时使用正确的并行组。
  4. MoE Token Dispatcher 适配standard.py):在 combine 方法中,将 get_local_dp_buffer() 改为 get_local_dp_buffer(get_tp_group()),与后续 reduce_scatterv 使用的组对齐。
  5. 动态组选择communicator.py _scatter_hidden_states):根据 tp_world_size 是否等于 attention_dp_size 动态决定使用 get_tp_group() 还是 get_attention_tp_group(),以兼容不同并行配置。
文件 模块 状态 重要度
python/sglang/srt/layers/dp_attention.py DP 缓冲 modified 6.52
python/sglang/srt/layers/communicator.py 层通信器 modified 6.07
python/sglang/srt/layers/communicator_nsa_cp.py NSA 通信 modified 4.7
python/sglang/srt/layers/moe/token_dispatcher/standard.py 专家分发 modified 4.92

关键符号

get_global_dp_buffer get_local_dp_buffer

关键源码片段

python/sglang/srt/layers/dp_attention.py core-logic

核心函数 get_global_dp_buffer 和 get_local_dp_buffer 签名变更,添加 group 参数使注册组与操作组一致

    @classmethod
    def get_local_dp_buffer(cls, group: GroupCoordinator) -> torch.Tensor:
        # 修复前:使用 get_tp_group() 导致与通信组不一致
        # 修复后:使用传入的 group 确保与后续操作组匹配
        with use_symmetric_memory(group, disabled=not cls._dp_max_padding):
            buffer = torch.empty(
                (cls._local_dp_buffer_len, cls._hidden_size),
                dtype=cls._dtype,
                device=cls._device,
            )
        return buffer

评论区精华

get_local_dp_buffer 是否应保留默认组 设计

ShangmingCai 提议使用 `Optional[GroupCoordinator] = None` 并默认回退 `get_tp_group()` 以保持向后兼容。wangfakang 回应:使用默认值容易导致组不一致,显式传入才是正确做法。

结论:采用显式参数,不设默认值,强制调用方明确通信组。 · 已解决

内存池复用导致组不一致 正确性

nvcastet 指出即使传入正确组,若内存池有足够 inactive memory,返回的 block 可能仍是之前注册的旧组,导致 symm 仍可能不生效。wangfakang 承认这是不同问题,并建议先合并此 PR。nvcastet 虽最终批准,但强调应在合并前或后续修复此问题。

结论:双方同意这是一个独立且更严重的问题,但本次 PR 未修复。需后续 PR 解决。 · unresolved

风险与影响

  • 内存池复用风险(由 nvcastet 提出):use_symmetric_memory 在池有足够内存时直接返回 block 而不重新注册,导致注册组可能仍是旧的 tp_group,从而 symm 仍可能不生效。此风险在本 PR 未修复,需后续 PR 解决。
  • 缺少测试覆盖:本次改动包含 4 个源码文件,但未添加对应的单元测试或集成测试,可能遗漏回归。
  • 影响面广communicator.py 修改涉及多个通信路径(如 _scattered_to_tp_attn_full_gather_hidden_states_and_residual_scatter_hidden_states),这些路径在多种并行策略中被调用,稍有偏差可能导致静默错误。
  • 用户影响:所有使用 --enable-dp-max-padding 或对称内存加速的分布式推理配置将受益于 symm 的正确启用,获得通信性能提升。但未修复内存池复用问题的场景可能仍无法正确启用 symm。
  • 系统影响:改动集中在分布式通信层,影响 DP attention、NSA CP、MoE 全 gather 等核心路径。对于单组通信(仅 TP)的用户无影响,但对多组混合(TP+CP+DP)影响较大。
  • 团队影响:此 PR 暴露了内存池与组绑定的深层设计问题,团队需后续跟踪修复。
内存池复用问题 缺少测试覆盖 多路径影响

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论