# PR #34869 完整报告

- 仓库：`sgl-project/sglang`
- 标题：Fix startup weight load after TorchAO removal
- 合并时间：2026-08-15 04:18
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/34869

---

# 执行摘要

- 一句话：移除 TorchAO 残留引用，修复启动权重加载
- 推荐动作：该 PR 值得快速浏览：它是一个典型的「跨 PR 收尾修复」案例，展示了大重构（#34304）后如何通过测试锁定契约。重点关注 `StartupWeightLoadOptions.from_server_args` 与 `ServerArgs` 的解耦方式，以及如何使用最简 `ServerArgs` 构造做回归测试。

# 功能与动机

PR #34304 移除了 TorchAO 集成及 --torchao-config 参数，但 startup_weight_load.py 中的 StartupWeightLoadOptions 数据契约仍残留 torchao_config 字段：from_server_args 读取 server_args.torchao_config（该属性已不存在），_get_unsupported_reason 也引用 options.torchao_config。这会导致启动权重加载路径在构造 options 时崩溃，因此需要补齐清理并加测试防护。

# 实现拆解

1. **清理数据契约**：在 `startup_weight_load.py` 的 `StartupWeightLoadOptions` 中删除 `torchao_config: str` 字段，同步删除 `from_server_args` 中 `torchao_config=server_args.torchao_config` 的赋值，避免访问不存在的 `ServerArgs` 属性。
2. **删除不支持项检查**：在 `_get_unsupported_reason` 的 basic_rules 中删除 `(bool(options.torchao_config), "TorchAO is not supported")` 这一规则，消除对已移除字段的引用。
3. **新增回归测试**：在 `test_startup_weight_load.py` 中新增 `test_options_accept_current_server_args_schema`，用最小 `ServerArgs(model_path="dummy", cuda_graph_config=CudaGraphConfig())` 调用 `StartupWeightLoadOptions.from_server_args`，断言返回合法对象，防止未来移除 server 参数时再破坏启动初始化。同时从 `_make_options` 中移除 `torchao_config=""` 并补充 `CudaGraphConfig`、`ServerArgs` 的导入。

关键文件：
- `python/sglang/srt/model_executor/model_runner_components/startup_weight_load.py`（模块 权重加载；类别 source；类型 data-contract；符号 StartupWeightLoadOptions, from_server_args, _get_unsupported_reason）: 核心修复文件：删除 StartupWeightLoadOptions 数据契约中的 torchao_config 字段及其在 from_server_args 和 _get_unsupported_reason 中的引用，解除启动路径崩溃。
- `test/registered/unit/model_executor/model_runner_components/test_startup_weight_load.py`（模块 权重加载；类别 test；类型 test-coverage；符号 test_options_accept_current_server_args_schema）: 新增回归测试 test_options_accept_current_server_args_schema，锁定 StartupWeightLoadOptions 与当前 ServerArgs schema 的兼容性，防止未来重复踩坑。

关键符号：StartupWeightLoadOptions.from_server_args, StartupWeightLoadOptions._get_unsupported_reason, test_startup_weight_load.test_options_accept_current_server_args_schema

## 关键源码片段

### `python/sglang/srt/model_executor/model_runner_components/startup_weight_load.py`

核心修复文件：删除 StartupWeightLoadOptions 数据契约中的 torchao_config 字段及其在 from_server_args 和 _get_unsupported_reason 中的引用，解除启动路径崩溃。

