HelloAI
L7 第 4 篇 🐥 难度 🕒 14 分钟

量化深度解析:GPTQ / AWQ / FP8 / GGUF 全谱

让 70B 模型塞进 24GB 显存——量化是消费级硬件跑大模型的关键。这一篇详解各家方案。

阿莱
2026/7/27

L7-03 推理优化里提过量化的基础—— 这一篇深度展开主流量化方法。

读完你能:在 RTX 4090 上跑 Llama 3 70B、理解所有 HuggingFace bitsandbytes 参数、选对量化方案。

量化的本质

原始 LLM 权重:通常 FP16(16-bit float)。 70B 模型 = 70B × 2 bytes = 140 GB

一张 RTX 4090 只有 24GB——根本装不下。

量化的目标:用更少的位数存权重,几乎不损失精度

数据类型对比

类型位数范围精度用途
FP3232±10³⁸极高训练(部分)
FP1616±10⁴中-高训练 + 推理标准
BF1616±10³⁸中(动态范围大)训练首选
FP88低-中新硬件(H100+)训练
INT88-128~127低(需 scale)推理
INT44-8~7很低(需 scale)推理(最常用)
INT22-2~1极低实验性

基础量化的数学

把 FP16 权重 → INT8:

# 假设权重在 [-2.0, 2.0] 之间
def quantize(weights, n_bits=8):
    max_int = 2 ** (n_bits - 1) - 1   # 127 for INT8
    scale = max(abs(weights.min()), abs(weights.max())) / max_int

    quantized = round(weights / scale)          # 现在是整数
    quantized = clip(quantized, -max_int, max_int)
    return quantized, scale

def dequantize(quantized, scale):
    return quantized * scale

存的是:量化后的整数 + 一个 scale 因子。 用的时候:dequantize 回浮点。

显存:每个权重 1 字节 + 偶尔的 scale ≈ 2 倍节省(vs FP16)。

各种量化方法

1. PTQ(Post-Training Quantization)—— 训完再量化

最简单——拿训好的模型直接转换:

LLM.int8()

bitsandbytes 库的方法。核心 insight

  • LLM 权重大部分能 INT8 量化
  • 但有少数”outlier”通道(值非常大)—— 它们保留 FP16
from transformers import BitsAndBytesConfig

config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained("Llama-3-70B", quantization_config=config)
# 70B 模型从 140GB → 70GB

性能损失 < 1%。但 PTQ 简单粗暴——还有更好的方法。

2. GPTQ(最经典的 INT4 方法)

2022 年发表的 GPTQ(Generative Pretrained Transformer Quantization)—— 用一小批校准数据,逐层最小化量化误差

核心思路

不简单四舍五入—— 调整每个权重,让”量化后的输出”和”量化前的输出”在校准集上最接近

对每个权重 w_i:
    寻找量化值 q_i ∈ {-8, -7, ..., 7}
    使得 ||W·x - W_quantized·x|| 最小

逐列优化,用 Hessian 信息加速

用法

pip install auto-gptq
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig

quantize_config = BaseQuantizeConfig(
    bits=4,           # INT4 量化
    group_size=128,   # 每 128 个权重共享一个 scale
    desc_act=False,
)

# 用一些校准数据量化
model = AutoGPTQForCausalLM.from_pretrained("Llama-3-70B")
model.quantize(calibration_data)
model.save_quantized("./Llama-3-70B-GPTQ")

结果

  • 70B 模型从 140GB → 35GB ← INT4,4 倍压缩
  • 精度损失:2-5%
  • 推理速度:和 FP16 相当或略快

3. AWQ(Activation-aware Weight Quantization)

2023 年提出的改进版—— 观察到少数”重要”权重比其它重要得多

核心思路

不是平等量化每个权重—— 给”重要权重”分配更多位数,“不重要”权重大幅压缩。

判断”重要”的标准:这个权重对应的激活有多大

直觉:如果激活恒为 0,再大的权重也没用。反之亦然。

优点(vs GPTQ)

  • 不需要长时间校准——更快
  • 某些任务上精度更好
  • 部分硬件友好(推理加速更稳定)
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer

model_name = "Llama-3-70B"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoAWQForCausalLM.from_pretrained(model_name)
model.quantize(tokenizer, quant_config={"bits": 4})

4. GGUF(llama.cpp 用的)

GGUF(GPT-Generated Unified Format)—— llama.cpp 项目的格式。

特点:

  • 极度灵活:支持 INT2、INT3、INT4、INT5、INT6、INT8 等
  • 混合精度:每个张量独立选位数
  • CPU 友好:能在没有 GPU 的机器上跑
  • 量化命名约定Q4_K_M (INT4, K-quant, Medium)

用法(社区最爱)

# 用 Ollama(最易用的 wrapper)
ollama pull llama3.3:70b-q4_K_M
ollama run llama3.3:70b-q4_K_M

或用 llama.cpp:

./llama-cli -m llama-3-70b.Q4_K_M.gguf -p "Tell me about AI"

GGUF 是消费级用户跑 LLM 的事实标准——Apple Silicon、AMD CPU 上跑 LLM 的首选。

5. FP8(新硬件友好)

H100/B200 等新 GPU 原生支持 FP8—— 用 8 位浮点数做训练 + 推理

