模型转换与量化:FP16/INT8/INT4量化原理、PTQ与QAT流程、精度评估

4.1 为什么量化是TensorRT-LLM落地的关键环节

大语言模型在推理阶段的主要瓶颈是显存带宽与计算吞吐。以LLaMA-70B为例,FP16权重占用约140GB显存,单张H100 80GB无法承载;即便使用多卡,访存开销也远高于计算开销。量化通过降低权重和激活值的位宽,同时压缩模型体积并提升计算密度,是TensorRT-LLM实现高吞吐、低延迟服务的必经之路。

TensorRT-LLM的量化并非简单调用torch.quantize,而是需要理解其底层引擎对张量布局、Kernel选择、反量化时机的约束。量化方案选错或校准不当,轻则精度损失超标,重则推理结果完全不可用。因此,掌握FP16/INT8/INT4的量化原理、PTQ与QAT的完整流程,以及精度评估方法,是模型上线前的必修课。

核心结论:量化是“精度-显存-吞吐”三角的平衡艺术。FP16是基线,INT8是性价比首选,INT4是极限压缩,但必须配合AWQ/GPTQ等算法与合理的KV Cache量化策略。

4.2 量化原理:从FP16到INT4的映射与误差来源

量化的数学本质是将浮点张量映射到低比特整数空间。以对称量化为例,核心公式为:

scale = max(|x|) / (2^(bits-1) - 1)
x_int = round(x / scale)
x_dequant = x_int * scale

TensorRT-LLM中,权重通常采用逐通道(Per-Channel)量化,激活值采用逐张量(Per-Tensor)或逐Token量化。Per-Channel能显著降低权重离群值带来的精度损失,但会增加反量化计算量。

FP16到INT8的转换相对温和,动态范围仅从约5位指数缩减到固定整数范围。而INT4量化只有16个离散级别,对离群值极其敏感。下图展示了不同位宽下权重分布与量化误差的关系:

不同位宽量化误差对比示意图 FP16 (基线) 动态范围: 5e-324 ~ 65504 精度: 10位有效数字 INT8 (256级) 量化误差: ~0.1% 推荐: 权重+激活 INT4 (16级) ! ! 量化误差: 1~5% 需AWQ/GPTQ补偿

从图中可以看出,FP16的连续分布被INT8的256个离散级别替代后,主体信息保留良好;而INT4仅有16个级别,离群值(红色感叹号处)会导致严重的信息丢失。这也是为什么INT4量化必须配合离群值感知的权重均衡算法(如AWQ的激活感知缩放、GPTQ的近似二阶优化)才能保证可用性。

4.3 PTQ与QAT:两种量化流程的完整对比

TensorRT-LLM支持两种主流量化路径:训练后量化(PTQ)和量化感知训练(QAT)。两者的核心区别在于:PTQ在模型训练完成后进行,需要少量校准数据;QAT在训练或微调阶段引入伪量化节点,让模型自适应低比特表示。

对比维度 PTQ (训练后量化) QAT (量化感知训练)
所需数据 数百条无标签校准样本 需要带标签训练数据
计算开销 低(分钟级) 高(需完整训练/微调)
精度保留 INT8良好,INT4需算法补偿 INT4精度显著优于PTQ
适用场景 快速上线、无训练资源 精度敏感、可微调模型
TensorRT-LLM支持 支持AWQ/GPTQ/SmoothQuant 支持QAT导出INT8/INT4

4.3.1 PTQ流程:校准与算法选择

在TensorRT-LLM中执行PTQ的标准流程如下:

  1. 准备校准数据:从训练集或真实业务采样中选取128~512条样本,覆盖不同长度和主题。
  2. 选择量化算法:权重使用RTN(舍入到最近)、AWQ或GPTQ;激活使用Max/Min或Percentile校准。
  3. 执行校准:运行TensorRT-LLM的量化脚本,生成量化权重和缩放因子。
  4. 构建引擎:将量化模型转换为TensorRT引擎,指定--quantize int4_awq等参数。
# 使用TensorRT-LLM的量化脚本(示例)
python convert_checkpoint.py \
    --model_dir ./llama-2-7b-hf \
    --output_dir ./llama-2-7b-int4-awq \
    --dtype float16 \
    --quant_method awq \
    --quantize_weight 4 \
    --calib_dataset ./calib_data.jsonl \
    --calib_size 128

