Eval bug: Gemma4 E4B MTP drafter crashes at slot init with fatal error in fattn.cu:110

用户在 llama-server 上加载以下模型时触发: 主模型: gemma-4-E4B-it-qat-UD-Q4_K_XL.gguf (来自 Unsloth) Draft 模型: mtp-gemma-4-E4B-it.gguf 启动参数包含 --spec-type draft-mtp --spe

Eval bug: Gemma4 E4B MTP drafter crashes at slot init with fatal error in fattn.cu:110

Eval bug: Gemma4 E4B MTP drafter crashes at slot init with fatal error in fattn.cu:110

快速结论: 该报错在使用 Gemma4 E4B 模型配合 MTP (Multi-Token Prediction) draft 模型进行推测解码(speculative decoding)时触发,发生在 slot 初始化阶段的 warmup decode 过程中。优先尝试关闭 flash attention(-fa off)作为临时工作区,或应用 fattn.cucase 512/576 分支的 fallback 修复。

问题场景

用户在 llama-server 上加载以下模型时触发:

  • 主模型:gemma-4-E4B-it-qat-UD-Q4_K_XL.gguf(来自 Unsloth)
  • Draft 模型:mtp-gemma-4-E4B-it.gguf
  • 启动参数包含 --spec-type draft-mtp --spec-draft-n-max 1

硬件环境为双 RTX 3090,使用 CUDA 后端。报错在加载模型时的 common_context_can_seq_rm 调用链中出现,最终落点在 ggml_cuda_flash_attn_ext

报错原文

ggml/src/ggml-cuda/fattn.cu:110: fatal error
  ggml_cuda_flash_attn_ext → ggml_cuda_graph_evaluate_and_capture
  → llama_decode → common_context_can_seq_rm → server_context_impl::load_model

原因分析

问题根本原因是 ggml_cuda_flash_attn_ext 中针对 512576 宽度(ncols)的 flash attention kernel 调度存在缺陷。在 Gemma4 E4B MTP 场景下,注意力计算的 GQA(Grouped Query Attention)ratio 超出了当前 kernel 实现所支持的路径,导致调度到了 BEST_FATTN_KERNEL_NONE 分支,从而触发 fatal error

可能原因:

  • Commit #24282 引入的 E4B/E2B 支持中,对 MTP draft 特殊形状的注意力计算适配不完整。
  • Rossmann 和 Triton 后端在 dispatch 到 ggml_cuda_flash_attn_ext_mma_f16 时,512 宽度下的 GQA 条件未正确处理。

环境排查

  • llama.cpp 版本: build 9584 (e25a32e98) 及之后版本(包括 ac4cddeb0)。
  • CUDA 版本: 13.3(用户之一),建议检查 CUDA 驱动版本(610.43.02 正常)。
  • ROCm 版本: 仅作记录,该问题在 AMD ROCm 后端同样出现(RX 7900 XTX)。
  • 模型文件: 确认下载的 .gguf 文件完整性;特别检查 draft 模型路径与参数是否匹配。
  • 编译选项: 建议确认是否开启 CUDA graphs(GGML_CUDA_GRAPHS)—— 部分用户使用了 ARCH=120a-real 自定义编译。但即使无 graphs 的常规 CUDA 编译也会崩溃。

解决步骤

  1. 临时工作区:关闭 flash attention
    llama-server 启动参数中添加 -fa off。这能让模型加载和服务正常运行,MTP 推测解码仍然有效。测试结果表明关闭后 draft-mtp 仍可正常工作,且带来约 39% 的 p50 延迟降低。
  2. 应用代码级修复(开发者/自编译用户):编辑 fattn.cu 文件
    修改 ggml/src/ggml-cuda/fattn.cu 中的 ggml_cuda_get_best_fattn_kernel() 函数,将以下 fallback 从 BEST_FATTN_KERNEL_NONE 改为 BEST_FATTN_KERNEL_TILE

    • case 512:return BEST_FATTN_KERNEL_TILE;
    • case 576:return BEST_FATTN_KERNEL_TILE;
  3. 可选:针对 GQA ratio 的精细化修复
    ggml_cuda_flash_attn_ext_mma_f16() 函数中,将原本的 case 512: 调用替换为基于 gqa_ratio 的条件分支:

    • 计算 gqa_ratio = Q->ne[2] / K->ne[2]
    • gqa_ratio > 4,调用 ...switch_ncols1<512, 512, 8>(ctx, dst)
    • gqa_ratio > 2,调用 ...switch_ncols1<512, 512, 4>(ctx, dst)
    • gqa_ratio > 1,调用 ...switch_ncols1<512, 512, 2>(ctx, dst)
    • 否则,保留原有调用 ...switch_ncols2<512, 512>(ctx, dst)
  4. 重新编译 CUDA 后端
    执行:

    cmake --build build --target ggml-cuda -j8

    无需完整的 clean 重新编译。
    注:以上代码修改方案由 Issue 评论区讨论提供,可优先尝试但尚未被官方合并,使用者应自行评估风险。

验证方法

重新运行相同的 llama-server 命令(保持 --spec-type draft-mtp 等参数)。成功后日志中应看到 speculative decoding context initializedserver is listening 等信息,不再出现 fattn.cu:110: fatal error。可使用任意请求测试服务是否正常响应。

参考来源

ggml-org/llama.cpp #24376

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

celebrityanime
celebrityanime
文章: 10694

发表回复

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