
在我们反复探讨的大模型落地的过程中,高性能与低成本的矛盾始终存在。想用好一个高性能拥有千亿参数大模型,都面临着存储占用高、推理速度慢的问题。模型量化作为一种核心的优化技术,通过将 32 位浮点数(FP32)转换为 8 位整数(INT8)甚至更低精度的数值,能实现模型体积压缩、推理速度提升的目标。
量化也是有计划的过程,选择INT4或INT8是个技术决策,但具体实施也要有综合评估的执行方案,是通过“低成本、快部署”的角度选择后训练量化(PTQ),还是通过“高精度、强适配”选择量化感知训练(QAT),也是我们需要深度考量的。对于开发者而言,如何根据项目的实际条件选择合适的量化方案,直接决定了模型在生产环境中的表现。今天我们就从核心概念、原理、执行流程、代码示例等方面,由浅入深地解析两种量化技术,并给出明确的选型建议。

量化的核心是数值映射:将浮点数的连续取值范围,映射到整数的离散取值范围。其核心公式如下:
具体解释可参考《大模型量化:INT4与INT8核心差异、选型指南及代码实现.53》
后训练量化,PTQ,全称Post-Training Quantization,是指模型训练完成后,直接对权重和激活值进行量化的技术。它不需要重新训练模型,仅需少量校准数据统计数值分布,计算出scale和zero_point,即可完成量化,低成本的快速改造。
可以通俗地理解为:买了一件现成的衣服(好比预训练 FP32 模型),觉得太大,直接裁剪改小(经过量化),无需重新定制。
可以理解为这是一个标准的INT8量化部署流程,将高精度FP32模型转换为高效INT8模型,基于真实数据分布计算量化参数,只需少量样本即可高效转换完成校准,同时确保量化后模型质量达标。

流程说明:
3.1 优点
3.2 缺点
大模型 PTQ 的核心是“静态量化 + 逐层校准”,需重点配置:校准样本数、量化位数、是否量化激活值、显存优化策略,避免内存溢出,此处我们选择参数量稍大的LLaMA-7B模型进行示例操作,核心围绕“参数配置→数据准备→模型量化→校准验证→模型保存”展开。
5.1 量化核心参数配置(PTQ 的规则定义)
bnb_config = BitsAndBytesConfig(
load_in_8bit=True, # 开启8位PTQ量化
bnb_4bit_compute_dtype=torch.float16, # 计算时用FP16,平衡精度与速度
bnb_4bit_quant_type="nf4", # 大模型专用nf4量化类型
bnb_4bit_use_double_quant=True, # 双重量化,进一步压缩且减少误差
llm_int8_threshold=6.0, # 激活值量化阈值,超过阈值的激活值用FP16
llm_int8_skip_modules=["lm_head", "embed_tokens"], # 跳过输出层和嵌入层
)关键说明:
5.2 校准数据加载与预处理(PTQ 的参考样本)
# 加载校准数据(2000条Alpaca样本)
calib_dataset = load_dataset("tatsu-lab/alpaca", split="train[:2000]")
tokenizer = AutoTokenizer.from_pretrained("openlm-research/open_llama_7b")
tokenizer.pad_token = tokenizer.eos_token
# 数据预处理函数
def preprocess_calib_data(examples):
texts = [f"### Instruction: {inst}\n### Response: {resp}"
for inst, resp in zip(examples["instruction"], examples["output"])]
return tokenizer(
texts, truncation=True, max_length=512, padding="max_length", return_tensors="pt"
)
# 数据格式转换
calib_dataset = calib_dataset.map(preprocess_calib_data, batched=True)
calib_dataset.set_format(type="torch", columns=["input_ids", "attention_mask"])关键说明:
5.3 模型加载与 PTQ 量化
model = AutoModelForCausalLM.from_pretrained(
"openlm-research/open_llama_7b",
quantization_config=bnb_config,
device_map="auto", # 自动分配显存
torch_dtype=torch.float16,
low_cpu_mem_usage=True, # 减少CPU内存占用
)关键说明:
5.4 校准与量化效果验证(PTQ 的误差校准 + 效果验收)
# 校准:前向传播统计激活值分布
calib_dataloader = torch.utils.data.DataLoader(calib_dataset, batch_size=8)
model.eval()
with torch.no_grad():
for batch in calib_dataloader:
input_ids = batch["input_ids"].to("cuda")
attention_mask = batch["attention_mask"].to("cuda")
model(input_ids=input_ids, attention_mask=attention_mask)
# 验证:生成测试文本
test_prompt = "### Instruction: 解释什么是模型量化\n### Response:"
inputs = tokenizer(test_prompt, return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens=100, temperature=0.7)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))关键说明:
5.5 量化模型保存(落地部署)
model.save_pretrained("./llama7b_ptq_8bit")
tokenizer.save_pretrained("./llama7b_ptq_8bit")关键说明:
5.6 执行过程
5.7 核心总结
量化感知训练,QAT,全称Quantization-Aware Training,是指在模型训练过程中,插入量化和反量化模拟节点,让模型感知量化误差并学习适应的技术,是高精度的量身定制。
正向传播时,模型会模拟 INT8 量化的过程(舍入、截断),再反量化回 FP32 进行计算;反向传播时,损失函数会包含量化误差,模型通过更新权重抵消误差的影响。最终导出的量化模型,精度几乎与原始 FP32 模型一致。
通俗地理解为:定制衣服时,裁缝提前考虑你后续要瘦身的需求,裁剪时预留余量,最后改完的衣服既合身又符合尺寸要求。

