快速结论:在 llama.cpp 的 CUDA 后端上运行 MoE 模型时,如果二进制或构建过程按较旧的 compute capability 生成 PTX(例如用 61-virtual),再在 Turing/Volta 等较新的显卡上通过 JIT 运行,那么遇到 5–8 个 token 的 MoE 小批次时,MUL_MAT_ID 走 MMVQ 内核路径就可能触发 Eval bug: CUDA: MUL_MAT_ID via MMVQ fails with "invalid argument" on Turing when device code is compiled for an older arch (e.g. 61-virtual)。优先核对二进制包含哪些架构,以及宿主机与设备端对最大批次数的判断是否一致。
适用环境:Issue 已确认的环境包括:Linux(Ubuntu 24.04 / Fedora)、CUDA 12.9 / 12.8 / CUDA 11 预编译后端、NVIDIA GTX 1660 Super(cc 7.5)、RTX 3070(cc 8.6)、Tesla P100(cc 6.0)、Tesla V100(cc 7.0);llama.cpp 构建提交包括 e7268bf6a 和 b11999(0893ec98f),涉及 -DGGML_CUDA_FORCE_MMQ=ON、-DCMAKE_CUDA_ARCHITECTURES="61-virtual;80-virtual" 等构建方式。Python、PyTorch 版本在 Issue 中没有明确证据,不要据此推断。
最快修复方案:Issue 中验证过的临时规避方式是降低 MoE 相关的小批次规模,例如把 -ub 设为 4,可以避开 5–7 或 5–8 token 的崩溃区间;在 P100 上,-ub 4 被明确报告可避免崩溃。这不是根因修复,只能绕过触发条件。
注意事项:改用原生 -DCMAKE_CUDA_ARCHITECTURES=75 构建虽然不崩溃,但在这些卡上提示处理约慢 5 倍,不适合作为常规方案。Issue 中提出的一行补丁 cc = ggml_cuda_highest_compiled_arch(cc); 已在作者环境和 V100 复现环境中验证有效,但截至该 Issue 讨论,补丁尚未合并,属于可优先尝试、需要自行验证的改动;其他以宿主侧 cc 为判断依据、设备侧却使用 __CUDA_ARCH__ 的逻辑,可能存在同类不一致。
问题场景
用户在 llama.cpp 的 CUDA 后端上运行 MoE 量化模型(如 IQ3_XXS、Q4_K_M),并通过 llama-server 发送聊天请求或让后续请求命中 prompt cache。典型触发条件是 MoE 路径产生 5–8 个 token 的小批次,此时 MUL_MAT_ID 走 MMVQ:宿主侧按真实显卡算力(如 7.5、7.0、6.0)选择最大批次数,设备端内核却按编译时的 __CUDA_ARCH__(如 610、500)使用更保守的上限,于是宿主侧启动了编译内核不支持的配置,导致 CUDA 报 invalid argument。Dense 模型不受影响。
报错原文
CUDA error: invalid argument
current device: 0, in function ggml_cuda_kernel_launch at ggml-cuda/common.cuh:1715
... ggml_cuda_mul_mat_vec_q(...)
/app/ggml/src/ggml-cuda/ggml-cuda.cu:109: CUDA error
CUDA error: invalid argument
current device: 1, in function ggml_cuda_kernel_launch at /app/ggml/src/ggml-cuda/common.cuh:1716
cudaGetLastError()
...
/app/libggml-cuda.so(_Z23ggml_cuda_mul_mat_vec_qR25ggml_backend_cuda_contextPK11ggml_tensorS3_S3_PS1_PK29ggml_cuda_mm_fusion_args_host+0x832)
CUDA error: invalid argument
current device: 0, in function ggml_cuda_kernel_launch at ggml/src/ggml-cuda/common.cuh:1713
ggml_abort
mul_mat_vec_q_switch_ncols_dst
ggml_cuda_mul_mat_vec_q(...)
ggml_backend_cuda_graph_compute(...)
原因分析
最可能的原因在 mmvq.cu:宿主侧的 get_mmvq_mmid_max_batch(type, cc) 使用设备真实算力,例如 cc 7.5 会进入 get_mmvq_mmid_max_batch_turing_plus,IQ3_XXS 返回 7;设备侧的 get_mmvq_mmid_max_batch_for_device() 使用 __CUDA_ARCH__,如果 PTX 是为 6.1 编译并在 Turing 上 JIT 执行,该值为 610,会落到 get_mmvq_mmid_max_batch_pascal_older,对应 IQ3_XXS 为 4。当 MoE 批次为 5–7 个 token 时,宿主侧按 7 启动内核,而内核实际按 4 的上限编译,二者不匹配,导致内核启动参数非法。
评论中补充了同类场景:P100 默认运行 compute_50 PTX,宿主侧对 cc 600 返回 MMVQ_MAX_BATCH_SIZE,设备侧 __CUDA_ARCH__ 为 500,冲突区间为 5–8 个 token;V100 运行 compute_61 PTX,宿主侧 cc 7.0 允许最多 8,设备端为 610,8 token 的缓存尾部即可稳定触发。Issue 中还有用户关闭融合后仍然崩溃,说明节点融合不是必要条件,宿主/设备最大批次不一致本身已足够触发。其他以 cc 为键、设备侧却依赖 __CUDA_ARCH__ 的判断,可能原因相同。
环境排查
- 确认 llama.cpp 构建或预编译镜像实际包含哪些 CUDA 架构,重点确认是否缺少当前显卡的原生架构,例如 Turing cc 7.5、Volta cc 7.0、Pascal cc 6.0。
- 确认构建参数,如
-DCMAKE_CUDA_ARCHITECTURES="61-virtual;80-virtual"、-DGGML_CUDA_FORCE_MMQ=ON;预编译二进制可用cuobjdump --list-elf查看 ELF 架构列表。 - 记录 CUDA 版本、NVIDIA 驱动版本、显卡型号与计算能力;Issue 中涉及的驱动包括 595.99.02、580.196.07。
- 确认模型类型是 MoE 还是 Dense;Dense 模型正常不能说明 CUDA 配置无问题。
- 确认触发时的批次规模,可通过简单聊天请求、命中 prompt cache 的后续请求,或将
-ub设在 5–8 区间来复现。 - 如需验证是否依赖 PTX JIT,可参考评论中的
CUDA_DISABLE_PTX_JIT=1测试,但这只是诊断手段,不是修复方案。
解决步骤
- 先做临时规避:在启动
llama-server时把-ub降到 4 或更低,避开 5–8 个 token 的 MoE 小批次崩溃区间。Issue 中 P100 用户明确报告-ub 4可避免崩溃,但这不是根因修复。 - 核对当前二进制是否缺少显卡原生架构。可用
cuobjdump --list-elf查看包含的 cubin 架构;如果只运行 compute_61 之类的旧 PTX,说明正在依赖 JIT,存在宿主/设备算力判断不一致的风险。 - 可优先尝试 Issue 中提出的一行补丁:在
get_mmvq_mmid_max_batch的 NVIDIA 分支中加入cc = ggml_cuda_highest_compiled_arch(cc);,然后重新构建 CUDA 后端。该补丁在作者的 61-virtual 构建和评论者 V100 的 61-virtual 构建上被报告有效,但需自行验证未合并代码。 - 如果不需要旧架构兼容,也可以用包含当前显卡原生算力的架构重新构建,例如为 cc 7.5 构建
75、为 cc 7.0 构建70。Issue 中确认原生 75 构建不崩溃、原生 70 构建在 V100 上通过多个缓存尾部场景,但原生 75 构建在 1660 Super 上提示处理约慢 5 倍,属于速度代价较高的方案。 - 不要只依赖关闭融合(
GGML_CUDA_DISABLE_FUSION=1)作为修复;评论中已经确认关闭融合后崩溃仍出现在mul_mat_vec_q_switch_ncols_dst。 - 如果使用预编译镜像,关注后续镜像是否包含该修复或更新了架构列表;Issue 讨论时补丁尚未合并,需以实际版本为准。
验证方法
使用原先稳定触发的场景重新测试:发送最小聊天请求,或构造命中 prompt cache 后只剩 5–8 个 token 未缓存尾部的后续请求;确认不再出现 CUDA error: invalid argument,且进程不中止。评论中使用的验证方式还包括对 P100 运行 test-backend-ops test -o MUL_MAT_ID,修补前中止、修补后 931 项全部通过;也可以在 -ub 5–8 区间用 llama-bench 观察不再中止。若采用 -ub 4 规避,应确认低批次下稳定,但需认识到更大批次仍可能触发原问题。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