优势:

  • 比 INT8 动态范围大
  • 训练时仍然能用(INT8 训练困难)
  • 硬件加速直接支持
# 用 NVIDIA Transformer Engine
import transformer_engine.pytorch as te

linear = te.Linear(in_features, out_features)
with te.fp8_autocast(enabled=True, fp8_recipe=fp8_recipe):
    output = linear(input)

预言:FP8 会逐渐取代 INT8 成为推理标准——前提是硬件支持普及。

6. QLoRA(量化 + LoRA)

L4-05 详讲过—— 把基础模型量化到 4-bit,再加 LoRA 微调

from transformers import BitsAndBytesConfig

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",          # 4-bit NormalFloat
    bnb_4bit_compute_dtype=torch.float16,
    bnb_4bit_use_double_quant=True,     # 量化 scale 本身
)

model = AutoModelForCausalLM.from_pretrained(
    "Llama-3-70B",
    quantization_config=bnb_config,
)
# 加 LoRA → 单卡 H100 微调 70B

这是 2023-2024 年最重要的工程突破之一

量化方法横向对比

方法位数精度损失速度易用性推荐场景
LLM.int8()INT8< 1%极易内存紧但要精度
GPTQINT42-5%中等GPU 推理
AWQINT42-4%中等GPU 推理(首选)
GGUFINT2-INT85-15%(INT4)极易CPU/Mac/消费级
FP8FP8<1%极快H100+
QLoRAINT4+LoRA训练时训练用单卡微调

哪些不能量化

不是所有部分都适合量化:

1. Embedding 层

输入层 / 输出层的 embedding 矩阵—— 对量化敏感——量化后效果显著下降。 通常保留 FP16

2. LayerNorm 参数

参数少(每层只有 1-2 个向量),没必要量化

3. 训练时的优化器状态

Adam 的 m、v 状态—— 量化后训练不稳定。 仍然用 FP16/FP32。

一个真实数据:Llama 3 70B 的量化对比

实测在 MMLU benchmark 上:

量化大小MMLU 分数损失
FP16 (原版)140 GB79.5-
INT8 (LLM.int8)70 GB79.2-0.3
INT4 (GPTQ)40 GB77.8-1.7
INT4 (AWQ)40 GB78.4-1.1
INT4 (GGUF Q4_K_M)42 GB78.0-1.5
INT2 (GGUF Q2_K)24 GB71.2-8.3

INT4 是 sweet spot——精度损失小,但显存压力大幅缓解。 INT2 损失太大——除非有特殊需求否则不用。

量化的工程坑

1. 校准数据的选择

GPTQ/AWQ 需要校准数据—— 选错数据 = 量化模型在某些任务上特别差

经验:用多样化的校准集(C4 等通用数据,加你的目标域数据)。

2. Group Size

group_size 越小(如 32),精度越高,但 metadata 开销大。 经验值:128

3. 推理框架支持

不是所有框架支持所有量化:

  • vLLM:支持 GPTQ、AWQ
  • TensorRT-LLM:支持自家量化 + GPTQ
  • llama.cpp:GGUF
  • HF Transformers:bitsandbytes(INT8/INT4)

选量化方法前先确认你的推理框架支持

4. 跨硬件性能

INT4 在 A100 上跑可能比 H100 还慢—— 因为 H100 有原生 INT4/FP8 加速。 新硬件用新量化

一个推荐选择流程

你的场景是?
├── 笔记本/Mac 上跑 → GGUF(Ollama / llama.cpp)
├── GPU 推理服务 → AWQ 或 GPTQ
├── 单卡微调 → QLoRA(INT4 base + LoRA)
├── 训练(H100+) → FP8 + BF16
└── 实验/快速原型 → bitsandbytes 8bit

量化的”未来”

1. 极端低位

研究在探索 INT2、INT1 量化—— 1-bit LLM(BitNet, 2024)甚至能保持大部分性能。 如果成熟——能让模型再小 16 倍。

2. 训练时量化

QAT(Quantization-Aware Training)—— 训练时就考虑量化。 比 PTQ 精度高,但成本贵。

3. 混合精度量化

不同层用不同位数—— 重要的留 INT8,不重要的压到 INT2。 理论上能精确分配”精度预算”

4. 硬件 + 软件协同

新硬件(H100/B200)原生支持各种低位运算—— 软件优化 + 硬件支持 让量化成为标准。

💡 实战建议

别一开始就上 INT4——按这个顺序:

  1. FP16 直接跑,看是否够用
  2. 显存不够 → INT8(损失极小)
  3. 还是不够 → INT4 GPTQ/AWQ
  4. 还是不够 → 上 GGUF + CPU offloading

精度损失永远是 trade-off—— 对生产关键场景,INT8 一般是上限。 INT4 适合”次重要”场景或个人玩。

下一篇推荐:L7-05 模型部署 + 服务化L7-06 训练优化进阶

📬

读到这里说明你认真在学 🎯

订阅每周精选 —— 下一篇新文章 / 新可视化第一时间送到邮箱。

💬

讨论区

· 用 GitHub 账号登录评论
⚠️ Giscus 评论未配置 —— 在 src/components/Comments.astro 顶部填入 仓库 ID 和分类 ID(见组件注释里的配置步骤)。