- 人工智能
- 计算机视觉
- 预训练
【免费下载链接】PaddleSeg
Easy-to-use image segmentation library with awesome pre-trained model zoo, supporting wide-range of practical tasks in Semantic Segmentation, Interactive Segmentation, Panoptic Segmentation, Image Matting, 3D Segmentation, etc.
本教程以 PaddleSeg 官方量化文档为主体,结合仓库内
deploy/slim/quant/的实际实现,系统讲解如何在 PaddleSeg 中使用量化训练(QAT)方法压缩语义分割模型:从量化原理、精度/性能收益,到 FP32 模型训练、量化训练、精度验证、预测模型导出与多端部署的完整链路。读完本文,你将掌握一套可复现的 INT8 分割模型产出与部署方案,并理解其底层实现机制。
1 量化概述:原理、收益与适用场景
1.1 什么是模型量化
模型量化是一种常见的模型压缩方法,核心思路是使用整数替代浮点数进行存储和计算。以最常见的 8bit 量化为例:将 32bit 浮点数转换为 8bit 整数后:
- 存储空间可减少约 4 倍(32bit ÷ 8bit = 4);
- 整数运算替换浮点数运算,可以加快模型推理速度、降低计算内存;
- 在嵌入式设备、移动端等算力和带宽受限场景中,量化几乎是分割模型落地的必经之路。
1.2 PaddleSeg 的量化方案:量化训练(QAT)
PaddleSeg 基于 PaddleSlim 集成了**量化训练(Quantization Aware Training,QAT)**方法,其特点如下:
| 维度 | 说明 |
|---|---|
| 概述 | 使用训练数据,在训练过程中模拟量化误差并更新权重,从而减小量化损失 |
| 优点 | 量化模型的精度高;使用量化模型预测,可以减少计算量、降低计算内存、减小模型大小 |
| 缺点 | 易用性稍差,需要一定时间产出量化模型 |
需要说明的是,QAT 需要重新执行一段训练过程来让网络适应量化噪声,因此产出周期比直接转换更长,但换来的是精度损失通常远小于朴素的后训练量化。
此外,从仓库实现看,PaddleSeg 的量化目录(deploy/slim/quant/)同时提供了两条路径:
- QAT 路径:qat_train.py、qat_val.py、qat_export.py,即本文主线;
- 静态离线量化(PTQ)路径:ptq.py,基于 PaddleSlim 的
quant_post_static,直接对已导出的 FP32 推理模型做 KL 校准,无需重新训练。
两条路径的配置细节都集中在 qat_config.py 的quant_config字典中,下文会深入解读。
2 量化模型的精度与性能表现
2.1 测试环境与测试方法
文档中给出的官方测试环境如下:
| 项目 | 配置 |
|---|---|
| GPU | V100 32G |
| CPU | Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz |
| CUDA | 10.1 |
| cuDNN | 7.6 |
| TensorRT | 6.0.1.5 |
| Paddle | 2.1.1 |
测试方法要点:
- 在 GPU 上使用 TensorRT 分别测试原始 FP32 模型和量化后的 INT8 模型;
- 使用 Cityscapes 全量验证数据集(1024x2048)进行测试;
- 单 GPU、Batchsize 为 1;
- 运行耗时为纯模型预测时间;
- 使用 Paddle Inference 的 Python API 测试:通过
use_trt参数设置是否使用 TensorRT,通过precision参数设置预测类型(FP32/INT8)。
2.2 量化前后精度与性能对照
| 模型 | 类型 | mIoU | 耗时(s/img) | 量化加速比 |
|---|---|---|---|---|
| ANN_ResNet50_OS8 | FP32 | 0.7909 | 0.281 | - |
| ANN_ResNet50_OS8 | INT8 | 0.7906 | 0.195 | 30.6% |
| DANet_ResNet50_OS8 | FP32 | 0.8027 | 0.330 | - |
| DANet_ResNet50_OS8 | INT8 | 0.8039 | 0.266 | 19.4% |
| DeepLabV3P_ResNet50_OS8 | FP32 | 0.8036 | 0.206 | - |
| DeepLabV3P_ResNet50_OS8 | INT8 | 0.8044 | 0.083 | 59.7% |
| DNLNet_ResNet50_OS8 | FP32 | 0.7995 | 0.360 | - |
| DNLNet_ResNet50_OS8 | INT8 | 0.7989 | 0.236 | 52.5% |
| EMANet_ResNet50_OS8 | FP32 | 0.7905 | 0.186 | - |
| EMANet_ResNet50_OS8 | INT8 | 0.7939 | 0.106 | 43.0% |
| GCNet_ResNet50_OS8 | FP32 | 0.7950 | 0.228 | - |
| GCNet_ResNet50_OS8 | INT8 | 0.7959 | 0.144 | 36.8% |
| PSPNet_ResNet50_OS8 | FP32 | 0.7883 | 0.324 | - |
| PSPNet_ResNet50_OS8 | INT8 | 0.7915 | 0.223 | 32.1% |
结果解读:
- 在 Cityscapes 全量验证集上,各模型的 INT8 mIoU 与 FP32 基本持平,部分模型(如 DANet、DeepLabV3P、EMANet、GCNet、PSPNet)甚至略有提升,说明 QAT 能在保持精度的前提下完成压缩;
- 推理耗时普遍缩短 20% ~ 60%,其中DeepLabV3P_ResNet50_OS8 加速比最高达 59.7%,DNLNet 也达到 52.5%;
- 加速收益与模型结构、算子构成强相关,实际部署时应以自己模型在目标硬件上的基准测试为准。
3 端到端示例:产出并部署一个量化分割模型
本节以视盘分割数据集 + PP-LiteSeg 模型为例,走通"训练 FP32 → 量化训练 → 精度验证 → 导出 → 部署"的完整流程。
3.1 环境准备
首先参考 安装文档 准备好 PaddleSeg 的基础环境。注意:量化功能要求 PaddlePaddle 版本 >= 2.2。
随后安装 PaddleSlim(仓库配套的量化训练依赖 PaddleSlim 的QATAPI 和paddleslim.quant模块):
git clone https://github.com/PaddlePaddle/PaddleSlim.git # 切换到特定 commit id git reset --hard 15ef0c7dcee5a622787b7445f21ad9d1dea0a933 # 安装 python setup.py install说明:文档中固定了 PaddleSlim 的 commit id,是为了保证与当前 PaddleSeg 版本接口兼容;自行安装时如遇 API 变化,建议保持与文档一致的版本。
3.2 产出量化模型
3.2.1 第一步:训练 FP32 模型
在产出量化模型之前,需要提前准备训练或 finetune 好的FP32 模型。此处使用视盘分割数据集和 PP-LiteSeg 模型,用 tools/train.py 从头开始训练。train.py输入参数的详细介绍请参考 训练文档。
在 PaddleSeg 目录下执行如下脚本,会自动下载数据集进行训练:
# 设置1张可用的GPU卡 export CUDA_VISIBLE_DEVICES=0 # windows下请执行以下命令 # set CUDA_VISIBLE_DEVICES=0 python tools/train.py \ --config configs/quick_start/pp_liteseg_optic_disc_512x512_1k.yml \ --do_eval \ --use_vdl \ --save_interval 250 \ --save_dir output_fp32训练结束后,精度最高的权重会保存到output_fp32/best_model目录下。
这里所用的示例配置文件 configs/quick_start/pp_liteseg_optic_disc_512x512_1k.yml 结构如下,量化训练阶段会复用同一份配置:
- 数据:
Dataset类型,数据集根目录data/optic_disc_seg,训练/验证各 2 类(视盘+背景),输入经ResizeStepScaling、RandomPaddingCrop(512x512)、RandomHorizontalFlip、RandomDistort、Normalize等增强; - 优化器:SGD,momentum 0.9,weight_decay 4.0e-5;
- 学习率调度:
PolynomialDecay,初始学习率 0.01,end_lr 0,power 0.9; - 损失:
CrossEntropyLoss,coef[1, 1, 1]; - 模型:
PPLiteSeg,backbone 为STDC2(带预训练权重)。
3.2.2 第二步:使用量化训练(QAT)产出量化模型
基于训练好的 FP32 权重,使用 deploy/slim/quant/qat_train.py 进行量化训练。
qat_train.py与train.py的输入参数基本相似,关键区别在于:
- 量化训练的学习率需要调小(示例中由 0.01 降至 0.001);
- 使用
--model_path参数指定 FP32 模型的权重作为初始化。
完整参数说明如下:
| 参数名 | 用途 | 是否必选项 | 默认值 |
|---|---|---|---|
| config | FP32 模型的配置文件 | 是 | - |
| model_path | FP32 模型的预训练权重 | 是 | - |
| iters | 训练迭代次数 | 否 | 配置文件中指定值 |
| batch_size | 单卡 batch size | 否 | 配置文件中指定值 |
| learning_rate | 初始学习率 | 否 | 配置文件中指定值 |
| save_dir | 模型和 visualdl 日志文件的保存根路径 | 否 | output |
| num_workers | 用于异步读取数据的进程数量,大于等于 1 时开启子进程读取数据 | 否 | 0 |
| use_vdl | 是否开启 visualdl 记录训练数据 | 否 | 否 |
| save_interval_iters | 模型保存的间隔步数 | 否 | 1000 |
| do_eval | 是否在保存模型时启动评估,启动时将会根据 mIoU 保存最佳模型至 best_model | 否 | 否 |
| log_iters | 打印日志的间隔步数 | 否 | 10 |
| resume_model | 恢复训练模型路径,如output/iter_1000 | 否 | None |
执行如下命令进行量化训练。量化训练结束后,精度最高的量化模型权重保存在output_quant/best_model目录下:
python deploy/slim/quant/qat_train.py \ --config configs/quick_start/pp_liteseg_optic_disc_512x512_1k.yml \ --model_path output_fp32/best_model/model.pdparams \ --learning_rate 0.001 \ --do_eval \ --use_vdl \ --save_interval 250 \ --save_dir output_quant源码级原理:从 qat_train.py 的实现可以看到完整调用链:
Config+SegBuilder读取配置并构建模型、数据集、损失与优化器(来自paddleseg.cvlibs);utils.load_entire_model(model, args.model_path)加载 FP32 预训练权重;skip_quant(model)决定哪些层参与量化(见下文);QAT(config=quant_config).quantize(model)对模型做量化改造(quant_config来自 qat_config.py);- 最后复用
paddleseg.core.train完成带量化的训练循环。
skip_quant的逻辑值得注意(脚本顶部注释也明确说明"Only conv2d and linear in backbone are quantized"):如果模型具备backbone属性,则遍历所有子层,将不属于 backbone 的Conv2D和Linear层打上skip_quant = True标记,即只量化骨干网络,而解码头(head)保持浮点精度——这是为了在"压缩收益"与"分割边界细节精度"之间取得平衡;若模型没有 backbone(如单阶段结构),则量化全部目标算子。
3.2.3 第三步:测试量化模型精度(可选)
如果需要单独验证量化模型的精度,可执行如下命令,使用 deploy/slim/quant/qat_val.py 加载量化模型权重并评估:
python deploy/slim/quant/qat_val.py \ --config configs/quick_start/pp_liteseg_optic_disc_512x512_1k.yml \ --model_path output_quant/best_model/model.pdparams从 qat_val.py 的源码可以看出,它与qat_train.py共享skip_quant与quant_config,先对模型做同样的量化改造再加载权重,随后调用paddleseg.core.evaluate进行评估;脚本还额外支持--aug_eval(多尺度+翻转增强评估)、--is_slide(滑窗评估,需配合--crop_size与--stride)、--data_format NHWC(当前仅DeepLabV3P模型支持 NHWC 布局)等评估选项。
3.2.4 第四步:导出量化预测模型
基于训练好的量化模型权重,使用 deploy/slim/quant/qat_export.py 导出预测量化模型,脚本参数如下:
| 参数名 | 用途 | 是否必选项 | 默认值 |
|---|---|---|---|
| config | 模型配置文件 | 是 | - |
| model_path | 量化模型的权重 | 否 | - |
| save_dir | 预测量化模型保存的文件夹 | 否 | ./output/inference_model |
| output_op | 设置在模型末端添加的输出算子,支持[argmax, softmax, none]。PaddleSeg 模型默认返回 logits(N*C*H*W);添加argmax算子可以得到每个像素的分割类别,结果维度是N*H*W、数据类型是int32;添加softmax算子可以得到每个像素每类的概率,结果维度是N*C*H*W、数据类型是float32 | 否 | argmax |
| with_softmax | 即将废弃的输入参数,建议使用--output_op。在网络末端添加 softmax 算子。由于 PaddleSeg 组网默认返回 logits,如果想要部署模型获取概率值,可以置为 True | 否 | False |
| without_argmax | 即将废弃的输入参数,建议使用--output_op。由于 PaddleSeg 组网默认返回 logits,为部署模型可以直接获取预测结果,默认在网络末端添加 argmax 算子。如果设置--without_argmax,则不会添加 argmax 算子 | 否 | False |
执行如下命令,导出预测量化模型并保存到output_quant_infer目录:
python deploy/slim/quant/qat_export.py \ --config configs/quick_start/pp_liteseg_optic_disc_512x512_1k.yml \ --model_path output_quant/best_model/model.pdparams \ --save_dir output_quant_infer导出细节(源码级):
- 脚本同样执行
skip_quant+QAT.quantize,再通过utils.load_entire_model加载量化权重; --without_argmax/--with_softmax为旧参数,设置后会输出废弃警告并被映射到--output_op(分别对应none/softmax);- 除
none外,模型末端会包一层WrappedModel(来自 paddleseg/deploy/export.py)以追加输出算子; - 最终调用
quantizer.save_quantized_model生成model.pdmodel(推理模型结构)与model.pdiparams(量化权重),默认输入 shape 为[None, 3, None, None]的 float32 张量,支持通过--input_shape固定尺寸导出; - 同时会依据验证集 transforms(默认
Normalize)生成deploy.yaml部署配置文件(若加--for_fd则生成 FastDeploy 兼容格式inference+inference.yml)。
3.3 部署量化模型
得到量化预测模型后,即可进入部署环节。PaddleSeg 官方针对不同部署形态提供了对应教程:
- Paddle Inference Python 部署
- Paddle Inference C++ 部署
- PaddleLite 部署
以 Python 部署为例,Paddle Inference 中通过use_trt开关启用 TensorRT、以precision指定 FP32/INT8 预测类型;配合导出时生成的deploy.yaml(含预处理 transforms 与模型路径),即可在服务端或端侧完成 INT8 分割推理。
4 量化训练的核心配置与调参要点
量化训练的所有超参数集中在 deploy/slim/quant/qat_config.py 的quant_config字典中,训练、验证、导出三个脚本统一引用,保证量化口径一致:
| 配置项 | 默认值 | 含义 |
|---|---|---|
| weight_preprocess_type | None | 权重预处理方式,默认不做预处理 |
| activation_preprocess_type | None | 激活预处理方式,默认不做预处理 |
| weight_quantize_type | channel_wise_abs_max | 权重量化方式,按通道取绝对值最大值做对称量化 |
| activation_quantize_type | moving_average_abs_max | 激活量化方式,用滑动平均统计激活绝对值最大值 |
| weight_bits | 8 | 权重量化位数 |
| activation_bits | 8 | 激活量化位数 |
| dtype | int8 | 量化后的数据类型(如 uint8、int8) |
| window_size | 10000 | range_abs_max 量化方式使用的窗口大小 |
| moving_rate | 0.9 | 滑动平均衰减系数 |
| quantizable_layer_type | ['Conv2D', 'Linear'] | 动态图量化时参与量化的层类型 |
调参要点:
weight_quantize_type采用channel_wise_abs_max而非全局abs_max,逐通道统计能显著降低权重量化误差,是分割模型精度保持的关键之一;- 激活侧使用
moving_average_abs_max,在训练过程中以 0.9 的衰减系数持续更新激活值范围估计,这就是"训练中模拟量化、减小量化损失"的具体机制; - 量化训练务必调小学习率(官方示例中从 0.01 降到 0.001),因为此时权重已在最优邻域附近,过大的学习率会破坏已学到的分布;
- 如追求更激进的压缩,可尝试将
weight_bits/activation_bits调至 4 等低位宽,但需要自行在精度与收益间权衡(官方默认 8bit 方案已由上文表格验证精度无损)。
5 参考资料
- PaddleSlim 官方仓库(安装命令见 3.1 节,请以其中对应版本的接口为准)
- PaddleSlim 文档
- 本文引用的仓库实现:qat_train.py、qat_val.py、qat_export.py、qat_config.py、ptq.py,示例配置 configs/quick_start/pp_liteseg_optic_disc_512x512_1k.yml
一句话总结:在 PaddleSeg 中做 INT8 量化,标准路径是"先训 FP32 → 用qat_train.py低学习率量化训练 →qat_val.py验证 →qat_export.py导出 → 接入 Paddle Inference / PaddleLite 部署",官方数据表明该方法可在 Cityscapes 上基本无损地将推理提速 20% ~ 60%。
- 人工智能
- 计算机视觉
- 预训练
【免费下载链接】PaddleSeg
Easy-to-use image segmentation library with awesome pre-trained model zoo, supporting wide-range of practical tasks in Semantic Segmentation, Interactive Segmentation, Panoptic Segmentation, Image Matting, 3D Segmentation, etc.
相关推荐
PaddleSeg 模型量化(QAT)实战:基于 PaddleSlim 的语义分割模型 INT8 量化训练与部署指南
PaddleSeg 模型量化(QAT)实战:基于 PaddleSlim 的语义分割模型 INT8 量化训练与部署指南 量化感知训练(Quantization A
人工智能计算机视觉预训练PaddleOCR 模型量化实战指南:基于 PaddleSlim 的 QAT 量化感知训练与 INT8 端侧部署
PaddleOCR 模型量化实战指南:基于 PaddleSlim 的 QAT 量化感知训练与 INT8 端侧部署 本篇技术指南围绕 PaddleOCR 官方文档
人工智能计算机视觉OCR深度学习大模型RAGAnomalib 模型部署与压缩实战:使用 NNCF 量化训练并导出 OpenVINO INT8 模型
Anomalib 模型部署与压缩实战:使用 NNCF 量化训练并导出 OpenVINO INT8 模型 导读 本篇文章聚焦 Anomalib https://l
人工智能计算机视觉深度学习模型评测
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考