Eval bug: `GGML_ASSERT(ggml_can_mul_mat(a, b)) failed` when –parallel is not power of 2 (embeddinggemma)

这个报错通常出现在 llama-server 以 embedding 模式(如 embeddinggemma / gemma-embedding2 模型)加载时,`--parallel`(即 `n_seq_max`)被设置为非 2 的幂,导致内部矩阵乘法形状不匹配并触发断言。优先排查并调整 `--p

快速结论:这个报错通常出现在 llama-server 以 embedding 模式(如 embeddinggemma / gemma-embedding2 模型)加载时,`–parallel`(即 `n_seq_max`)被设置为非 2 的幂,导致内部矩阵乘法形状不匹配并触发断言。优先排查并调整 `–parallel` / `n_seq_max` 取值。

适用环境:Issue 中已确认:llama.cpp build 7527 (7f459c9),GNU 14.3.0,Linux x86_64;硬件包括 RTX 4090(compute capability 8.9,VMM yes),且在 `CUDA_VISIBLE_DEVICES=`(纯 CPU)下同样复现。另有报告在 Windows 11 上通过 LM Studio 的 llama.cpp Vulkan 运行时(`llama.cpp-win-x86_64-vulkan-avx2@2.56.0`)、Intel UHD 770 iGPU 上复现。

最快修复方案:暂无确认的一步修复方案。Issue 中提到 #18536 应可修复该问题,但后续评论反馈在较新版本(含 embeddinggemma-2)上仍会复现,可优先尝试把 `–parallel`(`n_seq_max`)设置为 2 的幂。

注意事项:#18536 的修复范围在后续反馈中受到质疑,未必覆盖新的 `gemma-embedding2` 架构或上层调用方自行选择的 `n_seq_max` 值。即使把 `–parallel` 调整为 2 的幂可作为规避手段,也不代表底层断言逻辑已被彻底修正,请以实际版本与复现结果为准。

问题场景

用户在 llama.cpp 中以 embedding 模式启动服务时触发崩溃。典型命令为:

CUDA_VISIBLE_DEVICES= llama-server -hf ggml-org/embeddinggemma-300M-GGUF --embeddings --parallel 65 -fit off

使用模型为 ggml-org/embeddinggemma-300M-GGUF(Q8_0),并通过 `–parallel` 指定并发序列数。当 `–parallel` 不是 2 的幂(示例中为 65)时,服务在加载模型阶段即崩溃。后续评论中还出现两类相关场景:一是通过 LM Studio 内置的 “Chat with Documents” RAG 功能加载 embeddinggemma-2(740M,arch `gemma-embedding2`)时崩溃;二是用户使用 `–parallel 15`、`-c 16005`、`–kv-unified`、`–batch-size 2048`、`–ubatch-size 2048` 的参数组合时,重新编译最新 release 后仍复现同样断言。

报错原文

Eval bug: `GGML_ASSERT(ggml_can_mul_mat(a, b)) failed` when --parallel is not power of 2 (embeddinggemma)

/app/llama.cpp/ggml/src/ggml.c:3282: GGML_ASSERT(ggml_can_mul_mat(a, b)) failed
./llama.cpp/llama-server(+0x983896) [0x55ff50cf5896]
./llama.cpp/llama-server(+0x983e8d) [0x55ff50cf5e8d]
./llama.cpp/llama-server(+0x984070) [0x55ff50cf6070]
./llama.cpp/llama-server(+0x98c841) [0x55ff50cfe841]
./llama.cpp/llama-server(+0x68daa0) [0x55ff509ffaa0]
./llama.cpp/llama-server(+0x70a269) [0x55ff50a7c269]
./llama.cpp/llama-server(+0x670181) [0x55ff509e2181]
./llama.cpp/llama-server(+0x6716cb) [0x55ff509e36cb]
./llama.cpp/llama-server(+0x673d46) [0x55ff509e5d46]
./llama.cpp/llama-server(+0x6751b8) [0x55ff509e71b8]
./llama.cpp/llama-server(+0x3e68de) [0x55ff507588de]
./llama.cpp/llama-server(+0x3e7992) [0x55ff50759992]
./llama.cpp/llama-server(+0x3ec2a4) [0x55ff5075e2a4]
./llama.cpp/llama-server(+0x3c60e6) [0x55ff507380e6]
./llama.cpp/llama-server(+0x3c8e37) [0x55ff5073ae37]
./llama.cpp/llama-server(+0x261d5b) [0x55ff505d3d5b]
./llama.cpp/llama-server(+0x182615) [0x55ff504f4615]
./llama.cpp/llama-server(+0x184c07) [0x55ff504f6c07]

后续评论中报告同一断言在经过 `build_pooling` 的调用栈中复现,示例:

GGML_ASSERT(ggml_can_mul_mat(a, b)) failed in ggml.c, same stack through build_pooling

原因分析

最可能的原因是 embedding 路径(pooling 相关图构建)在 `–parallel` / `n_seq_max` 为非 2 的幂时,生成的张量形状无法满足 `ggml_can_mul_mat` 对矩阵乘法的形状约束,从而在 `ggml.c` 中触发断言。Issue 正文中用户观察到:当 `–parallel` 不是 2 的幂时,llama-server 崩溃;后续评论也指出崩溃点经过 `build_pooling`。

Issue 中有人提到 #18536 应可修复该问题,但同时给出建议:在不使用 unified cache 时,应尽量让总 `n_ctx` 能被序列数整除,并出现了如下提示:

llama_context: n_ctx is not divisible by n_seq_max - rounding down to 16640

不过,后续评论反馈在较新版本上仍可复现,且覆盖到新的 `gemma-embedding2` 架构,因此该修复可能未完全覆盖所有调用路径或架构。(此为基于评论的推断,非 Issue 中已确认的最终结论。)

环境排查

  • 确认 llama.cpp 的具体 build 号(Issue 中为 7527 / 7f459c9)与编译方式(GNU 14.3.0,Linux x86_64)。
  • 确认模型:embeddinggemma-300M-GGUF(Q8_0)或 embeddinggemma-2(740M,arch `gemma-embedding2`)。
  • 确认是否启用 embedding 模式(`–embeddings` / `–embedding`)以及 pooling 方式(示例中为 `–pooling mean`)。
  • 确认 `–parallel` / `n_seq_max` 取值是否为 2 的幂,以及 `-c`、`–batch-size`、`–ubatch-size`、`–kv-unified` 的组合。
  • 确认执行后端:CUDA(RTX 4090)还是纯 CPU(`CUDA_VISIBLE_DEVICES=`);评论中还包括 Vulkan(Intel UHD 770 iGPU)。
  • 若通过 LM Studio 等上层工具加载,注意其内部是否自行设置了非 2 的幂的 `–parallel` / `n_seq_max`。

解决步骤

  1. 记录当前完整启动命令与崩溃日志,确认崩溃发生在加载阶段还是推理阶段。
  2. 检查 `–parallel`(`n_seq_max`)取值,可优先尝试改成 2 的幂(如 64、128)后再启动,观察断言是否消失。
  3. 若不使用 unified cache,尽量让总 `n_ctx` 能被序列数整除,避免出现 “n_ctx is not divisible by n_seq_max – rounding down” 的提示。
  4. 将 llama.cpp 更新到包含 #18536 的版本后再测,并记录 build 号;若仍复现,可对比旧版与新版行为。
  5. 如果通过 LM Studio 等上层工具触发,可尝试绕过其内置 RAG 流程,直接对 OpenAI 兼容的 `/v1/embeddings` 端点做单条、批量、并发测试,以判断是否为上层自行配置的 `n_seq_max` 导致。
  6. 若以上规避方式均无效,可将完整命令、build 号、模型架构与完整堆栈附到 Issue 中继续反馈。

验证方法

使用调整后的 `–parallel`(2 的幂)与参数组合重新启动 llama-server,观察模型加载与 `/v1/embeddings` 请求期间是否还会出现 `GGML_ASSERT(ggml_can_mul_mat(a, b)) failed`。若加载与推理阶段均不再触发断言,且 embedding 结果可正常返回,说明规避生效。若在新 build 上仍复现,则说明该修复未覆盖你的调用路径或模型架构。

参考来源

ggml-org/llama.cpp #18532

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 29001

发表回复

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