Prhub

#30492 [refactor] Adopt get_parallel() everywhere and close out the parallel wrapper surface

原始 PR 作者 ch-wan 合并时间 2026-07-09 17:09 文件变更 71 提交数 2 评论 1 代码增减 +341 / -415

执行摘要

全局统一并行拓扑访问模式,启用采用检查

根据 PR body:ParallelContext is the read-through surface for parallel topology, but adoption had gaps: the decode-context-parallel dimension was never wrapped, a few files regressed back to raw getters inside the already-swept directories, dp_attention still exported a re-export family shadowing the canonical accessors, and ~150 call sites outside the original sweep still read the raw getters directly.

值得精读。该 PR 展示了如何系统性地统一代码库中的 API 访问模式:通过中心化 wrapper、逐步迁移、删除冗余、引入回归检查。其 override() 上下文管理器设计模式尤其值得借鉴。

讨论亮点

无公开 review 评论,PR 由作者自行合并。PR 正文和提交信息已清晰说明动机和修改范围。

实现拆解

  1. 扩充 ParallelContext 维度:在 runtime_context.py_PARALLEL_FIELDSParallelContext 类中新增 dcp_sizedcp_rankdcp_group 属性,委托到 parallel_state 的对应 getter,并注册到 override() 可覆盖字段。

  2. 删除冗余重新导出:在 layers/dp_attention.py 中移除 compute_dp_attention_local_info 整个函数、_LOCAL_ATTN_DP_SIZE / _LOCAL_ATTN_DP_RANK 全局变量,以及 get_attention_tp_groupget_attention_tp_rankget_attention_tp_sizeget_attention_cp_groupget_attention_cp_rankget_attention_cp_size 六个重新导出函数。这些函数的调用方直接改用 get_parallel().attn_*

  3. 全包调用点迁移:对约 71 个文件中的并行拓扑读取调用进行替换。典型模式为将 get_tensor_model_parallel_rank() 改为 get_parallel().tp_rank,将 get_attention_tp_size() 改为 get_parallel().attn_tp_size。涉及 model_loader/loader.pymodel_executor/ 下多个 runner 文件、managers/layers/ 子系统文件等。同时清理相应 import 语句,统一从 runtime_context 导入 get_parallel

  4. 新增采用检查测试:创建 test/registered/unit/test_parallel_adoption_ratchet.py,用正则扫描 sglang/srt 包下排除豁免路径后的所有 .py 文件,禁止出现直接调用原始 getter 的模式。豁免路径为 distributed/(定义原始 getter)、layers/dp_attention.py(委托基板)、debug_utils/dumper.py(第三方同名 getter)。

  5. 适应性调整测试:部分测试因导入绑定被删除而改用 get_parallel().override(...) 模拟并行拓扑状态。

文件 模块 状态 重要度
python/sglang/srt/runtime_context.py 运行上下文 modified 6.99
python/sglang/srt/layers/dp_attention.py DP 注意 modified 8.44
test/registered/unit/test_parallel_adoption_ratchet.py 合规检查 added 6.89
python/sglang/srt/model_loader/loader.py 模型加载 modified 6.49
python/sglang/srt/model_executor/model_runner_kv_cache_mixin.py KV 缓存 modified 6.26
python/sglang/srt/model_executor/runner/decode_cuda_graph_runner.py 解码图运行 modified 6.02

关键符号

compute_dp_attention_local_info get_attention_tp_group get_attention_tp_rank get_attention_tp_size get_attention_cp_group get_attention_cp_rank get_attention_cp_size dcp_size dcp_rank dcp_group TestParallelAdoptionRatchet.test_no_legacy_parallel_getters_in_swept_dirs

关键源码片段

python/sglang/srt/runtime_context.py core-logic

并行拓扑 wrapper 的核心文件,新增 DCP 维度属性并更新 override 字段集。

