llama.cpp

量化(Quantization)是本地运行大规模语言模型的主要议题,因为它能减少内存占用。毫无疑问,llama.cpp原生支持大规模语言模型的量化,并且一如既往地保持了灵活性。

在高层次上,llama.cpp所支持的所有量化都是权重量化(weight quantization):模型参数被量化为低位(bit)数,在推理过程中,它们会被反量化(dequantize)并用于计算。

此外,你可以在单一的量化模型中混合使用不同的量化数据类型,例如,你可以使用一种量化数据类型量化嵌入权重(embedding),而使用另一种量化其他权重。通过适当的量化类型组合,只需略微增加bpw (bit-per-weight, 位权比),就能达到更低的量化误差。示例程序llama-quantize支持许多量化预设,如Q4_K_M和Q8_0。

如果你发现量化误差仍然超出预期,你可以引入自己的量化尺度,例如由AWQ计算的,或者使用校准数据用llama-imatrix来计算一个“重要性矩阵”(importance matrix),然后在量化过程中使用以提高量化模型的质量。

在本文档中,我们将展示量化和评估量化模型性能的常见方法。我们会假设你手头有llama.cpp的示例程序。如果没有,请查看我们的指南

获取GGUF

现在,假设你想量化Qwen3-8B-Instruct。你需要首先创建一个GGUF文件,如下所示:

python convert-hf-to-gguf.py Qwen/Qwen3-8B --outfile Qwen3-8B-F16.gguf

由于 Qwen3 以 bfloat16 混合精度训练,以下方法在受支持的计算机上可保留完整参数信息:

python convert-hf-to-gguf.py Qwen/Qwen3-8B --outtype bf16 --outfile Qwen3-8B-BF16.gguf

有时,可能最好将fp32作为量化的起点。在这种情况下,使用

python convert-hf-to-gguf.py Qwen/Qwen3-8B --outtype f32 --outfile Qwen3-8B-F32.gguf

无校准量化GGUF

最简单的方法是,你可以根据需求直接将模型量化到低位数。下面是一个将模型量化到8 bit的例子:

./llama-quantize Qwen3-8B-F16.gguf Qwen3-8B-Q8_0.gguf Q8_0

Q8_0是一个量化预设的代号。你可以在llama-quantize的源代码中找到所有预设。寻找变量QUANT_OPTIONS。对于 8B 模型常用的包括Q8_0Q5_K_MQ4_K_M。字母大小写不重要,所以q8_0q4_K_m都是可以接受的。

现在,你可以使用基于llama.cpp的应用程序中的量化模型的GGUF文件。确实很简单。

然而,量化模型的准确性偶尔可能低于预期,特别是对于低位数量化。程序甚至可能阻止你这样做。

有几种方法可以提高量化模型的质量。一种常见的方法是在目标域中使用校准数据集来识别真正重要的权重,并以这些权重具有较低量化误差的方式量化模型,如下两种方法中将介绍。

使用AWQ尺度量化GGUF

注意

仍需为Qwen3更新。

为了提高量化模型的质量,一种可能的解决方案是应用AWQ尺度,遵循这个脚本。首先,当你使用autoawq运行model.quantize()时,记得添加export_compatible=True,如下所示:

...
model.quantize(
    tokenizer,
    quant_config=quant_config,
    export_compatible=True
)
model.save_pretrained(quant_path)
...

上述代码实际上不会量化权重。相反,它会根据数据集调整权重,使它们“更容易”量化。[1]

然后,当你运行convert-hf-to-gguf.py时,记得将模型路径替换为新模型的路径:

python convert-hf-to-gguf.py <quant_path> --outfile qwen2.5-7b-instruct-f16-awq.gguf

最后,你可以像最后一个例子那样量化模型:

./llama-quantize qwen2.5-7b-instruct-f16-awq.gguf qwen2.5-7b-instruct-q8_0.gguf Q8_0

这样,应该有可能以更低的bpw实现相似的质量。

使用重要性矩阵量化GGUF

另一个可能的解决方案是使用”重要矩阵”[2],参照这里

首先,你需要使用校准数据集(-f)计算模型权重的重要性矩阵数据(-m):

./llama-imatrix -m Qwen3-8B-F16.gguf -f calibration-text.txt --chunk 512 -o Qwen3-8B-imatrix.dat -ngl 80

文本被切割成长度为--chunk的块进行计算。最好,文本应代表目标领域。最终结果将保存在名为qwen3-8b-imatrix.dat-o)的文件中,然后可以使用:

./llama-quantize --imatrix Qwen3-8B-imatrix.dat \
    Qwen3-8B-F16.gguf Qwen3-8B-Q4_K_M.gguf Q4_K_M

对于1 bit或2 bit的低位数量化混合,如果你不提供--imatrixllama-quantize将打印出有用的警告。

困惑度(Perplexity)评估

llama.cpp为我们提供了一个示例程序来计算困惑度,这评估了给定文本对模型而言的“不可能”程度。它主要用于比较:困惑度越低,模型对给定文本的记忆越好。

要做到这一点,你需要准备一个数据集,比如”wiki测试集”[3]。你可以使用以下命令下载数据集:

wget https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-raw-v1.zip?ref=salesforce-research -O wikitext-2-raw-v1.zip
unzip wikitext-2-raw-v1.zip

然后你可以使用以下命令运行测试:

./llama-perplexity -m Qwen3-8B-Q8_0.gguf -f wiki.test.raw -ngl 80

稍等一段时间,你将得到模型的困惑度。这里提供了不同类型的量化模型的数值。观察差异可能有助于理解不同量化方式的潜在表现。

结束语

在本指南中,我们展示了如何使用llama.cpp进行量化和评估困惑度。更多信息,请访问llama.cpp GitHub仓库

We usually quantize the fp16 model to 4, 5, 6, and 8-bit models with different quantization mixtures, but sometimes a particular mixture just does not work, so we don’t provide those in our Hugging Face Hub. However, others in the community may have success, so if you haven’t found what you need in our repos, look around.

享受你新鲜量化的模型吧!