# PR #35918 完整报告

- 仓库：`sgl-project/sglang`
- 标题：[DeepSeek V4] Add W4A4 MegaMoE server flag
- 合并时间：2026-08-22 09:44
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/35918

---

# 执行摘要

- 一句话：新增 W4A4 MegaMoE 统一 server flag，替代两个 SGLang 环境变量
- 推荐动作：值得精读。这是一个典型的“配置入口收敛”PR，样本价值在于三处：一是 handler 抽取到 `arg_groups` 与同期 config bags 重构的协同方式；二是“运行时环境变量转发 → 启动期 flag 注入”的端到端迁移路径（含 `mega_moe.py` 运行时读取点的同步收敛）；三是文档数据契约（`_playground.jsx` 的 derive/apply、三个模型 snippet、模板）与代码变更的强联动。对计划新增或收敛 server flag 的开发者有直接参考价值，无需精读 kernel 实现。

# 功能与动机

PR body 明确指出：DeepSeek V4 W4A4 MegaMoE 目前要求用户手动设置两个 SGLang 特有的环境变量（`SGLANG_OPT_DEEPGEMM_MEGA_MOE_USE_FP4_ACTS` 与 `SGLANG_OPT_DEEPGEMM_MEGA_MOE_USE_MXF4_KIND`），需要暴露为单一 server 参数并用 DeepGEMM 原生环境变量配置。其深层动机是消除两层配置割裂：`DG_USE_*` 是 DeepGEMM 的原生开关，SGLang 不应让用户同时面对 SGLang 抽象变量与底层厂商变量；同时这也是 SRT 同期“环境变量 → CLI flag”迁移方向的一部分（与 #35905-#35910 配置重构系列同频）。

# 实现拆解

1. **新增钩子文件 `python/sglang/srt/arg_groups/mega_moe_hook.py`**：将原先内联在 `ServerArgs` 类中的 `handle_moe_runner_backend_alias` 迁移出来，并新增 `handle_w4a4_mxfp4_megamoe_env` 与统一入口 `handle_mega_moe`。前者负责把 `--moe-runner-backend megamoe` 归一化为 `moe_a2a_backend = megamoe`；后者在 flag 启用时直接执行 `os.environ["DG_USE_FP4_ACTS"] = "1"` 与 `os.environ["DG_USE_MXF4_KIND"] = "1"`。抽取的动因是保持 `_run_resolution_pipeline` 的 dispatcher 风格。
2. **`server_args.py` 接入新 flag**：新增字段 `enable_w4a4_mxfp4_megamoe`（类型 `A[bool, ...]`，归入 `NS("exec.moe")`，默认 `False`），并在 `_run_resolution_pipeline` 顶部（`_resolved_overrides = []` 之后、dummy-model 边界之前）改为调用 `handle_mega_moe(self)`，同时删除类内原 `_handle_moe_runner_backend_alias` 方法。提前到 dummy 边界之前是为了让所有进程（包括 dummy 模型路径）在 fork 前就完成环境变量注入。
3. **`mega_moe.py` 移除运行时转发层**：删除 `_apply_mega_moe_dg_env` 函数与 `_MEGA_MOE_DG_ENV_APPLIED` 全局标记；`_get_mega_moe_symm_buffer` 不再调用转发函数；`_run_mega_routed` 中 `use_fp4_acts` 由读取 `envs.SGLANG_...USE_FP4_ACTS` 改为 `os.getenv("DG_USE_FP4_ACTS") == "1"`，直接消费 DeepGEMM 原生变量。
4. **`environ.py` 完成 deprecation**：从 `Envs` 类中删除两个 `EnvBool` 字段（不再有运行时读取），并在 `_DEPRECATED_ENVS` 中新增两条 warning-only 条目，告警文案提示改用 `--enable-w4a4-mxfp4-megamoe`；`SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK` 保留为环境变量（数值调优类入口未迁移）。
5. **文档、模板与测试联动**：三个模型 snippet（`deepseek-v4.jsx`、`kimi-k3.jsx`、`qwen3.8.jsx`）的 `w4a4` 选项从 `env` 数组改为 `flags: ["--enable-w4a4-mxfp4-megamoe"]`，`_playground.jsx` 的 `deriveFromBase` 改从 flag 推导 `mmQuant`、`apply` 增加 quant flag 的 strip/insert 逻辑；`.claude/skills/cookbook-add-model/templates/config.jsx.tmpl` 模板同步，`docs/scripts/check_cookbook_configs.mjs` 新增校验；B200 与 CP 两个 E2E 测试的 launch 命令改用新 flag；`test_server_args.py` 与 `test_environ.py` 新增回归测试。

