模型优化

这篇文章整理模型压缩与量化相关的核心知识点,重点包括图优化、QATPTQ、量化细节和不同部署框架中的落地方式。

1. 模型压缩与图优化

在真正进入量化之前,通常先做计算图层面的优化。这样可以减少冗余算子,也更容易发现性能瓶颈。

1.1 算子耗时分析

可以先用框架或推理引擎的 profiling 功能定位瓶颈,例如:

  • onnxruntime 中开启 enable_profiling=true
  • 查看每个算子的执行时间
  • 判断瓶颈是在 CPU、GPU 还是 NPU 上

1.2 常见图优化方式

  • 常量折叠:FoldConstant
  • 算子融合:例如 Conv + BN + Activation
  • 冗余算子消除
  • 等价算子替换

一些典型例子:

  • MatMul + Add 替换为 GEMM
  • 连续的 reshape + reshape 合并
  • 成对的 unsqueeze + squeeze 消除

1.3 工具链相关优化

可以关注这些工具在图层面的处理能力:

  • onnx-simplifier
  • RKNN
  • TensorRT

这里可以重点分析:

  • 是否存在算子落回 CPU 执行
  • 是否发生不必要的数据搬运
  • 是否有引擎不支持的节点导致性能退化

1.4 异构平台视角

部署时还需要考虑不同硬件的执行特点:

  • GPU
  • NPU
  • CPU

不同平台对于算子支持、数据格式、量化方式的偏好并不一致,量化方案最好和目标硬件一起设计。

2. 量化基础概念

2.1 什么是量化

量化的核心是把高精度数值表示转换成低比特表示,以减少:

  • 模型体积
  • 内存带宽占用
  • 推理延迟

2.2 常见目标

  • 提升推理速度
  • 降低显存或内存占用
  • 适配硬件推理单元
  • 在精度和性能之间寻找平衡

3. QAT:量化感知训练

3.1 QAT 的本质

QAT 本质上还是训练或微调,只是在训练过程中显式模拟量化误差,让模型逐步适应低比特表示。

3.2 实践中的重点

  • 训练配置要尽量贴近目标硬件
  • 某些硬件不支持非对称量化,需要提前对齐限制
  • 量化节点的插入位置会影响最终精度

例如:

  • TensorRT 对某些量化形式支持有限
  • 实际部署中经常需要约束为特定的 INT8 方案

3.3 常见工具

  • torch.ao
  • pytorch_quantization

这类工具通常会涉及:

  • 节点白名单,如 ConvLinearMaxPool
  • 激活量化与权重量化的插入方式
  • 前向中的 fake quant
  • 反向传播时对量化参数的处理

3.4 QAT 中常见问题

  • 量化参数初始化如何确定
  • 节点融合后插桩位置如何变化
  • 动态图如何转换为更稳定的静态表示
  • 不同量化方法如 LSQLSQ+ 的适用场景

4. PTQ:训练后量化

4.1 PTQ 的特点

PTQ 不需要重新训练模型,通常只需要校准数据即可完成量化,工程落地成本更低。

4.2 常见实现路径

  • RKNN 的 PTQ
  • TensorRT 的 PTQ
  • ONNX Runtimequantize_static
  • 一些模型转换链路中的量化工具,如 onnx2tf

4.3 PTQ 关注点

  • 校准数据集是否有代表性
  • 激活分布是否稳定
  • 某些层是否不适合量化
  • 是否需要混合精度

5. ONNX 中的量化表示

5.1 QDQ 节点

ONNX 里常见的量化表达方式是 QDQ

  • QuantizeLinear
  • DequantizeLinear

它的优点是表达清晰,便于在图层面对量化节点进行插入、分析和转换。

5.2 常见用途

  • 表达量化后的计算图
  • 为后端推理引擎提供量化信息
  • 用于分析哪些节点被量化、哪些节点保持浮点

6. 量化中的关键细节

6.1 权重量化与激活量化

  • 权重量化:通常更稳定,离线处理方便
  • 激活量化:对推理时输入分布更敏感

6.2 静态量化与动态量化

  • 静态量化:推理前已确定量化参数
  • 动态量化:激活在推理时再量化,常见于仅权重量化场景

6.3 对称量化与非对称量化

量化时一般会涉及:

  • scale
  • zero_point

需要区分:

  • 对称量化
  • 非对称量化
  • 线性量化
  • 非线性量化

6.4 常见精度表示

  • W8A8
  • W8A16
  • FP16
  • FP8

6.5 量化粒度

  • per-tensor
  • per-channel

粒度不同,通常会影响:

  • 精度表现
  • 实现复杂度
  • 硬件支持程度

6.6 校准方法

常见校准方式:

  • MinMax
  • KL

对于 hard-case,常见手段包括:

  • 调整校准集
  • 改变量化粒度,如 channel-wise
  • 逐层分析误差来源

6.7 混合量化

如果全量化导致精度掉点严重,可以考虑:

  • 把尾部非线性算子移出量化路径
  • 保留部分层为高精度
  • 采用混合量化策略

例如常见需要重点观察的节点:

  • sigmoid
  • nms

7. 大模型量化

对于大模型,常见方案往往偏向 weight-only

  • GPTQ
  • AWQ

这类方法的核心目标通常是:

  • 降低权重存储成本
  • 尽量控制精度损失
  • 提高大模型推理可部署性

8. 一个可扩展的整理框架

后续如果继续补内容,可以按下面结构补充实例:

  1. 原始模型与目标硬件
  2. 图优化前后的差异
  3. PTQ 流程与结果
  4. QAT 流程与结果
  5. 逐层误差分析
  6. 混合量化策略
  7. TensorRT / RKNN / ONNX Runtime 的部署差异