这是一个量化感知训练的完整流程,通过训练让模型主动适应量化误差,通过模型在训练中体验量化误差,学习补偿,精度通常比训练后量化(PTQ)精度损失更小,迭代优化支持参数调整重新训练。
核心步骤:
3.1 优点
3.4 不足
大模型 QAT 无法全量训练(显存 / 算力成本过高),主流方案是“PTQ 预量化 + LoRA-QAT 微调”:先做 8 位 PTQ,再用 LoRA 低秩适配量化误差,仅微调部分参数,大幅降低算力消耗,模型同样采用已有的LLaMA-7B模型示例;
5.1 双核心配置(PTQ 基础 + LoRA-QAT 核心)
# 1.1 PTQ预量化配置(兜底基础量化)
bnb_config = BitsAndBytesConfig(
load_in_8bit=True,
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
llm_int8_threshold=6.0,
llm_int8_skip_modules=["lm_head", "embed_tokens"],
)
# 1.2 LoRA-QAT核心配置(适配量化误差的关键)
lora_config = LoraConfig(
r=64, # 低秩维度
lora_alpha=128,
target_modules=["q_proj", "v_proj"], # 仅微调注意力Q/V层
lora_dropout=0.05,
bias="none", # 不微调偏置
task_type="CAUSAL_LM", # 因果语言模型
)关键说明:
5.2 模型加载与 QAT 初始化
# 加载PTQ预量化模型
model = AutoModelForCausalLM.from_pretrained(
"openlm-research/open_llama_7b",
quantization_config=bnb_config,
device_map="auto",
torch_dtype=torch.float16,
low_cpu_mem_usage=True,
)
tokenizer = AutoTokenizer.from_pretrained("openlm-research/open_llama_7b")
tokenizer.pad_token = tokenizer.eos_token
# 准备模型用于8位QAT训练
model = prepare_model_for_kbit_training(model)
# 注入LoRA层,仅微调部分参数
model = get_peft_model(model, lora_config)
# 打印可训练参数占比
model.print_trainable_parameters() # 输出:trainable params: ~7M || all params: ~7B || trainable%: 0.1关键说明:
5.3 训练数据加载与预处理(QAT的“误差适配样本”)
# 加载1万条Alpaca训练数据,完整数据的子集,降低成本
train_dataset = load_dataset("tatsu-lab/alpaca", split="train[:10000]")
# 数据预处理
def preprocess_train_data(examples):
texts = [f"### Instruction: {inst}\n### Response: {resp}"
for inst, resp in zip(examples["instruction"], examples["output"])]
return tokenizer(
texts, truncation=True, max_length=512, padding=False
)
train_dataset = train_dataset.map(preprocess_train_data, batched=True)
data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)关键说明:
5.4 训练参数配置与 QAT 执行
# 训练参数配置
training_args = TrainingArguments(
output_dir="./llama7b_qat_8bit",
per_device_train_batch_size=4, # 单卡batch size
gradient_accumulation_steps=8, # 梯度累加
learning_rate=2e-4,
num_train_epochs=3,
fp16=True, # FP16训练
gradient_checkpointing=True, # 显存优化
logging_steps=10,
save_steps=100,
optim="paged_adamw_8bit", # 8位优化器
report_to="none",
push_to_hub=False,
)
# 初始化Trainer并启动训练
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
data_collator=data_collator,
)
trainer.train()关键说明:
5.5 模型保存与 QAT 效果验证
# 保存QAT后的模型(仅保存LoRA权重)
model.save_pretrained("./llama7b_qat_8bit")
# 验证效果
model.eval()
test_prompt = "### Instruction: 解释什么是模型量化\n### Response:"
inputs = tokenizer(test_prompt, return_tensors="pt").to("cuda")
outputs = model.generate(
**inputs, max_new_tokens=100, temperature=0.7, do_sample=True
)
print("QAT量化后生成结果:")
print(tokenizer.decode(outputs[0], skip_special_tokens=True))核心说明:
5.6 执行过程
5.7 核心总结


1. 第一步:优先尝试 PTQ
2. 第二步:PTQ 不达标,评估 QAT 可行性
3. 第三步:折中方案,PTQ+QAT 混合量化
对于参数量动辄百亿、千亿的大模型而言,量化技术是落地的必经之路:

简单来说,PTQ 和 QAT 的选择就是一场成本和精度的博弈。如果我们的项目着急上线,手里只有少量数据,算力也不太够,那PTQ就是优选,几分钟就能搞定,虽然精度降一点,但胜在快、省钱。
如果我们的项目是核心业务,比如看病的医疗模型、开车的自动驾驶模型,精度差一点都不行,而且我们手里有数据、有 GPU,那就果断上QAT,虽然要花时间重新训练,但精度几乎和原模型一样,稳赚不亏。
要是刚好卡在中间,数据和算力都有限,那就试试混合方案:先用 PTQ 快速量化,再用少量数据微调一下,既省钱又能提升精度,完美折中。量化技术没有绝对的好坏,只有合适与不合适。根据项目的实际情况选对方案,才能让模型在生产环境中发挥最大价值。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。