
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.py和sparse_attn_indexer.py
解决步骤
- 确认问题触发场景: 检查 prefill prompt 长度是否超过 ~20K tokens。如果是,则问题可能由该 bug 导致。
- 确认后端选择: 验证是否在使用
ROCMAiterMLASparseBackend(ROCm 下唯一可用后端,无 fallback)。 - 应用修复补丁(可优先尝试): 参考 PR #40049 的修复方案:
- 在
rocm_aiter_sparse_attn_indexer()的 prefill 循环中,将缓冲区分配移至循环外,使用current_workspace_manager().get_simultaneous()在循环前一次性分配k_fp8_full和k_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。
- 在
- 临时规避方案: 如果无法应用补丁,尝试:
- 缩短 prefill prompt 至 20K tokens 以内。
- 在可行的情况下设置
use_sparse=False(但需确认模型是否支持非 sparse 模式)。
- 验证修复: 使用 Issue 中的最小复现脚本,测试不同 prompt 长度(20000、40000、60000、80000、100000),检查输出是否正确。
验证方法
运行复现脚本,检查以下条件:
- 对于 20K tokens 以下 prompt,输出应正常(无乱码)。
- 对于 20K-25K tokens prompt,输出应正常(部分修复后)。
- 对于 25K tokens 以上 prompt,输出应正常(完全修复后)。
- 通过 MD5/sha256 哈希验证输出的一致性,避免 tokenizer 压缩导致的误判。