# 构建引擎
trtllm-build \
    --checkpoint_dir ./llama-2-7b-int4-awq \
    --gemm_plugin float16 \
    --max_batch_size 8 \
    --max_input_len 2048 \
    --max_seq_len 4096 \
    --output_dir ./engine
实操建议:校准数据的选择直接影响量化质量。优先使用与线上推理分布一致的样本(如同领域的Prompt),避免使用纯随机文本。对于代码模型,应使用代码样本校准;对于对话模型,应使用多轮对话样本。

4.3.2 QAT流程:伪量化与端到端微调

QAT的核心是在模型前向传播中插入伪量化节点(FakeQuant),模拟量化误差,让权重在训练中逐步适应低比特表示。TensorRT-LLM的QAT流程通常借助torchao或NVIDIA TensorRT Model Optimizer实现:

# 使用TensorRT Model Optimizer进行QAT(伪代码)
from modelopt.torch.quantization import quantize, QAT

# 定义量化配置
qat_config = QAT(
    quant_algo="INT4_AWQ",
    calib_data=calib_loader,
    num_calib_steps=128
)

# 应用QAT
qat_model = quantize(model, qat_config)

# 微调训练(通常1~3个epoch,学习率降低10倍)
train(qat_model, train_loader, epochs=2, lr=1e-5)

# 导出为TensorRT-LLM格式
export_quantized_model(qat_model, output_dir="./qat_model")

QAT的关键超参数包括:伪量化起始步数(建议前10%训练步数不做量化,让模型先收敛)、学习率调度(比正常微调低10~50倍)、批大小(保持与原始训练一致)。QAT后的模型通常能恢复PTQ损失的50%~80%精度,尤其在4比特场景下效果显著。

4.4 精度评估:量化前后必须验证的指标

量化是否成功,不能只看Loss或Perplexity,需要从多个维度评估。TensorRT-LLM部署场景中,推荐以下评估矩阵:

  • 困惑度(PPL):在标准语料(如Wikitext)上对比量化前后PPL变化,通常INT8应小于0.5,INT4应小于2.0。
  • 下游任务准确率:MMLU、GSM8K、HumanEval等,按业务场景选择2~3个任务。
  • 输出质量抽样:人工或LLM-as-Judge对比量化前后的回答质量。
  • 数值误差分析:对比量化模型与FP16模型的隐藏层输出余弦相似度。
# 使用lm-evaluation-harness评估量化模型
lm_eval --model vllm \
    --model_args pretrained=./llama-2-7b-int4-awq,quantization=awq \
    --tasks mmlu,gsm8k \
    --batch_size auto \
    --output_path ./eval_results.json
常见误区:仅用PPL评估量化模型是不够的。某些模型PPL变化很小,但在代码生成或数学推理任务上准确率下降超过10%。务必结合业务场景做任务级评估,并保留FP16基线结果作为对照。

4.5 案例复盘:LLaMA-2-7B的INT4量化实战

某企业需要将LLaMA-2-7B部署到2张A10(24GB)显卡上,目标吞吐提升3倍。我们对比了三种方案:

方案 显存占用 MMLU准确率 吞吐 (tokens/s) 结论
FP16基线 13.5GB 45.3% 820 作为对照
INT8 PTQ 7.2GB 44.8% (-0.5) 1450 精度损失可接受
INT4 AWQ 4.1GB 43.9% (-1.4) 2310 精度略降,吞吐翻倍

最终选择INT4 AWQ方案,但针对MMLU中下降明显的“法律”和“医学”子任务,额外收集了500条领域数据做QAT微调,将准确率恢复到44.7%。这一案例说明:PTQ快速上线,QAT精调兜底是量化落地的标准组合拳。

4.6 量化选型决策清单

在实际项目中,可按下述清单快速决策:

  1. 显存是否紧张?不紧张则保持FP16,省去所有量化风险。
  2. INT8 PTQ后PPL增加是否小于1.0?是则直接采用INT8。
  3. 需要INT4时,优先尝试AWQ/GPTQ,若精度不达标再考虑QAT。
  4. KV Cache是否量化?长序列场景下KV Cache INT8可节省30%显存。
  5. 是否开启--use_fp8?H100等硬件支持FP8时,精度优于INT8且速度更快。

量化不是“越低越好”,而是“够用就好”。建议在项目初期就建立量化评估流水线,将PPL、任务准确率、吞吐、延迟纳入CI/CD,每次模型更新自动跑一遍量化验证,确保上线质量。