简介
模型量化是一种重要的模型压缩技术。其核心目标是在可控精度损失下,将大模型中浮点型权重(通常为 float32 等高精度格式)近似转换为低精度离散值表示(通常为 int8)。
具体而言,该技术通过将模型的权重(Weights)和/或激活值(Activations)从 FP32、BF16、FP16 等高精度格式压缩至 INT8、INT4、FP8 等低精度格式,为实现三大目标:显著减小模型体积、提升推理速度、降低计算资源消耗,同时最大限度保留模型精度。
工业实践中,INT8 是当前主流方案;低于 8 比特的量化称为低比特量化。其中 1 比特量化作为理论极限,可将 FP32 精度的模型体积压缩至约 1/32。
模型量化的核心对象
-
权重(Weight):模型训练后学习到的固定参数。量化权重可有效减少模型大小、内存及存储空间。
-
激活值(Activation):模型前向传播时,各层依据输入数据实时计算出的中间结果。量化激活值不仅能大幅降低内存占用,更重要的是,与权重量化相结合,可充分借助整数计算提升性能。
-
KV cache:Transformer 解码时缓存的历史 Key/Value 向量(用于避免重复计算)。量化 KV 缓存对提高长序列生成的吞吐量意义重大。
-
梯度(Gradient):反向传播中的参数更新量(仅在训练阶段需要量化)。梯度量化能够降低分布式训练的通信开销及显存占用,需结合量化感知训练(QAT)以保证精度。
对象 | 量化收益 | 技术难点 | 典型方案 |
---|---|---|---|
权重 | 模型体积↓4-8倍,加载速度↑ | 离群值处理 | GPTQ/AWQ(INT4) |
激活值 | 计算速度↑2-4倍,显存占用↓30-50% | 动态范围大,实时性要求 | SmoothQuant/FP8 |
KV缓存 | 长序列内存↓50-75%,吞吐量↑2倍+ | 累积误差控制 | 分组量化+稀疏化 |
梯度 | 训练通信开销↓50%,显存占用↓ | 收敛稳定性 | QAT+FP8通信 |
模型量化的目的
-
参数压缩: 减少模型所需的存储空间,降低模型加载时间。
-
计算加速:降低计算复杂度,提高模型的推理速度。
-
减少显存:减少显存占用,使大模型能在更小的设备上运行。
不同量化精度下的显存占用对比
精度 | 数据类型大小 | 总显存占用 |
---|---|---|
全精度(FP32) | 4 字节 / 参数 | 97GB |
FP16 | 2 字节 / 参数 | 49GB |
FP8 | 1 字节 / 参数 | 25GB |
INT8 | 1 字节 / 参数 | 16GB |
INT4 | 0.5 字节 / 参数 | 13GB |
随着量化精度降低(数据类型表示所需字节数减少 ),模型总显存占用呈现明显下降趋势 。比如从全精度 FP32(4 字节 / 参数 )到 FP16(2 字节 / 参数 ),显存占用近乎减半;进一步到 FP8、INT8(1 字节 / 参数 ),显存占用持续降低;INT4 精度下,数据类型大小仅 0.5 字节 / 参数 ,显存占用也相应降至 13GB 。
模型量化在减少显存占用方面的显著效果,低精度量化能有效压缩模型对显存的需求,有助于大模型在资源受限环境下的部署与推理 ,不过实际应用中需在显存占用、计算效率和模型精度损失之间做好权衡。
Qwen-7B-Chat量化效果
分类
根据量化技术实施的阶段和对训练过程的依赖程度,可以将模型量化分为量化感知训练(Quantization - Aware Training,QAT)和训练后量化(Post - Training Quantization,PTQ)。
量化感知训练(QAT)
量化感知训练,即训练时量化,是一种在模型训练过程中就引入量化操作的方法。在传统的深度学习模型训练中,模型参数通常以高精度(如 FP32)进行存储和计算。而 QAT 则打破了这一常规模式,它在训练过程中模拟量化过程,使得模型在学习参数的同时,也能够适应量化带来的精度损失。
具体来说,在 QAT 的训练过程中,前向传播时,模型的权重和激活值会被量化成低精度表示(如 INT8),以模拟实际部署时的量化情况;反向传播时,使用量化后的参数计算梯度,并更新原始的高精度参数。通过这种方式,模型能够在训练过程中逐渐学习到如何在低精度表示下保持良好的性能。
QAT 的优势在于其量化效果较好。由于模型在训练阶段就对量化误差进行了适应,因此相较于训练后量化,在相同的低精度量化条件下,QAT 往往能够更好地保持模型的准确性,尤其适用于对模型性能要求较高且能够承受额外训练成本的场景,比如医疗影像诊断、金融风险评估等对预测精度要求苛刻的领域。然而,QAT 也存在一定的局限性,它需要额外的训练时间和计算资源,并且需要有充足的训练数据来保证模型能够学习到合适的参数,以应对量化带来的影响。
训练后量化(PTQ)
训练后量化,顾名思义,是在模型已经完成训练之后,对训练好的模型进行量化处理的方法。与 QAT 不同,PTQ 不需要重新进行训练过程,而是通过对训练好的模型进行分析和处理,将模型参数从高精度转换为低精度表示。
通常,PTQ 会先利用少量的校准数据来统计模型中权重和激活值的分布情况,然后根据这些统计信息确定量化参数,如缩放因子和零点,进而将模型参数量化为低精度格式。这种方法的优点是量化资源需求较小,操作相对简单且耗时短。它不需要像 QAT 那样重新进行训练,大大节省了时间和计算资源,能够快速地将训练好的模型转换为低精度版本,适用于对部署速度要求较高的场景,比如在移动设备、嵌入式设备上快速部署深度学习模型。
不过,由于 PTQ 没有在训练过程中对量化误差进行适应,在一些情况下,尤其是采用较低的量化精度时,模型的性能可能会出现较为明显的下降。为了尽可能减少这种性能损失,研究人员提出了各种改进的 PTQ 算法,如基于统计信息的量化、基于优化的量化等,以提高训练后量化模型的性能。
QAT与PTQ的关键对比
维度 | QAT | PTQ |
---|---|---|
实施阶段 | 训练中 | 训练完成后 |
计算成本 | 高(需反向传播) | 极低(仅前向校准) |
数据依赖 | 需完整训练数据集 | 仅需小批量校准数据 |
精度表现 | 最优(尤其INT4以下) | 中等(INT8可达近无损) |
部署速度 | 慢(需迭代训练) | 快(分钟级完成) |
典型应用 | 低比特压缩、高精度要求场景 | 快速部署、资源受限环境 |
量化训练方法概览
分类 | 方法名称 | 论文链接 | 简介 |
---|---|---|---|
训练时量化 | LLM-QAT | LLM-QAT: Data-Free Quantization Aware Training for Large Language Models | 利用预训练模型生成结果实现无数据蒸馏,量化权重、激活和KV缓存,支持4比特量化,增强长序列处理能力 |
参数高效微调 | PEQA | Memory-Efficient Fine-Tuning of Compressed LLMs via Sub-4-bit Integer Quantization | 双阶段量化感知PEFT技术:先量化全连接层为低比特整数+标量向量,再微调标量向量,实现快速任务切换和高效部署 |
高效微调 | QLORA | QLORA: Efficient Finetuning of Quantized LLMs | 引入NF4数据类型、双重量化和分页优化器,使65B模型微调仅需48GB显存,基本保持原始性能 |
计算优化 | LUT-GEMM | nuqmm: Quantized Matmul for Efficient Inference | 通过BCQ格式优化矩阵乘法,仅量化权重,显著提升计算效率降低延迟 |
混合精度 | LLM.int8() | LLM.int8(): 8-bit Matrix Multiplication | 混合精度分解:对多数权重/激活8bit量化,对离群特征保留16bit高精度计算 |
训练后量化 | ZeroQuant | ZeroQuant: Efficient Post-Training Quantization | 权重group-wise + 激活token-wise量化,通过逐层知识蒸馏缓解精度损失,支持4bit权重量化 |
训练后量化 | GPTQ | GPTQ: Accurate Post-Training Quantization | 块内参数顺序量化+剩余参数调整补偿误差,需校准数据集,实现高精度生成模型量化。 专用于大语言模型的量化技术。通过分析并选择性地优化数据,来减少关键部分的损失。 逐层量化,在模型的每一层中找到对结果影响不太大的权重,并对其量化。然后,对该层因量化产生的误差进行补偿,来防止误差积累,保持模型的计算精度。 |
比特精度研究 | k-bit Inference | The Case for 4-bit Precision | 通过推理缩放定律分析,证明4比特在模型大小与精度间达到最佳平衡 |
激活感知 | AWQ | AWQ: Activation-aware Weight Quantization | 保留1%显著权重减少误差,采用激活感知的逐通道缩放技术确定最优因子 |
混合精度 | OWQ | OWQ: Lessons from Activation Outliers | 分析激活异常放大误差机制,对受影响权重采用更高精度量化 |
稀疏量化 | SpQR | SpQR: Sparse-Quantized Representation | 隔离异常权重高精度存储,其余压缩为3-4比特 |
激活量化 | SmoothQuant | SmoothQuant: Accurate Activation Quantization | 在用PTQ、QAT等方法量化之前,先对参数范围做调整,让模型更容易被量化。 引入逐通道缩放变换平滑激活幅度,解决激活值离群点问题;即重新分配参数的范围,使其在量化时更加均衡,从而减少信息损失。 |
通道优化 | RPTQ | RPTQ: Reorder-based PTQ for LLMs | 通道分组量化+重排集成,缓解通道范围差异和离群值影响 |
硬件友好 | OliVe | OliVe: Hardware-friendly OVP Quantization | 采用outlier-victim对(OVP)量化,局部处理异常值实现低开销高性能 |
异常抑制 | Outlier Suppression+ | Outlier Suppression+ | 通道级平移缩放操作纠正激活异常不对称分布,定量分析最优值 |
浮点量化 | ZeroQuant-FP | ZeroQuant-FP: W4A8 Quantization Using FP | 探索FP8/FP4浮点量化,FP8激活优于INT8,FP4权重优于INT4,采用2幂次缩放因子和LoRC策略增强效果 |
-
技术演进趋势:
-
从基础PTQ(如GPTQ)→ 激活感知(AWQ)→ 异常处理(SmoothQuant)→ 硬件友好(OliVe)
-
比特精度:8bit → 4bit(QLORA/SpQR)→ 混合精度(LLM.int8/OWQ)
-
-
核心突破:
-
4bit实用化:LLM-QAT/QLORA/SpQR实现无损4bit量化
-
异常值处理:>50%方法专注解决激活/权重离群值问题
-
硬件协同:LUT-GEMM/OliVe等专为硬件加速设计
-
-
精度-效率平衡:
-
训练时方案(QAT/PEQA)精度更高但成本大
-
训练后方案(GPTQ/AWQ)部署快但需校准
-
浮点量化(ZeroQuant-FP)在精度和硬件支持间取得新平衡
-
量化推理框架
BitsAndBytes
BitsAndBytes 以 “减少大模型显存占用” 为核心目标,深度适配低资源设备推理与微调场景。通过创新量化技术,在保证模型功能的前提下,压缩参数存储与计算需求,让大模型能在消费级硬件、资源受限环境中稳定运行,填补高端算力与实际应用间的鸿沟 。
适用场景
-
消费级显卡加载大模型:对于想在 RTX 4080/4090 等消费级显卡运行大模型的用户,BitsAndBytes 是 “破局钥匙”。传统大模型因参数精度高、显存占用大,难在消费级硬件加载,而它通过量化压缩,将模型显存需求大幅降低,让玩家、个人开发者无需顶级算力,也能体验大模型推理,拓宽技术触达范围。
-
模型微调场景(以 LoRA 微调为例):进行 LoRA 等模型微调时,BitsAndBytes 可协同增效。微调需加载模型并更新部分参数,显存压力仍存。它通过量化优化基础模型,释放更多显存空间,支持更大批次数据训练、更复杂微调任务,同时减少算力消耗,让微调更高效、更易执行,助力开发者快速迭代模型 。
-
快速测试与研究 LLMs:在大模型测试、研究场景,效率与便捷性至关重要。BitsAndBytes 支持快速部署量化模型,无需繁琐配置高端算力,就能快速验证模型思路、测试算法效果。无论是学术研究探索模型潜力,还是企业快速试错验证需求,它都能缩短从想法到实践的路径,加速大模型创新进程 。
代码示例
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torchmodel_name = "/ai/data/DeepSeek-R1-Distill-Qwen-1.5B"use_4bit = True
bnb_4bit_compute_dtype = "float16"
bnb_4bit_quant_type = "nf4"
use_nested_quant = False
compute_dtype = getattr(torch, bnb_4bit_compute_dtype)bnb_config = BitsAndBytesConfig(load_in_4bit=use_4bit,bnb_4bit_quant_type=bnb_4bit_quant_type,bnb_4bit_compute_dtype=compute_dtype,bnb_4bit_use_double_quant=use_nested_quant,
)model = AutoModelForCausalLM.from_pretrained(model_name,torch_dtype="auto",device_map="auto",quantization_config=bnb_config
)
tokenizer = AutoTokenizer.from_pretrained(model_name)history, response = [], ""query = input("请输入内容:")
messages = [{"role": "system", "content": "你是一个智能助手,擅长用中文回答用户的提问。"}]
while query:for query_h, response_h in history:messages.append({"role": "user", "content": query_h})messages.append({"role": "assistant", "content": response_h})messages.append({"role": "user", "content": query})text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True)model_inputs = tokenizer([text], return_tensors="pt").to(model.device)generated_ids = model.generate(**model_inputs,max_new_tokens=1024,temperature = 0.7,top_p = 0.8,repetition_penalty=1.1)generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]print(response)history.append([query, response])query = input("请输入内容:")
这段代码主要实现了基于BitsAndBytes
量化技术加载大模型并进行交互式对话的功能。通过transformers
库加载指定的因果语言模型(这里是DeepSeek-R1-Distill-Qwen-1.5B
),利用BitsAndBytes
进行量化优化,降低显存占用,最终实现用户与模型的实时对话交互。
代码中量化配置是核心,通过BitsAndBytesConfig
实现 4-bit 量化,关键参数及作用如下:
-
load_in_4bit=use_4bit
:启用 4-bit 量化模式,将模型权重从原始高精度(如 FP16/FP32)压缩为 4-bit 存储,大幅降低显存占用(仅为原始的 1/4~1/8)。 -
bnb_4bit_quant_type=bnb_4bit_quant_type
:指定量化类型为nf4
(Normalized Float 4),这是专为大模型设计的 4-bit 数据类型,相比普通 INT4 能更好地保留模型精度,尤其适合低比特量化场景。 -
bnb_4bit_compute_dtype=compute_dtype
:设置计算时的精度为float16
,即量化后的权重在参与计算(如矩阵乘法)时会临时转换为 16-bit 浮点数,平衡计算效率与精度损失。 -
bnb_4bit_use_double_quant=use_nested_quant
:关闭 “双重量化”(嵌套量化),该技术会对量化参数本身再进行一次量化以进一步节省内存,此处因use_nested_quant=False
未启用。
TensorRT-LLM
TensorRT-LLM 是 NVIDIA 推出的专为深度学习大模型打造的推理优化工具,核心定位是通过深度技术优化,实现大模型推理性能的极致提升,为生产级部署提供低延迟、高吞吐量的解决方案。
在 TensorRT-LLM 中,量化方法的选择需综合考量权重精度格式、激活精度格式和校准算法三大核心组成部分。不同推理场景下的性能瓶颈存在差异,因此需针对性选择量化策略,以实现性能与精度的平衡。
适用场景
根据推理批量大小的不同,性能瓶颈存在差异,需匹配差异化量化策略:
- 小批量推理场景(批量大小≤4)
-
瓶颈特征:推理受 “内存限制”,吞吐量取决于权重从 GPU 内存到缓存的加载效率(受内存带宽约束)。
-
推荐策略:优先选择仅权重量化方法,通过减少权重显存占用提升加载效率,如 INT4 AWQ、INT4-FP8 AWQ 或微软 FP6-LLM 方案,可显著提升性能。
-
-
大批量推理场景(批量大小≥16)
-
瓶颈特征:内存带宽与计算密度共同成为关键限制,需同时优化存储与计算效率。
-
推荐策略:选择权重与激活联合量化 + 低精度计算 Kernel 的方案,具体可按以下优先级选择:
-
FP8 量化:精度损失极小,性能强劲,优先推荐;
-
INT4-FP8 AWQ:若 FP8 性能未达预期,可尝试此方案;
-
INT4 AWQ 或 INT8 SQ:针对 Ampere 及更早版本 GPU,兼容性更佳。
-
-
量化方法 | 小批量性能 | 大批量性能 | 精度下降 | 详情 |
---|---|---|---|---|
FP8 | 中 | 中 | 非常低 | - 采用 min-max 校准进行 FP8 逐张量权重和激活量化; - 将 FP16/BF16 模型压缩至原始大小的 50%; - 校准时间:分钟级; - 部署依赖:TensorRT、TensorRT-LLM,支持 GPU 架构:Ada、Hopper 及更高版本。 |
INT8 SmoothQuant | 中 | 中 | 中 | - 基于 SmoothQuant 校准变体的 8 位整数量化; - 采用逐通道权重量化、逐张量激活量化; - 将 FP16/BF16 模型压缩至原始大小的 50%; - 校准时间:分钟级; - 部署依赖:TensorRT、TensorRT-LLM,支持大多数 GPU 架构。 |
INT4 Weights only AWQ(W4A16) | 高 | 低 | 低 | - 通过 AWQ 校准实现 4 位整数仅权重量化(group-wise/block-wise); - 将 FP16/BF16 模型压缩至原始大小的 25%; - 校准时间:数十分钟级; - 部署依赖:TensorRT-LLM,支持 GPU 架构:Ampere 及更高版本。 |
INT4-FP8 AWQ(W4A8) | 高 | 中 | 低 | - 采用 AWQ 校准进行 4 位整数权重量化(group-wise/block-wise)+ FP8 逐张量激活量化; - 将 FP16/BF16 模型压缩至原始大小的 25%; - 校准时间:数十分钟级; - 部署依赖:TensorRT-LLM,支持 GPU 架构:Ada、Hopper 及更高版本。 |
代码示例
from tensorrt_llm.builder import Builder, BuilderConfig
from tensorrt_llm.models import PretrainedModel
from tensorrt_llm.quantization import QuantMode
from tensorrt_llm.runtime import ModelRunner
import tensorrt_llm
import torch
from transformers import AutoTokenizer# 模型路径与量化配置
model_name = "/ai/data/DeepSeek-R1-Distill-Qwen-1.5B"
quant_mode = QuantMode.INT4_WEIGHTS # 4位权重量化(可切换为INT8、FP8等)
batch_size = 4 # 批量大小,影响量化策略选择
max_seq_len = 1024 # 最大序列长度# 1. 加载Tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_name)
if tokenizer.pad_token is None:tokenizer.pad_token = tokenizer.eos_token# 2. 配置TensorRT-LLM量化参数
builder = Builder()
builder_config = BuilderConfig(precision_mode="float16", # 基础计算精度(与量化协同工作)tensor_parallel=1, # 单卡部署,多卡可调整quant_mode=quant_mode, # 核心量化模式max_batch_size=batch_size,max_input_len=max_seq_len,max_output_len=max_seq_len,
)# 针对INT4量化的额外配置(以AWQ为例)
if quant_mode == QuantMode.INT4_WEIGHTS:builder_config.quantization.awq=True # 启用AWQ量化算法builder_config.quantization.group_size=128 # 分组量化大小,平衡精度与效率builder_config.quantization.bits=4 # 明确量化位数# 3. 加载并转换模型为TensorRT-LLM格式(含量化)
model = PretrainedModel(model_name)
# 构建量化引擎(耗时步骤,需校准数据时会自动进行校准)
engine = builder.build_engine(model, builder_config)# 4. 创建推理运行器
runner = ModelRunner(engine)# 5. 交互式对话
history = []
print("开始对话(输入空内容退出):")
while True:query = input("用户:")if not query:break# 构建对话历史messages = [{"role": "system", "content": "你是一个智能助手,用中文回答问题。"}]for q, a in history:messages.append({"role": "user", "content": q})messages.append({"role": "assistant", "content": a})messages.append({"role": "user", "content": query})# 编码输入input_ids = tokenizer.apply_chat_template(messages,return_tensors="pt",padding=True,truncation=True,max_length=max_seq_len)# 推理outputs = runner.generate(input_ids=input_ids,max_new_tokens=1024,temperature=0.7,top_p=0.8,repetition_penalty=1.1)# 解码输出response = tokenizer.decode(outputs[0][len(input_ids[0]):], skip_special_tokens=True)print(f"助手:{response}")history.append((query, response))
-
核心量化配置:通过
BuilderConfig
的quant_mode
指定量化模式,示例中使用INT4_WEIGHTS
(仅权重量化),也可根据场景选择INT8
(权重 + 激活量化)、FP8
等。 -
AWQ 量化支持:当启用 INT4 量化时,
awq=True
表示使用 AWQ 算法(激活感知权重量化),通过group_size=128
进行分组量化,在压缩模型至原始大小 25% 的同时,最大限度保留精度。 -
精度协同:
precision_mode="float16"
表示量化后的权重在计算时会临时转换为 16 位浮点数,避免低精度计算导致的误差累积,平衡效率与性能。 -
自动校准:构建引擎时,TensorRT-LLM 会根据量化模式自动进行校准(如收集权重 / 激活分布),无需手动编写校准逻辑,简化量化流程。
-
场景适配:若需优化大批量推理(如
batch_size≥16
),可将quant_mode
改为INT4_WEIGHTS | QuantMode.INT8_ACTIVATIONS
(权重 4 位 + 激活 8 位),并配合FP8
计算精度进一步提升吞吐量。
简要对比
对比维度 | BitsAndBytes | TensorRT-LLM |
---|---|---|
主要目的 | 在有限显存下部署大模型 | 追求推理的高速度、低延迟 |
使用门槛 | 相对更低,简单了解该训练框架即可 | 要理解 NVIDIA 硬件优化方式、TensorRT 部署流程等 |
对硬件要求 | 普通消费级 GPU 即可 | 仅限 NVIDIA GPU,最好是支持 Tensor Core 的系列 |
量化精度 | 8-bit、4-bit 等低比特数 | 支持 FP16、INT8,结合硬件加速实现更高推理效率 |
部署场景 | - 本地环境快速验证或小规模部署 - 小显存服务器或工作站 | - 需要处理大量请求的生产环境 - 追求极致性能的大规模部署 |
参考文献
https://zhuanlan.zhihu.com/p/11886909512
https://www.zhihu.com/question/627484732/answer/3261671478
深入大模型量化技术,大模型端侧落地已Ready? - 智源社区