PaddleClas 模型裁剪与量化算法全解:PACT 量化与 FPGM 裁剪的部署加速实战

原创2026-10-03 21:34:012,134 阅读
文章标签:人工智能深度学习计算机视觉

PaddleClas 模型裁剪与量化算法全解:PACT 量化与 FPGM 裁剪的部署加速实战

深度学习模型因其计算复杂度高、参数冗余多,在边缘设备、低功耗场景和实时推理系统中往往难以直接部署。模型压缩技术通过在保持精度的前提下降低参数量与计算量,成为打通"训练—部署"链路的关键一环。本文以 PaddleClas 官方算法文档为主线,系统讲解其在图像分类任务中主推的两类压缩算法——PACT 量化与 FPGM 裁剪:既从数学原理上剖析"为什么有效",也从配置文件、源码与自动化压缩工具三个层面给出可直接落地的操作方案。读完本文,你将掌握在 PaddleClas 中启用 PACT 量化训练、FPGM 结构化裁剪,以及通过 PaddleSlim 自动压缩(量化+蒸馏)产出 INT8 模型并加速部署的完整实战技能。

1. 为什么需要模型压缩:计算复杂度与参数冗余

深度学习在图像分类上取得卓越效果的同时,也带来了两个部署层面的瓶颈:

  • 计算复杂度高:卷积、全连接等算子在前向推理时消耗大量算力,限制了在高帧率、低功耗场景下的实时性;
  • 参数冗余:大规模网络参数占用大量存储与通信带宽,尤其在端侧(手机、嵌入式设备)上,模型体积直接决定了可用性。

模型压缩算法通过降低参数冗余,能够同时减少存储占用、通信带宽与计算复杂度。在众多压缩手段中,**量化(Quantization)与裁剪(Pruning)**应用最为广泛。在 PaddleClas 中,官方主推以下两种算法:

  • 量化方法:PACT(PArameterized Clipping acTivation)
  • 裁剪方法:FPGM(Filter Pruning via Geometric Median)

二者的具体算法参数定义与扩展能力由 PaddleSlim 提供,PaddleClas 负责将其接入分类训练/压缩流程。

2. PACT 量化:用可学习截断解决激活值量化难题

2.1 量化的两个对象:Weight 与 Activation

模型量化主要包括两个部分:

  1. 权重(Weight)量化:对网络参数做低比特(如 INT8)映射;
  2. 激活值(Activation)量化:对前向传播过程中的特征图做低比特映射。

只有对两部分同时量化,才能获得最大的计算效率收益(此时卷积/全连接算子可以在 INT8 整数运算下执行)。对于权重,可以通过网络正则化等手段让分布尽量紧凑,减少离群点与不均匀分布;但对于激活值,一直缺乏有效的分布控制手段,这正是 PACT 要解决的问题。

2.2 PACT 的动机:ReLU 造成激活值范围"无限大"

PACT 提出时的关键观察是:当使用权重量化方案去量化激活值时,激活值的量化结果与全精度结果相差较大。

根本原因在于:权重基本分布在 0 到 1 的范围内,而经过 ReLU 激活函数后,激活值取值范围是(理论上的)无限大。若直接按全局最大绝对值确定量化 scale,绝大多数数值会集中在很小的量化区间内,导致严重的舍入误差。

2.3 核心思想:截断式 ReLU 与可学习截断上界 α

为此,PACT 引入**截断式 ReLU(Clipped ReLU)**作为激活函数:在量化激活值之前,先去掉分布中的离群点,从而将量化带来的精度损失降到最低——在某些任务上甚至能达到比原模型更高的准确率。

PACT 量化示意图:通过裁剪激活值分布来缩小量化映射范围

其关键在于截断上界 α 是一个可学习的参数,它保证每一层都能通过训练学到各自不同的量化范围,从而最大程度降低量化带来的舍入误差。PACT 的量化公式如下:

PACT 量化公式

从公式可以看出,PACT 的思想是用上述量化函数替代 ReLU 本身:对输入大于 0 的部分以阈值 α 进行截断,再按 α 进行对称量化映射。

2.4 PaddleSlim 中的改进:对正负两侧同时截断

在 PaddleSlim 中,上述公式被进一步改进为:

PaddleSlim 改进后的 PACT 量化公式

改进后的做法是:在激活值与待量化的算子(卷积、全连接等)之间插入 PACT 预处理。它不仅对大于 0 的分布进行截断,也对小于 0 的部分做同样的限制,从而更完整地圈定待量化数值范围,降低量化损失。与此同时,截断阈值保持为可训练参数——在量化训练过程中,模型会自动找到合理的截断阈值,进一步降低量化精度损失。

