# PR #27964 完整报告

- 仓库：`sgl-project/sglang`
- 标题：[Spec] Retire Spec V1
- 合并时间：2026-06-12 07:15
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/27964

---

# 执行摘要

- 一句话：移除 SGLANG_ENABLE_SPEC_V2 环境变量
- 推荐动作：该 PR 是 Spec V1 退役的收尾工作，对于理解 SGLang 推测解码的演进和配置清理策略有参考价值。建议关注 `speculative_hook.py` 中弃用警告的添加方式，以及测试 fixture 中配置属性的重命名模式。

# 功能与动机

SGLANG_ENABLE_SPEC_V2 曾是用于选择 Spec V2 worker 的开关，但所有推测解码算法现已默认使用 V2，该标志的唯一剩余效果是作为 --disable-overlap-schedule 的别名，造成混淆。这是退役 Spec V1 的最后一步用户可见操作。

# 实现拆解

1. **移除环境变量定义**：在 `python/sglang/srt/environ.py` 中删除 `SGLANG_ENABLE_SPEC_V2` 的 Envs 条目。
2. **核心运行时清理**：在 `python/sglang/srt/arg_groups/speculative_hook.py` 的 `handle_speculative_decoding` 函数中，删除所有依赖该标志设置 `disable_overlap_schedule` 的代码（`_handle_dflash`、`_handle_frozen_kv_mtp`、`_handle_eagle_family` 各有一份），改为由用户通过 `--disable-overlap-schedule` 直接控制；同时添加 `os.getenv` 弃用警告。
3. **DeepSeek V4 钩子清理**：在 `python/sglang/srt/arg_groups/deepseek_v4_hook.py` 的 `apply_deepseek_v4_defaults` 中，移除强制启用 Spec V2 的逻辑（V2 已是默认）。
4. **测试框架迁移**：所有原通过 `envs.SGLANG_ENABLE_SPEC_V2.override(...)` 选择同步路径的测试（如 `test_deepep_large.py`、`test_step3p5_flash_chain_mtp.py`、`test_eagle_constrained_decoding.py`、`standalone_fixture.py`、`spec_eagle_fixture.py`、`test_dflash.py`、`test_qwen35_fp4_mtp.py` 等），改为直接传入 `--disable-overlap-schedule` 参数；对应的类属性从 `enable_spec_v2` / `spec_v2` 重命名为 `disable_overlap`。
5. **文档更新**：更新 `docs_new/` 下的相关文档，将推荐设置改为 `--disable-overlap-schedule`，并删除 Ascend 页面中 75 行过时配置 export。

关键文件：
- `python/sglang/srt/arg_groups/speculative_hook.py`（模块 推测配置；类别 source；类型 dependency-wiring；符号 handle_speculative_decoding, _handle_dflash, _handle_frozen_kv_mtp, _handle_eagle_family）: 核心运行时变更：删除基于环境变量的 overlap 调度选择逻辑，添加弃用警告，并移除 import。
- `python/sglang/srt/arg_groups/deepseek_v4_hook.py`（模块 V4 配置；类别 source；类型 dependency-wiring；符号 apply_deepseek_v4_defaults）: 移除 DeepSeek V4 中强制启用 Spec V2 的逻辑，因为 V2 已是默认。
- `python/sglang/srt/environ.py`（模块 环境变量；类别 source；类型 core-logic）: 删除 SGLANG_ENABLE_SPEC_V2 的环境变量定义，这是该标志的源头。
- `test/registered/ep/test_deepep_large.py`（模块 EP 测试；类别 test；类型 test-coverage）: 重要的 DeepEP 测试迁移：将 envs.SGLANG_ENABLE_SPEC_V2.override(False) 改为 --disable-overlap-schedule。
- `test/registered/models_e2e/test_step3p5_flash_chain_mtp.py`（模块 链式 MTP；类别 test；类型 test-coverage；符号 setUpClass）: 链式 MTP 测试迁移：删除 setUpClass 中对 SGLANG_ENABLE_SPEC_V2.override(True) 的调用。
- `test/registered/spec/eagle/test_eagle_constrained_decoding.py`（模块 Eagle 约束；类别 test；类型 test-coverage）: Eagle 约束解码测试迁移：将 spec_v2 属性改为 disable_overlap，并动态添加 --disable-overlap-schedule。

关键符号：handle_speculative_decoding, apply_deepseek_v4_defaults, _handle_dflash, _handle_frozen_kv_mtp, _handle_eagle_family

## 关键源码片段

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

核心运行时变更：删除基于环境变量的 overlap 调度选择逻辑，添加弃用警告，并移除 import。

```python
# file: python/sglang/srt/arg_groups/speculative_hook.py
# 在 _handle_dflash、_handle_frozen_kv_mtp、_handle_eagle_family 中
# 删除以下重复代码块（每个算法 handler 各有一份）：
# if (
# not envs.SGLANG_ENABLE_SPEC_V2.get()
# and not server_args.disable_overlap_schedule
# ):
# server_args.disable_overlap_schedule = True
# 现在 disable_overlap_schedule 仅由用户通过 --disable-overlap-schedule 控制。

# 新增的弃用警告（位于 handle_speculative_decoding 函数开头）：
if os.getenv("SGLANG_ENABLE_SPEC_V2") is not None:
    logger.warning(
        "SGLANG_ENABLE_SPEC_V2 has been removed: speculative decoding "
        "always runs the V2 worker. Use --disable-overlap-schedule to "
        "select the non-overlap (synchronous) path."
    )

```

# 评论区精华

PR 无实质技术讨论。作者手动 rerun 了 `test_deepep_large.py` 和 `test_moriep_small.py`，其中 deepep 测试通过，moriep 因未注册 CI 被跳过。

- 暂无高价值评论线程

# 风险与影响

- 风险：主要风险是用户升级后若设置 `SGLANG_ENABLE_SPEC_V2=0`，原先的同步路径不再自动生效，需改用 `--disable-overlap-schedule`。PR 已添加一次性日志告警以缓解迁移冲突。测试中的 `disable_overlap` 属性重命名可能影响外部 fork/ 自定义测试，但官方测试已全部适配。DeepSeek V4 钩子移除了 force-set，但 V2 已是默认，无功能变化。
- 影响：**用户影响**：之前显式设置该环境变量的用户需移除设置，或改用 `--disable-overlap-schedule`。**系统影响**：无性能或稳定性变化。**团队影响**：减少一个废弃配置点的维护负担。
- 风险标记：废弃标志删除 , 用户脚本兼容性 , 默认行为变更 , 测试属性重命名

# 关联脉络

- PR #27959 [Spec] Remove the DFLASH V1 worker path: 同一功能线：移除 DFLASH V1 worker，是 Spec V1 退役的另一部分。
- PR #27950 [Spec] Fold the DFLASH worker base into DFlashWorkerV2 on BaseSpecWorker: 同一功能线：折叠 DFLASH worker，为 V1 移除做准备。
- PR #27967 Add SGLANG_ENABLE_WAR_BARRIER to force-enable the overlap scheduler WAR barrier on non-CUDA (e.g. AMD): 涉及调度和环境变量，与 SGLANG_ENABLE_SPEC_V2 的清理有间接关联。