Prhub

#44527 [ROCm][DSv3.2] Eliminate per-decode FillFunctor launches in sparse-MLA hot loop

原始 PR 作者 frida-andersson 合并时间 2026-07-28 10:12 文件变更 1 提交数 3 评论 12 代码增减 +0 / -2

执行摘要

消除 DSv3.2 稀疏 MLA 解码热循环中的冗余 FillFunctor 启动

在 ROCm 稀疏 MLA 解码路径上,每次解码步骤都会启动两个 FillFunctor<T> 内核,造成纯启动开销和带宽浪费:FillFunctor<float> (out_logits.fill_(float("-inf"))) 和 FillFunctor<int> (topk_indices_buffer[:N] = -1)。根据 PR body 描述,上游已通过 current_workspace_manager() 在分配时预填充 out_logits,但未移除每步的 fill 调用;而 topk_indices_buffer 的填充也是冗余的,因为下游内核(如 sampler.cu:400)会完全覆盖活动行。删除这两行可将解码热循环 wall time 降低 44%,并为后续解码腾出更多 GPU 时间。

值得精读。本 PR 展示了一个典型的性能优化模式:消除冗余 GPU 内核启动。对于运行 DeepSeek 模型且使用 ROCm 的团队,此变更可直接带来吞吐提升。同时,review 中关于工作区管理的讨论(使用 current_workspace_manager 替代全局变量)是值得学习的架构实践。

讨论亮点

关键讨论点

  • CUDA 兼容性风险(reviewer tjtanaa):对于 sparse_attn_indexer.py 中删除 topk_indices_buffer[:N] = -1 的变更,tjtanaa 指出需要确保不影响 CUDA 路径的行为,因为其内核行为可能不同。作者 frida-andersson 回复指出,已检查 sampler.cu(line 400),其中 topKPerRowDecode/topKPerRowPrefill 内核会直接向未使用的 outIndices 槽写入 -1,因此预填充在两条路径上都是冗余的。
  • 使用 workspace manager:在较早的迭代中,frida-andersson 曾引入全局变量 _PAGED_MQA_LOGITS_BUF 进行工作区管理。tjtanaa 指出应使用已有的 current_workspace_manager()get_simultaneous()。作者采纳建议,rebase 后删除全局变量,仅保留一行 out_logits.fill_ 删除。
  • 其他 reviewer:AndreasKaratzas 标签了 @zyongye 以获取另一视角的审查。最终 tjtanaa 批准了 PR。

实现拆解

  1. 删除 out_logits.fill_ 调用:在文件 vllm/v1/attention/ops/rocm_aiter_mla_sparse.pyrocm_fp8_paged_mqa_logits 函数中删除 out_logits.fill_(float("-inf"))。该工作区已由上游的 current_workspace_manager().get_simultaneous() 在分配时预填充,每步重复填充是冗余的。
  2. 删除 topk_indices_buffer 预填充:在同一个文件中,删除 rocm_aiter_sparse_attn_indexer 函数内的 topk_indices_buffer[: hidden_states.shape[0]] = -1。类似地,在 vllm/model_executor/layers/sparse_attn_indexer.py 中也删除了对应的行(但 rebase 后上游已通过 skip_topk_buffer_clear 门控移除了该文件变更,最终只保留 ROCm 特定路径的删除)。
  3. 正确性验证:在 MI355X TP=4 上使用 GSM8K 20-shot 测试验证精度(FP8 KV cache),结果与发布基线一致(0.9492±0.006 vs 基准)。同时通过 profiler 确认两个 FillFunctor 内核不再出现在解码热循环中。
文件 模块 状态 重要度
vllm/v1/attention/ops/rocm_aiter_mla_sparse.py 注意力后端 modified 3.78
vllm/model_executor/layers/sparse_attn_indexer.py 稀疏索引器 modified 2.0

关键符号

rocm_fp8_paged_mqa_logits rocm_aiter_sparse_attn_indexer

关键源码片段

vllm/v1/attention/ops/rocm_aiter_mla_sparse.py core-logic

核心变更文件,删除了两个冗余的预填充操作,直接消除 FillFunctor 内核启动。

# 删除前(每次 decode 步骤都会触发额外的 FillFunctor 内核启动):
# out_logits.fill_(float("-inf")) # 冗余,因为 workspace 已在分配时预填充
# topk_indices_buffer[: hidden_states.shape[0]] = -1 # 冗余,因为下游内核会完全覆盖活动行# 对应函数签名和保留的核心调用不变:
def rocm_fp8_paged_mqa_logits(
    q_fp8: torch.Tensor,
    kv_cache_fp8: torch.Tensor,
    ...
) -> torch.Tensor:
    # 使用上游提供的 workspace manager 获取预填充的工作区
    (out_logits,) = current_workspace_manager().get_simultaneous(
        ((batch_size * next_n, max_model_len), torch.float32),
    )
    # 删除:out_logits.fill_(float("-inf")) # 这行已被移除
    deepgemm_fp8_paged_mqa_logits(
        q_fp8, kv_cache_fp8, ..., out_logits,
    )
    return out_logitsdef rocm_aiter_sparse_attn_indexer(
    hidden_states: torch.Tensor,
    seq_lens: torch.Tensor,
    ...
) -> None:
    # 删除:topk_indices_buffer[: hidden_states.shape[0]] = -1 # 这行已被移除
    if has_prefill:
        prefill_metadata = layer_attn_metadata.prefill
        ...

(注:此处展示删除后的代码骨架,实际变更仅移除两行,无其他改动。)

评论区精华

CUDA 兼容性风险 正确性

tjtanaa 担心删除 sparse_attn_indexer.py 中的 topk_indices_buffer 预填充会影响 CUDA 路径,因为其内核行为可能不同。

结论:作者检查 sampler.cu 确认下游内核会覆盖所有必要位置,且最终 rebase 后未修改 CUDA 路径,风险消除。 · 已解决

工作区管理方式 设计

tjtanaa 建议使用现有的 current_workspace_manager().get_simultaneous() 替代全局变量 _PAGED_MQA_LOGITS_BUF。

结论:作者采纳建议,rebase 后删除全局变量,仅保留删除冗余 fill_ 的行。 · 已解决

风险与影响

  • 回归风险:删除预填充操作主要影响稀疏 MLA 解码路径。如果下游内核(如 topKPerRowDecode)在某些配置下未完全覆盖输出缓冲区,可能导致读取未定义值。但作者通过代码审查确认 sampler.cu 中的内核会写入所有必要位置,且 GSM8K 精度测试通过,降低此风险。
  • CUDA 路径风险:初始 PR 还修改了 sparse_attn_indexer.py(通用 CUDA 路径),但 review 中引起争议。最终 rebase 后仅保留 ROCm 特定文件的修改,规避了 CUDA 兼容性问题。
  • 性能退化风险:无,变更仅删除冗余操作,预计仅带来性能提升。
  • 影响范围:仅影响 ROCm 平台下使用稀疏 MLA 的 DeepSeek v3.2 模型解码路径。涉及一个核心函数 rocm_fp8_paged_mqa_logits 和一个索引器函数 rocm_aiter_sparse_attn_indexer
  • 性能影响:消除两个 FillFunctor 内核启动(约占用 25 秒窗口内 2.0 秒 GPU 时间),解码热循环耗时降低 44%。对长序列、高并发场景收益明显。
  • 正确性影响:通过 GSM8K 20-shot 测试验证,精度无退化。
  • 团队影响:简化了 ROCm 特定路径的代码,减少维护负担。
核心路径变更 缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论