- 人工智能
- 计算机视觉
- 预训练
【免费下载链接】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.
本指南以 docs/deployment/inference/cpp_inference_linux_cn.md 为骨架,结合 deploy/cpp 目录下的真实源码与运行脚本,系统讲解如何用 Paddle Inference 的 C++ 接口在 Linux 服务器(X86 CPU 或 Nvidia GPU)上部署 PaddleSeg 导出的预测模型。读完本文,你将掌握:预测库与依赖环境的完整准备流程、预测模型的导出与目录规范、
test_seg示例程序的编译运行,以及 Naive / TensorRT 固定 Shape / TensorRT 动态 Shape 三种 GPU 部署方式的选择与配置。
1. 部署方案总览
飞桨针对不同场景提供了多个预测引擎来部署分割模型,而 Paddle Inference 是其中面向服务器端高性能部署的 C++/Python 推理引擎,支持 NV GPU 与 X86 CPU 两种主流硬件。本文档对应的完整 C++ 示例程序位于 deploy/cpp/src/test_seg.cc,配套的编译运行脚本、依赖安装脚本存放在 deploy/cpp 目录,主要部署步骤为:
- 准备环境:安装 Paddle Inference C++ 预测库、CUDA/cudnn/TensorRT(GPU 场景)以及 OpenCV、yaml-cpp、gflags、glog 等辅助库;
- 准备模型和图片:导出/下载预测模型(
model.pdmodel、model.pdiparams、deploy.yaml)与测试图片; - 编译、执行:通过 CMake 编译示例,按 CPU / GPU Naive / GPU TensorRT 等场景选择对应脚本运行。
仓库还提供了其他平台的部署文档可供对照:Windows 上的 C++ 部署、Python 推理 以及 推理 Benchmark。
2. 准备环境
2.1 准备基础环境(CUDA / cudnn / TensorRT)
如果只在 X86 CPU 上部署,可以完全跳过本节,不需要 CUDA、cudnn 与 TensorRT 的准备工作。
如果在 Nvidia GPU 上部署,则必须安装 CUDA 与 cudnn。此外,Paddle Inference 在 GPU 上支持通过 TensorRT 加速,可根据需要安装。
官方为快速上手提供了两个版本的 CUDA、cudnn、TensorRT 打包文件,可用wget直接下载:
wget https://paddle-inference-dist.bj.bcebos.com/tensorrt_test/cuda10.1-cudnn7.6-trt6.0.tar wget https://paddle-inference-dist.bj.bcebos.com/tensorrt_test/cuda10.2-cudnn8.0-trt7.1.tgz下载解压后,CUDA 和 cudnn 需要按照 NVIDIA 官方安装文档进行安装;TensorRT 则只需要设置库路径即可,例如:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/work/TensorRT-7.1.3.4/lib如果你使用 Docker,可以直接拉取官方提供的带 GPU 环境的镜像,在容器内部配置基础环境:
docker pull registry.baidubce.com/paddlepaddle/paddle:2.1.2-gpu-cuda10.2-cudnn72.2 准备 Paddle Inference C++ 预测库
- X86 CPU 部署:下载命名中带
manylinux_cpu_xxx的 Paddle Inference C++ 预测库; - Nvidia GPU 部署:下载与机器 CUDA、cudnn、TensorRT、GCC 版本对应的 C++ 预测库。
不同 C++ 预测库根据文件名区分。请结合机器的操作系统、CUDA 版本、cudnn 版本、是否使用 MKLDNN 或 OpenBlas、是否使用 TensorRT、GCC 版本等信息,选择准确版本(建议选择版本 >= 2.3 的预测库)。
下载得到paddle_inference.tgz压缩文件后解压,将解压出的paddle_inference目录保存到仓库的deploy/cpp/下。之后的编译脚本(如 run_seg_cpu.sh)会通过LIB_DIR="${work_path}/paddle_inference"自动定位该目录。
如果需要自行从源码编译 Paddle Inference C++ 预测库,可参考飞桨官方源码编译文档,本文不再赘述。
2.3 安装其他依赖库
示例程序使用了 OpenCV 读取图片、yaml-cpp 读取配置文件、gflags 管理命令行参数、glog 管理日志输出。这些库在仓库中均提供了现成的安装脚本,位于 deploy/cpp 目录下,按需执行即可:
# OpenCV 3.4.7:下载源码、编译并安装到 /usr/local/opencv3 sh install_opencv.sh # yaml-cpp 0.7.0:编译安装为共享库(YAML_BUILD_SHARED_LIBS=ON) sh install_yaml.sh # gflags:git clone 后编译安装 sh install_gflags.sh # glog:git clone 后编译安装 sh install_glog.sh实际生产部署时,这些库可根据自身场景按需安装;本示例为了演示完整流程而全部使用。
3. 准备模型和图片
3.1 下载测试模型与图片
在deploy/cpp/目录下执行如下命令,下载官方测试模型(PP-LiteSeg 的推理模型):
wget https://paddleseg.bj.bcebos.com/dygraph/demo/pp_liteseg_infer_model.tar.gz tar xf pp_liteseg_infer_model.tar.gz如果需要测试其他模型,请参考 模型导出文档 将训练好的模型导出为预测模型格式。
再下载一张 cityscapes 验证集图片作为输入:
wget https://paddleseg.bj.bcebos.com/dygraph/demo/cityscapes_demo.png3.2 预测模型目录规范
导出的预测模型是一个目录,内部包含以下四个文件:
output/inference_model ├── deploy.yaml # 部署相关的配置文件,主要说明数据预处理方式等信息 ├── model.pdmodel # 预测模型的拓扑结构文件 ├── model.pdiparams # 预测模型的权重文件 └── model.pdiparams.info # 参数额外信息,一般无需关注其中deploy.yaml是部署配置的关键,它记录了模型文件、权重文件以及数据预处理方式。从 deploy/cpp/src/test_seg.cc 中load_yaml()的解析逻辑可以确认,其结构大致为:
Deploy: model: model.pdmodel # 拓扑结构文件 params: model.pdiparams # 权重文件 transforms: # 预处理变换列表 - type: Normalize # 归一化变换 - type: Resize # 缩放变换,含 target_size: [宽, 高]C++ 程序正是通过解析Deploy.model、Deploy.params找到模型文件,并遍历Deploy.transforms判断是否执行归一化与缩放、读取Resize的target_size来复现训练时的预处理流程。Python 侧对应的解析实现位于 paddleseg/deploy/infer.py(DeployConfig类),deploy/python/collect_dynamic_shape.py 同样复用了它来加载配置。
3.3 用 Netron 可视化模型并核对输出类型
model.pdmodel可以使用 Netron 工具打开进行模型可视化,从而看到预测模型的输入输出个数、数据类型(如 int32_t、int64_t、float 等)。
PaddleSeg 分割模型的输出通常是逐像素的类别标签,示例程序默认按int32_t读取输出。如果模型的输出数据类型不是 int32_t,执行默认代码会报错,此时需要手动修改 deploy/cpp/src/test_seg.cc 中的下面这行,改成模型实际的输出数据类型:
std::vector<int32_t> out_data(out_num);3.4 检查目录结构
请确认deploy/cpp/下已经存放了预测库、模型、图片,最终应类似于:
PaddleSeg/deploy/cpp |-- paddle_inference # 预测库 |-- pp_liteseg_infer_model # 模型 |-- cityscapes_demo.png # 图片 ...4. X86 CPU 上部署
在deploy/cpp/目录下执行sh run_seg_cpu.sh,脚本会自动完成编译并在 X86 CPU 上执行预测,分割结果保存在当前目录的out_img.jpg图片中。
从 run_seg_cpu.sh 可以看到完整的编译与运行过程:
# 编译参数:CPU 场景关闭 GPU 与 TensorRT cmake .. \ -DDEMO_NAME=test_seg \ -DWITH_MKL=ON \ -DWITH_GPU=OFF \ -DUSE_TENSORRT=OFF \ -DWITH_STATIC_LIB=OFF \ -DPADDLE_LIB=./paddle_inference make -j # 运行:CPU 设备 + MKLDNN 加速 ./build/test_seg \ --model_dir=./pp_liteseg_infer_model \ --img_path=./cityscapes_demo.png \ --devices=CPU \ --use_mkldnn=trueCMakeLists.txt 中定义了本示例的全部 CMake 选项,含义如下:
| CMake 选项 | 说明 | 默认值 |
|---|---|---|
WITH_MKL | 是否使用 MKL/OpenBlas 数学库 | ON |
WITH_GPU | 编译 GPU 支持(CPU 场景设为OFF) | OFF |
WITH_STATIC_LIB | 使用静态库还是动态库 | ON(示例脚本中设为OFF以使用共享库) |
USE_TENSORRT | 是否编译 TensorRT 支持 | OFF |
WITH_ROCM | 是否编译 ROCm 支持 | OFF |
PADDLE_LIB | 预测库路径(必填,未设置会报错) | - |
DEMO_NAME | 可执行程序名(必填,对应src/test_seg.cc) | - |
TENSORRT_ROOT | TensorRT 根目录(仅USE_TENSORRT=ON且WITH_GPU=ON时必须设置,未设置会报错) | - |
程序运行时的行为由test_seg.cc中用 gflags 声明的命令行参数控制,完整参数表如下:
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
--model_dir | string | 推理模型目录(包含 deploy.yaml 与模型文件,必填) | 空 |
--img_path | string | 测试图片路径 | 空 |
--devices | string | 使用 GPU 或 CPU | GPU |
--use_trt | bool | 使用 GPU 时是否启用 TensorRT | false |
--trt_precision | string | TensorRT 精度,支持fp32/fp16/int8 | fp32 |
--use_trt_dynamic_shape | bool | 使用 GPU 和 TensorRT 时是否启用动态 Shape | false |
--dynamic_shape_path | string | 若设置,则从该路径读取 TRT 动态 Shape 信息 | 空 |
--use_mkldnn | bool | 使用 CPU 时是否启用 MKLDNN | false |
--save_dir | string | 输出图片保存目录 | 空 |
4.1 示例程序的执行链路
结合 test_seg.cc 的main()流程,可以清晰地看到一次完整推理的底层调用链:
- 解析命令行:
google::ParseCommandLineFlags,并校验--model_dir非空; - 加载部署配置:读取
model_dir/deploy.yaml,通过load_yaml()提取模型文件名、权重文件名与预处理参数; - 图像预处理:
read_process_image()完成 BGR→RGB 通道转换;若配置了Resize则按target_size缩放;若配置了Normalize则执行img = (img / 255 - 0.5) / 0.5(即 mean=0.5、std=0.5 的归一化);最后通过hwc_img_2_chw_data()将 HWC 排布的图像转为 CHW 排布的float数据; - 创建 Predictor:
create_predictor()中根据--devices分支构造paddle_infer::Config——CPU 场景可开启EnableMKLDNN()与SetCpuMathLibraryNumThreads(5);GPU 场景调用EnableUseGpu(100, 0); - 输入输出:
GetInputHandle/Reshape/CopyFromCpu写入输入,predictor->Run()执行推理,GetOutputHandle+CopyToCpu读取输出; - 结果可视化:将类别标签转成
uint8_t灰度图,用cv::equalizeHist做直方图均衡化便于肉眼看清楚分割区域,最后写为out_img.jpg。
5. Nvidia GPU 上部署
在 GPU 上部署前,需要先明确部署场景:多次预测时输入图像的尺寸是否变化。
- 固定 Shape 模式:多次预测时输入图像的尺寸不变;
- 动态 Shape 模式:每次预测时输入图像的尺寸可以变化。
Paddle Inference 在 GPU 上支持两种执行方式:
- Naive 方式:使用 Paddle 自实现的 Kernel 执行预测;它使用相同的配置方法同时支持固定 Shape 与动态 Shape 模式;
- TRT 方式:使用集成的 TensorRT 执行预测,通常比 Naive 方式速度更快;但固定 Shape 与动态 Shape 需要不同的配置方法。
5.1 Naive 方式部署
如果使用 Naive 方式部署分割模型(固定 Shape 或动态 Shape 均可),直接执行:
sh run_seg_gpu.shrun_seg_gpu.sh 会以WITH_GPU=ON、USE_TENSORRT=OFF编译,然后运行:
./build/test_seg \ --model_dir=./pp_liteseg_infer_model \ --img_path=./cityscapes_demo.png \ --devices=GPU脚本会自动完成编译、加载模型、加载图片、执行预测,结果同样保存在out_img.jpg。
5.2 TRT 方式 + 固定 Shape 模式部署
使用 TRT 方式、固定 Shape 模式部署 PaddleSeg 分割模型:
- 打开 run_seg_gpu_trt.sh,将
TENSORRT_ROOT设置为机器中 TensorRT 库的路径,例如:TENSORRT_ROOT='/work/TensorRT-7.1.3.4/' - 执行
sh run_seg_gpu_trt.sh; - 预测结果保存在
out_img.jpg。
脚本在 CMake 阶段通过-DTENSORRT_ROOT=${TENSORRT_ROOT}传入 TRT 路径,CMakeLists.txt 会据此找到NvInfer.h并自动读取、打印 TensorRT 主版本号,同时链接libnvinfer与libnvinfer_plugin;运行阶段追加了--use_trt=True --trt_precision=fp32。
常见问题:PaddleSeg 的分割模型通常支持任意输入尺寸,模型内部存在动态 Shape 的算子。因此使用 TRT 方式、固定 Shape 模式部署时经常报错。遇到这种情况,建议改用下面的 TRT 方式 + 动态 Shape 模式部署。
5.3 TRT 方式 + 动态 Shape 模式部署(推荐)
Paddle Inference 提供了多种方法支持 TRT 动态 Shape 部署,此处推荐一种通用性较强的方案,主要步骤为:准备预测模型和样本图像 → 离线收集动态 Shape → 部署执行。
第一步:准备预测模型和样本图像
这一步的目的是为后续离线收集动态 Shape 提供素材,因此准备的样本图像必须覆盖实际预测时会遇到的最大和最小图像尺寸。前面小节中我们已经准备好了预测模型和一张测试图片。
第二步:离线收集动态 Shape
请参考 安装文档 安装 PaddlePaddle 和 PaddleSeg 的依赖项。然后在deploy/cpp路径下执行:
python ../python/collect_dynamic_shape.py \ --config pp_liteseg_infer_model/deploy.yaml \ --image_path ./cityscapes_demo.png \ --dynamic_shape_path ./dynamic_shape.pbtxt各参数含义:
| 参数 | 说明 |
|---|---|
--config | 导出模型时生成的部署配置(deploy.yaml),必填 |
--image_path | 待预测图片的路径、目录或文件列表,必填;传目录即可一次处理多张样本图 |
--dynamic_shape_path | 动态 Shape 保存路径,默认./dynamic_shape.pbtxt |
从 collect_dynamic_shape.py 的源码可以看到其工作原理:
- 首先通过
is_support_collecting()检查当前 PaddlePaddle 版本是否支持collect_shape_range_info与enable_tuned_tensorrt_dynamic_shape接口,不支持时会提示重装最新 GPU 版 PaddlePaddle; - 随后用
DeployConfig解析 deploy.yaml,构建PredictConfig并调用enable_use_gpu(1000, 0)与collect_shape_range_info(dynamic_shape_path); - 接着按顺序加载每一张样本图,执行与真实推理完全一致的数据预处理(
cfg.transforms(data)),reshape 后送入输入句柄并predictor.run(); - 运行期间会以进度条显示进度;如果某张图过大导致 GPU 显存不足,会捕获异常并删除已生成的动态 Shape 文件,此时需要换用尺寸更小的样本图重新收集。
执行完成后,动态 Shape 信息(各输入尺寸的最小、最大与最优范围)被保存到./dynamic_shape.pbtxt。
第三步:部署执行
打开 run_seg_gpu_trt_dynamic_shape.sh,设置两个关键变量:
TENSORRT_ROOT='/work/download/TensorRT-7.1.3.4/' # TensorRT 库路径 DYNAMIC_SHAPE_PATH='./dynamic_shape.pbtxt' # 上一步收集的动态 Shape 文件执行sh run_seg_gpu_trt_dynamic_shape.sh,预测结果保存在out_img.jpg。该脚本的运行参数为:
./build/test_seg \ --model_dir=./pp_liteseg_infer_model \ --img_path=./cityscapes_demo.png \ --devices=GPU \ --use_trt=True \ --trt_precision=fp32 \ --use_trt_dynamic_shape=True \ --dynamic_shape_path=./dynamic_shape.pbtxt5.4 动态 Shape 的两种配置来源
在 test_seg.cc 中,动态 Shape 的配置有两种来源:
- 未指定
--dynamic_shape_path时:代码内置了一组兜底范围——最小{1, 3, 112, 112}、最大{1, 3, 1024, 2048}、最优{1, 3, 512, 1024},通过SetTRTDynamicShapeInfo直接设置; - 指定
--dynamic_shape_path时:调用EnableTunedTensorRtDynamicShape(path, true),使用离线收集的 Shape 范围文件,这也是实际生产部署推荐的方式,因为其范围与真实数据分布一致,能避免显存浪费或推理失败。
5.5 TensorRT 精度选择
无论固定 Shape 还是动态 Shape,TRT 的推理精度都由--trt_precision控制,可选fp32、fp16、int8(默认fp32)。test_seg.cc 会分别映射为PrecisionType::kFloat32/kHalf/kInt8并调用EnableTensorRtEngine(1 << 20, 1, 3, ...)创建 TRT 引擎;传入其他值会直接LOG(FATAL)报错。fp16与int8通常能带来更低的延迟,但需结合精度损失评估后使用。
6. 结果与后续优化建议
执行任意一种部署方式后,out_img.jpg即为分割结果(该示例图片输出时做了直方图均衡化,便于可视化观察分割区域)。若需要批量验证,可参考 deploy/python/infer.py 等 Python 推理脚本中的图片列表处理方式,也可以将--img_path指向包含多张图片的目录。
几点实践建议:
- CPU 场景:开启
--use_mkldnn=true能显著提升 X86 上的推理速度,且无需额外安装依赖; - GPU 场景:追求吞吐与低延迟优先选用 TRT 方式;若输入尺寸变化频繁,务必走“离线收集动态 Shape → 动态 Shape 模式部署”的完整链路;
- 输出类型:换用自定义模型前,先用 Netron 确认输出张量的数据类型,并同步修改 test_seg.cc 中的
out_data类型; - 环境一致性:预测库、TensorRT、CUDA 的版本必须与编译机器保持一致,尤其是 GPU 场景,否则会出现链接或运行时错误。
如需进一步了解模型导出细节,请查阅 模型导出文档;Windows 平台的类似流程见 Windows C++ 部署文档。
- 人工智能
- 计算机视觉
- 预训练
【免费下载链接】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 基于 FastDeploy 的 CPU/GPU Python 部署实战:语义分割模型从环境搭建到 Paddle-TensorRT 加速
PaddleSeg 基于 FastDeploy 的 CPU/GPU Python 部署实战:语义分割模型从环境搭建到 Paddle TensorRT 加速 本文
人工智能计算机视觉预训练PaddleSeg 语义分割模型 C++ 部署实战:FastDeploy 在 CPU/GPU/Paddle-TensorRT 上的全流程指南
PaddleSeg 语义分割模型 C++ 部署实战:FastDeploy 在 CPU/GPU/Paddle TensorRT 上的全流程指南 本文基于 Padd
人工智能计算机视觉预训练PaddleSeg 语义分割模型 FastDeploy 部署实战:CPU/GPU 推理与 Paddle-TensorRT 加速
PaddleSeg 语义分割模型 FastDeploy 部署实战:CPU/GPU 推理与 Paddle TensorRT 加速 本篇指南基于 PaddleSeg
人工智能计算机视觉预训练
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考