```python
# startup_weight_load.py（关键片段）
# StartupWeightLoadOptions 是启动权重加载的配置契约，
# 本 PR 移除了已随 TorchAO 集成分离的 torchao_config 字段。
@dataclasses.dataclass(frozen=True, slots=True, kw_only=True)
class StartupWeightLoadOptions:
    device: str
    is_cuda_platform: bool
    cuda_graph_enabled: bool
    prefill_cuda_graph_backend: Backend
    is_draft_worker: bool
    speculative_algorithm: Optional[str]
    # ...（并行维度、offload 等字段省略）
    enable_memory_saver: bool
    enable_weights_cpu_backup: bool
    # torchao_config 字段已删除，避免与已移除的 ServerArgs 属性冲突
    enable_lora: bool
    # ...（其余加载相关字段省略）

    # 从 ServerArgs 投影出启动加载所需的全部参数，
    # 若此处引用了已删除的 server_args 属性会直接抛 AttributeError。
    @classmethod
    def from_server_args(
        cls,
        *,
        server_args: ServerArgs,
        is_draft_worker: bool,
    ) -> StartupWeightLoadOptions:
        cuda_graph_config = server_args.cuda_graph_config
        cuda_graph_enabled = any(
            getattr(cuda_graph_config, phase).backend != Backend.DISABLED
            for phase in Phase.ALL
        )
        return cls(
            device=server_args.device,
            is_cuda_platform=current_platform.is_cuda(),
            cuda_graph_enabled=cuda_graph_enabled,
            prefill_cuda_graph_backend=cuda_graph_config.prefill.backend,
            is_draft_worker=is_draft_worker,
            # torchao_config=server_args.torchao_config 已删除，
            # 否则在 TorchAO 移除后启动即崩溃
            enable_lora=server_args.enable_lora,
            has_lora_paths=bool(server_args.lora_paths),
            prefetch_num_threads=server_args.weight_loader_prefetch_num_threads,
            # ...（其余字段同理从 server_args 投影）
        )

```

### `test/registered/unit/model_executor/model_runner_components/test_startup_weight_load.py`

新增回归测试 test_options_accept_current_server_args_schema，锁定 StartupWeightLoadOptions 与当前 ServerArgs schema 的兼容性，防止未来重复踩坑。

```python
# test_startup_weight_load.py（新增测试片段）
# 该测试用最小 ServerArgs 构造 options，确保移除的 server 参数
# 不会再次破坏启动权重加载的初始化路径。
def test_options_accept_current_server_args_schema(self):
    """Removed server options must not break overlap startup initialization."""
    options = StartupWeightLoadOptions.from_server_args(
        # 只给 model_path 和 cuda_graph_config，其余全部走默认值
        server_args=ServerArgs(
            model_path="dummy", cuda_graph_config=CudaGraphConfig()
        ),
        is_draft_worker=False,
    )

    # 只要 from_server_args 没有因缺失 torchao_config 抛 AttributeError，
    # 并且能返回合法 options 对象，就说明数据契约与当前 server_args 对齐。
    self.assertIsInstance(options, StartupWeightLoadOptions)

```

# 评论区精华

该 PR 的 review 讨论较少：审核人 Qiaolin-Yu 直接 APPROVED，无评论。Issue 评论中主要是作者发起 `/rerun-test` 触发两个相关测试（`test_startup_weight_load.py` 与 `test_startup_weight_load.py` 的单元版本），两个测试均通过。核心价值在于用测试锁定了「移除 server 参数后不得破坏启动初始化」这一契约。

- 移除 torchao_config 字段的合理性与测试覆盖 (design): 采用数据契约清理与回归测试双管齐下的方案，测试通过后合入。

# 风险与影响

- 风险：
 1. **兼容性风险**：若用户仍通过旧配置文件或代码直接构造 `StartupWeightLoadOptions(torchao_config=...)`，会因字段删除而报 TypeError；但 TorchAO 集成已整体移除，属预期行为。
 2. **回归风险**：`_get_unsupported_reason` 中删除 TorchAO 检查后，若未来 TorchAO 重新引入，需要重新加回；但目前无此迹象。
 3. **测试覆盖范围**：新增测试仅验证 `from_server_args` 能构造 options，未覆盖 `_get_unsupported_reason` 的行为，但该函数不再引用 torchao_config，风险可控。
 - 影响：影响范围为启动路径的权重加载模块：修复后 SGLang 服务在移除 TorchAO 后能正常完成启动权重加载与 CUDA graph capture 重叠逻辑初始化。对使用该功能的用户是启动崩溃的阻断性修复；对系统整体无性能或功能影响。团队需注意后续与 server_args 相关的改动需同步更新此处的数据契约。
 - 风险标记：启动路径崩溃修复 , 数据契约变更 , 测试覆盖新增

# 关联脉络

- PR #34304 Remove the torchao integration (--torchao-config): 本 PR 是 #34304 的收尾修复：#34304 移除了 torchao 集成与 --torchao-config 参数，但漏改了 startup_weight_load.py 中的残留引用，导致启动权重加载崩溃。