本地跑大模型实战(七):llama.cpp 性能调优,让推理更快更省
本文是《本地大模型搭应用实战》系列第 7 篇。前面六篇解决了"能不能用"------部署、量化、API、tool call、RAG、agent。本篇解决"用得爽不爽"。同一台机器同一个模型,配置不同,token/s 能差好几倍。
影响性能的核心因素
本地推理的性能由几个变量决定,按影响力从大到小排:
- 模型规模与量化:8B Q4 比 32B Q8 快不是一个数量级的事情------参数量×每参数 bit 直接决定计算量
- GPU 卸载层数:纯 CPU vs 全部 GPU vs 混合,这是最大的速度变量
- 上下文长度:生成式推理的计算复杂度与上下文长度正相关。4K 和 32K 上下文的内存占用和计算量差数倍
- 批处理大小:batch size 越大,GPU 利用率越高,但延迟也越高
- KV cache:缓存机制直接决定重复请求的响应速度
- 线程数:CPU 推理时影响大,GPU 推理时影响小
关键参数逐个讲
--n-gpu-layers:最大加速杠杆
决定多少层神经网络卸载到 GPU。经验法则:
纯 CPU:--n-gpu-layers 0 → 2-10 tok/s(8B Q4)
部分 GPU:--n-gpu-layers 16 → 10-30 tok/s
全部 GPU:--n-gpu-layers -1 → 30-100+ tok/s
如何确定你的硬件能 offload 多少层?启动 server 时加 --verbose,看日志里的 total VRAM used。逐次调大 --n-gpu-layers,直到 VRAM 使用接近总显存的 85-90%(留 10-15% 给 KV cache 和系统)。超过 95% 会触发 OOM。
--ctx-size:上下文长度
默认通常是 2048 或 4096。对短对话来说够用,但对 RAG(需要拼接多个 chunk)或长文档问答,必须调大。
调大 --ctx-size 的代价:
- 显存/内存占用线性增长
- 首 token 延迟增加(需要处理更长的 prompt)
- 生成阶段的 token/s 变化不大
建议:按实际需要设,别为了"万无一失"设到模型理论最大。8K 能解决的事不设 32K。
--batch-size:吞吐 vs 延迟
batch size 决定一次处理多少 token 的 prompt 编码。数值越大:
- 长 prompt 的首 token 延迟越低(处理相同文本用时少)
- 内存占用增加
- 对生成阶段的逐 token 速度几乎无影响
常用值:256(低延迟,小模型)、512(平衡)、1024+(大模型+高吞吐)。
--threads:CPU 推理
纯 CPU 推理时,--threads 直接影响速度。设为核心数(非线程数),例如 8 核设 8。超过物理核心数不会更快,反而因上下文切换变慢。
GPU 推理时,只需少量 CPU 线程(4-8)处理 tokenizer、数据搬运等辅助工作,设太多提升微乎其微。
--flash-attn:免费提速
Flash Attention 是一种优化的注意力计算方式,在支持的 GPU 上能显著降低显存占用和提升速度。llama.cpp 中加 --flash-attn 即可启用,无副作用。有就开。
KV cache 相关
--cache-type-k q8_0 --cache-type-v q8_0:将 KV cache 量化为 8bit,显存占用减半,质量损失几乎不可感知--cache-reuse:启动缓存复用,对重复 prompt 场景(如系统提示不变、只变用户问题)能大幅降低首 token 延迟
CPU / GPU / 混合,怎么选
| 硬件条件 | 策略 | 典型速度(8B Q4) |
|---|---|---|
| 无独显,32GB+ RAM | 纯 CPU,--threads 8-16 |
5-10 tok/s |
| 8GB 显存 | 部分 GPU offload(~20 层) | 15-25 tok/s |
| 12-16GB 显存 | 大部分或全部 GPU offload | 30-60 tok/s |
| 24GB+ 显存 | 全部 GPU offload | 50-100+ tok/s |
纯 CPU 跑 14B 模型:2-5 tok/s,勉强可用于对话。超过 32B 的模型,纯 CPU 基本不可用于交互式场景,需 GPU 或接受十几秒才出一个字的现实。
怎么测
llama.cpp 自带了 benchmark 工具。编译时加 -DGGML_BUILD_BENCHMARKS=ON 可得 llama-bench:
bash
./llama-bench -m qwen3-8b-q4_k_m.gguf -p 512 -n 128
输出示例:
| model | size | backend | ngl | pp 512 | tg 128 |
| qwen3-8b-q4_k_m | 4.68 GiB | CUDA | 99 | 1430.71 | 85.47 |
pp 512 = prompt processing 512 tokens 的速度(tokens/s),tg 128 = text generation 128 tokens 的速度。
对于日常使用,也可以用实际的 llama-server + 固定 prompt 测端到端延迟:
bash
time curl -s http://localhost:8080/v1/chat/completions \
-d '{"messages":[{"role":"user","content":"一句话介绍量子计算"}],"max_tokens":50}'
改参数后用同样的 prompt 对比,才是公平的。
调优速查表
| 目标 | 优先调 |
|---|---|
| 更快 | --n-gpu-layers(加满或尽可能多)、--flash-attn(有就开) |
| 省显存 | --cache-type-k q8_0 --cache-type-v q8_0、降低 --ctx-size、降低 --n-gpu-layers |
| 更高并发 | 提高 --parallel(server 并行请求数)、确保足够 VRAM 后加 --batch-size |
| 降低首 token 延迟 | --cache-reuse、加大 --batch-size |
| 纯 CPU 提速 | 加 --threads(到物理核心数)、确保编译时启用了 AVX2/AVX512 |
小结
调优有明确抓手:先选对量化(第 2 篇),再尽量把层数 offload 到 GPU,然后根据场景调 batch size 和上下文长度。改完用 benchmark 验证。下一篇收官------把七篇的能力整合成落地决策框架。
标签 :llama.cpp、性能优化、大模型、本地部署、模型推理、GPU、LLM