# PR #36917 完整报告

- 仓库：`sgl-project/sglang`
- 标题：[Diffusion] Reject incompatible transformer fallback
- 合并时间：2026-08-30 16:33
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/36917

---

# 执行摘要

- 一句话：拒绝分布式执行请求下的原生 Diffusers transformer 回退
- 推荐动作：值得精读。核心价值不在代码量，而在「准入控制优于静默降级」的设计取舍：用模板方法 + hook 把契约校验注入所有组件 loader，避免了逐个模型特判；报错信息刻意列出全部冲突项并给出两条修正路径，属于良好的用户引导实践。关注 `ComponentLoader` 基类的两个 hook 与 `TransformerLoader` 的具体实现，可作为后续组件加载准入逻辑的参考范式。

# 功能与动机

PR body 明确说明动机："reject native Diffusers fallback when a transformer component requires TP, sequence parallelism, Ulysses, Ring, or exact-component FSDP"。此前 `ComponentLoader.load()` 的模板方法在定制加载失败后会静默回退到 Diffusers/transformers 原生实现，但原生实现的 transformer 无法兑现分布式执行契约（TP/SP/Ulysses/Ring/FSDP），不兼容的配置会在推理阶段才暴露错误。本 PR 决定把问题提前到加载期暴露，并给出明确的修正路径；同时 FSDP 需要按 loader 区分准入——native DiT 与 MOVA bridge 构造分片参数，保留 FSDP 请求是合法的，其他 loader 复制加载自己的模块则必须撤销 FSDP 请求。

# 实现拆解

变更入口在 `python/sglang/multimodal_gen/runtime/loader/component_loaders/component_loader.py`，通过模板方法 + hook 的方式推广到所有组件 loader。

1. **基类契约扩展**：新增 `supports_fsdp_inference = False` 类属性，以及两个 hook——`validate_native_fallback(server_args, component_name)`（默认空实现）和 `disable_unsupported_component_fsdp(server_args, component_name)`（当 loader 不支持 FSDP 且 `server_args.should_use_fsdp_for_component()` 返回 True 时，调用 `server_args.disable_fsdp_for_component()` 撤销请求）。
2. **模板方法接入调用点**：在 `load()` 中两处插入——方法开头先调用 `disable_unsupported_component_fsdp`，确保复制加载的组件不会响应分片请求；在 `should_raise_customized_load_error()` 检查通过、真正执行 native fallback 之前调用 `validate_native_fallback`，使「先撤销不支持的 FSDP，再校验 fallback 契约」成为所有组件 loader 的通用流程。
3. **TransformerLoader 实现准入校验**：在 `transformer_loader.py` 中收集 `tp_size`、`sp_degree`、`ulysses_degree`、`ring_degree` 大于 1 的项以及组件 FSDP 请求，任一命中即抛 `RuntimeError`，报错信息列出全部冲突项并指引用户改用 SGLang-native transformer 实现或关闭分布式配置；同时将 `supports_fsdp_inference` 置为 True。
4. **BridgeLoader 声明 FSDP 支持**：MOVA dual tower bridge 加载时构造分片参数，把 `supports_fsdp_inference` 置为 True，避免被基类的撤销逻辑误伤。
5. **测试配套**：新增 `test_transformer_loader_fallback.py`，`TestTransformerLoaderFallbackAdmission` 用 `SimpleNamespace` 伪造 server args 覆盖三类场景（分布式配置被拒绝、复制执行放行、仅 FSDP 物化器保留请求）；`test_vae_loader.py` 与 `test_image_encoder_loader.py` 给 fixture 补充 `should_use_fsdp_for_component` 假实现以适配基类新调用。

