使用llama.cpp量化Qwen0.6B模型CPU运行
目录
在上一篇文章记一次小模型微调/蒸馏学习(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等。
运行环境:ubuntu 20.04.6(WSL2)
显卡: NVIDIA GeForce RTX 3080 12G
CUDA Version: 12.9
Driver Version: 576.88
NVIDIA-SMI 576.88
python 环境管理器: uv
安装 llama.cpp
下载 llama.cpp 的 Linux 预编译包 GitHub Releases,下载 Ubuntu x64 (CPU) 。
解压后给予权限:
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
curl -L -o convert_hf_to_gguf.py \
https://raw.githubusercontent.com/ggml-org/llama.cpp/master/convert_hf_to_gguf.py
安装依赖。
pip install numpy safetensors sentencepiece tqdm
# 如遇到 × This environment is externally managed 的错误,用虚拟环境即可解决。
# python3 -m venv myenv
# source myenv/bin/activate
转为 GGUF
# `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
./llama-quantize addr-extract.f16.gguf addr-extract.Q5_K_M.gguf Q5_K_M
启动 REST 服务
可以使用 openai 协议的客户端测试。
./llama-server -m addr-extract.Q5_K_M.gguf --host 0.0.0.0 --port 8000 -t 8 -c 2048
一些参数启动组合
按照我服务器配置 CPU: E5-1630 v4,内存 64G,无gpu,目标并发10。
1. 吞吐优先(并发 10 全接住)
./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,减少争用)
./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(单卡)
./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)
./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
性能与稳定性
--threads / --threads-batch
--numa distribute|isolate
--cpu-mask / --cpu-range
内存
--ctx-size
--n-predict
--mmap、--mlock
--cache-type-k / --cache-type-v(需要更长 ctx/更多并发时)
服务
--parallel、--cont-batching
--cache-prompt、--cache-reuse
--host、--port、--api-key
B) GPU offload
--n-gpu-layers(最核心)
--device、多卡则 --split-mode + --tensor-split
--flash-attn
C) 结构化抽取(JSON 输出)
--json-schema-file(或 --grammar-file)
--temperature (采样侧) 0 或很低、--top-p 收紧、必要时 --seed 固定
--n-predict (服务侧:)设上限(比如 256/512)