快速结论:在 Android/Termux 上通过 shim 把 llama.cpp 的 Vulkan 后端指向高通 Adreno 闭源驱动时,只要 -ngl >= 1 就会静默 SIGABRT(exit 134);问题通常不在驱动本身,而是运行时缺少驱动的着色器编译器后端 libllvm-qgl.so,优先排查该文件是否被复制到驱动可加载路径。
适用环境:llama.cpp master 0c1e57098bba43ac29e6e3b677cdceebdd22334f(2026-10-01),-DGGML_VULKAN=ON -DCMAKE_BUILD_TYPE=Release,clang 21.1.8 for Android aarch64;设备 Qualcomm Adreno 830 / Snapdragon 8 Elite(SM8750),Android 16,Termux 非 root;模型 Qwen2.5-Coder-7B Q4_K_M。对照组为同机 Turnip Mesa 驱动。
最快修复方案:把 /vendor 下的 libllvm-qgl.so(约 21.5 MB)一并复制到运行时的驱动加载路径,与 libllvm-glnext.so、libgsl.so 放在一起。Issue 中同一二进制、同一参数、同一设备的 A/B 验证结果:缺少该文件 → exit 134(仅 231 字节输出);补齐该文件 → exit 0。
注意事项:该文件不在 vulkan.adreno.so 的 DT_NEEDED 里,是运行时由 libllvm-glnext.so 首次编译 shader 时惰性 dlopen 的,所以静态依赖检查看不到它,容易漏拷。此结论来自单一设备的复现,其他 Adreno 机型或 Android 版本的编译器拆分方式可能不同,仍需按同样方式核对。
问题场景
在 Android/Termux 上用 llama.cpp 的 Vulkan 后端跑推理或 llama-bench,并通过一个约 90 行的 shim(导出 vk_icdGetInstanceProcAddr / vkGetInstanceProcAddr / vk_icdNegotiateLoaderICDInterfaceVersion,转发到高通的 qglinternal::vkGetInstanceProcAddr)让 libvulkan 加载到高通 Adreno 闭源驱动。此时任何 -ngl >= 1 的 offload 路径都会在模型 warm-up 阶段崩溃,进程无任何错误输出;-ngl 0 正常。
报错原文
Vulkan: aborts with no diagnostic on the Qualcomm Adreno driver (works on Turnip, same binary, same args)
llama-bench -m qwen2.5-coder-7b.gguf -ngl 1 -p 8 -n 8 -r 1
-> exit 134 (SIGABRT), 231-byte log
sched_reserve: Vulkan0 compute buffer size = 24.73 MiB
sched_reserve: graph (pp bs=64, tg bs=1): nodes = 126/126, splits = 468/74
sched_reserve: reserve took 8.7 ms
common_init_: warming up the model with an empty run - please wait ...
-> SIGABRT
0 && "Failed to load core compiler"
vendor/qcom/proprietary/graphics/adreno200/shadercompiler/
HighLevelCompiler/lib/LA/thin_compiler/Context.cpp:52
原因分析
已确认根因不是驱动软件缺陷,而是运行时缺少驱动的一个组件:Adreno 的 Vulkan shader 编译器被拆成两个库,libllvm-glnext.so(约 2 MB,由 vulkan.adreno.so 直接加载)和 libllvm-qgl.so(约 21.5 MB)。后者不在 vulkan.adreno.so 的 DT_NEEDED 中,由 libllvm-glnext.so 在第一次编译 shader 时惰性 dlopen。当 libllvm-qgl.so 缺失时,编译器前端找不到后端,走到 libllvm-glnext.so 内的一个 assert 并 abort(),于是进程 SIGABRT。
这同时解释了“完全没有诊断输出”的现象:这些编译器库不使用 __android_log_*,而是通过 fprintf/fwrite 写 stderr,在 Android 上会进入 tombstone 而不是 logcat。因此 Issue #29794 那类在创建路径上加日志的补丁看不到任何东西——创建与 pipeline 设置都成功了,失败发生在之后的首次 compute dispatch(warm-up)里,且直接杀掉进程而不是返回 VkResult。此前观察到的 int dot 能力差异(Turnip 报 0、高通驱动报 1)只是两个驱动的能力差异,没有证据指向它是触发条件。
另外,Issue 中提到 shader 编译失败若被捕获并标记 pipeline_failures、把受影响 op 退回 CPU(参考 whisper.cpp PR #3719 的做法),可以把静默进程死亡变成“N ops unavailable, running on CPU”这类可见信息,但这条路属于改进建议,并非本次问题的修复手段。
环境排查
- llama.cpp 构建:master
0c1e57098bba43ac29e6e3b677cdceebdd22334f,-DGGML_VULKAN=ON -DCMAKE_BUILD_TYPE=Release,clang 21.1.8 for Android aarch64,on-device 构建。 - 设备与系统:Qualcomm Adreno 830 / Snapdragon 8 Elite(SM8750),Android 16,Termux(非 root)。
- 模型:Qwen2.5-Coder-7B Q4_K_M(4.36 GiB)。
- ICD 选择:
VK_ICD_FILENAMES指向 shim.json 时走高通驱动,unset 时走 Turnip,用于 A/B 对照。 - 驱动加载路径下的文件完整性:确认
libllvm-glnext.so、libgsl.so、libllvm-qgl.so是否都已从/vendor复制到同一可加载路径。 - 复现参数:
-ngl 0正常,-ngl 1/2/4/99均 exit 134。
解决步骤
- 确认当前 Runtime 驱动目录里有哪些编译器相关文件,重点看是否只有
libllvm-glnext.so和libgsl.so,而缺少libllvm-qgl.so。 - 从设备
/vendor中取出libllvm-qgl.so(约 21.5 MB),复制到 shim 所指向的驱动可加载路径,与libllvm-glnext.so放在一起。 - 保持二进制与参数不变,重新运行崩溃命令:
VK_ICD_FILENAMES=<shim.json> llama-bench -m qwen2.5-coder-7b.gguf -ngl 1 -p 8 -n 8 -r 1。 - 若补齐后仍崩溃,用
-v观察是否仍能走到common_init_: warming up the model with an empty run,并检查 tombstone 中是否有Failed to load core compiler之类的 assert 信息,以确认缺失的文件是否还有其他。
验证方法
在同一设备、同一二进制、同一命令下仅改变 libllvm-qgl.so 是否存在,观察退出码:缺失时为 exit 134(SIGABRT,总输出约 231 字节,仅 device line);存在时为 exit 0。Issue 的 A/B 结果即为该对照,补齐后 llama-bench 能正常完成 warm-up 并继续跑到基准测试输出。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: llama-index-embeddings-azure-openai 0.6.0 is still dependent on llama-index-llms-azure-openai>=0.4.0,<0.6](https://www.chat-gpts.plus/wp-content/uploads/2026/10/23325-955c0d99-768x403.jpg)