关键文件：
- `python/sglang/srt/arg_groups/mega_moe_hook.py`（模块 配置钩子；类别 source；类型 core-logic；符号 handle_mega_moe, handle_moe_runner_backend_alias, handle_w4a4_mxfp4_megamoe_env）: 新增的 Mega-MoE 配置钩子文件，集中承载 runner backend 别名归一化与 W4A4 环境变量注入，是本次配置迁移的核心入口。
- `python/sglang/srt/server_args.py`（模块 服务参数；类别 source；类型 core-logic；符号 _run_resolution_pipeline, enable_w4a4_mxfp4_megamoe）: 新增 `enable_w4a4_mxfp4_megamoe` 字段并在 `_run_resolution_pipeline` 顶部接入 `handle_mega_moe`，删除类内旧 handler，是配置管道的接入点。
- `python/sglang/srt/layers/moe/mega_moe.py`（模块 专家路由；类别 source；类型 core-logic；符号 _get_mega_moe_symm_buffer, _run_mega_routed）: 删除 `_apply_mega_moe_dg_env` 转发层与 `_MEGA_MOE_DG_ENV_APPLIED` 全局标记，`use_fp4_acts` 改为直接读取 DeepGEMM 原生变量，是运行时行为收敛的关键。
- `python/sglang/srt/environ.py`（模块 环境变量；类别 source；类型 core-logic；符号 _DEPRECATED_ENVS）: 从 `Envs` 中删除两个旧变量定义并在 `_DEPRECATED_ENVS` 中登记 warning-only 条目，决定旧配置的兼容行为。
- `docs/src/snippets/_playground.jsx`（模块 交互组件；类别 source；类型 core-logic；符号 deriveFromBase, apply）: Playground 交互组件从 env 推导改为 flag 推导，并同步 quant flag 的 strip/insert 逻辑，保证 UI 生成的启动命令与真实 CLI 一致。
- `test/registered/unit/server_args/test_server_args.py`（模块 参数测试；类别 test；类型 test-coverage；符号 test_enable_w4a4_mxfp4_megamoe_sets_deepgemm_env, test_w4a4_mxfp4_megamoe_disabled_preserves_deepgemm_env）: 新增两个核心回归测试：flag 启用时设置 DeepGEMM 环境变量、禁用时保留外部环境变量，验证配置管道行为。
- `test/registered/unit/test_environ.py`（模块 环境测试；类别 test；类型 test-coverage；符号 test_w4a4_mxfp4_megamoe_envs_warn_to_use_cli_flag）: 验证两个旧环境变量的 deprecation 告警文案指向新 flag，且不保留 replacement 转发。
- `.claude/skills/cookbook-add-model/templates/config.jsx.tmpl`（模块 文档模板；类别 other；类型 data-contract；符号 megamoeQuant）: cookbook 模型模板的 megaMoE 量化子选项从 env 契约改为 flags 契约，决定未来新增模型 cookbook 的默认配置写法。

关键符号：handle_mega_moe, handle_moe_runner_backend_alias, handle_w4a4_mxfp4_megamoe_env, _apply_mega_moe_dg_env, _run_resolution_pipeline