# python/sglang/srt/runtime_context.py ( 片段 )_PARALLEL_FIELDS = frozenset(
    {
        # ... 已有字段 ...
        "dcp_size", # 新增 DCP world size
        "dcp_rank", # 新增 DCP rank
        # ...
        "dcp_group", # 新增 DCP group
    }
)class ParallelContext:
    """并行拓扑命名空间;唯一实例状态是 _overrides。"""
    # ...
​
    @property
    def dcp_size(self) -> int:
        """返回 decode-context-parallel world size。"""
        return self._v("dcp_size", _ps().get_dcp_world_size)
​
    @property
    def dcp_rank(self) -> int:
        """返回 decode-context-parallel rank。"""
        return self._v("dcp_rank", _ps().get_dcp_rank)
​
    @property
    def dcp_group(self) -> Any:
        """返回 decode-context-parallel group。"""
        return self._v("dcp_group", _ps().get_dcp_group)
python/sglang/srt/layers/dp_attention.py core-logic

删除 6 个重新导出函数和 compute_dp_attention_local_info,简化初始化流程。

# python/sglang/srt/layers/dp_attention.py ( 变更后 )# 删除的符号:
# _LOCAL_ATTN_DP_SIZE, _LOCAL_ATTN_DP_RANK ( 全局变量 )
# compute_dp_attention_local_info ( 整个函数 )
# get_attention_tp_group / rank / size (6 个 re-export 函数 )def initialize_dp_attention(
    server_args: ServerArgs,
    model_config: ModelConfig,
):
    global _ATTN_DP_RANK, _ATTN_DP_SIZE
    dp = get_flags().dp
    dp.max_len_with_idle = (
        getattr(model_config.hf_config, "hybrid_override_pattern", None) is not None
    )
    enable_dp_attention = server_args.enable_dp_attention
    dp_size = server_args.dp_size
    attn_cp_size = server_args.attn_cp_size
    dp.enabled = enable_dp_attention
​
    tp_rank = get_tensor_model_parallel_rank()
    tp_size = get_tensor_model_parallel_world_size()
​
    _, _, _ATTN_DP_RANK, _ = compute_dp_attention_world_info(
        enable_dp_attention, tp_rank, tp_size, dp_size, attn_cp_size
    )
    # 已移除 compute_dp_attention_local_info 调用和 _LOCAL_ATTN_DP_* 赋值
    _ATTN_DP_SIZE = dp_size if enable_dp_attention else 1
    # ...

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  • 回归风险(高):约 71 个文件中约 80 个调用点被替换,任何遗漏或错误的映射(如 attn_tp_sizeget_attention_tp_size 语义不一致)可能导致运行时错误。PR 中引入了采用检查测试作为回归屏障,并通过 DeepSeek-V3.2 tp2 冒烟测试验证热路径。
  • 删除风险(中):compute_dp_attention_local_info 和局部 DP 变量被彻底删除,需确认没有任何外部模块(如 benchmark 脚本、实验性特性)依赖这些符号。PR body 称从不在读写路径外使用。
  • 测试覆盖风险(低):单元测试套件和注意力 unittest 树(179 passed, 538 subtests)保持与 base 一致,但更大规模集成测试未被包含。
  • 第三方兼容性(低):debug_utils/dumper.py 被豁免,因为其 Megatron 插件使用同名第三方 getter。
  • 开发体验:显著降低认知负载——整个 sglang/srt 包统一通过 get_parallel() 获取并行拓扑,配合 override() 上下文管理器使测试更加简单可靠。
  • 代码库健康度:消除了并行访问的两种风格(原始 getter vs wrapper),提升一致性;共减少约 415 行代码,删除大量重复 re-export。
  • 影响范围:跨 71 个文件,覆盖模型加载、运行时、缓存、注意力层、量化、调试等多个子系统,但每个文件改动量很小(多为替换调用点 + 调整 import)。
  • 向后兼容:无外部 API 破坏——删除的是内部 re-export 函数和从未公开的 compute_dp_attention_local_info
大规模调用点替换 依赖关系复杂 测试覆盖要求高 可能遗漏调用点

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论