版权与内容来源声明
本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容,均在附表 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 位,计算在更高精度进行。
那量化图啥?图两件事:
- 模型文件变小,能塞进更小的显存;
- 每次要把权重从显存搬进计算单元时,搬的数据量少了——这就省了"显存带宽"。
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 或更小 |
| 缺校准直接 RTN | 3 位以下易崩 | 用 GPTQ / AWQ 做校准量化 |
量化速查卡:把"三处对象 / 粒度 / 校准"这张关系图整理成了单页卡,配合本章对照着看更顺。放在资料包里,扫码即可获取:
第 6 章 先看显存,还是先看速度?一张表做判断
6.1 先问"你卡在哪"
很多人一上来就问"量化后快多少",但其实第一步该问的是"你卡在哪"。下面这张表给你一个判断顺序。
| 你的首要诉求 | 该优先关注哪种量化 | 推荐做法 | 注意 |
|---|---|---|---|
| 显存放不下模型 | 权重量化(省存储) | GGUF Q4_K_M / bitsandbytes 4 位 | 先看能不能装下,别急着追速度 |
| 长上下文爆显存 | KV Cache 量化 | 推理框架的 KV Cache 精度配置设 INT8 | 长上下文能力需单独验证 |
| 要更高吞吐 | 激活值 + 低精度 kernel | W8A8 / 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.89 | 4 位安全默认,性价比高 |
| 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 论文):
- 先把基座模型量化成4 位 NF4并冻结——这部分显存占用很小,能力损失也很小;
- 在冻结的量化模型之上,接一小撮可训练的 LoRA 低秩适配器;
- 训练时,梯度"穿过"冻结的量化权重,只更新那撮适配器。
论文的核心卖点是:把 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) | 多少个权重共用同一套缩放规则,越细损失越小 |
| NF4 | QLoRA 提出的 4 位数据类型,专门适配近似正态的权重分布 |
写在最后:这篇用到的资料
写这篇文章时,我把一个 70 亿参数的模型从 FP16 压到 4 位,亲眼看着它从塞不进显存到能在本机跑起来,顺手也整理了几份配套的东西:
- 大模型学习路线图:从零基础到能自己动手做 Agent,按阶段说明每一步该学什么、哪些可以先跳过
- 《LangChain + LangGraph + MCP 智能体开发实战》视频课:7 个模块,从私有化部署、Embedding+RAG 到 MCP+Agent 全流程
- AI 大模型知识库(在线可查):Agent Skills 从入门到落地、Claude Skills 完全指南等专题,按目录浏览即可
- 640 套 AI 大模型行业报告 + 经典 PDF 书籍:看行业落地案例和别人怎么做的时候用得上
- 大模型零基础到精通教学视频:跟着敲一遍,比只读文档快得多
资料是我自己整理的,放在下面这个码上,扫码即可获取:
添加时备注「AI」,优先通过。
资料按「先路线、再动手、最后查漏」的顺序整理好了,建议先看学习路线那一份,照着它挑一条适合自己当前基础的路径再往下看。