Prhub

#26335 [Spec] Async-assert probes across EAGLE/MTP; zero `tgt_cache_loc`

原始 PR 作者 hnyls2002 合并时间 2026-05-27 02:34 文件变更 23 提交数 15 评论 1 代码增减 +171 / -94

执行摘要

为 EAGLE/MTP 添加异步断言探测并清理 NaN 检测路径

引用 PR body:test_eagle_infer_b::TestEAGLEServerAdditional (page_size=256, topk=5, fa3, fp16) 测试已不稳定数天,有三种失败模式:NaN 目标 logits、copy_all_layer_kv_cache_tiled 中的非法地址、embed_tokens(input_ids) 中 token id 超出 vocab size。本 PR 是深度防御 + 仪器化,不声称修复 bug,只缩小非法地址暴露面并确保下一次触发时能给出精确的异步断言。

建议 SRT speculative 路径维护者和使用 DeepSeek 系列模型用户关注本 PR 的防御性增强。环境变量合并和废弃标志移除的设计值得参考,异步断言的使用模式可在类似场景复用。若频繁遇到 flaky 测试或非法地址问题,建议在 CI 中启用 SGLANG_ENABLE_ASYNC_ASSERT 环境变量。

讨论亮点

本 PR 无人工 review 讨论,仅有一个自动机器人的配额警告评论,与技术内容无关。

实现拆解

  1. 创建独立探测模块:新增 python/sglang/srt/utils/async_probe.py,包含四个异步断言函数 maybe_detect_nanmaybe_detect_infmaybe_detect_oobmaybe_detect_page_aligned。所有函数通过 SGLANG_ENABLE_ASYNC_ASSERT 环境变量门控,默认关闭,避免生产环境开销。
  2. 修改 get_src_tgt_cache_loc 默认值:在 spec_utils.py 中将 tgt_cache_loctorch.empty_like 改为 torch.zeros_like,使得任何未被覆盖的尾部索引落在预留的 padding slot 0 上,而非缓存分配器返回的随机垃圾值,从而减少非法地址触发概率。
  3. 插入探测点:在 eagle_info.pyeagle_info_v2.pyeagle_worker.pyeagle_worker_v2.pymulti_layer_eagle_worker_v2.pyfrozen_kv_mtp_worker.py 等文件的合适位置(如 softmax 后、top_k/top_p renorm 后、accept_index 索引前、input_ids 使用前)添加 maybe_detect_nan/inf/oob 调用,覆盖每种推测解码变体的关键数据约束。
  4. 清理废弃功能:删除 server_args.py 中的 enable_nan_detection 字段和 --enable-nan-detection CLI 参数;移除 sampler.py_preprocess_logits 中基于 CPU 同步的 NaN 替换逻辑(torch.where + crash_on_warnings 分支),因为异步断言已取代其角色;在 environ.py 中将两个独立 env 合并为一个 SGLANG_ENABLE_ASYNC_ASSERT
  5. 内存池防御:在 mem_cache/memory_pool.pymove_kv_cache 入口添加 tgt_loc / src_loc 越界探测,避免因 OOB 索引导致 copy_all_layer_kv_cache_tiled 内核中的非法地址。
文件 模块 状态 重要度
python/sglang/srt/utils/async_probe.py 异步探测 added 8.5
python/sglang/srt/speculative/spec_utils.py 推测解码 modified 7.19
python/sglang/srt/layers/sampler.py 采样器 modified 6.34
python/sglang/srt/server_args.py 参数配置 modified 6.03
python/sglang/srt/environ.py 环境配置 modified 5.59
python/sglang/srt/speculative/eagle_info.py 推测解码 modified 6.21
python/sglang/srt/mem_cache/memory_pool.py 缓存管理 modified 5.59

关键符号

maybe_detect_nan maybe_detect_inf maybe_detect_oob maybe_detect_page_aligned get_src_tgt_cache_loc

关键源码片段

python/sglang/srt/speculative/spec_utils.py core-logic

移除原生的 maybe_detect_nan/oob 函数定义,并修改 get_src_tgt_cache_loc 将 empty_like 改为 zeros_like,显著降低因未初始化缓存位置导致的非法地址风险。

@torch.compile(dynamic=True, disable=_is_npu)
def get_src_tgt_cache_loc(
    seq_lens: torch.Tensor,
    out_cache_loc: torch.Tensor,
    accept_index: torch.Tensor,
    num_correct_drafts: torch.Tensor,
    draft_token_num: int,
    page_size: int,
):
    src_cache_loc = out_cache_loc[accept_index]
    # Use zeros_like instead of empty_like: any uncovered tail stays at slot 0
    # (reserved padding) instead of caching-allocator garbage, reducing risk
    # of illegal-address crashes in subsequent gather kernels.
    tgt_cache_loc = torch.zeros_like(src_cache_loc)
    extended_len = seq_lens + draft_token_num
    keep_len = torch.minimum(
        (seq_lens + num_correct_drafts + 1 + page_size - 1) // page_size * page_size,
        extended_len,
    )
    to_free_num_slots = extended_len - keep_len
    return src_cache_loc, tgt_cache_loc, to_free_num_slots

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. 废弃的 --enable-nan-detection CLI 参数移除可能破坏依赖该参数的旧启动脚本;
  2. 合并环境变量后,旧变量 SGLANG_SPEC_NAN_DETECTIONSGLANG_SPEC_OOB_DETECTION 不再生效,已无迁移代码,用户需手动设置 SGLANG_ENABLE_ASYNC_ASSERT
  3. 异步断言依赖 torch._assert_async,在某些 PyTorch 版本或非 CUDA 后端上可能不可用或行为不一致;
  4. 探测调用默认关闭,但若错误启用可能带来微小 GPU 开销;
  5. 移除 sampler 中 NaN 恢复路径后,若其他路径仍有 NaN 且探测未打开,可能导致更快崩溃(但这是期望行为)。

影响范围:直接涉及 sglang/srt 中所有 EAGLE v1/v2、multi-layer v2、frozen-KV MTP 以及内存池模块的推测解码路径。用户无感知(探测默认关闭)。对于使用 --enable-nan-detection 的用户,需迁移至 SGLANG_ENABLE_ASYNC_ASSERT=1。开发者在调试 flaky 测试时将受益于更精确的异步断言定位。

废弃 CLI 移除可能破坏旧脚本 环境变量迁移无后向兼容 异步断言依赖 PyTorch 实现 探测默认关闭但若误开有微小开销

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论