☰
图解模型量化:模型变小,到底牺牲了什么
2026/9/29 20:03:25 网站建设 项目流程

版权与内容来源声明
本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容,均在附表 A 中标注来源;引用官方原文保持原样,不作改写。文中命令、版本号与界面截图以本文成文时的实测/核验结果为准,标注「待验证」的部分请以你本地环境实际输出为判断依据。本文不推荐任何不合规的软件获取方式,也不对任何收益结果作承诺。转载请注明出处。

第 1 章 先说清楚:量化到底"变小"了什么

1.1 变小的是"记账精度",不是参数数量

很多人以为量化是"把模型砍小、参数变少"。其实不是。参数个数一个没少,变小的是"每个参数用多少位二进制来记录"。

打个比方:原来每个参数用 16 位(FP16,2 字节)记一个数;量化到 4 位(比如 NF4)后,每个参数只用约 0.5 字节。模型还是那个模型,层数、参数量都没变,只是"记账精度"变粗了。

这就是量化最容易被误解的地方:它压缩的是"数值精度",不是"参数数量"。

1.2 三处被压缩精度的地方(先预告)

而真正被压缩精度的,其实不是一处,而是三处不同的东西——权重、激活值、KV Cache。后面几章我们逐个拆开看,先记住一句话:被量化的对象不同,省下来的可能是"显存",也可能是"显存带宽",但不一定省计算量,也不一定真的更快。

第 2 章 三处被量化的东西,省下的分别是啥

2.1 权重(weights):最常被量化的对象

权重就是模型训练出来的那几十亿个参数,平时多以 FP16 或 BF16 存储。量化把它们压成 INT8、INT4 或 NF4。

省下的是显存 / 磁盘占用:4 位权重每个参数约 0.5 字节,相比 FP16 的 2 字节约为原来的 1/4(这里只算权重的字节,缩放因子等元数据会再多占一点点)。Hugging Face 官方量化概述里也把量化的首要作用描述为"降低加载和使用模型的内存需求"。

用 bitsandbytes 做 4 位权重量化,代码上就是给加载函数传一个配置:

⚠️代码待验证

