# PR #31816 完整报告

- 仓库：`sgl-project/sglang`
- 标题：config: read parallel config leaves via get_parallel()
- 合并时间：2026-07-22 16:18
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/31816

---

# 执行摘要

- 一句话：并行配置读取迁移至 get_parallel() 访问器
- 推荐动作：建议团队在合并前确认两个 P1 问题的修复情况，并补充验证。值得精读此 PR 以理解 RuntimeContext 配置 API 的推进策略，为后续同类迁移提供模板。

# 功能与动机

引入结构化的 RuntimeContext 配置 API，通过域名空间读取解析后的配置，使 ServerArgs 成为只读记录。此 PR 逐步替换并行配置读取，为后续完全配置分离铺路。

# 实现拆解

实现拆解：

1. 在 `runtime_context` 中暴露 `get_parallel()` 访问器，返回 `ParallelContext` 对象，该对象持有解析后的并行配置叶子值（如 `tp_size`、`pp_async_batch_depth`、`enable_dp_attention` 等）。

2. 在核心模块 `model_runner.py` 中，将 `_initialize_elastic_ep_joiner`、`maybe_init_expert_location_metadata`、`maybe_init_hisparse_coordinator`、`_expand_eplb_metadata_for_scale`、`_elastic_global_rank`、`_finalize_scale_up` 等函数中对 `self.server_args.xxx` 的调用替换为 `get_parallel().xxx`。同时调整 import 引入 `get_parallel` 并移除不再使用的 `get_server_args` 导入。

3. 在调度器 `scheduler_pp_mixin.py` 中，将 `pp_async_batch_depth`、`require_attn_tp_allgather` 等读取从 `self.server_args` 改为 `get_parallel()`。

4. 在控制面 `tokenizer_control_mixin.py` 中，将 `dp_size`、`enable_dp_attention`、`enable_dp_attention_local_control_broadcast` 等读取迁移。

5. 在多个模型文件（如 `longcat_flash.py`、`qwen3_next.py`、`llama.py`、`apertus.py`、`arcee.py`、`gpt_oss.py` 等）中，将 `lm_head` 的 `use_attn_tp_group` 等配置从 `get_server_args().enable_dp_lm_head` 改为 `get_parallel().enable_dp_lm_head`，同时清理 import。

6. 配套变更：移除不再需要的 `get_server_args` 导入（某些文件可能残留，如 review 指出的 `communicator.py` 和 `gpt_oss.py` 中仍有未迁移的调用）。无新增测试文件，但 CI 应覆盖（若通过）。

关键文件：
- `python/sglang/srt/model_executor/model_runner.py`（模块 模型执行器；类别 source；类型 data-contract；符号 _initialize_elastic_ep_joiner, maybe_init_expert_location_metadata, _expand_eplb_metadata_for_scale）: 核心模型执行器，包含 elastic EP 加入器、专家负载均衡、HiCache 协调器等关键并行配置读取迁移。
- `python/sglang/srt/managers/scheduler_pp_mixin.py`（模块 调度器；类别 source；类型 dependency-wiring；符号 event_loop_pp, event_loop_pp_disagg_prefill, init_pp_loop_state）: 调度器的 Pipeline Parallel 事件循环，pp_async_batch_depth 等配置读取迁移。
- `python/sglang/srt/managers/tokenizer_control_mixin.py`（模块 控制面；类别 source；类型 dependency-wiring；符号 update_control_communicator_fan_out, init_weights_update_group）: 控制面管理 FanOut 通信器的初始化与扇出配置，dp_size、enable_dp_attention 等读取迁移。

关键符号：_initialize_elastic_ep_joiner, event_loop_pp, update_control_communicator_fan_out, init_communicators, _expand_eplb_metadata_for_scale

## 关键源码片段

### `python/sglang/srt/managers/tokenizer_control_mixin.py`

控制面管理 FanOut 通信器的初始化与扇出配置，dp_size、enable_dp_attention 等读取迁移。

```python
# 文件 : python/sglang/srt/managers/tokenizer_control_mixin.py
# 变更点 : primary_group_control 的读取从 self.server_args 迁移到 get_parallel()

def update_control_communicator_fan_out(self: TokenizerManager, worker_count: int):
    # [ 变更 ] 使用 get_parallel() 替代 self.server_args
    primary_group_control = (
        get_parallel().enable_dp_attention
        and not get_parallel().enable_dp_attention_local_control_broadcast
    )
    if primary_group_control:
        control_fan_out = (
            worker_count + self.server_args.tp_size - 1
        ) // self.server_args.tp_size
    else:
        control_fan_out = worker_count

    for spec in _COMMUNICATOR_SPECS:
        getattr(self, f"{spec[0]}_communicator").set_fan_out(worker_count)

    self.get_internal_state_communicator.set_fan_out(control_fan_out)

```
（注意：这里 worker_count 的组内 size 仍读取 server_args.tp_size，因为 tp_size 是实时拓扑 size，保留旧访问模式以体现 PR 意图。）

# 评论区精华

Review 评论提出了两个 P1 级别问题：

- 在 `communicator.py` 的 `enable_moe_dense_fully_dp` 函数中移除了 `get_server_args` 导入但仍在调用该函数，导致 `NameError`。建议保留导入或迁移该读取。
- 在 `gpt_oss.py` 的 `GptOssSparseMoeBlock.forward` 中同样移除了导入但仍有调用，导致 `NameError`。
- 另外，`scheduler.py` 中关于 `speculative_draft_load_format` 的覆盖问题被标记为 P2，评论建议保持目标 ServerArgs 不被污染。目前这些在合并版本中是否已修复不得而知，但存在风险。

- enable_moe_dense_fully_dp 中 get_server_args 未迁移 (correctness): 需要修复此残留调用。
- GptOssSparseMoeBlock.forward 中 get_server_args 未迁移 (correctness): 需修复。

# 风险与影响

- 风险：核心风险：部分文件中 `get_server_args` 导入被移除但函数体仍有调用，引致 Python `NameError`。涉及 `communicator.py: enable_moe_dense_fully_dp` 和 `gpt_oss.py: GptOssSparseMoeBlock.forward`。

兼容性风险：若用户自定义 Manager 未调用 `publish`，访问 `get_parallel()` 可能读取到未初始化的配置。

回归风险：虽然声称行为保持，但若配置值在 `ServerArgs` 与 `ParallelContext` 间出现不一致（如未正确发布），可能引起静默错误。

无新增测试覆盖，增加了回归检测难度。

- 影响：影响范围：61 个源码文件变动，涉及模型定义、调度器、引擎入口、通信层等，但变更模式统一，功能无变化。

对用户：无直接影响，后台配置读取方式改变。

对开发：长期有利于配置系统解耦，短期需警惕未迁移完的遗留调用。

对团队：后续需继续推广该模式到其他配置域。

- 风险标记：未完全迁移的遗留调用 , 缺少测试覆盖 , 核心配置路径变更

# 关联脉络

- PR #31815 Stack base: config: read parallel config leaves via get_parallel() (earlier step): 此 PR 堆叠在 #31815 之上，属于同一系列引入 RuntimeContext 配置 API。