开始之前
一份编译好的 llama.cpp,以及一个诚实的问题:你到底在优化哪一个环节——token 生成和提示词处理受限于不同的东西,优化一个不会影响另一个。本文分开讲这两者,因为把它们混为一谈正是 CPU 调优建议里最常见的错误。
nproc --all # logical (with hyperthreads)
lscpu | grep -E "^Core|^Socket" # physical cores真正能让生成变快的是什么
每生成一个 token 都要把所有权重读一遍,所以在 CPU 上——和 GPU 一模一样——上限就是「带宽 ÷ 权重体积」。BLAS 库改变不了这个算术。真正管用的是两个杠杆。一是线程数:设成物理核心数,而不是 `nproc` 报出来的、把超线程也算进去翻倍的数字,超过物理核心数之后主要是增加争用。不写 `-t` 时 llama.cpp 本来就是这么做的:它用物理核心数,在混合架构的 Intel 处理器上只用性能核,启动日志里会打印 `system_info: n_threads = N`。二是量化档位,因为文件越小,每个 token 要读的字节就越少。
./build/bin/llama-server \
-m ./models/Llama-3.1-8B-Q4_K_M.gguf \
-c 4096 \
--host 127.0.0.1 --port 8080
# No -t: llama.cpp uses your physical core count (P-cores only on
# hybrid Intel). Override with -t N only to test a different value.OpenBLAS 真正能帮上什么忙
这正是本文要纠正的地方:llama.cpp 自己的构建文档明确写着,BLAS 加速只在批大小超过 32 的提示词处理阶段有用,对生成速度完全没有影响。如果你的场景是聊天——短提示词、长生成——OpenBLAS 几乎买不到什么。如果是批量处理大段文档、批大小很大的场景,用 `-DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS` 编译才值得。
sudo apt install -y libopenblas-dev
cmake -B build -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS
cmake --build build --config Release -j$(nproc)
# This changes prompt-processing speed on large batches.
# It will not change your tokens-per-second while chatting.确认调整真的有效
把生成速度和提示词处理速度分开测。`llama-bench` 正是干这个的:它把提示词处理(`pp512`)和生成(`tg128`)分成两行报告,每行是五次运行的平均值。现在的 `llama-cli` 是聊天程序,默认已经不打印耗时,不适合做这件事。如果你为了让聊天变快而编译了 BLAS,结果生成速度的数字没动,那不是构建坏了,而是上面文档写明的行为。
./build/bin/llama-bench -m ./models/Llama-3.1-8B-Q4_K_M.gguf
# Two rows, two different bottlenecks:
# pp512 t/s <- prompt processing (BLAS can move this)
# tg128 t/s <- generation (bandwidth-bound; BLAS will not)
# Compare thread counts in one run:
./build/bin/llama-bench -m ./models/Llama-3.1-8B-Q4_K_M.gguf -t 4,8,16数字大概该是什么样
Llama 3.1 8B 的 Q4_K_M 权重是 4.6 GB。本索引没有实测的 CPU 吞吐记录,而系统内存带宽在不同机器之间的差异,比显卡显存带宽的差异大得多——它取决于你的内存条数量、速度和通道配置,不只是 CPU 型号——所以本文不会重复旧版本里那个没有来源的「Hetzner 约 12 tok/s」「AWS 约 15 tok/s」的说法。你可以自己算:找到你机器的真实内存带宽(查规格,不是查 CPU 的宣传数字),除以 4.6 GB,就是你自己的理论上限。
出问题时
编译了 BLAS 之后生成速度没变快:符合预期——见上文。把 `-t` 设得比物理核心数还高会更慢而不是更快:超线程共享执行单元,超过物理核心数之后增加的是调度开销,不是吞吐量。提示词处理很快但生成还是慢:这是正常的,是带宽上限,不是配置问题——剩下真正管用的杠杆只有换更小的量化档位或加内存通道。如果你需要的是持续稳定的快速交互式聊天,而不是偶尔用一下 CPU 推理,诚实的答案是上一张 GPU,哪怕是小的:任何一张独显的显存带宽通常都是消费级 CPU 的好几倍。
常见问题
OpenBLAS 能让 llama.cpp 生成 token 更快吗?
不能。llama.cpp 自己的构建文档写明,BLAS 加速只在批大小超过 32 的提示词处理阶段有用,对生成性能完全没有影响。如果你的场景是交互式聊天,编译 OpenBLAS 不会改变你的 tok/s。
CPU 推理该用多少线程?
用 `lscpu` 查到的物理核心数,而不是开了超线程时 `nproc` 报出来的数字。那个数字是翻倍的,超过物理核心数通常只会增加争用,而不是吞吐量。其实很少需要手动设置:不写 `-t` 时,llama.cpp 本来就用物理核心数,在混合架构的 Intel 处理器上只用性能核。想试别的值,`llama-bench -t 4,8,16` 可以一次并排测出来。
CPU 推理和 GPU 比起来有多慢?
本索引没有实测的 CPU 吞吐数据可以引用,而且系统内存带宽在不同机器间差异太大,给一个数字也没什么意义。可以确定的是:任何一张独显的显存带宽通常是系统内存的好几倍,而生成速度正比于「带宽 ÷ 模型权重体积」——所以差距通常很大,GPU 占优。
这篇指南用到了什么
- 格式
- GGUF
接下来
看看 💻 32 GB RAM (CPU) 还能跑哪些模型反向查询 —— 32GB、4096 上下文,按质量排序本文涉及的模型
它真的跑起来了吗?
复制命令并不等于它能用,所以站内只在这里问一次。除了你的这个回答之外,不收集任何东西。