llama.cpp 部署前沿大模型
本册覆盖 llama.cpp v0.9.0 的完整部署链路:参数语义、显存与 KV 计算、并行拓扑、逐模型可复制命令、调优方法与故障排查。
00导读
llama.cpp 的定位
llama.cpp 是一个纯 C/C++ 的 LLM 推理实现,基于 ggml 张量库,零 Python 依赖,可编译到几乎任何平台:x86、ARM、Apple Silicon、CUDA、ROCm、Vulkan、SYCL、Metal、甚至浏览器(WASM)。
2026 年它的定位非常清晰:
它不是用来跑万亿 MoE 的。1.6T 的模型即便量化到 2-bit 也要几百 GB,llama.cpp 的多卡能力(pipeline / experimental tensor parallel)撑不住这个量级。
它的真正价值在三处:
| 场景 | 为什么选它 |
|---|---|
| 本地 / 边缘部署 | 单机、单卡、甚至 CPU,无 Python 环境,一个二进制文件 |
| 极致量化 | 支持 1.5–8 bit 的几十种量化格式,让 70B 跑在 24GB 显卡上 |
| 快速验证与原型 | -hf user/repo 一条命令拉模型就跑,无需写代码 |
2026 年的一个新变化:llama.cpp 的 speculative decoding 能力大幅增强,已经支持 EAGLE-3、MTP、DFlash、DSpark、n-gram 系(ngram-simple / ngram-map-k / ngram-map-k4v / ngram-mod / ngram-cache)。这让它在小模型 + 低延迟场景下的竞争力明显提升。
数据基准
| 组件 | 基线 |
|---|---|
| llama.cpp | v0.9.0(2026-11-04) |
| 模型格式 | GGUF |
| 后端 | CPU / CUDA 12 / CUDA 13 / ROCm / MUSA / SYCL / Vulkan / Metal / CANN |
| Python | 仅转换脚本需要 |
三个必须先建立的心智模型
① GGUF 是唯一格式。
llama.cpp 只认 GGUF。HF 上的 safetensors 必须先转:
python convert_hf_to_gguf.py <hf-model-dir> --outtype bf16 --outfile model.gguf
或者直接下社区已转好的:
# 直接从 HF 拉,自动选量化 llama-cli -hf ggml-org/gemma-3-1b-it-GGUF
② -ngl(GPU layers)是最重要的参数。
它决定「多少层放进显存」。放不下的层会跑在 CPU 上——速度会掉一到两个数量级。所以 -ngl 的目标永远是「能放多少放多少」。
新版本的默认值是 auto,配合 --fit on(默认开启)会自动按显存调整未设置的参数。
③ 多卡是「流水」不是「张量」。
--split-mode layer(默认)是流水并行:每卡持有一段连续的层,KV 跟着层走。这种方式通信量最小,但需要足够多的 token 才能填满流水线。
--split-mode tensor 是实验性的张量并行,能降低延迟,但对互联带宽敏感,且限制很多(KV 必须是 f16/bf16/f32,--fit 不支持)。
012026 的部署格局
llama.cpp 能跑什么、不能跑什么
能跑(官方生态支持良好):
| 模型族 | 说明 |
|---|---|
| Llama 3.x / 4 | 最成熟 |
| Qwen 2.5 / 3 | 支持完善 |
| Gemma 3 / 4 | 官方有 GGUF 仓库 |
| gpt-oss 20b / 120b | 官方支持 |
| Mistral / Mixtral | 支持 |
| DeepSeek 蒸馏版 | 支持 |
| Phi / Granite / Command-R | 支持 |
不建议跑:
| 模型 | 原因 |
|---|---|
| DeepSeek-V4(1.6T) | 量化后仍数百 GB,多卡能力不足 |
| Kimi-K3(2.8T) | 同上 |
| Qwen3.5-397B | 即便 2-bit 也约 100 GB,需 4×A100,不划算 |
| GLM-5(744B) | 边界情况,2-bit 约 190 GB |
| MiniMax-M3(427B) | 边界情况 |
边界判断经验:
量化后大小 ≈ 参数量 × bits / 8
| 模型规模 | 4-bit 大小 | 2-bit 大小 | 可行性 |
|---|---|---|---|
| 7B | 3.5 GB | 1.8 GB | ✅ 单卡/CPU |
| 32B | 16 GB | 8 GB | ✅ 单张 24GB |
| 70B | 35 GB | 18 GB | ✅ 单张 48GB / 双卡 |
| 120B(gpt-oss,MXFP4) | — | ~63 GB | ✅ 单张 80GB |
| 235B | 118 GB | 59 GB | ⚠️ 多卡 |
| 397B | 199 GB | 99 GB | ⚠️ 4–8 卡 |
| 744B | 372 GB | 186 GB | ❌ 不推荐 |
| 1.6T | 800 GB | 400 GB | ❌ 不可行 |
除权重外还要 KV Cache 和计算缓冲。上表的 2-bit 数字是理论下限。
2026 年 llama.cpp 的能力增长
Speculative decoding 的方法矩阵(来自 docs/speculative.md):
| 方法 | --spec-type 值 | 需要 draft 模型 | 说明 |
|---|---|---|---|
| Draft model | draft-simple | ✅ | 最经典,小模型起草 |
| EAGLE-3 | draft-eagle3 | ✅ | 读取目标模型 hidden states,接受率更高 |
| MTP | draft-mtp | ✅ | 目标模型自带 MTP 头 |
| DFlash | draft-dflash | ✅ | 块扩散,一次前向产出整块草稿 |
| DSpark | draft-dspark | ✅ | DeepSeek 系的融合草稿模块 |
| N-gram (simple) | ngram-simple | ❌ | 零额外模型 |
| N-gram (map-k) | ngram-map-k | ❌ | 基于哈希表 |
| N-gram (map-k4v) | ngram-map-k4v | ❌ | 变体 |
| N-gram (mod) | ngram-mod | ❌ | 模运算索引 |
| N-gram (cache) | ngram-cache | ❌ | 缓存式 |
可以混用:带 draft 模型的方法可以与不带 draft 模型的方法组合。
02显存预算与 KV 计算
显存划分
┌────────────────────────────────────────────────────┐
│ Weights(-ngl 层在 GPU,其余在 CPU)│ KV │ Compute │
└────────────────────────────────────────────────────┘llama.cpp 的显存管理和其它框架最大的不同:权重可以部分放 CPU。
-ngl N → 前 N 层放 GPU -ngl 999 → 全部放 GPU(等价于 all) -ngl auto → 自动(默认)
关键:放不下的层走 CPU,每 token 都要通过 PCIe 传输权重/激活。速度会掉 10–100 倍。所以:
-ngl 的目标不是「刚好装下」,而是「尽量多放」。如果 40 层里有 36 层能放 GPU,不要满足于 36——试试能不能通过降 -c(上下文)或 -ctk q8_0 挤出第 37 层。
--fit 自动适配
--fit on(默认)会自动调整未显式设置的参数来适配设备内存。
# 什么都没设,让它自己算 llama-server -m model.gguf
--fit 与 --split-mode tensor 不兼容。用 tensor 模式时需要手动设 --ctx-size。
KV Cache 计算
KV_bytes_per_token = 2 × n_layers × n_kv_heads × head_dim × kv_dtype_bytes
n_kv_heads 由架构决定:MHA 等于 n_heads,GQA 等于 n_heads / g,MQA 等于 1。三者公式相同,只是取值不同。
llama.cpp 的 KV 精度用 -ctk(K)和 -ctv(V)分别控制:
| 值 | 字节 | 说明 |
|---|---|---|
f32 | 4 | 最高精度 |
f16 | 2 | 默认 |
bf16 | 2 | 与 f16 同大小 |
q8_0 | ~1.06 | 8-bit 量化,几乎无损 |
q5_1 | ~0.75 | 5-bit |
q5_0 | ~0.69 | |
q4_1 | ~0.63 | |
q4_0 | ~0.56 | |
iq4_nl | ~0.56 |
实践建议:
-ctk q8_0 -ctv q8_0是最划算的一档:省一半显存,精度损失极小- 不要只量化 K 或只量化 V:通常两个一起
-ctv量化要求开 Flash Attention(-fa on)
量化的收益
权重侧:
| 量化 | bits/权重 | 70B 模型大小 | 相对质量 |
|---|---|---|---|
| F16 / BF16 | 16 | 140 GB | 基准 |
| Q8_0 | 8.5 | 75 GB | 几乎无损 |
| Q6_K | 6.6 | 58 GB | 极小损失 |
| Q5_K_M | 5.7 | 50 GB | 很小损失 |
| Q4_K_M | 4.8 | 42 GB | 最常用平衡点 |
| Q3_K_M | 3.9 | 34 GB | 可感知损失 |
| Q2_K | 3.0 | 26 GB | 明显损失 |
| IQ1_S | ~1.6 | 14 GB | 仅极限场景 |
。再往下质量下降明显快于体积下降。
怎么估算总显存
总显存 ≈ 权重(量化后) + KV(ctx × per_token) + 计算缓冲(约 1–2 GB)
例:Llama-3.3-70B,Q4_K_M,32K 上下文,q8_0 KV
权重: 42 GB KV: 2 × 80 × 8 × 128 × 1.06 ≈ 174 KiB/token × 32768 ≈ 5.4 GB 缓冲: ~1.5 GB 总计: ≈ 49 GB → 需要 2× 24GB 或 1× 48GB
03架构与参数作用点
llama-server 的组件
┌──────────────────────────────────────────────┐
│ httplib(HTTP 层) │
│ · OpenAI 兼容:chat/completions, responses │
│ · Anthropic Messages API │
│ · /v1/embeddings, /rerank │
│ · /metrics, /slots, /props │
│ · Web UI │
└───────────────────┬──────────────────────────┘
▼
┌──────────────────────────────────────────────┐
│ server-context(多 slot 管理) │
│ · -np 个 slot,每个 slot 一条独立对话 │
│ · slot 可保存/恢复 KV(--slot-save-path) │
└───────────────────┬──────────────────────────┘
▼
┌──────────────────────────────────────────────┐
│ llama_context(批处理与采样) │
│ · continuous batching(-cb,默认开) │
│ · logical batch (-b) / physical batch (-ub) │
│ · speculative decoding │
└───────────────────┬──────────────────────────┘
▼
┌──────────────────────────────────────────────┐
│ libllama + ggml(计算图) │
│ · 后端:CPU / CUDA / ROCm / Metal / Vulkan │
│ · 层分配:-ngl / --n-cpu-moe │
└──────────────────────────────────────────────┘一次请求的路径
① HTTP 接入 /v1/chat/completions
↓
② 模板渲染 Jinja(--jinja,默认开)
↓ --chat-template-kwargs
③ slot 分配 -np 个 slot 中找一个空的
↓ --parallel
④ 分词 内置 tokenizer(GGUF 里带)
↓
⑤ 批处理 continuous batching
↓ -b / -ub
⑥ 推理 层在 GPU / CPU 之间切分
↓ -ngl / --n-cpu-moe
⑦ 采样 + 推测 可选 speculative
↓ --spec-type
⑧ 输出 流式 / 全量
↓ --reasoning-format两个 batch 参数的区别
这是 llama.cpp 特有的概念,容易混淆:
| 参数 | 名称 | 含义 |
|---|---|---|
-b, --batch-size | 逻辑批大小 | 一次 prompt 处理最多多少个 token(默认 2048) |
-ub, --ubatch-size | 物理批大小 | 单个计算图里最多多少个 token(默认 512) |
关系:逻辑批会被拆成多个物理批依次计算。
-b影响吞吐(一次能吃多长的 prompt)-ub影响显存峰值(单个计算图多大)- 显存不够时,优先降
-ub
04核心参数详解
4.1模型与上下文
| 参数 | 默认 | 说明 |
|---|---|---|
-m, --model | — | GGUF 文件路径 |
-hf <user>/<repo>[:quant] | — | 直接从 HF 拉取并选择量化 |
-mu, --model-url | — | 从 URL 拉取 |
-md, --model-draft | — | 草稿模型路径(投机解码) |
-mm, --mmproj | — | 多模态投影器路径 |
--alias | — | API 里显示的模型名(逗号分隔多个) |
-c, --ctx-size | 0(从模型读) | 上下文长度 |
-n, --predict | -1(无限) | 最大生成 token 数 |
--keep | 0 | 保留 prompt 开头的多少 token(-1 = 全部) |
--rope-scaling | 模型默认 | none / linear / yarn |
--rope-scale | — | 缩放倍数 |
--rope-freq-base | — | RoPE 基频 |
4.2GPU 与内存
| 参数 | 默认 | 说明 |
|---|---|---|
-ngl, --gpu-layers | auto | 最重要的参数:放 GPU 的层数。可用 999 或 all |
-sm, --split-mode | layer | none / layer / row(废弃)/ tensor(实验) |
-ts, --tensor-split | 自动 | 各卡分配比例,如 3,1 表示 75% / 25% |
-mg, --main-gpu | 0 | 主 GPU(split-mode none 时选卡) |
-dev, --device | 自动 | 限定设备,如 CUDA1 |
--list-devices | — | 列出可用设备与显存 |
--n-cpu-moe N | 0 | 把前 N 层的 MoE 专家权重放 CPU |
--n-cpu-ffn N | 0 | 把前 N 层的稠密 FFN 权重放 CPU |
--moe-cache-mib N | 0 | MoE 专家在 CPU 的 GPU 缓存大小(MiB) |
-fit, --fit | on | 自动适配未设置的参数到设备内存 |
--mlock | 关 | 锁定内存,防止换出 |
--no-mmap | 关(即默认 mmap) | 禁用内存映射 |
--n-cpu-moe 是 2026 年 llama.cpp 最有价值的参数之一。MoE 模型的专家权重占用巨大但每次只激活少量,把它放 CPU 只传激活的那部分,比把整层放 CPU 高效得多。这让 120B–235B 的 MoE 模型在单机上变得可行。
4.3KV Cache
| 参数 | 默认 | 说明 |
|---|---|---|
-ctk, --cache-type-k | f16 | K 的精度:f32/f16/bf16/q8_0/q4_0/q4_1/iq4_nl/q5_0/q5_1 |
-ctv, --cache-type-v | f16 | V 的精度,同上 |
-fa, --flash-attn | auto | on / off / auto |
--swa-full | 关 | 用全尺寸 SWA cache |
--slot-save-path | 关闭 | slot KV 的保存路径 |
-ctv 量化必须开 Flash Attention。设了 -ctv q8_0 但 -fa off 会报错。
4.4批处理与并行
| 参数 | 默认 | 说明 |
|---|---|---|
-b, --batch-size | 2048 | 逻辑批大小 |
-ub, --ubatch-size | 512 | 物理批大小(显存峰值由它决定) |
-np, --parallel | -1(自动) | slot 数,即并发对话数 |
-cb, --cont-batching | 开启 | 连续批处理 |
-t, --threads | -1(自动) | 生成阶段的 CPU 线程数 |
-tb, --threads-batch | 同 -t | 批处理/prompt 阶段的线程数 |
-C, --cpu-mask | — | CPU 亲和性掩码(十六进制) |
-Cr, --cpu-range | — | CPU 范围,如 0-7 |
--cpu-strict | 0 | 严格 CPU 放置 |
--prio | 0 | 进程优先级:-1 低 / 0 普通 / 1 中 / 2 高 / 3 实时 |
--poll | 50 | 轮询级别 0–100 |
4.5服务
| 参数 | 默认 | 说明 |
|---|---|---|
--host | 127.0.0.1 | 监听地址 |
--port | 9931 | 端口 |
--api-key | 无 | API 密钥(逗号分隔多个) |
--api-key-file | — | 密钥文件,一行一个,# 开头为注释 |
--metrics | 关闭 | Prometheus 指标端点 |
--slots | — | slot 监控端点 |
--props | 关闭 | 允许 POST /props 改全局属性 |
--path | — | 静态文件目录(Web UI) |
--timeout | 3600 | 读写超时(秒) |
--media-path | 关闭 | 本地媒体文件目录 |
--models-dir | — | 模型目录(支持动态加载多模型) |
--jinja | 开启 | 用 Jinja 模板引擎 |
--chat-template-kwargs | — | 传给模板的 JSON 参数 |
--reasoning-format | — | none / deepseek / deepseek-legacy |
--tool-server | — | 内置工具服务(如 demo) |
,不是 8000 也不是 30000。这个很容易踩。
4.6采样
| 参数 | 默认 |
|---|---|
--temp | 0.80 |
--top-k | 40(0 = 关闭) |
--top-p | 0.95(1.0 = 关闭) |
--min-p | — |
4.7投机解码
| 参数 | 说明 |
|---|---|
--spec-type | 逗号分隔的方法列表 |
--model-draft / -md | 草稿模型路径 |
--spec-draft-n-max | 最大草稿 token 数 |
--target-model-dir | 转换 EAGLE-3 / DFlash 时指定目标模型 |
05并行策略选型
本引擎的推理拓扑与 KV 存放
为便于阅读,下图使用小规模设备组解释机制,不代表旗舰模型能装入这些设备。
layer 是按层放置,tensor 是实验性权重/KV 切分,不是路由专家 EP。这里不画不存在对应配置的 TEP/DEP;-ngl 和 CPU offload 也不是 EP。
官方依据:llama.cpp 并行与配置文档。图示策略存在不代表某个模型、精度、硬件组合已实测。
三种 split mode
| 模式 | 机制 | 何时用 | 限制 |
|---|---|---|---|
none | 单卡,--main-gpu 选卡 | 显式限制在单卡 | — |
layer(默认) | 流水并行:每卡持连续的一段层,KV 跟着层走 | 默认选择;要更大显存 + 快 prefill;能容忍慢互联 | — |
row | 旧的行切分 TP | 已废弃,勿用 | 性能差 |
tensor | 实验性 TP:权重和 KV 都切 | 要低延迟;快互联(NVLink) | KV 必须 f16/bf16/f32;--fit 不支持;FA 必须开 |
流水 vs 张量的本质差异
官方文档讲得很清楚:
Pipeline-parallel runs different layers on different GPUs and processes tokens sequentially through the pipeline. This minimizes data transfers between GPUs but requires many tokens to scale well. Tensor-parallel splits each layer across GPUs and does multiple cross-GPU reductions per layer. This enables parallelizing any workload but is much more bottlenecked by the GPU interconnect speed. Pipeline-parallel maximizes batch throughput; tensor-parallel minimizes latency.
翻译成决策规则:
你的目标是? ├─ 吞吐(离线批处理、多用户)→ --split-mode layer(默认) └─ 延迟(单用户交互)→ --split-mode tensor(需 NVLink)
分配比例
# 两张卡显存不同:第一张 3 份,第二张 1 份 llama-server -m model.gguf -ts 3,1 # 等价写法(比例归一化) llama-server -m model.gguf -ts 75,25
比例按 --device 的顺序对应。
MoE 的 CPU 卸载策略
这是 llama.cpp 在 MoE 上的独门技巧。
传统做法:-ngl 放不下的层整层放 CPU。但 MoE 层的专家权重占绝大部分,而每次只激活 top-k 个。
llama.cpp 的做法:
# 把前 N 层的 MoE 专家权重放 CPU,注意力/共享专家留在 GPU llama-server -m model.gguf --n-cpu-moe 20 # 给 CPU 上的 MoE 专家一个 GPU 缓存 llama-server -m model.gguf --n-cpu-moe 20 --moe-cache-mib 2048
稠密模型用 --n-cpu-ffn:
llama-server -m model.gguf --n-cpu-ffn 10
让 120B 级 MoE 在单张 24–48GB 显卡上可跑。这是 llama.cpp 相对其它框架的独特优势。
06逐模型实战配置
6.1快速上手:一条命令
# 从 HF 直接拉(自动选量化) llama-cli -hf ggml-org/gemma-3-1b-it-GGUF # 服务化 llama-server -hf ggml-org/gemma-3-1b-it-GGUF
6.2gpt-oss-120b(推荐的重点模型)
117B 总参 / 5.1B 激活,原生 MXFP4,量化后约 63 GB。
单张 80GB 卡:
llama-server \ -m gpt-oss-120b-mxfp4.gguf \ -ngl 999 \ -c 131072 \ -fa on \ -ctk q8_0 -ctv q8_0 \ --jinja \ --reasoning-format deepseek \ --host 0.0.0.0 --port 8000 \ --alias gpt-oss-120b
单张 48GB 卡(用 MoE 卸载):
llama-server \ -m gpt-oss-120b-mxfp4.gguf \ -ngl 999 \ --n-cpu-moe 16 \ --moe-cache-mib 4096 \ -c 32768 \ -fa on
双卡(流水):
llama-server \ -m gpt-oss-120b-mxfp4.gguf \ -ngl 999 \ -sm layer \ -c 65536 \ -fa on
工具调用:
llama-server \ -m gpt-oss-120b-mxfp4.gguf \ -ngl 999 \ --jinja \ --tool-server demo
gpt-oss 用 harmony chat 格式,--jinja 会从 GGUF 元数据里读模板。
验证:
curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-oss-120b", "messages": [{"role":"user","content":"Explain eigenvalues briefly."}], "max_tokens": 256 }'
6.3Llama-3.3-70B
70B 稠密,Q4_K_M 约 42 GB。
单张 48GB(如 RTX 6000 Ada / A6000):
llama-server \ -m Llama-3.3-70B-Instruct-Q4_K_M.gguf \ -ngl 999 \ -c 32768 \ -fa on \ -ctk q8_0 -ctv q8_0 \ -b 2048 -ub 512
双卡 24GB(流水):
llama-server \ -m Llama-3.3-70B-Instruct-Q4_K_M.gguf \ -ngl 999 \ -sm layer \ -ts 1,1 \ -c 16384 \ -fa on \ -ctk q8_0 -ctv q8_0
纯 CPU(64GB 内存,慢但可用):
llama-server \ -m Llama-3.3-70B-Instruct-Q4_K_M.gguf \ -ngl 0 \ -t 32 \ -c 8192
CPU 上 70B Q4 大约 2–4 tok/s(取决于 CPU)。只适合离线/实验。
6.4Qwen3 系列
# Qwen3-32B,单张 24GB llama-server \ -m Qwen3-32B-Q4_K_M.gguf \ -ngl 999 \ -c 32768 \ -fa on \ -ctk q8_0 -ctv q8_0 \ --jinja # Qwen3-30B-A3B(MoE),用 CPU 卸载跑在 16GB 卡上 llama-server \ -m Qwen3-30B-A3B-Q4_K_M.gguf \ -ngl 999 \ --n-cpu-moe 24 \ -c 32768 \ -fa on
6.5投机解码实战
EAGLE-3
# 1) 转换草稿模型(必须指定目标模型以继承 tokenizer) python convert_hf_to_gguf.py AngelSlim/Qwen3-4B_eagle3 \ --target-model-dir Qwen/Qwen3-4B \ --outtype bf16 \ --outfile Qwen3-4B-eagle3.gguf # 2) 启动 llama-server \ -m Qwen3-4B.gguf \ -md Qwen3-4B-eagle3.gguf \ --spec-type draft-eagle3
官方支持的 EAGLE-3 草稿模型(部分):
yuhuili/EAGLE3-LLaMA3.1-Instruct-8Byuhuili/EAGLE3-LLaMA3.3-Instruct-70BAngelSlim/Qwen3-{1.7B,4B,8B,14B,32B}_eagle3Tengyunw/qwen3_8b_eagle3Tengyunw/qwen3_30b_moe_eagle3RedHatAI/gpt-oss-20b-speculator.eagle3lmsys/EAGLE3-gpt-oss-120b-bf16nvidia/gpt-oss-120b-Eagle3-long-context
DFlash
python convert_hf_to_gguf.py z-lab/Qwen3-4B-DFlash \ --target-model-dir Qwen/Qwen3-4B \ --outtype bf16 \ --outfile Qwen3-4B-DFlash.gguf llama-server \ -m Qwen3-4B.gguf \ -md Qwen3-4B-DFlash.gguf \ --spec-type draft-dflash \ --spec-draft-n-max 15 \ -fa on --jinja
N-gram(零额外模型)
llama-server \ -m model.gguf \ -ngl 999 \ --spec-type ngram-simple
适合代码补全、模板化输出这类重复性强的场景。对自由文本收益有限。
混用
# 同时用 draft 模型 + n-gram llama-server \ -m model.gguf \ -md draft.gguf \ --spec-type draft-simple,ngram-simple
6.6多模态
llama-server \ -m model.gguf \ --mmproj mmproj-model-f16.gguf \ -ngl 999 \ -c 8192
-hf 拉取时,如果仓库里有 mmproj,会自动关联。
6.7配置速查
| 场景 | 关键参数 |
|---|---|
| 单卡尽量跑满 | -ngl 999 -fa on -ctk q8_0 -ctv q8_0 |
| 显存不够 | --n-cpu-moe N(MoE)/ --n-cpu-ffn N(稠密)/ 降 -c / 降 -ub |
| 多卡吞吐 | -sm layer -ts 1,1(默认) |
| 多卡低延迟 | -sm tensor + -fa on + 非量化 KV |
| 多用户 | -np 4 + -cb(默认开) |
| 低延迟单用户 | --spec-type draft-eagle3 |
| 代码补全 | --spec-type ngram-simple |
| 生产 API | --api-key xxx --metrics --host 0.0.0.0 |
07调优方法论
先定位瓶颈
| 现象 | 瓶颈 | 检查 |
|---|---|---|
| 生成慢(< 5 tok/s)但 GPU 利用率低 | 层在 CPU 上 | 看启动日志的 offloaded N/M layers to GPU |
| prefill 慢 | -b 太小 / -ub 太小 | 提高 -b(与显存权衡) |
| 显存刚好卡住 | KV 太大 | -ctk q8_0 -ctv q8_0;降 -c |
| 多用户时变慢 | slot 太少 | 提高 -np |
| 延迟抖动 | 调度开销 | 降 -np;考虑 --prio 2 |
按顺序调
第一步:确保层都在 GPU
看启动日志:
load_tensors: offloaded 41/41 layers to GPU
如果是 offloaded 35/41 layers,说明 6 层在 CPU——这是最大的性能杀手。
解决:降 -c、量化 KV、用 --n-cpu-moe(MoE)。
第二步:量化 KV
-ctk q8_0 -ctv q8_0 -fa on
省一半 KV 显存,精度几乎无损。
第三步:调 -b / -ub
-b 2048是默认,长 prompt 场景可提到 4096-ub 512是默认,显存紧可降到 256 或 128- 提高
-b提升 prefill 吞吐;提高-ub提升单批效率但增显存
第四步:调线程(CPU 推理时)
-t $(nproc) # 生成阶段 -tb $(nproc) # prompt 阶段
一般设为物理核数。超线程核心不计入,设成逻辑核数反而变慢。
CPU 亲和性:
-Cr 0-31 # 限定在前 32 个核 --cpu-strict 1
第五步:投机解码
- 交互场景:EAGLE-3 收益最大
- 代码/模板:n-gram
- 有一定成本(额外显存放 draft 模型),要权衡
按场景的配方
| 场景 | 配置 |
|---|---|
| 本地单用户聊天 | -ngl 999 -fa on -ctk q8_0 -ctv q8_0 -np 1 --spec-type draft-eagle3 |
| 本地多用户 API | -ngl 999 -np 8 -cb -b 4096 --host 0.0.0.0 --api-key xxx |
| 离线批处理 | -ngl 999 -b 8192 -ub 1024 -np 1(大 batch 吞吐优先) |
| CPU 部署 | -ngl 0 -t <物理核数> -c 4096 -ctk q8_0 |
| 边缘设备 | -ngl 999 -c 4096 -ctk q4_0 -ctv q4_0(极致省显存) |
| MoE 大模型单卡 | -ngl 999 --n-cpu-moe N --moe-cache-mib 4096 |
性能观测
# 内置性能计时 --perf # Prometheus --metrics curl http://localhost:9931/metrics
llama.cpp 的日志会打印每个请求的:
- prompt eval time(prefill)
- eval time(decode)
- tokens per second
这是最直接的调优依据。
08生产化与排错
8.1容器
官方提供多个镜像:
| 镜像 | 内容 |
|---|---|
ghcr.io/ggml-org/llama.cpp:server | 仅 llama-server |
ghcr.io/ggml-org/llama.cpp:server-cuda | CUDA 12 |
ghcr.io/ggml-org/llama.cpp:server-cuda13 | CUDA 13 |
ghcr.io/ggml-org/llama.cpp:server-rocm | ROCm |
ghcr.io/ggml-org/llama.cpp:server-musa | MUSA |
ghcr.io/ggml-org/llama.cpp:server-intel | SYCL |
ghcr.io/ggml-org/llama.cpp:full | 含转换与量化工具 |
ghcr.io/ggml-org/llama.cpp:light | 仅 CLI |
docker run -d \ --gpus all \ --name llama-server \ -p 8000:8000 \ -v /models:/models \ ghcr.io/ggml-org/llama.cpp:server-cuda13 \ -m /models/model.gguf \ -ngl 999 \ -c 32768 \ -fa on \ --host 0.0.0.0 --port 8000 \ --api-key your-secret-key \ --metrics
8.2端点
| 端点 | 说明 |
|---|---|
/v1/chat/completions | OpenAI 兼容对话 |
/v1/completions | 补全 |
/v1/responses | Responses API |
/v1/embeddings | 向量 |
/v1/models | 模型列表 |
/rerank | 重排序 |
/health | 健康检查 |
/metrics | Prometheus(需 --metrics) |
/slots | slot 状态(需 --slots) |
/props | 全局属性(需 --props 才能改) |
/ | Web UI |
支持 Anthropic Messages API,可直接接 Claude Code:
llama-server -m model.gguf -ngl 999 --jinja --host 0.0.0.0 --port 8000 ANTHROPIC_BASE_URL=http://localhost:8000 \ ANTHROPIC_AUTH_TOKEN=dummy \ claude
8.3故障排查
| 现象 | 原因 | 处理 |
|---|---|---|
| 速度只有几 tok/s | 层被 offload 到 CPU | 看日志 offloaded N/M;降 -c;量化 KV;--n-cpu-moe |
| 启动 OOM | 层数 × 权重 + KV 超了 | 降 -ngl;降 -c;降 -ub |
-ctv q8_0 报错 | 没开 Flash Attention | 加 -fa on |
tensor 模式报错 | KV 是量化格式 / --fit 开着 | -ctk f16 -ctv f16;--fit off |
| 模型加载失败 | GGUF 版本不匹配 | 重新转换或升级 llama.cpp |
| 中文乱码 / 分词异常 | tokenizer 缺失 | 确认 GGUF 内含 tokenizer |
| 工具调用不生效 | 模板不支持 | 加 --jinja;检查 --chat-template-kwargs |
| 推理内容混在 content | --reasoning-format 未设 | 设 deepseek 或 deepseek-legacy |
| 多用户时排队 | -np 太小 | 提高 -np(代价是每个 slot 的上下文变小) |
| 端口连不上 | 默认 9931 | 检查 --port |
| 多模态报错 | mmproj 未加载 | 加 --mmproj |
8.4安全
- 默认只监听 127.0.0.1:要对外必须显式
--host 0.0.0.0 - 默认无鉴权:务必设
--api-key或--api-key-file --media-path会暴露本地文件读取,只在可信环境开--props允许运行时改配置,生产环境慎开
09附录
A. 参数速查
| 参数 | 一句话 |
|---|---|
-m | 模型路径 |
-hf | 从 HF 直接拉 |
-ngl | 放 GPU 的层数,最重要的参数 |
-c | 上下文长度 |
-fa | Flash Attention |
-ctk / -ctv | K/V 的 KV Cache 精度 |
-b / -ub | 逻辑 / 物理批大小 |
-np | slot 数(并发对话) |
-cb | 连续批处理(默认开) |
-sm | split mode:layer / tensor / none |
-ts | 各卡分配比例 |
--n-cpu-moe | MoE 专家放 CPU 的层数 |
--n-cpu-ffn | 稠密 FFN 放 CPU 的层数 |
--moe-cache-mib | CPU 专家在 GPU 的缓存 |
--fit | 自动适配内存(默认 on) |
-t / -tb | 生成 / 批处理线程数 |
--jinja | Jinja 模板(默认开) |
--spec-type | 投机解码方法 |
-md | 草稿模型 |
--reasoning-format | 推理内容格式 |
--api-key | 鉴权 |
--metrics | Prometheus |
--port | 端口(默认 9931) |
B. 环境变量
| 变量 | 作用 |
|---|---|
LLAMA_ARG_* | 所有参数都有对应的环境变量形式(见参数表) |
LLAMA_API_KEY | 等价 --api-key |
CUDA_VISIBLE_DEVICES | 控制可见 GPU |
MODEL_ENDPOINT | 指定 HF 兼容的模型源 |
LLAMA_ARG_N_GPU_LAYERS | 等价 -ngl |
C. 量化格式选择指南
| 格式 | 用途 |
|---|---|
Q8_0 | 几乎无损,体积大 |
Q6_K | 高保真 |
Q5_K_M | 高质量 |
Q4_K_M | 默认推荐,性价比最佳 |
Q4_0 | 更快但质量略低 |
Q3_K_M | 显存极度受限 |
Q2_K | 仅极限场景 |
IQ4_XS / IQ3_XS | i-quant,同体积下质量更好但更慢 |
IQ1_S / IQ2_XXS | 极端压缩,质量明显下降 |
D. 来源
| 来源 | 用途 |
|---|---|
| github.com/ggml-org/llama.cpp/tools/server/README.md | server 全部参数(自动生成) |
| .../docs/multi-gpu.md | 多卡 split mode 与配方 |
| .../docs/speculative.md | 投机解码方法矩阵 |
| .../docs/models.md | 模型获取与量化 |
| .../docs/docker.md | 镜像列表 |
| .../docs/function-calling.md | 工具调用 |
| .../docs/multimodal.md | 多模态 |
| github releases | 版本核验 |
本文档基于 2026-11-06 可获取的公开资料整理。llama.cpp 的参数表由代码自动生成,迭代频繁;具体参数的默认值请以 llama-server --help 输出为准。