## 关键源码片段

### `python/sglang/srt/arg_groups/mega_moe_hook.py`

新增的 Mega-MoE 配置钩子文件，集中承载 runner backend 别名归一化与 W4A4 环境变量注入，是本次配置迁移的核心入口。

```python
# python/sglang/srt/arg_groups/mega_moe_hook.py
# 新增的 Mega-MoE 配置钩子：把原先内联在 ServerArgs 类里的两个 handler
# 抽取出来，保持 _run_resolution_pipeline 的 dispatcher 风格单一职责。

from __future__ import annotations

import logging
import os
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from sglang.srt.server_args import ServerArgs

logger = logging.getLogger(__name__)


def handle_mega_moe(server_args: ServerArgs) -> None:
    # 统一入口：先归一化 runner backend 别名，再按需注入 DeepGEMM 原生变量
    handle_moe_runner_backend_alias(server_args)
    handle_w4a4_mxfp4_megamoe_env(server_args)


def handle_moe_runner_backend_alias(server_args: ServerArgs) -> None:
    # --moe-runner-backend megamoe 是 --moe-a2a-backend megamoe 的别名；
    # 归一化后后续逻辑只需读取 moe_a2a_backend 一个字段
    if server_args.moe_runner_backend != "megamoe":
        return

    if server_args.moe_a2a_backend not in ("none", "megamoe"):
        logger.warning(
            "--moe-runner-backend megamoe is an alias for "
            "--moe-a2a-backend megamoe; overriding "
            "--moe-a2a-backend %s.",
            server_args.moe_a2a_backend,
        )
    server_args.moe_runner_backend = "auto"
    server_args.moe_a2a_backend = "megamoe"


def handle_w4a4_mxfp4_megamoe_env(server_args: ServerArgs) -> None:
    # 唯一入口：flag 启用时把 DeepGEMM 原生开关写入进程环境，
    # 后续 fork 出的各 scheduler 进程都会继承这两个变量
    if not server_args.enable_w4a4_mxfp4_megamoe:
        return

    os.environ["DG_USE_FP4_ACTS"] = "1"
    os.environ["DG_USE_MXF4_KIND"] = "1"

```

### `python/sglang/srt/layers/moe/mega_moe.py`

删除 `_apply_mega_moe_dg_env` 转发层与 `_MEGA_MOE_DG_ENV_APPLIED` 全局标记，`use_fp4_acts` 改为直接读取 DeepGEMM 原生变量，是运行时行为收敛的关键。

```python
# python/sglang/srt/layers/moe/mega_moe.py（关键分支节选）
# 旧实现里 use_fp4_acts 由 SGLANG_OPT_DEEPGEMM_MEGA_MOE_USE_FP4_ACTS 读取，
# 再经 _apply_mega_moe_dg_env() 转发成 DG_USE_FP4_ACTS；本 PR 删除转发层，
# 直接以 DeepGEMM 原生变量为准——该变量唯一的写入入口是
# arg_groups/mega_moe_hook.py 的 handle_w4a4_mxfp4_megamoe_env。

def _get_mega_moe_symm_buffer(
    group,
    num_experts: int,
    num_max_tokens_per_rank: int,
    num_topk: int,
    hidden: int,
    intermediate_hidden: int,
) -> SymmBuffer:
    # 移除了 _apply_mega_moe_dg_env() 调用：环境变量已在 ServerArgs
    # 解析期写入进程环境，这里不再需要惰性转发
    import deep_gemm

    key = (
        id(group),
        num_max_tokens_per_rank,
        num_experts,
        num_topk,
        hidden,
        intermediate_hidden,
    )
    buf = _MEGA_MOE_SYMM_BUFFER.get(key)
    if buf is None:
        buf = deep_gemm.get_symm_buffer_for_mega_moe(
            group,
            num_experts,
            num_max_tokens_per_rank,
            num_topk,
            hidden,
            intermediate_hidden,
            use_fp8_dispatch=True,
            activation="swiglu",
        )
        _MEGA_MOE_SYMM_BUFFER[key] = buf
    return buf

# 在 _run_mega_routed 内部：
use_fp4_acts = os.getenv("DG_USE_FP4_ACTS") == "1"
if use_fp4_acts:
    # FP4 路径走 DeepGEMM 的 mega_moe_pre_dispatch，处理 E2M1 packing 变体；
    # jit 实现只发射 FP8
    deep_gemm.mega_moe_pre_dispatch(
        hidden_states,
        topk_ids_in,
        topk_weights_in,
        buf.x,
        buf.x_sf,
        buf.topk_idx,
        buf.topk_weights,
        num_tokens=num_tokens,
        group_size=32,
        use_fp4_acts=True,
    )
else:
    # FP8 路径走 sglang 内置的 mega_moe_pre_dispatch（jit 实现）
    mega_moe_pre_dispatch(
        hidden_states,
        topk_ids_in,
        topk_weights_in,
        buf.x,
        buf.x_sf,
        buf.topk_idx,
        buf.topk_weights,
        quant_group_size=32,
    )

```

