在上一篇文章记一次小模型微调/蒸馏学习(Qwen3-0.6B 从收货地址中提取结构化信息) 中已经蒸馏出数据,由于服务器没有显卡,我将模型转为GGUF,然后量化为Q5_K_M,使用llama.cpp 进行推理。
- 此处我打算使用 llama.cpp 的 Linux 预编译包(含 server/quantize),未自己进行编译。
- 如果按照上一篇文章训练出来了模型,那么一般在
output/v0-xxx-xxx文件夹内可以看见checkpoint-xxx-merged文件夹,为模型合并后的目录(含 tokenizer、config、model 权重) - 由训练参数可看出,使用的是
bfloat16,所以,为了在纯CPU上运行,量化为Q5_K_M(PS: 我也尝试过Q8_0 但感觉效果没有Q5_K_M好,可能是均匀量化的原因?这里还是需要一批样本数据进行验证,纯个人感受。)
ps: 后续涉及到执行python命令,请自行按照自己的python 环境管理器运行,例如我使用的uv,那么执行python前加一个前缀uv / uv run等。
1
2
3
4
5
6
| 运行环境:ubuntu 20.04.6(WSL2)
显卡: NVIDIA GeForce RTX 3080 12G
CUDA Version: 12.9
Driver Version: 576.88
NVIDIA-SMI 576.88
python 环境管理器: uv
|
测试地址#
Demo测试地址,这是经过 Q5_K_M 量化后的QWen3-0.6B GUFF模型,运行在纯CPU环境。限制:总并发数:8,单ip频率: 5秒/次。
安装 llama.cpp#
下载 llama.cpp 的 Linux 预编译包 GitHub Releases,下载 Ubuntu x64 (CPU) 。
解压后给予权限:
1
2
| chmod +x llama-quantize
chmod +x llama-server
|
将模型转为 GGUF f16母版#
merged 目录是标准 HF 结构(有 model.safetensors / config.json / tokenizer.json),所以目的是为了做 f16 母版,后续量化都基于它。
下载llama官方用于 “HF → GGUF” 的转换转换脚本convert_hf_to_gguf.py
1
2
| curl -L -o convert_hf_to_gguf.py \
https://raw.githubusercontent.com/ggml-org/llama.cpp/master/convert_hf_to_gguf.py
|
安装依赖。
1
2
3
4
5
| pip install numpy safetensors sentencepiece tqdm
# 如遇到 × This environment is externally managed 的错误,用虚拟环境即可解决。
# python3 -m venv myenv
# source myenv/bin/activate
|
转为 GGUF#
1
2
3
4
5
| # `v6-20260305-022233/checkpoint-646-merged` 按照自己的模型目录来。
python3 convert_hf_to_gguf.py \
output/v6-20260305-022233/checkpoint-646-merged \
--outtype f16 \
--outfile addr-extract.f16.gguf
|
量化为Q5_K_M#
1
| ./llama-quantize addr-extract.f16.gguf addr-extract.Q5_K_M.gguf Q5_K_M
|
启动 REST 服务#
可以使用 openai 协议的客户端测试。
1
| ./llama-server -m addr-extract.Q5_K_M.gguf --host 0.0.0.0 --port 8000 -t 8 -c 2048
|
自此,llama.cpp 就算运行好了,以下是文章是一些参考。
一些参数启动组合(参考)#
按照我服务器配置 CPU: E5-1630 v4,内存 64G,无gpu,目标并发10。
1. 吞吐优先(并发 10 全接住)#
1
2
3
4
5
6
7
8
9
| ./llama-server \
-m /path/model.gguf \
--host 0.0.0.0 --port 8080 \
--threads 8 --threads-batch 8 \
--ctx-size 2048 --n-predict 256 \
--parallel 10 --cont-batching \
--cache-prompt --cache-reuse 256 \
--temperature 0.0 --top-p 1.0 --top-k 0 \
--api-key-file /path/keys.txt
|
| 参数 | 含义 | 常见坑 / 建议 |
|---|
./llama-server | 启动 HTTP 推理服务(OpenAI-like API / WebUI / slots 等) | 跟 llama-cli 不同:这里要考虑并发、超时、鉴权、缓存 |
-m /path/model.gguf | 加载 GGUF 模型文件 | 磁盘/文件系统会影响加载速度;生产建议配合 --mmap(默认开)与 --mlock(可选) |
--host 0.0.0.0 | 监听所有网卡地址 | 对外暴露服务时必用;注意防火墙/反代/鉴权 |
--port 8080 | 监听端口 | 跟反向代理(Nginx/Traefik)端口映射一致即可 |
--threads 8 | 生成阶段使用的 CPU 线程数(decode / token-by-token 阶段) | 通常设为“物理核数”或略小;设太大→上下文切换、延迟抖动 |
--threads-batch 8 | prefill/批处理阶段线程数(处理 prompt、并发 prefill) | prefill 更吃内存带宽,线程过多会“带宽打满但不更快”;可与 --threads 不同 |
--ctx-size 4096 | 上下文长度上限(KV cache 按此分配) | 越大越吃内存(并发 slots 也会乘上去);抽取任务一般 2k~8k 足够 |
--n-predict 256 | 每次请求最多生成 256 tokens(输出上限) | 服务端强烈建议设上限,避免异常请求无限生成拖垮服务 |
--parallel 10 | slots 数:服务端同时维护多少条“独立上下文/会话槽位” | 并发越高越占 KV 内存;parallel × ctx-size 是内存大头 |
--cont-batching | 连续/动态 batching:把多个请求的 prefill/decode 合并调度以提升吞吐 | 并发多时很赚;但可能增加尾延迟(P99) |
--cache-prompt | 启用 prompt caching:重复前缀(尤其 system prompt)可复用 KV | 对“固定系统提示词 + 多请求”极其有效 |
--cache-reuse 256 | 复用缓存的“最小 chunk 尺寸”(越大越保守) | 0 表示几乎不启用 shifting;256 表示前缀相似度高时才复用,减少误复用带来的开销 |
--temperature 0.0 | 温度=0 → 近似贪心解码(最确定) | 信息抽取/结构化输出首选;创作类别用更高温度 |
--top-p 1.0 | nucleus 关闭(不过滤) | 温度已是 0 时,top-p 影响很小;这里主要表达“别再加随机性” |
--top-k 0 | top-k 关闭 | 同上:温度 0 时基本无影响,但组合上更“确定性” |
--api-key-file /path/keys.txt | 从文件加载 API keys(可多个)用于鉴权 | 对外服务必开;文件权限要管好 |
稳定性来自:temperature=0 +(可选)关闭 top-k/top-p
吞吐来自:parallel + cont-batching
成本控制来自:ctx-size、n-predict、prompt cache(cache-prompt/cache-reuse)
2. 多余请求排队(限制 slot,减少争用)#
1
2
3
4
5
6
7
8
| ./llama-server \
-m /path/model.gguf \
--host 0.0.0.0 --port 8000 \
--threads 8 --threads-batch 6 \
--ctx-size 2048 --n-predict 256 \
--parallel 10 --cont-batching \
--cache-prompt --cache-reuse 256 \
--temperature 0.0 --top-k 0 --top-p 1.0
|
3. GPU offload(单卡)#
1
2
3
4
5
6
| ./llama-server \
-m /path/model.gguf \
--device 0 --n-gpu-layers all \
--ctx-size 4096 --n-predict 512 \
--parallel 8 --cont-batching \
--flash-attn on
|
把模型层 offload 到 GPU,提升吞吐/降低延迟。
| 参数 | 含义(工程语义) | 建议 |
|---|
--device 0 | 指定使用哪块 GPU(设备索引)进行 offload | 多卡时要配合 --list-devices 确认索引 |
--n-gpu-layers all | 将尽可能多的层放到 VRAM(all=全放,或放到显存顶住为止) | 最关键性能参数:放得越多通常越快;显存不够就改成具体数字或用 auto |
--flash-attn on | 强制启用 FlashAttention(GPU 上减少显存带宽压力/加速注意力) | 一般 GPU 推理建议 auto/on;遇到兼容问题再 off |
--ctx-size 4096 | 上下文仍决定 KV 大小;GPU 推理时 KV 也可能占显存/或分配到主存(取决于配置) | ctx 大会挤占显存,影响能 offload 的层数 |
--parallel 8 + --cont-batching | GPU 上合并 batch 对吞吐提升非常明显 | 高并发 GPU 服务的“吞吐来源” |
4. 强制 JSON 合法(Schema)#
1
2
3
4
5
| ./llama-server \
-m /path/model.gguf \
--json-schema-file /path/schema.json \
--temperature 0.0 --top-k 0 --top-p 1.0 \
--n-predict 256
|
这一条的目标不是速度,而是:输出结构必须合法(地址抽取最常用)。
| 参数 | 含义 | 你关心的“到底约束了什么” |
|---|
--json-schema-file /path/schema.json | 用 JSON Schema 约束解码(相当于“只允许生成符合 schema 的 token 序列”) | 硬约束:字段类型、必填字段、对象结构、枚举范围等;能显著减少“漏字段/多字段/语法错” |
--temperature 0.0 | 降随机性,提升可复现与稳定 | schema 已经约束结构,但温度 0 能减少内容漂移/幻觉 |
--top-k 0 / --top-p 1.0 | 进一步避免采样随机性 | 在结构化任务里,通常宁可确定性也不要“文采” |
--n-predict 256 | 限制输出长度 | schema 也可能允许较大对象;上限能防止异常膨胀 |
llama 启动参数详解(AI)#
可使用 ./llama-server --help 查看,我当前使用的是b8204版本,命令与你当前可能不同。
此处分为3类启动参数。
- 运行/内存/设备(common):决定吞吐、延迟、能否跑得起来
- 采样(sampling):决定输出风格与稳定性
- 服务端/示例专用(server/example-specific):并发、缓存、鉴权、模板等
1) Common params(性能/内存/设备)#
| 参数 | 作用 | 默认值(你贴的) | 何时需要调 | 常用度 |
|---|
-t, --threads N | 生成阶段使用的 CPU 线程数 | -1(自动) | CPU 推理时强烈建议手动设为物理核/NUMA策略内核数;避免过度抢占 | 高 |
-tb, --threads-batch N | prefill/批处理线程数(吃满内存带宽) | = --threads | prefill 慢时可调大;也可与生成分开以稳定延迟 | 中 |
-C, --cpu-mask M / -Cr, --cpu-range lo-hi | CPU 亲和性(绑核) | 空 | 多租户/NUMA 机器、追求稳定延迟时必用 | 中 |
--cpu-strict <0|1> | 严格按亲和性放置线程 | 0 | 绑核后想更“硬”的隔离 | 低~中 |
--prio N / --prio-batch N | 进程/线程优先级 | 0 | 线上低延迟服务、避免被抢占(注意权限) | 低~中 |
--poll <0...100> | 工作等待策略(忙等 vs 休眠) | 50 | 低延迟可提高;省电/散热可降低 | 低 |
-c, --ctx-size N | 上下文长度(KV cache 规模随之增长) | 0(从模型读) | 需要更长上下文/多轮;或为了省内存而减小 | 高 |
-n, --n-predict N | 生成 token 上限 | -1(无限) | 服务端务必设上限避免“跑飞” | 高 |
-b, --batch-size N | 逻辑最大 batch(prefill 吞吐) | 2048 | 并发多、长 prompt 时调;过大可能导致内存峰值 | 中 |
-ub, --ubatch-size N | 物理 micro-batch(更贴近实际算子切分) | 512 | GPU/CPU 都可能用:想提高吞吐但受显存/内存限制时调 | 中 |
--keep N | 保留 prompt 前 N tokens 不参与丢弃/重算(与交互/续写相关) | 0 | 交互式、需要保留系统提示词等 | 低~中 |
--swa-full / --ctx-checkpoints / --swa-checkpoints | 与 SWA/上下文检查点相关(提高长上下文处理/缓存行为) | false / 8 | 你明确在做长上下文 & 想用 checkpoint/回滚能力 | 低 |
-fa, --flash-attn [on|off|auto] | FlashAttention(主要影响 GPU) | auto | GPU 推理一般保持 auto/on;CPU 基本无感 | 中 |
--perf | 打开内部性能计时 | false | 你在压测/定位瓶颈时 | 中 |
-e, --escape | 处理 \n 等转义 | true | 只在你需要“原样”字符串时关掉 | 低 |
--rope-scaling {none,linear,yarn} | RoPE 外推策略 | 模型默认(常为 linear) | 你要“超训练长度”上下文时才碰 | 中 |
--rope-scale / --rope-freq-base / --rope-freq-scale | RoPE 频率缩放细节(NTK/外推) | 从模型读 | 不懂就别动;外推效果/困惑度会受影响 | 低~中 |
--yarn-*(orig-ctx/ext-factor/attn-factor/beta-*) | YaRN 外推的一组超参 | 多为 -1/0 | 你确定用 YaRN 外推并且要调质量/稳定性 | 低 |
-kvo, --kv-offload | KV cache offload(把 KV 放到不同设备/内存策略) | enabled | 多 GPU / 设备内存不够时;或要控制主显存占用 | 中 |
-ctk, --cache-type-k TYPE / -ctv, --cache-type-v TYPE | KV cache 的 K/V 精度(f16/q8/q4…) | f16/f16 | 省内存(尤其长 ctx + 多并发);代价是可能降质/增算 | 中~高 |
--repack / --no-repack | 权重重排/打包(提升访问效率) | enabled | 一般保持默认;极少数兼容问题才关 | 低 |
--mmap / --no-mmap | 内存映射加载模型(快、占用小) | enabled | 容器/网络盘/奇怪 FS 导致抖动时可能关 | 中 |
--mlock | 锁页:防止模型被换出/压缩 | off | 线上稳定性、避免 page-out(需要权限,内存要够) | 中 |
--numa TYPE | NUMA 优化(distribute/isolate/numactl) | 未启用 | 双路/多路 CPU 服务器强烈建议研究 | 中 |
-dev, --device <...> | 指定 offload 设备(GPU/加速卡) | 未指定 | 你要明确用哪块卡/多卡 | 中 |
--list-devices | 列设备 | — | 只用于查看 | 低 |
-ngl, --gpu-layers N | offload 到 VRAM 的层数(速度关键) | auto | 有 GPU 就是核心参数:更多层=更快(直到显存顶住) | 高 |
-sm, --split-mode {none,layer,row} | 多 GPU 切分策略 | layer | 多卡推理/显存拼接 | 中 |
-ts, --tensor-split ... | 多 GPU 分配比例 | — | 多卡手动配比 | 中 |
-mg, --main-gpu INDEX | 主 GPU 选择 | 0 | 多卡指定主卡 | 低~中 |
-fit, --fit [on|off] / --fit-target / --fit-ctx | 自动调参以“塞进显存/内存” | on / 1024 / 4096 | 你想少算账让它自动收敛到可跑配置 | 中 |
--lora FNAME / --lora-scaled ... | 加载 LoRA(可多份) | — | 你做 PEFT 推理时 | 中 |
--control-vector* | 控制向量(实验特性) | — | 做风格/行为控制实验 | 低 |
-m, --model FNAME | 模型路径 | — | 必填 | 高 |
-hf, --hf-repo ... / --hf-file / --hf-token | 从 HF 拉取模型/文件 | — | 不想手动下载 gguf 时 | 中 |
--offline | 强制离线,只用缓存 | off | 生产环境/无网机器 | 中 |
--override-kv KEY=TYPE:VALUE | 覆盖 gguf 元数据(高级) | — | 你非常清楚自己在改什么 | 低 |
--check-tensors | 检查非法 tensor 值 | false | 怀疑模型损坏/加载异常 | 低 |
2) Sampling params(输出风格/稳定性)#
| 参数 | 作用 | 默认值 | 何时需要调 | 常用度 |
|---|
-s, --seed | 随机种子(复现性) | -1 随机 | 评测/回归测试要固定 | 中 |
--temp, --temperature | 温度(随机性) | 0.80 | 要稳定就降(0~0.3);要发散就升 | 高 |
--top-k | Top-K 截断 | 40 | 与 top-p 搭配;更稳可降 | 中 |
--top-p | Nucleus | 0.95 | 更稳可降到 0.8~0.9;更自由可升 | 高 |
--min-p | Min-P(低概率截断) | 0.05 | 想减少胡言乱语/罕见词可提高一点 | 中 |
--typical-p | Typical sampling | 1.00(关) | 你明确要“更像训练分布”时才用 | 低 |
--repeat-last-n | 重复惩罚窗口 | 64 | 长文重复明显就增大 | 中 |
--repeat-penalty | 重复惩罚强度 | 1.00(关) | 1.05~1.2 常见;过高会伤连贯性 | 中 |
--presence-penalty / --frequency-penalty | 类 OpenAI 的重复惩罚 | 0 | 需要控制复读时 | 低~中 |
--mirostat / --mirostat-lr / --mirostat-ent | Mirostat 自适应熵控制 | off | 你想“长文稳定熵”且知道在干嘛 | 低 |
--ignore-eos | 忽略 EOS 继续生成 | off | 只在流式/特殊需求,服务端一般别开 | 低 |
--logit-bias ... | 对 token 施加偏置 | — | 禁词/强制倾向,工程上很有用 | 中 |
--grammar / --grammar-file | BNF grammar 约束生成 | '' | 结构化输出(JSON)强烈建议用 | 高(做抽取时) |
-j, --json-schema / --json-schema-file | JSON Schema 约束 | — | 比 grammar 更直观:强制合法 JSON | 高(做抽取时) |
--samplers / --sampling-seq | 自定义采样器链 | 有默认链 | 你在研究采样策略时才改 | 低 |
--dry-* / --xtc-* / --adaptive-* / --dynatemp-* | 一堆高级采样增强 | 默认多为关闭 | 追求特定风格/去重复/自适应才用 | 低 |
3) Server / example-specific params(并发/缓存/鉴权/模板)#
3.1 并发与批处理(吞吐核心)#
| 参数 | 作用 | 默认值 | 何时需要调 | 常用度 |
|---|
-np, --parallel N | server slots 数(并发请求槽位) | -1 auto | 线上服务按 QPS/延迟目标配置 | 高 |
-cb, --cont-batching | 连续/动态 batching | enabled | 并发多时吞吐暴涨;但要留意尾延迟 | 高 |
--threads-http N | HTTP 线程数 | -1 | 高并发下避免请求处理成为瓶颈 | 中 |
-to, --timeout N | 读写超时(秒) | 600 | 生产一般缩短,避免连接占用 | 中 |
--warmup | 空跑 warmup | enabled | 生产建议开,减少首请求抖动 | 中 |
--sleep-idle-seconds | 空闲休眠 | -1 off | 节能/桌面用;线上通常关闭 | 低 |
3.2 Prompt/KV 缓存(省算力的关键)#
| 参数 | 作用 | 默认值 | 何时需要调 | 常用度 |
|---|
--cache-prompt | 启用 prompt caching | enabled | 复用系统提示词/固定前缀时大幅省 prefill | 高 |
--cache-reuse N | 允许 KV shifting 的最小复用 chunk | 0 | 你有大量相似前缀请求时调大更赚 | 中 |
--slot-save-path PATH | 保存 slot 的 KV cache | disabled | 需要跨重启保留上下文/会话时 | 低~中 |
-cram, --cache-ram N | cache 最大 RAM(MiB) | 8192 | 内存紧张或想限制缓存占用 | 中 |
3.3 鉴权、路由、静态资源#
| 参数 | 作用 | 默认值 | 何时需要调 | 常用度 |
|---|
--host / --port | 监听地址/端口 | 127.0.0.1:8080 | 对外服务、容器部署必配 | 高 |
--api-key KEY / --api-key-file | API 鉴权 | none | 对外网暴露必开 | 高 |
--ssl-key-file / --ssl-cert-file | TLS | none | 直出 HTTPS(或交给 Nginx) | 中 |
--path / --api-prefix | 静态目录 / API 前缀 | 空 | 你需要挂 WebUI 或反向代理路径 | 中 |
--webui / --no-webui | Web UI | enabled | 生产通常关;本地调试可开 | 中 |
--metrics | Prometheus metrics | disabled | 生产监控 | 中 |
--slots | slots 监控端点 | enabled | 一般保持开 | 中 |
--props | 允许 POST /props 改全局属性 | disabled | 多租户/安全考虑;一般别开 | 低 |
3.4 Chat 模板与“思考”格式#
| 参数 | 作用 | 默认值 | 何时需要调 | 常用度 |
|---|
--chat-template ... / --chat-template-file ... | 指定/覆盖 chat 模板 | 从模型元数据取 | 模型模板不匹配、你要统一输出风格时 | 中 |
--jinja / --no-jinja | 是否启用 jinja 模板引擎 | enabled | 只有在排障/兼容时才关 | 低 |
--reasoning-format | 思考内容如何返回(none/deepseek/legacy) | auto | 你要对外 API 隐藏/剥离思考时 | 中 |
--reasoning-budget | 限制思考预算(-1 不限,0 关闭) | -1 | 低延迟/确定性场景可设 0 | 中 |
--prefill-assistant | 若最后一条是 assistant,是否预填 | enabled | 你做特定对话协议兼容时 | 低 |
哪些参数最常用?#
A) CPU 推理/CPU Server#
性能与稳定性#
1
2
3
| --threads / --threads-batch
--numa distribute|isolate
--cpu-mask / --cpu-range
|
内存
1
2
3
4
| --ctx-size
--n-predict
--mmap、--mlock
--cache-type-k / --cache-type-v(需要更长 ctx/更多并发时)
|
服务
1
2
3
| --parallel、--cont-batching
--cache-prompt、--cache-reuse
--host、--port、--api-key
|
B) GPU offload#
1
2
3
| --n-gpu-layers(最核心)
--device、多卡则 --split-mode + --tensor-split
--flash-attn
|
C) 结构化抽取(JSON 输出)#
1
2
3
| --json-schema-file(或 --grammar-file)
--temperature (采样侧) 0 或很低、--top-p 收紧、必要时 --seed 固定
--n-predict (服务侧:)设上限(比如 256/512)
|
llama.cpp量化方案(如 Q4_K_M、Q5_K_S)的区别#
llama.cpp量化方案(如 Q4_K_M、Q5_K_S)的区别