2.5 PaddleClas 中的落地:Slim.quant 配置节

在 PaddleClas 的模型配置体系中,量化训练通过 Slim 配置节开启。以 ResNet50_vd 量化训练配置 为例,关键片段如下:

# for quantization or prune model
Slim:
  ## for quantization
  quant:
    name: pact
  • Slim.quant.name: pact 即指定使用 PACT 量化方法;
  • 其余为常规训练配置:Arch(网络结构、类别数、是否加载预训练)、Loss(训练/评估损失,此处训练使用带 label smoothing 的 CELoss)、Optimizer(Momentum + Cosine 学习率衰减)、DataLoader(ImageNet 训练/验证数据流)、Metric(Top1/Top5 精度评估)。

PaddleClas 在 ppcls/configs/slim/ 目录下为多种模型预置了量化与裁剪配置,包括 MobileNetV3_large_x1_0_quantization.yaml、PPLCNet_x1_0_quantization.yaml、ResNet50_vehicle_cls_quantization.yaml、ResNet50_vehicle_reid_quantization.yaml、GeneralRecognition_PPLCNet_x2_5_quantization.yaml 等,覆盖通用分类、车辆分类/ReID、通用识别等场景,可直接作为修改模板。

3. FPGM 裁剪:从"范数最小"到"几何冗余"

3.1 传统范数剪枝的两大前提

模型剪枝(Pruning)是减小模型体积、提升推理效率的重要手段。传统网络剪枝方法一般将网络 filter(卷积核)的范数 作为其重要性度量:范数值越小,代表该 filter 越不重要,可以将其从网络中裁剪掉;范数越大则越重要,予以保留。

FPGM 指出,这类方法要成立,必须同时依赖两个条件:

  1. filter 的范数偏差应该足够大,这样重要与不重要的 filter 才能被很好地区分开;
  2. 不重要的 filter 的范数应该足够小,使其与重要 filter 有明显距离。

然而在真实网络中,这两个条件往往无法同时满足——所有 filter 的范数可能分布得很集中,此时按范数排序裁剪会伤及重要结构。

3.2 FPGM 的核心思想:利用几何中心的可表达性

基于上述分析,FPGM(Filter Pruning via Geometric Median)转而利用层内 filter 的几何中心特性:处于几何中心附近的 filter,可以被其他 filter 的线性组合所表达,即信息冗余度高,因此可以将其剔除。

这样一来,剪枝判断从"范数小 = 不重要"转变为"位置冗余 = 可删除",完全避开了前面提到的两点范数假设。下图直观对比了 FPGM 与基于范数的传统方法在筛选被剪 filter 时的差异(详细数学推导可参见 CVPR 2019 论文 Filter Pruning via Geometric Median for Deep Convolutional Neural Networks):

FPGM 与基于范数剪枝方法的对比示意图

3.3 PaddleClas 中的落地:Slim.prune 配置节

FPGM 裁剪同样通过 Slim 配置节启用。以 ResNet50_vd 裁剪配置 为例:

# for quantization or prune model
Slim:
  ## for prune
  prune:
    name: fpgm
    pruned_ratio: 0.3
  • Slim.prune.name: fpgm 指定裁剪算法为 FPGM;
  • Slim.prune.pruned_ratio: 0.3 表示期望裁剪 30% 的通道/滤波器,该比例需要根据精度-速度权衡调整。

PaddleClas 同样为多种模型预置了裁剪配置:MobileNetV3_large_x1_0_prune.yaml、ResNet50_vd_prune.yaml、ResNet50_vehicle_cls_prune.yaml、ResNet50_vehicle_reid_prune.yaml 等,覆盖通用分类与车辆识别场景。

4. 自动化压缩:ACT 工具链与量化蒸馏一体化

除手工编写 Slim 配置做量化/裁剪训练外,PaddleClas 在 deploy/slim/act/ 目录下提供了图像分类模型自动压缩(ACT)示例,将"量化训练(QAT)+ 蒸馏"组合成一条命令完成,产出可直接部署的压缩模型。

4.1 自动压缩启动方式

以 ResNet50 为例,单卡启动:

export CUDA_VISIBLE_DEVICES=0
python run_ppclas.py \
        --compression_config_path='./configs/ResNet50/qat_dis.yaml' \
        --reader_config_path='./configs/ResNet50/data_reader.yaml' \
        --save_dir='./save_quant_ResNet50/'