### `python/sglang/srt/environ.py`

从 `Envs` 中删除两个旧变量定义并在 `_DEPRECATED_ENVS` 中登记 warning-only 条目，决定旧配置的兼容行为。

```python
# python/sglang/srt/environ.py（_DEPRECATED_ENVS 节选）
# 两个旧变量已从 Envs 类中移除（不再有运行时读取），只保留 warning-only
# deprecation 条目：用户仍设置旧变量时得到告警，并被引导改用新 server flag。
_DEPRECATED_ENVS = {
    # ... 其他条目 ...
    "SGLANG_OPT_DEEPGEMM_MEGA_MOE_USE_FP4_ACTS": _DeprecatedEnv(
        note="Please use '--enable-w4a4-mxfp4-megamoe' instead."
    ),
    "SGLANG_OPT_DEEPGEMM_MEGA_MOE_USE_MXF4_KIND": _DeprecatedEnv(
        note="Please use '--enable-w4a4-mxfp4-megamoe' instead."
    ),
    # ... 其他条目 ...
}


def _handle_deprecated_envs():
    # 对每个旧变量执行 deprecation 处理：仅告警、不转发值，
    # 同时把遗留的 SGL_ 前缀重写为 SGLANG_
    for old_name, deprecation in _DEPRECATED_ENVS.items():
        deprecation.apply(old_name)

    for key, value in list(os.environ.items()):
        if key.startswith("SGL_") and key not in _DEPRECATED_ENVS:
            new_key = key.replace("SGL_", "SGLANG_", 1)
            warnings.warn(
                f"Environment variable {key} is deprecated, please use {new_key}"
            )
            os.environ[new_key] = value

```

# 评论区精华

两个 review 评论均为作者 Fridge003 的合入前自审：

1. **flag 命名精确化**：在 `.claude/skills/cookbook-add-model/templates/config.jsx.tmpl` 的 diff 上要求 “Please rename this flag to `--enable-w4a4-mxfp4-megamoe`”。结论：已采纳，全仓库（`server_args.py`、三个模型 snippet、Playground、模板、测试）统一使用新名。`mxfp4` 精确描述了该路径的量化格式（E2M1 FP4 激活 + MXF4 mainloop），与 SRT 已有的 `flashinfer_mxfp4_moe_precision` 命名风格一致。
2. **handler 归属重构**：在 `server_args.py` 上要求 “Please move `_handle_w4a4_megamoe_env` and `_handle_moe_runner_backend_alias` to a newly created `mega_moe_hook.py` under arg_groups”。结论：已采纳，新增 `arg_groups/mega_moe_hook.py`，`_run_resolution_pipeline` 中改为调用 `handle_mega_moe(self)`。这与 #35906 引入的 `arg_groups` 声明式处理模式（`overrides.py`、`speculative_hook.py`）一致。

