高级端侧 / 本地 3 分钟阅读发布于 · 更新于

将自己的模型量化为 GGUF

用 llama.cpp 的 quantize 工具将任意 HF 模型转为 GGUF Q4_K_M 本地推理。

面向的技术栈

llama.cpp convert_hf_to_gguf.py · llama-quantize · 目标 Q4_K_M

最近一次修改后未重新实机运行 —— 命令请当作起点,而不是已验证的配方。

GGUFllama.cppquantizecustom

开始之前

一个 Hugging Face safetensors 格式的微调或合并模型、一份编译好的 llama.cpp,以及足够同时容纳三份模型的磁盘空间:原始权重、中间的高精度 GGUF、最终的量化文件。以 BF16 的 7B 模型为例大约是 14 GB + 14 GB + 5 GB —— 要按这个总量预留磁盘,而不是只按起始模型的大小。

bash
pip install -r requirements.txt   # inside your llama.cpp checkout
df -h .

转换为 GGUF

转换脚本是 `convert_hf_to_gguf.py`。旧教程里流传的 `convert.py` 这个名字在仓库里已经不存在了 —— 如果你在别处看到的指南还在用它,说明那篇指南是改名之前写的。先转换成高精度的中间文件;直接从 safetensors 转成低位宽不是这套流程的工作方式。llama.cpp 自己的示例用的是 `--outtype bf16`,而默认的 `auto` 会替你选保真度最高的 16 位类型。对一个以 BF16 发布的模型强行指定 `f16`,可能让 BF16 本来存得下的数值溢出。较新的架构(比如 Gemma 4)需要 transformers 5,而 requirements 文件装的是 4,所以如果脚本认不出你的模型,先 `pip install -U transformers`。

bash
python convert_hf_to_gguf.py /path/to/my-model \
  --outfile my-model-bf16.gguf \
  --outtype bf16

量化

量化的可执行文件是 `llama-quantize` —— 旧教程里那个裸 `quantize` 的名字随着 CLI 工具的重命名一起变了。Q4_K_M 是几乎所有人都该从这里开始的档位:本索引在这个档位上公布的质量损失中位数相对 FP16 是 2.9%(基于公布了该数字的 79 个模型),而且本站每一个提供 GGUF 的模型都提供这个档位。

bash
./build/bin/llama-quantize my-model-bf16.gguf my-model-Q4_K_M.gguf Q4_K_M

做得更好:重要性矩阵

普通量化会一视同仁地对待每一个权重。重要性矩阵(imatrix)先用有代表性的文本跑一遍 F16 模型算出来,告诉量化器哪些权重更重要、该被保护 —— 这正是 Q4_K_M 已经优于朴素 4-bit 取整的原因,只是做得更彻底。这一步是「值得发布的量化版本」和「勉强能用的量化版本」之间的分水岭。

bash
# .gguf extension = current format; any other extension writes the legacy one
./build/bin/llama-imatrix \
  -m my-model-bf16.gguf \
  -f calibration-data.txt \
  -o my-model.imatrix.gguf \
  -ngl 99   # offload to the GPU if the model fits; much faster

./build/bin/llama-quantize \
  --imatrix my-model.imatrix.gguf \
  my-model-bf16.gguf my-model-Q4_K_M.gguf Q4_K_M

确认它真的没问题

加载量化后的文件,用 `llama-cli` 跑一个真实的提示词 —— 它会套用模型的聊天模板,所以顺带也检验了模板。现在的 `llama-cli` 是一个聊天程序,加 `-st` 才会回答一次就退出。转换「成功」但输出乱码是一种真实的失败模式,通常是转换过程中分词器或聊天模板不匹配,而不是量化本身的问题。把文件大小和预期对比一下:Q4_K_M 文件大小应该接近「参数量 × 每参数 0.6 字节」,如果差得很远,说明转换过程选错了精度。

bash
# -st = single turn: answer once and exit. Without it llama-cli is a chat
# session and waits for your next message.
./build/bin/llama-cli -m my-model-Q4_K_M.gguf -p "Explain quantization in one sentence." -n 64 -st

ls -lh my-model-Q4_K_M.gguf   # sanity-check the size

出问题时

转换脚本报未知架构错误:你的模型用了 `convert_hf_to_gguf.py` 还不认识的层类型 —— 先查一下脚本支持的架构列表,别急着认为是工具坏了。输出通顺但答非所问(自我重复、无视提示词):通常是原模型自带的聊天模板不匹配,而不是量化的问题 —— 先用 BF16 中间文件验证一下,再怀疑量化那一步。转换到一半磁盘满了:这就是开头说的「三份拷贝」问题 —— 确认量化文件没问题之后再清理 F16 中间文件,而不是提前清。如果你不想自己跑这一套,Hugging Face 上的 GGUF-my-repo Space 跑的是同一套流程,每六小时从 llama.cpp 的 main 分支同步一次。

常见问题

convert_hf_to_gguf.py 是什么,convert.py 去哪了?

`convert_hf_to_gguf.py` 是当前把 Hugging Face safetensors 权重转成 GGUF 文件的脚本。`convert.py` 是旧名字,仓库里已经不存在了 —— 任何还在用这个名字的教程都是改名之前写的。

llama-quantize 是什么,跟 quantize 是一回事吗?

是同一个工具,只是现在的名字变了。这个可执行文件和 llama.cpp 的其他 CLI 工具(`llama-server`、`llama-cli`)一起,从裸名字 `quantize` 改了名,所以旧教程里的 `./quantize` 在新版编译出来的目录里已经不存在了。

量化一定要用重要性矩阵(imatrix)吗?

不需要 —— 没有它量化也能跑。imatrix 会先用有代表性的文本跑一遍 F16 模型,告诉量化器哪些权重更重要,从而提升效果。自己快速测试可以跳过;要发布给别人用的量化版本,就该做这一步。

这篇指南用到了什么

格式
GGUF

它真的跑起来了吗?

复制命令并不等于它能用,所以站内只在这里问一次。除了你的这个回答之外,不收集任何东西。

相关指南

部署指南仅供学习参考。每个模型均有独立许可协议 — 下载或部署前请阅读 Hugging Face 官方模型卡。