多卡启动(ImageNet 这类大数据集上可获得近似线性加速比,注意同步调整学习率):

export CUDA_VISIBLE_DEVICES=0,1,2,3
python -m paddle.distributed.launch run_ppclas.py \
        --save_dir='./save_quant_resnet50/' \
        --compression_config_path='./configs/ResNet50/qat_dis.yaml' \
        --reader_config_path='./configs/ResNet50/data_reader.yaml'

该流程内部调用 paddleslim.auto_compression.AutoCompression 接口完成量化训练与蒸馏。

4.2 自动压缩配置文件详解

以 PPLCNet_x1_0 的 qat_dis.yaml 为例,一个典型的量化+蒸馏压缩配置包含四大部分:

Global:
  model_dir: PPLCNet_x1_0_infer        # Inference 模型目录
  model_filename: inference.pdmodel    # 模型结构文件
  params_filename: inference.pdiparams # 权重参数文件
  batch_size: 32
  input_name: x                        # 模型输入 tensor 名称

Distillation:
  alpha: 1.0                           # 蒸馏损失权重
  loss: l2                             # 蒸馏损失类型

QuantAware:
  use_pact: true                       # 启用 PACT 量化
  activation_bits: 8                   # 激活值量化位宽
  is_full_quantize: false
  onnx_format: True                    # 输出 ONNX 兼容格式
  activation_quantize_type: moving_average_abs_max
  weight_quantize_type: channel_wise_abs_max
  not_quant_pattern:                   # 不参与量化的算子模式
  - skip_quant
  quantize_op_types:                   # 参与量化的算子类型
  - matmul
  - matmul_v2
  weight_bits: 8                       # 权重量化位宽

TrainConfig:
  epochs: 1
  eval_iter: 1000
  learning_rate:
    type: CosineAnnealingDecay
    learning_rate: 0.015
  optimizer_builder:
    optimizer:
      type: Momentum
    weight_decay: 0.00002
  origin_metric: 0.7132               # 原始模型精度,用于压缩后对比

参数含义要点:

  • QuantAware.use_pact: true 是本仓库 ACT 示例中默认开启的 PACT 量化开关,与前述 PACT 算法一一对应;
  • activation_bits / weight_bits 控制量化位宽,默认均为 8;
  • activation_quantize_type 与 weight_quantize_type 决定量化 scale 的计算方式(如 moving_average_abs_max、channel_wise_abs_max),直接影响量化精度与计算效率;
  • quantize_op_types 列出实际量化的算子,not_quant_pattern 提供按算子名跳过量化的通道;
  • TrainConfig.learning_rate 需与 batch size 保持线性关系(如单卡 batch_size=32 对应 lr=0.015,batch size 缩小 4 倍则 lr 除以 4,多卡则按卡数倍增)。

deploy/slim/act/configs/ 下还提供了 MobileNetV3_small_x1_0、PPHGNet_small、SwinTransformer_base、CLIP_vit_base_patch16_224、ResNet50 等模型的现成 qat_dis.yaml 与 data_reader.yaml 组合,可直接替换使用。data_reader.yaml 中的数据预处理与 DataLoader 配置与 PaddleClas 主训练流程保持一致。

4.3 ACT 压缩效果参考(仓库 README 实测数据)

根据 deploy/slim/act/README.md 中记录的实测基准(GPU 为 NVIDIA Tesla V100 单卡 + TensorRT-8.0.3.4,CPU 为 Intel Xeon Gold 6271C、10 线程,测试 batch_size 均为 4),量化+蒸馏策略在保持精度基本不变的同时显著降低 GPU 推理耗时:

模型 策略 压缩训练评估 Top-1 Acc GPU 耗时(ms) CPU 耗时(ms)
MobileNetV3_small_x1_0 Baseline 68.01 2.4 27.2
MobileNetV3_small_x1_0 量化+蒸馏 66.94 1.6 27.5
ResNet50_vd Baseline 79.05 5.9 23.5
ResNet50_vd 量化+蒸馏 78.62 2.8 17.8
PP-HGNet_small Baseline 81.33 6.5 22.6
PP-HGNet_small 量化+蒸馏 81.25 4.0 22.9
SwinTransformer_base_patch4_window7_224 Baseline 83.26 18.5 942.7
SwinTransformer_base_patch4_window7_224 量化+蒸馏 83.26 9.2 955.1
PP-LCNet_x1_0 Baseline 71.05 2.3 45.7
PP-LCNet_x1_0 量化+蒸馏 70.70 1.6 43.2
CLIP_vit_base_patch16_224 Baseline 85.36 13.9 68.9
CLIP_vit_base_patch16_224 量化+蒸馏 85.36 8.3 66.5