- flag 命名从 --enable-w4a4-megamoe 改为 --enable-w4a4-mxfp4-megamoe (design): 已采纳；server_args.py、三个模型 snippet、Playground、模板与测试全量统一使用新名，与 SRT 既有 `flashinfer_mxfp4_moe_precision` 命名风格对齐。
- Mega-MoE handler 抽取到独立 hook 文件 (design): 已采纳；新增 arg_groups/mega_moe_hook.py，pipeline 顶部改为调用 handle_mega_moe(self)，类内旧方法删除。

# 风险与影响

- 风险：
 1. **旧环境变量静默失效**：两个旧的 `SGLANG_OPT_DEEPGEMM_MEGA_MOE_*` 变量仅保留 warning 不转发，若用户仍只依赖旧变量，W4A4 路径不会开启。这是有意为之，但属于行为变化，需要靠告警文案引导。
 2. **`os.environ` 直接覆盖而非 `setdefault`**：旧转发逻辑用 `setdefault`（外部显式 `DG_USE_*` 优先），新逻辑在 flag 启用时无条件覆盖为 `1`。`test_enable_w4a4_mxfp4_megamoe_sets_deepgemm_env` 已断言覆盖行为，说明是有意设计，但外部用户若同时设置 `DG_USE_FP4_ACTS=0` 会被忽略。
 3. **多进程环境继承依赖 fork 时序**：环境变量注入发生在 `ServerArgs` 解析期，依赖所有 worker 在 resolution 之后 fork。PR 已在 GB300 实测四个 scheduler 进程均收到变量，但未来若引入更早 fork 的进程模型需重新验证。
 4. **文档数据契约联动面广**：三个模型 snippet + Playground + cookbook 模板同时变更 `w4a4` 选项的 flags/env 契约，`check_cookbook_configs.mjs` 虽新增校验，但任何一侧遗漏都会导致 Playground 展示与实际启动命令不一致。
 - 影响：**用户侧**：DeepSeek V4 / Kimi-K3 / Qwen3.8 的 W4A4 用户启动命令从“导出两个 SGLang 环境变量”简化为“加一个 `--enable-w4a4-mxfp4-megamoe` flag”，cookbook 与 Playground 同步更新，降低配置门槛。**系统侧**：配置注入时机提前到解析期，kernel 运行时不再读取 SGLang 抽象 env，`mega_moe.py` 与 `environ.py` 的状态面收敛；`_run_resolution_pipeline` 的 dispatcher 入口增加一个 hook 调用，对配置重构系列是正向演进。**团队侧**：提供了一个可复制的“env → CLI flag”迁移范式（钩子文件 + deprecation + 文档契约 + 双测试），后续同类迁移可直接照搬。
 - 风险标记：旧环境变量仅告警不生效 , os.environ 直接覆盖非 setdefault, 多进程继承依赖 fork 时序 , 文档数据契约联动面广

# 关联脉络

- PR #35910 config: publish before the launcher reads effective configuration: 同属 `server_args._run_resolution_pipeline` 的配置重构脉络；本 PR 在该 pipeline 顶部新增 `handle_mega_moe` 调用，依赖该系列确立的声明式解析与发布纪律。
- PR #35906 config: project the config bags from the resolution result: 引入了 arg_groups 目录下的声明式处理模式（overrides.py 等），本 PR 新增的 mega_moe_hook.py 与该目录结构同构，是同一架构方向的延续。
- PR #35854 [AMD] Update amd deepseek v4 cookbook 0822: 同时改动了 `docs/src/snippets/configs/deepseek-ai/deepseek-v4.jsx` 与 `docs/cookbook/autoregressive/DeepSeek/DeepSeek-V4.mdx`，后续 DeepSeek-V4 cookbook 迭代需保持数据契约同步。