ValueError: No valid attention backend… sparse not supported` — **no fallback exists** |

用户在 ROCm 环境(AMD MI355X gfx950)上使用 vLLM 推理 glm_moe_dsa 架构的稀疏 MLA 模型(如 GLM-5.1-FP8)时,当 prefill prompt 长度超过约 20,000 tokens,模型产生乱码输出。此问题影响 prefill 路径(非 de

ValueError: No valid attention backend... sparse not supported` — **no fallback exists** |

ValueError: No valid attention backend… sparse not supported — no fallback exists

快速结论:此报错发生在 ROCm 环境下运行稀疏 MLA 模型(如 GLM-5.1-FP8)时,因为 ROCM_AITER_MLA_SPARSE 是唯一可用后端,且该后端在 prefill 长度超过 ~20K tokens 时存在已知 bug。优先排查 prefill 长度是否超过阈值,或考虑使用非稀疏模式。

问题场景

用户在 ROCm 环境(AMD MI355X gfx950)上使用 vLLM 推理 glm_moe_dsa 架构的稀疏 MLA 模型(如 GLM-5.1-FP8)时,当 prefill prompt 长度超过约 20,000 tokens,模型产生乱码输出。此问题影响 prefill 路径(非 decode 路径),且 ROCM_AITER_MLA_SPARSE 是 ROCm 下唯一可用的稀疏 MLA 后端。

报错原文

ValueError: No valid attention backend... sparse not supported

原因分析

确认为 vLLM 内部 bug,非 ROCm 底层库问题。vLLM 的 rocm_aiter_mla_sparse.py 存在两个已知缺陷:

  • Bug 1:缺少 skip_kv_gather 判断和单次预分配缓冲区 — ROCm 路径在每次子 chunk 迭代时分配新的 torch.empty 缓冲区,并无条件重新 gather KV 数据,而 CUDA 参考实现 sparse_attn_indexer.py 在循环前分配一次共享工作区,并按 chunk 切片使用。对于超过 ~20K tokens 的 prompt,split_indexer_prefill_chunks 在第一个子 chunk 后将 skip_kv_gather 设为 True,但 ROCm 路径忽略此标志,导致产生未初始化的 FP8 key 缓冲区 → logits 损坏 → 第一个生成 token 即输出乱码。
  • Bug 2:profiling 阶段缺少工作区预留rocm_aiter_sparse_attn_indexer_fake 函数直接使用 torch.empty 分配缓冲区,未调用 current_workspace_manager().get_simultaneous(),导致 peak memory 被低估,运行时工作区可能与 KV cache 内存重叠。

重要提示:此问题在每次 prefill 时独立触发(非累积性),与 aiter 库或 ROCm 底层栈无关。

环境排查

  • vLLM 版本: 0.19.1rc1.dev296+gbcc2306ce(此 bug 可能存在于多个 nightly 版本)
  • aiter 版本: 0.1.10.post3(此版本已修复 decode 路径的 #39303 bug,但 prefill 路径仍受影响)
  • 模型架构: glm_moe_dsa(稀疏 MLA 模型,如 GLM-5.1-FP8 754B MoE FP8 E4M3)
  • 硬件: AMD Instinct MI355X OAM (gfx950:sramecc+:xnack-),4 卡 TP=4
  • 模型参数: 必须设置 use_sparse=True 且 TP=4(aiter ASM MLA 内核仅支持 gqa=16)
  • 必看文件: vllm/v1/attention/ops/rocm_aiter_mla_sparse.pysparse_attn_indexer.py

解决步骤

  1. 确认问题触发场景: 检查 prefill prompt 长度是否超过 ~20K tokens。如果是,则问题可能由该 bug 导致。
  2. 确认后端选择: 验证是否在使用 ROCMAiterMLASparseBackend(ROCm 下唯一可用后端,无 fallback)。
  3. 应用修复补丁(可优先尝试): 参考 PR #40049 的修复方案:
    • rocm_aiter_sparse_attn_indexer() 的 prefill 循环中,将缓冲区分配移至循环外,使用 current_workspace_manager().get_simultaneous() 在循环前一次性分配 k_fp8_fullk_scale_full,然后按 chunk.total_seq_lens 切片使用。
    • 添加 if not chunk.skip_kv_gather: 判断,仅对需要 gather 的 chunk 执行 cp_gather_indexer_k_quant_cache_triton
    • rocm_aiter_sparse_attn_indexer_fake 中调用 current_workspace_manager().get_simultaneous() 正确注册 peak memory。
  4. 临时规避方案: 如果无法应用补丁,尝试:
    • 缩短 prefill prompt 至 20K tokens 以内。
    • 在可行的情况下设置 use_sparse=False(但需确认模型是否支持非 sparse 模式)。
  5. 验证修复: 使用 Issue 中的最小复现脚本,测试不同 prompt 长度(20000、40000、60000、80000、100000),检查输出是否正确。

验证方法

运行复现脚本,检查以下条件:

  • 对于 20K tokens 以下 prompt,输出应正常(无乱码)。
  • 对于 20K-25K tokens prompt,输出应正常(部分修复后)。
  • 对于 25K tokens 以上 prompt,输出应正常(完全修复后)。
  • 通过 MD5/sha256 哈希验证输出的一致性,避免 tokenizer 压缩导致的误判。

参考来源

vllm-project/vllm #40018

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 10111

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注