关键文件：
- `python/sglang/multimodal_gen/runtime/loader/component_loaders/component_loader.py`（模块 组件加载器；类别 source；类型 core-logic；符号 supports_fsdp_inference, validate_native_fallback, disable_unsupported_component_fsdp, load）: 契约机制的核心：新增 `supports_fsdp_inference` 类属性、`validate_native_fallback` 与 `disable_unsupported_component_fsdp` 两个 hook，并在 `load()` 模板方法中接入调用点，让所有组件 loader 统一执行 FSDP 撤销与 fallback 校验。
- `python/sglang/multimodal_gen/runtime/loader/component_loaders/transformer_loader.py`（模块 组件加载器；类别 source；类型 core-logic；符号 supports_fsdp_inference, validate_native_fallback）: 实现 TransformerLoader 的准入校验：收集 TP/SP/Ulysses/Ring/FSDP 请求并抛 RuntimeError，是本 PR 行为变更的直接落点；同时声明 `supports_fsdp_inference = True`。
- `python/sglang/multimodal_gen/runtime/loader/component_loaders/bridge_loader.py`（模块 组件加载器；类别 source；类型 core-logic；符号 supports_fsdp_inference）: MOVA dual tower bridge 声明 `supports_fsdp_inference = True`，保证其分片参数构造逻辑不被 `disable_unsupported_component_fsdp` 撤销。
- `python/sglang/multimodal_gen/test/unit/test_transformer_loader_fallback.py`（模块 加载器测试；类别 test；类型 test-coverage；符号 TestTransformerLoaderFallbackAdmission, test_parallel_execution_rejects_native_fallback, test_replicated_execution_keeps_native_fallback_available, test_only_fsdp_materializers_keep_the_component_request）: 新增的准入测试，覆盖分布式拒绝、复制执行放行、FSDP 按 loader 准入三类核心场景，是本 PR 行为契约的直接验证。
- `python/sglang/multimodal_gen/test/unit/test_vae_loader.py`（模块 加载器测试；类别 test；类型 test-coverage；符号 should_use_fsdp_for_component）: 为 `_FakeServerArgs` 补充 `should_use_fsdp_for_component` 假实现，适配基类新增的 FSDP 撤销调用。
- `python/sglang/multimodal_gen/test/unit/test_image_encoder_loader.py`（模块 加载器测试；类别 test；类型 test-coverage；符号 should_use_fsdp_for_component）: 为 fixture 补充 `should_use_fsdp_for_component` 假实现，确保既有测试在基类新调用下继续通过。

关键符号：ComponentLoader.validate_native_fallback, ComponentLoader.disable_unsupported_component_fsdp, ComponentLoader.load, TransformerLoader.validate_native_fallback

## 关键源码片段

### `python/sglang/multimodal_gen/runtime/loader/component_loaders/component_loader.py`

契约机制的核心：新增 `supports_fsdp_inference` 类属性、`validate_native_fallback` 与 `disable_unsupported_component_fsdp` 两个 hook，并在 `load()` 模板方法中接入调用点，让所有组件 loader 统一执行 FSDP 撤销与 fallback 校验。

```python
class ComponentLoader(ABC):
    """组件加载基类：约定组件的加载优先级与 fallback 规则。"""

    # 该 loader 是否支持 FSDP 推理；只有构造分片参数的 loader 才置为 True，
    # 例如 DiT 的 TransformerLoader、MOVA 的 BridgeLoader
    supports_fsdp_inference = False

    def validate_native_fallback(
        self, _server_args: ServerArgs, _component_name: str
    ) -> None:
        """校验 native fallback 是否满足组件的运行时契约。

        默认不施加限制；需要拒绝特定执行配置的 loader 覆盖此方法，
        例如 TransformerLoader 会拒绝分布式执行下的 native fallback。
        """
        pass

    def disable_unsupported_component_fsdp(
        self, server_args: ServerArgs, component_name: str
    ) -> None:
        """loader 不支持 FSDP 时，撤销 server_args 上对该组件的 FSDP 请求。"""
        if (
            not self.supports_fsdp_inference
            and server_args.should_use_fsdp_for_component(component_name)
        ):
            server_args.disable_fsdp_for_component(component_name)

    def load(
        self,
        component_model_path: str,
        server_args: ServerArgs,
        component_name: str,
        transformers_or_diffusers: str,
    ):
        """模板方法：先撤销不支持的 FSDP 请求，定制加载失败后校验 fallback 契约。"""
        self._native_load_manages_placement = False
        # 加载前撤销 FSDP：复制加载的组件不应响应分片请求
        self.disable_unsupported_component_fsdp(server_args, component_name)
        # ... 先尝试定制加载 ...
        except Exception as e:
            # ... 判断是否允许抛错、是否需要 native loader ...
            # 真正降级前校验契约，不满足直接抛错而非静默带病运行
            self.validate_native_fallback(server_args, component_name)
            # ... 然后才执行 native fallback 加载与告警日志 ...

```

### `python/sglang/multimodal_gen/runtime/loader/component_loaders/transformer_loader.py`

实现 TransformerLoader 的准入校验：收集 TP/SP/Ulysses/Ring/FSDP 请求并抛 RuntimeError，是本 PR 行为变更的直接落点；同时声明 `supports_fsdp_inference = True`。

