目录

使用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类启动参数。

  1. 运行/内存/设备(common):决定吞吐、延迟、能否跑得起来
  2. 采样(sampling):决定输出风格与稳定性
  3. 服务端/示例专用(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)