当我尝试在 x86_64 架构的 Debian 12 (bookworm) 系统上运行 ollama 程序时,遇到“非法指令”错误。作为普通用户和 root 用户都会出现此问题。
OS: Debian 12 (bookworm)
Kernel: Linux debian 6.1.0-17-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.69-1 (2023-12-30) x86_64 GNU/Linux
CPU: Intel(R) Celeron(R) CPU G1840 @ 2.80GHz
每当我尝试运行 ollama 或任何相关命令(例如 ollama --version)时,我都会收到“非法指令”错误。我按照各种故障排除步骤来诊断问题,包括重新安装 llama、验证 CPU 架构以及检查是否缺少依赖项。
我尝试在 Debian 12 (bookworm) x86_64 系统上运行 ollama 程序,并期望它执行时不会出现错误,并提供预期的输出或版本信息。但是,当我运行 ollama 和相关命令(例如 ollama --version)时,我遇到了“非法指令”错误。这个错误是意外的,它阻止了程序按预期运行。
您需要一个不需要新 CPU 功能的程序版本。
多年来,x86-64 中添加了许多扩展,只有较新的 CPU 支持。特别是 AVX 和其他 SIMD 扩展;您的 Celeron G1840 有 SSE4.2,但没有 AVX 或更高版本 (https://www.intel.com/content/www/us/en/products/sku/80800/intel-celeron-processor-g1840-2m-cache- 2-80-ghz/specations.html - CPU 核心是 Haswell 微架构,但它是 Pentium/Celeron,因此他们通过禁用 AVX/AVX2/FMA 和 BMI1/2 来削弱它。
不幸的是,只有 Ice Lake 和后来的 Pentium/Celeron CPU 具有这些
-march=x86-64-v3
功能。
您构建的
ollama
可能假定您的 CPU 不具备某些 CPU 功能 (/proc/cpuinfo
)。你可以运行 gdb ollama
然后在 GDB 中运行 run
,或者如果你需要传递 args则运行
run -foo /path
当 GDB 在 SIGILL 停止时,
disas $pc, +15
反汇编从故障地址开始的最多 15 个字节,并查看第一条指令以找出故障所在。如果它以 v
开头,例如 vmovdqa (%rdi), %xmm0
,则它是 AVX 指令。
你的操作系统对此无能为力;它足够新,如果您的 CPU 支持 AVX(或 AVX-512),它就会启用它。
Skylake 有一个勘误表,其中 Pentium/Celeron 型号报告 BMI1/2 在 CPUID 中可用,但无论如何它们都会出现错误,因此尝试检测 CPU 支持的程序将被误导。
但是 CPUID 错误是 Skylake 中的新错误,因此不会影响您;我记得人们 (包括我自己)惊讶甚至有没有 BMI 扩展的 Skylake CPU,或者担心所有 SKL 型号都缺乏 BMI。而且它是通过微代码更新修复的,这正是可更新微代码可以轻松修复的事情。
也许英特尔通过禁用机器代码中的 VEX 前缀解码来禁用这些 CPU 上的 AVX,BMI 指令也依赖于机器代码。如果是这样,禁用体重指数可能只是一个可以接受的牺牲品,而不是真正的目标。 (我不知道非 VEX BMI 指令如何在这些 CPU 上执行。这实际上只是
tzcnt
;lzcnt
和 popcnt
有自己的功能位。对于非 VEX BMI 指令,tzcnt
的工作方式与 bsf
相同) -零输入,并且大多数编译器生成的代码不依赖于 input=0 行为。)