```python
class TransformerLoader(ComponentLoader):
    """(视频/音频) DiT transformer 的共享 loader。"""

    # DiT 加载时构造分片参数，因此保留组件的 FSDP 请求
    supports_fsdp_inference = True

    def validate_native_fallback(
        self, server_args: ServerArgs, component_name: str
    ) -> None:
        """原生 Diffusers fallback 无法兑现分布式执行，收集全部请求并拒绝。"""
        requested_distributed_execution = []
        # TP / SP / Ulysses / Ring 任一大于 1，或组件请求 FSDP，都视为分布式执行
        if server_args.tp_size is not None and server_args.tp_size > 1:
            requested_distributed_execution.append(f"tp_size={server_args.tp_size}")
        if server_args.sp_degree is not None and server_args.sp_degree > 1:
            requested_distributed_execution.append(f"sp_degree={server_args.sp_degree}")
        if server_args.ulysses_degree is not None and server_args.ulysses_degree > 1:
            requested_distributed_execution.append(
                f"ulysses_degree={server_args.ulysses_degree}"
            )
        if server_args.ring_degree is not None and server_args.ring_degree > 1:
            requested_distributed_execution.append(
                f"ring_degree={server_args.ring_degree}"
            )
        if server_args.should_use_fsdp_for_component(component_name):
            requested_distributed_execution.append("FSDP")
        if requested_distributed_execution:
            # 报错信息列出全部冲突项，并给出两条修正路径
            raise RuntimeError(
                f"Native Diffusers fallback for transformer component "
                f"{component_name!r} cannot honor requested distributed execution: "
                f"{', '.join(requested_distributed_execution)}. Use an SGLang-native "
                "transformer implementation or set tp_size, sp_degree, "
                "ulysses_degree, and ring_degree to 1 without FSDP."
            )

```

# 评论区精华

本 PR 没有 review 评论线程，唯一的讨论来自作者 mickqian 对 CI 失败的处置说明：NVIDIA multimodal shards 在依赖安装阶段（`scripts/ci/cuda/ci_install_dependency.sh` 导入 `deep_ep`）发生 `Bus error (core dumped)`，未启动任何 diffusion 测试。作者判定这是不稳定的 runner 环境问题，与本次变更无源码级关联（PR 在依赖安装前没有执行路径），因此不重跑同一失败。

- CI 失败由不稳定 runner 导致，与 PR 无关 (other): 判定为不稳定 runner 环境失败，与本次变更无源码级关联，不重跑同一失败。

# 风险与影响

- 风险：
 - **行为变更（有意为之）**：分布式配置下的 transformer 原生回退从「静默降级」变为「启动报错」。已有依赖该回退的部署会直接失败，但报错信息给出了修正路径，属于可控的破坏性变更。
 - **契约依赖**：新逻辑依赖 `ServerArgs` 上的 `should_use_fsdp_for_component` / `disable_fsdp_for_component` 方法。测试中所有用 `SimpleNamespace` 或假对象伪造 server args 的地方都必须补齐这两个方法，否则加载路径会 `AttributeError`；本 PR 已修复两处已知 fixture，但不排除其他测试或嵌入场景遗漏。
 - **覆盖盲区**：目前只有单元测试，没有真实多 GPU 集成测试验证报错与引导流程；且基类默认 `validate_native_fallback` 是空实现，VAE、text encoder 等组件若存在类似的分布式契约问题，本次并未覆盖。
 - **兼容性**：单卡与复制执行路径完全不变，`load()` 的返回结构与日志格式不变，对主流单卡 diffusion 推理无影响。
- 影响：
 - **用户 / 部署影响**：多 GPU diffusion 部署（TP/SP/Ulysses/Ring/FSDP）中，若 transformer 组件没有 SGLang-native 实现，现在会在启动期直接报错并给出明确的修正指引，而不是带病运行到推理阶段。单卡与复制执行用户完全无感知。
 - **系统影响**：仅在加载期增加一次校验与一次可能的状态撤销，无运行时性能开销。
 - **团队影响**：确立了组件 loader 的新契约约定——新增 loader 必须声明 `supports_fsdp_inference`，并视需求覆盖 `validate_native_fallback`；后续 diffusion 组件加载的准入逻辑有了统一的扩展点。
 - 风险标记：分布式场景行为变更（静默回退变启动报错）, 缺少多 GPU 集成测试 , 依赖 ServerArgs FSDP 新契约方法

# 关联脉络

- PR #36916 [Diffusion] Detect quantized transformer replacements: 同属 diffusion 组件加载校验系列，两者都在 transformer 加载路径上新增准入 / 检测逻辑，防止加载阶段的错误静默发生。
- PR #36907 [Diffusion] Enforce component attention backend application: 同属加载契约强制系列，采用相同的『拒绝不兼容配置』模式，完善组件级 attention backend 与 fallback 行为约束。
- PR #36991 [Diffusion] Add exact component precision overrides: 同为组件加载器契约扩展，让组件级配置（精度、FSDP、fallback）在加载与驻留阶段贯通。