从表中可以看到,INT8 量化在 GPU + TensorRT 下通常能获得约 1.5~2 倍的推理加速,而精度损失普遍控制在 1 个百分点以内;Transformer 类模型(如 SwinTransformer)在 GPU 上的收益尤为明显。此外,deploy/slim/auto_compression/README.md 中的 MobileNetV3_large_x1_0 示例显示,量化+蒸馏在 ARM CPU(SDM865)上可将单张推理耗时从 16.62ms 降至 9.85ms,说明该方案同样适用于端侧部署。

5. 压缩模型的推理部署与加速

5.1 部署加速选型

压缩产出的 INT8 模型在不同硬件上有不同的加速手段:

  • GPU:使用 TensorRT 推理引擎加速;
  • CPU:使用 MKLDNN(MKL-DNN) 加速库。

以 test_ppclas.py 的调用方式为例,TensorRT + INT8 推理:

python test_ppclas.py \
      --model_path=./save_quant_resnet50 \
      --use_trt=True \
      --use_int8=True \
      --use_gpu=True \
      --data_path=./dataset/ILSVRC2012/

MKLDNN + INT8 推理:

python test_ppclas.py  \
      --model_path=./save_quant_resnet50 \
      --data_path=./dataset/ILSVRC2012/ \
      --cpu_num_threads=10 \
      --use_mkldnn=True \
      --use_int8=True

5.2 推理参数速查表

参数名 含义
model_path inference 模型文件所在目录,需包含 .pdmodel 与 .pdiparams 两个文件
model_filename 模型目录下的模型文件名称
params_filename 模型目录下的参数文件名称
data_path 数据集路径
batch_size 预测一个 batch 的大小
image_size 输入图像大小(注意 InceptionV3 等模型输入为 299,需相应修改)
use_gpu 是否使用 GPU 预测
use_trt 是否使用 TensorRT 预测引擎
use_mkldnn 是否启用 MKL-DNN 加速;与 use_gpu 同时为 True 时忽略该选项
cpu_num_threads CPU 预测线程数,默认 10
use_fp16 使用 TensorRT 时是否启用 FP16
use_int8 是否启用 INT8 推理

5.3 常见问题:CPU 上 MKLDNN 推理精度异常

针对 MKLDNN 推理 CLIP_vit_base_patch16_224、SwinTransformer_base_patch4_window7_224 及其压缩模型时出现的精度严重下降问题,需要在预测配置中删除两个融合 pass:

config.delete_pass("fc_mkldnn_pass")
config.delete_pass("fc_act_mkldnn_fuse_pass")

这两行代码已写入 test_ppclas.py 对应位置(默认注释状态),遇到上述模型的精度异常时取消注释即可恢复。

6. 总结:算法原理与工程落地的完整映射

压缩算法 核心原理 PaddleClas 配置入口 典型配置文件
PACT 量化 以可学习截断上界 α 的 Clipped ReLU 替代 ReLU,压缩激活分布、减少离群点,降低量化映射损失 Slim.quant.name: pact;ACT 中 QuantAware.use_pact: true ResNet50_vd_quantization.yaml、qat_dis.yaml
FPGM 裁剪 利用 filter 的几何中心特性剔除可被其他 filter 表达的红余 filter,从信息冗余度而非范数大小出发做剪枝 Slim.prune.name: fpgm + pruned_ratio ResNet50_vd_prune.yaml

结合本仓库 ppcls/configs/slim/ 与 deploy/slim/act/ 的现成配置,开发者可以:

  1. 直接修改 Slim 配置节,复用主训练流程(tools/train.py)完成量化/裁剪训练;
  2. 一键 ACT 自动压缩,用 run_ppclas.py 将量化训练与蒸馏结合,自动产出 INT8 部署模型;
  3. 按部署平台选择 TensorRT / MKLDNN 加速,并在压缩后通过 Top-1 Acc 与原模型对比验证压缩收益。

PACT 与 FPGM 一"量化"一"裁剪",分别从数值映射与结构冗余两个维度切入,配合 PaddleSlim 的参数化实现与 PaddleClas 的工程化配置,为图像分类模型在 GPU、CPU 与端侧设备上的高效部署提供了一条低精度损失的完整路径。

登录后查看全文
PaddleClas