执行摘要
- 一句话:为配置发布添加进程角色记录
- 推荐动作:该 PR 是结构化配置 API 系列的重要一环,值得精读,尤其是
_ConfigBag 的 __slots__ 移除和 torch.compile 追踪支持的设计决策。自动化 review 提出的风险点需要在后续 PR 中跟进。建议关注同一系列的其他 PR(#31812、#31814-#31817)以理解完整上下文。
功能与动机
随着结构化 RuntimeContext 配置 API 的推进,需要记录配置是由哪个进程角色发布的(scheduler/tokenizer/encoder等),以便未来实现更精细的配置隔离和审计。同时,遗留的 setter 需要成为角色特定的 shim,为从全局函数迁移到命名空间访问器铺平道路。该 PR 是 stacked series 的一部分,行为保持,仅添加角色记录。
实现拆解
- 在
python/sglang/srt/runtime_context.py 中新增 publish 函数,接受 server_args、role 和可选的 hf_config,调用 get_context().set_server_args(server_args) 并记录 _publish_role;新增 publish_role 函数返回当前角色。同时新增 preserve_config 上下文管理器,快照并恢复整个配置生命周期(服务器参数和配置袋)。
- 重构
_ConfigBag 类:移除 __slots__,将叶子节点和子 bag 作为真实实例属性存储(通过 __dict__),使得 torch.compile / Dynamo 可以追踪属性读取(如 get_exec().comm.enable_symm_mem);添加 _set_sub 方法注册子 bag;修改 _set 方法同时更新书签字典和实例属性;修改 override 上下文管理器使用 _set 以确保一致性。
- 在
python/sglang/srt/server_args.py 中,将 set_global_server_args_for_tokenizer 从 set_global_server_args_for_scheduler 的函数别名改为独立函数,内部调用 publish(server_args, role="tokenizer");同时更新 set_global_server_args_for_scheduler 的文档字符串并改为调用 publish(server_args, role="scheduler")。
- 在各个进程入口点添加
publish 调用:scheduler.py::run_scheduler_process 发布角色 "scheduler",data_parallel_controller.py::run_data_parallel_controller_process 发布角色 "scheduler",encode_server.py 发布角色 "encoder",expert_backup_manager.py 发布角色 "expert_backup"。
- 在
python/sglang/srt/speculative/draft_worker_common.py::build_draft_tp_worker 中,将手动备份恢复替换为 get_context().preserve_config() 上下文管理器,使得快照包含所有的后发布覆盖,避免因重新发布而丢失覆盖。
- 测试文件
test/registered/unit/test_runtime_context_override.py 新增三个测试用例覆盖角色记录:验证 publish 记录角色、遗留 shims 记录角色、reset_context 清除角色。
关键文件:
python/sglang/srt/runtime_context.py(模块 运行时上下文;类别 source;类型 core-logic;符号 _set_sub, preserve_config, publish, publish_role): 核心变更文件:新增publish/publish_role/preserve_config函数,重构_ConfigBag以支持torch.compile追踪属性,变更配置发布机制。
python/sglang/srt/server_args.py(模块 服务器参数;类别 source;类型 core-logic;符号 set_global_server_args_for_tokenizer): 将set_global_server_args_for_tokenizer从别名变为独立函数,为遗留setter分配明确角色,是配置迁移的关键一步。
python/sglang/srt/speculative/draft_worker_common.py(模块 推测解码;类别 source;类型 dependency-wiring): 使用preserve_config上下文管理器替换手动备份恢复,确保draft构建配置保护包含所有后发布覆盖。
test/registered/unit/test_runtime_context_override.py(模块 配置测试;类别 test;类型 test-coverage;符号 test_publish_records_role, test_legacy_shims_record_roles, test_reset_clears_role): 新增三个测试用例覆盖角色记录功能,验证行为正确性。
python/sglang/srt/managers/scheduler.py(模块 调度器;类别 source;类型 dependency-wiring): 在run_scheduler_process入口添加publish调用,确保调度进程的配置命名空间早期可用。
python/sglang/srt/managers/data_parallel_controller.py(模块 DP控制器;类别 source;类型 entrypoint): 在DP控制器进程入口添加publish调用,记录角色scheduler。
python/sglang/srt/disaggregation/encode_server.py(模块 编码服务器;类别 source;类型 dependency-wiring): 在编码服务器入口添加publish调用,记录角色encoder。
python/sglang/srt/elastic_ep/expert_backup_manager.py(模块 专家备份;类别 source;类型 dependency-wiring): 在专家备份管理器入口添加publish调用,记录角色expert_backup。
关键符号:publish, publish_role, preserve_config, _set_sub, set_global_server_args_for_scheduler, set_global_server_args_for_tokenizer
关键源码片段
python/sglang/srt/runtime_context.py
核心变更文件:新增publish/publish_role/preserve_config函数,重构_ConfigBag以支持torch.compile追踪属性,变更配置发布机制。
# _ConfigBag : resolved-config namespace bag, read-only by bare assignment.
# Leaves are stored as real instance attributes (in __dict__ ) so that
# torch.compile can trace attribute reads without graph-breaking.
def _set(self, name: str, value: Any) -> None:
'''Internal write that bypasses the read-only guard.
Updates both the bookkeeping map and the real attribute (traceable read).'''
object.__getattribute__(self, '_fields')[name] = value
object.__setattr__(self, name, value) # real attribute for traceability
def _set_sub(self, name: str, sub: '_ConfigBag') -> None:
'''Register a nested bag as both a bookkeeping entry and a real
attribute (so ``bag.sub`` is a plain, traceable attribute load).'''
object.__getattribute__(self, '_subs')[name] = sub
object.__setattr__(self, name, sub) # now torch.compile can see it
@contextmanager
def override(self, **kwargs):
'''Scoped, transactional test-only override of this bag's own leaves.
Keys validated before any write; restored on exit.'''
fields = object.__getattribute__(self, '_fields')
unknown = set(kwargs) - set(fields)
if unknown:
path = object.__getattribute__(self, '_path')
raise ValueError(f'unknown config leaf for {path!r}: {sorted(unknown)}')
saved = {name: fields[name] for name in kwargs}
for name, value in kwargs.items():
self._set(name, value) # uses traceable _set
try:
yield self
finally:
for name, value in saved.items():
self._set(name, value) # restore via traceable path
python/sglang/srt/server_args.py
将set_global_server_args_for_tokenizer从别名变为独立函数,为遗留setter分配明确角色,是配置迁移的关键一步。
# Legacy publish shims — prefer runtime_context.publish(server_args, role=...)
# in new code. Imports are in-function to keep cycle-free at import time.
def set_global_server_args_for_scheduler(server_args: ServerArgs):
'''Legacy publish shim (role=scheduler).'''
from sglang.srt.runtime_context import publish
publish(server_args, role='scheduler')
def set_global_server_args_for_tokenizer(server_args: ServerArgs):
'''Legacy publish shim (role=tokenizer). Not aliased to the scheduler shim:
the process role differs.'''
from sglang.srt.runtime_context import publish
publish(server_args, role='tokenizer')
评论区精华
自动化 review 提出了 5 条建议:
风险与影响
- 风险:
- 核心配置路径变更:
_ConfigBag 从 __slots__ 切换到 __dict__,影响内存和属性查找,但换来 torch.compile 可追踪性,属于设计权衡。
- 测试覆盖缺口:自动化建议指出两个现有测试需要更新(tokenizer 别名测试和 ratchet 计数测试),若未更新会导致 CI 失败。
- 配置隔离风险:
preserve_context 仅保存引用,在 draft 构建中如果目标 ServerArgs 被突变,恢复时可能出现配置袋与源不一致。
- 角色一致性:
set_server_args 不清除角色,可能导致遗留 setter 后角色仍残留旧值,违反预期。
- 兼容性:
set_global_server_args_for_tokenizer 从别名变为独立函数,任何依赖 is 比较的代码可能失败。
- 自引用注解:若未启用
from __future__ import annotations,在 Python 3.10-3.13 上导入 runtime_context 会抛出 NameError。
- 影响:
- 用户影响:无直接用户可见变更,行为保持。
- 系统影响:配置发布机制增加了角色追踪,为未来配置隔离和审计奠定基础。
_ConfigBag 的变更可能影响所有通过命名空间读取配置的代码(如 get_exec().comm.enable_symm_mem),使其在 torch.compile 下不再图打断。
- 团队影响:开发者需要在新代码中使用
publish(server_args, role=...) 替代直接调用 set_server_args。遗留 setter 仍然可用但会被逐步淘汰。
- 影响范围:中。涉及 8 个文件,包括运行时上下文核心、服务器参数、调度器、DP 控制器、编码服务器、专家备份管理器和 draft 工作线程。
- 风险标记:核心路径变更(配置机制), 测试合同未同步更新, 配置隔离风险(draft构建), 角色一致性未保证, 自引用注解兼容性, 遗留setter行为变化
关联脉络
- PR #31814 config: read resolved config via namespace accessors: 同一结构化配置系列,本PR的角色记录依赖该PR建立的命名空间访问器基础设施。
- PR #31815 config: load-time declarations write the config bags: 实现声明写入配置包,本PR的publish机制使用这些包。
- PR #31816 config: read parallel config leaves via get_parallel(): 继续配置访问器迁移,本PR的角色记录与并行配置读取共同演进。
- PR #31817 test: publish resolved config in unit fixtures for the namespace API: 测试夹具发布解析配置,与本PR的publish角色记录测试互补。
参与讨论