Prhub

#30512 [DSA] Fix IMA in fused top-k v2: write all output slots on tie overflow

原始 PR 作者 Jiminator 合并时间 2026-07-08 19:49 文件变更 1 提交数 3 评论 6 代码增减 +9 / -0

执行摘要

修复 fused DSA top-k v2 在 tie 溢出时的 IMA 问题

GLM-5.2 with MTP (EAGLE) 和 fused DSA top-k v2 路径(默认开启)在 CUDA graphs 下约 1 分钟内即因 CUDA 非法内存访问崩溃。GPU coredump 指出崩溃发生在 sparse-MLA decode FMHA 的 UTMALDG.2D.GATHER4 指令上,原因是一个垃圾 paged-KV 索引由 top-k v2 产生。经过诊断,collect 最多保留 kMaxNumTie=1024 个阈值 bin 的并列结果,当 above_count < topk - 1024 时,handle_tie 写入的输出槽位数少于 topk,下游 transform pass 会尝试页转换所有 topk 个槽位,未写入的槽位包含未初始化的 staging memory,导致非法 KV 索引。

建议合入。这是一次针对特定崩溃的精确定位和修复,逻辑清晰、影响面小、风险低。值得关注的是团队如何通过 GPU coredump 定位到稀疏注意力的 KV 索引问题,这种诊断方法对于 SGLang 的其他类似问题有借鉴意义。

讨论亮点

Review 中 DarkSharpness 指出初始化代码应移到 if (num_ties <= topk) 分支内部,以确保只在需要时执行,且逻辑上更清晰。作者 Jiminator 在提交 4eacbdb 中完成了该调整,并解释由于循环从 t = num_ties 开始,效果等价,但放在分支内可读性更好。DarkSharpness 最终批准并评价“This fix should be 100% safe.”

实现拆解

仅在 python/sglang/jit_kernel/include/sgl_kernel/deepseek_v4/topk_impl.cuhhandle_tie 函数中,在 if (num_ties <= topk) 分支内,对于已有的部分写入(只写了前 num_ties 个槽位),增加一个循环将所有剩余的 [num_ties, topk) 槽位填充为 -1u(空 token 哨兵)。共 9 行新增代码,每个线程每次至多执行 2 次循环迭代。该改动不影响 kernel 的其他路径,也不影响性能。

文件 模块 状态 重要度
python/sglang/jit_kernel/include/sgl_kernel/deepseek_v4/topk_impl.cuh JIT 内核 modified 4.0

关键符号

handle_tie

关键源码片段

python/sglang/jit_kernel/include/sgl_kernel/deepseek_v4/topk_impl.cuh core-logic

核心修改文件:在 handle_tie 函数中增加 padding 循环,确保所有 topk 输出槽位都被初始化。

// 文件 : topk_impl.cuh
// handle_tie 函数的 num_ties <= topk 分支中
if (num_ties <= topk) {
    if (tx < num_ties)
        problem.emit(base + tx, tie_buffer[tx].idx);    // 当 ties 数量少于 topk 时(因为 collect 阶段最多保留 kMaxNumTie 个),
    // 剩余未写入的槽位必须被填充为 -1 ("no token") 哨兵。
    // 否则下游 transform pass 会读到未初始化的 staging memory,
    // 转换出垃圾页表索引,导致 sparse attention kernel 中发生非法内存访问 (IMA)。
    for (uint32_t t = num_ties + tx; t < topk; t += kBlockSize) {
        problem.emit(base + t, -1u);
    }
} else if (num_ties <= kWarpSize) {
    // 其他分支保持不变 ...
}

评论区精华

padding 初始化应移入 num_ties <= topk 分支 设计

DarkSharpness 建议将 padding 初始化代码从函数起始位置移到 `if (num_ties <= topk)` 分支内部,以确保只在需要时执行且代码更清晰。

结论:作者接受建议并在提交 4eacbdb 中完成移动,保持逻辑等价但可读性更好。 · 已解决

风险与影响

风险极低:改动仅在 tie overflow 且 num_ties <= topk 时填充未写入的槽位,使用已有的 -1 哨兵值,不影响任何其他路径。该路径之前会导致 IMA,填充后确保了内存安全。未经单元测试覆盖(PR 作者称手动验证了 kernel 测试和真实 workload),但逻辑简单可靠。

影响范围:修复了 GLM-5.2 with MTP 在 fused DSA top-k v2 路径下的稳定性和可用性问题。对于不使用该路径的场景(如 legacy top-k、disable-cuda-graph)无影响。Accuracy 和吞吐量不变(作者提供了 GSM8K 和 AIME25 基准结果)。全量 agentic sweep 中 0 IMA,之前在该 workload 的 concurrency-16 步骤上必崩。

核心路径变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论