fromtransformersimportBitsAndBytesConfigimporttorch config=BitsAndBytesConfig(load_in_4bit=True,# 加载时直接压成 4 位bnb_4bit_quant_type="nf4",# NF4:面向正态权重的 4 位类型bnb_4bit_use_double_quant=True,# 双重量化:再省约 0.4 位/参数bnb_4bit_compute_dtype=torch.bfloat16,# 计算时反量化到的精度)

注意最后一行:权重"存 4 位",但"算"的时候回到 bf16——这正是第 3 章要说的"存低比特、算高比特"。

2.2 激活值(activations):推理时每层的中间结果

“激活值"说白了就是模型每算完一层,吐出来的那批临时中间结果。它们本来以 FP16 存在显存里。如果连激活值一起量化(比如权重 INT8 + 激活 INT8,常写作 W8A8,配合 SmoothQuant 这类方法),就能用上更低精度的计算单元,省的是"计算时的显存带宽"和"计算量”。

2.3 KV Cache 与一张总表

KV Cache 是大模型生成文字时的"记忆缓存"。模型一字一字往外蹦,每生成一个新字都要回头看前面所有字;为了不重复计算,它会把前面每个字对应的"注意力键值"缓存下来。它随上下文长度线性增长,长文本时可能比权重还占显存。把 KV Cache 从 FP16 量化到 INT8 或 INT4,省下的同样是显存,而且主要救的是"长上下文"场景。主流推理框架(如 vLLM)支持通过配置项把 KV Cache 设为更低精度(社区与厂商文档均有说明,非本文逐一核验原文)。

把三处摆在一起对比会更清楚:

被量化的对象它是什么(人话)常见量化目标省下的是一定省计算量吗
权重 weights模型训练出来的参数INT8 / INT4 / NF4模型本身的显存 / 磁盘占用不一定(常需反量化再算)
激活值 activations每层算出来的中间结果W8A8 等计算时的显存带宽、计算量配合低精度 kernel 时才会
KV Cache历史 token 的注意力键值缓存INT8 / INT4长上下文下的显存不一定(常需反量化再算)

第 3 章 为什么省下来的是"显存带宽",不一定是"速度"

3.1 先分清两个词

显存带宽就是"数据从显存搬到计算单元这条路,每秒能搬多少";而真正做乘法的"计算量"是另一回事。这两个常被混为一谈,但量化对它们的影响完全不同。

3.2 很多方案是"存低比特、算高比特"

关键点:很多量化方法把权重压成低比特存储,但真正做矩阵乘法时,又把它反量化回较高精度(比如 bf16 或 fp32)再算。bitsandbytes 的 4 位模块就是这样:权重存成 4 位,计算在更高精度进行。

那量化图啥?图两件事:

  1. 模型文件变小,能塞进更小的显存;
  2. 每次要把权重从显存搬进计算单元时,搬的数据量少了——这就省了"显存带宽"。

GPTQ 论文自己说得很直白:它的加速来自减少显存搬运(memory movement),并不带来计算量的减少。换句话说,权重量化让"搬数据"更快更省,但"算数据"这一步未必变快。

3.3 一张表看清"省不省速度"

所以你会看到一种反直觉现象:同一个 4 位模型,在某些框架里推理并不比FP16 快,甚至更慢——因为反量化的开销可能吃掉带宽省下来的收益。Hugging Face 在选择量化方法的文档里也明确写着:bitsandbytes 方案"不保证推理加速"。

你期待的收益权重量化能不能给说明
模型装进更小显存能存储位宽直接下降
减少显存搬运能加载权重的数据量变小
推理一定更快不一定取决于是否有配套低精度 kernel、是否反量化
减少计算量往往不能多数方案计算前先反量化

第 4 章 为什么量化后效果常常没明显下降

4.1 均匀噪声 + 大模型"皮实"

一种常见的直观解释:低比特量化给每个权重叠加的是一个"四舍五入"式的、大致均匀的误差。而大模型权重存在大量冗余,对这类小幅均匀扰动并不敏感。GPTQ 论文在结论里也表述为"在标准指标(如困惑度)上精度损失很小";AWQ 同样报告了在低比特下保持较好效果。困惑度是衡量语言模型"预测确定性"的指标,越低越好。

4.2 量化粒度:按层 / 按通道 / 按分组

"量化粒度"就是多少个权重共用同一套缩放规则。粒度越粗,误差越容易互相叠加;粒度越细,越能贴合局部数值范围,损失越小。

  • per-tensor(整层 / 整张量一个缩放):最粗,4 位以下容易掉点;
  • per-channel(按输出通道):AWQ 用的就是"逐通道缩放"来保护重要通道;
  • per-group(按分组):GPTQ 的典型做法是"把连续 g 个权重分成一组,每组独立量化",group_size 128 是 4 位的事实标准;组更小(如 32)精度更好,但元数据开销更高。

GPTQ 论文原话是"对连续的 g 个权重做独立量化(grouping)",并指出分组能在 4 位下显著减少中等模型的精度损失。

粒度怎么分特点代价
per-tensor整个张量共用一个缩放最简单,但 4 位以下易掉点精度风险高
per-channel每个输出通道一个缩放AWQ 用来保护重要通道中等元数据
per-group(g=128)每 128 个权重一组GPTQ 4 位事实标准略增元数据
per-group(g=32)每 32 个权重一组极低比特下更稳元数据更高

4.3 校准数据(calibration)的作用

“校准数据"就是用来观察数值实际分布范围的一小批样本。量化要定一个"最大值 / 缩放因子”,这个值定得准不准,直接决定误差大小。

  • GPTQ 用"一小批随机选取的数据"做校准;
  • AWQ 更讲究:它不看权重分布,而是看激活分布来找出"重要通道",并且明确说"不依赖反向传播或重建,因此不会过拟合到校准集"——这解释了为什么 AWQ 在指令微调模型、多模态模型上泛化也不错。

所谓"朴素四舍五入"(RTN,round-to-nearest)长这样,没有任何校准,直接按最大值缩放后取整:

⚠️代码待验证

importtorchdefround_to_nearest(w,bits=4):scale=w.abs().max()/(2**(bits-1)-1)returntorch.round(w/scale)*scale

换句话说,没有校准数据,很多方法只能做最朴素的"四舍五入"(RTN),而 RTN 在 3 位以下很容易崩——这是下一章要讲的风险。

第 5 章 什么时候量化会明显"掉链子"

5.1 小模型与长尾任务

大模型参数多、冗余大,扛得住量化;小模型本身余量就小,同样压到 4 位,损失往往更明显。

如果你的任务分布和校准数据差得很远(比如高度专业的领域、少见的句式),量化引入的误差就可能放大。这也是为什么通用模型量化后"日常聊天看不出差别",但一上专业评测就容易露怯。

5.2 粒度太粗

用 per-tensor 甚至不做分组,在 4 位以下损失会明显上升。GPTQ 论文就展示过:不分组在 4 位及以下"往往会损失更多精度"。

5.3 缺校准 / 用错方法

GPTQ 论文明确指出:在 3 位时,朴素 RTN(round-to-nearest)会崩,而 GPTQ 仍能保持不错效果。AWQ 也用实验说明,保护那 1% 的"显著权重"对保住质量至关重要——AWQ 的核心观察就是"权重并非同等重要,保护约 1% 的显著权重就能大幅降低量化误差"。所以"随便四舍五入压到 3 位"和"用 GPTQ / AWQ 认真压到 3 位",结果天差地别。

风险场景为什么会掉缓解办法
小模型压到 4 位以下冗余少,容错低优先保 8 位或 4 位带分组
长尾专业任务校准数据覆盖不到用贴近任务的校准集
粒度太粗(per-tensor)误差易叠加用 group_size=128 或更小
缺校准直接 RTN3 位以下易崩用 GPTQ / AWQ 做校准量化

量化速查卡:把"三处对象 / 粒度 / 校准"这张关系图整理成了单页卡,配合本章对照着看更顺。放在资料包里,扫码即可获取:

第 6 章 先看显存,还是先看速度?一张表做判断

6.1 先问"你卡在哪"

很多人一上来就问"量化后快多少",但其实第一步该问的是"你卡在哪"。下面这张表给你一个判断顺序。

你的首要诉求该优先关注哪种量化推荐做法注意
显存放不下模型权重量化(省存储)GGUF Q4_K_M / bitsandbytes 4 位先看能不能装下,别急着追速度
长上下文爆显存KV Cache 量化推理框架的 KV Cache 精度配置设 INT8长上下文能力需单独验证
要更高吞吐激活值 + 低精度 kernelW8A8 / AWQ 融合 kernel需要配套计算内核才真快
想在自己数据上微调量化后加适配器QLoRA(见第 7 章)只训适配器,基座冻结
边缘 / CPU 部署通用格式GGUF(llama.cpp 生态)GPU 提速不如专用方案

6.2 GGUF 的等级命名与怎么选

补充一点实操命名:llama.cpp 的 GGUF 量化等级用Q数字_K_变体命名,比如Q4_K_M("K"代表 k-quant 混合精度方案,M 是 medium 档)。llama.cpp 官方量化文档给出的 Llama 3.1 8B 对照里,Q4_K_M 的有效位宽约 4.89、体积约 4.9 GB,原始 BF16 / FP32 约 32.1 GB(llama.cpp 官方文档,第三方硬件实测,非本文实测)。日常本地部署,Q4_K_M常被当作 4 位的安全默认档。

GGUF 等级有效位宽(llama.cpp 文档)定位
Q4_K_M~4.894 位安全默认,性价比高
Q5_K_M~5.70有余量时质量更好
Q6_K~6.56接近 FP16
Q8_0~8.50质量接近 FP16,但体积接近翻倍

把模型做成 GGUF 并量化到 Q4_K_M,llama.cpp 的命令行长这样:

⚠️代码待验证

./llama-quantize model-f32.gguf model-Q4_K_M.gguf Q4_K_M

如果卡在长上下文,给推理框架打开 KV Cache 量化(以 vLLM 为例,把 KV Cache 设成 FP8):

⚠️代码待验证

python-mvllm.entrypoints.openai.api_server\--model你的模型id\--kv-cache-dtype fp8_e5m2

第 7 章 为什么"量化后再微调(QLoRA)"是常见折中

7.1 QLoRA 的做法

如果你既要"省显存",又想"让模型学点自己的东西",纯量化(只压不动)和全精度微调(贵)之间,有一个甜点:QLoRA。

QLoRA 的做法(出自 QLoRA 论文):

  1. 先把基座模型量化成4 位 NF4并冻结——这部分显存占用很小,能力损失也很小;
  2. 在冻结的量化模型之上,接一小撮可训练的 LoRA 低秩适配器;
  3. 训练时,梯度"穿过"冻结的量化权重,只更新那撮适配器。

论文的核心卖点是:把 65B 模型的微调显存从16 位全量微调需要的 780GB 以上,压到单张 48GB 显存的 GPU 以内,且任务表现与 16 位全量微调相当。

NF4 本身也不是随便选的:QLoRA 论文称它是"对正态分布权重在信息论上最优的 4 位数据类型"——因为预训练权重大多近似正态分布。再加上"双重量化(Double Quantization)":把量化常数本身再量化一次,bitsandbytes 文档说明这能再省约 0.4 位 / 参数。

7.2 为什么它是折中

  • 比起"纯量化推理":QLoRA 多了一个可训练适配器,能让模型适配你的任务;
  • 比起"全精度微调":它不用动、也不用存完整的高精度副本,显存和成本都低得多。

一句话:量化负责"省",适配器负责"改",两者合起来就是低成本定制大模型的工程甜点。

QLoRA 实操模板:把"4 位 NF4 + 双重量化 + LoRA 配置"的关键代码与注意事项整理成了模板。放在资料包里,扫码即可获取:

附表 A:本文引用事实与出处对照表

事实出处(标题 + 域名 / arXiv 编号)本文位置
量化通过用更低精度存储权重来降低显存,部分方法需校准、部分可即时量化Hugging Face Transformers《Quantization》概述页(huggingface.com/docs/transformers/quantization)第 1、2 章
bitsandbytes 方案"不保证推理加速"Hugging Face《选择量化方法》(huggingface.tw/docs/transformers/quantization/selecting)第 3 章
NF4 是 QLoRA 提出的 4 位数据类型,面向正态分布权重;双重量化再省约 0.4 位 / 参数bitsandbytes 文档(huggingface.co/docs/diffusers/…/bitsandbytes)+ QLoRA 论文第 4、7 章
GPTQ 加速"来自减少显存搬运,并不带来计算量的减少";并采用对连续 g 个权重的分组量化GPTQ 论文 arXiv:2210.17323第 3、4 章
GPTQ:3 位时朴素 RTN 会崩,而 GPTQ 仍可保持效果;用少量随机数据校准GPTQ 论文 arXiv:2210.17323第 4、5 章
AWQ:保护约 1% 显著权重可大幅降低量化误差;按激活(非权重)分布找重要通道;不过拟合校准集AWQ 论文 arXiv:2306.00978第 4、5 章
QLoRA:把 65B 微调显存从 780GB+ 压到单张 48GB GPU,且表现与 16 位全量微调相当;NF4 对正态权重信息论最优QLoRA 论文 arXiv:2305.14314(NeurIPS 2023)第 7 章
GGUF 命名 Q数字_K_变体;Llama 3.1 8B 原始约 32.1GB,Q4_K_M 约 4.9GB(第三方硬件实测)llama.cpp 官方 quantize 文档(github.com/ggml-org/llama.cpp)第 6 章
主流推理框架支持把 KV Cache 设为 INT8 / FP8 等更低精度vLLM 等框架文档(社区与厂商资料,非本文逐一核验原文)第 2、6 章

附表 B:术语速查表

术语人话解释
量化(Quantization)用更少的二进制位来记录同一个数,精度变粗、体积变小
权重(Weights)模型训练出来的参数,量化最先动的就是它
激活值(Activations)模型每算完一层吐出来的中间结果
KV Cache推理时为避免重复计算,缓存的历史 token 的注意力键值
显存带宽数据从显存搬到计算单元这条路,每秒能搬多少
校准数据(Calibration)用来观察数值实际分布范围的一小批样本
量化粒度(Group size)多少个权重共用同一套缩放规则,越细损失越小
NF4QLoRA 提出的 4 位数据类型,专门适配近似正态的权重分布

写在最后:这篇用到的资料

写这篇文章时,我把一个 70 亿参数的模型从 FP16 压到 4 位,亲眼看着它从塞不进显存到能在本机跑起来,顺手也整理了几份配套的东西:

  • 大模型学习路线图:从零基础到能自己动手做 Agent,按阶段说明每一步该学什么、哪些可以先跳过
  • 《LangChain + LangGraph + MCP 智能体开发实战》视频课:7 个模块,从私有化部署、Embedding+RAG 到 MCP+Agent 全流程
  • AI 大模型知识库(在线可查):Agent Skills 从入门到落地、Claude Skills 完全指南等专题,按目录浏览即可
  • 640 套 AI 大模型行业报告 + 经典 PDF 书籍:看行业落地案例和别人怎么做的时候用得上
  • 大模型零基础到精通教学视频:跟着敲一遍,比只读文档快得多

资料是我自己整理的,放在下面这个码上,扫码即可获取:






添加时备注「AI」,优先通过。

资料按「先路线、再动手、最后查漏」的顺序整理好了,建议先看学习路线那一份,照着它挑一条适合自己当前基础的路径再往下看。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询