尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Paddle Lite 端侧推理全流程实战:从模型准备、opt 优化到多端部署

Paddle Lite 端侧推理全流程实战:从模型准备、opt 优化到多端部署 Paddle Lite 端侧推理全流程实战从模型准备、opt 优化到多端部署【免费下载链接】Paddle-LitePaddlePaddle High Performance Deep Learning Inference Engine for Mobile and Edge (飞桨高性能深度学习端侧推理引擎项目地址: https://gitcode.com/GitHub_Trending/pa/Paddle-Lite导读本文基于 Paddle Lite 官方快速入门教程系统梳理一套完整的端侧推理落地路径如何把 PaddlePaddle 或其他深度学习框架产出的模型经过 opt 工具优化配合官方预编译库或源码编译得到的预测库在 Android、iOS、ARM Linux、x86 等终端上完成 C / Java / Python 推理程序的开发与部署。读完本文你将掌握模型格式准备、opt 优化与算子检查、预测库获取、五步 API 编程以及 Profiler 性能与精度分析这一整条链路并能直接对照仓库中的示例代码动手实践。Paddle Lite 是什么Paddle Lite 是一款轻量级、灵活性强、易于扩展的高性能深度学习预测框架面向移动端与边缘端设计支持 ARM CPU、OpenCLGPU、Metal、x86、XPU 以及华为麒麟/昇腾 NPU、高通 QNN、寒武纪 MLU、芯原 TIM-VX、联发科 APU、颖脉 NNA 等多种硬件终端。其核心能力来自两处强大的图优化能力包含量化、子图融合、混合调度、Kernel 优选等优化手段优化后的模型更轻量、资源占用更少、执行速度更快多端统一的推理 API提供 C、Java、Python 三种 API同一份业务代码可以适配不同的硬件后端。从宏观上看将 Paddle Lite 集成到自己的项目只需四步准备模型 → 模型优化 → 下载或编译预测库 → 开发应用程序。整个流程可以用仓库中的 docs/images/workflow.png 直观表示。图片出处docs/quick_start/tutorial.md展示了从模型准备到应用部署的完整预测流程。下面按这四步逐一展开并补充各环节的源码与工具实现细节。一、准备模型让模型成为 Paddle Lite 认识的格式Paddle Lite 直接支持 PaddlePaddle 深度学习框架产出的模型格式。根据训练时使用的执行模式保存方式不同执行模式保存 API说明静态图模式save_inference_modelPaddle Lite 对这类预测模型已做充分支持动态图模式paddle.jit.savePaddle Lite 可以支持绝大部分此类预测模型如果你的模型是由 Caffe、TensorFlow、PyTorch 等第三方框架产出的则需要先用X2Paddle工具将其转换为 PaddlePaddle 格式再由 opt 转换为 Paddle Lite 可执行格式。也就是说第三方框架模型通常需要经历两次转化第三方模型 → X2Paddle → PaddlePaddle 格式 → opt → Paddle Lite 可执行格式。针对这一场景X2Paddle 还集成了 opt 能力提供一键转换 API以 ONNX 模型为例from x2paddle.convert import onnx2paddle onnx2paddle(model_path, save_dir, convert_to_liteTrue, # 是否调用 opt 工具默认为 False lite_valid_placesarm, # 指定目标硬件平台默认 arm lite_model_typenaive_buffer) # 模型类型protobuf / naive_buffer默认 naive_buffer其中lite_valid_places支持arm、opencl、x86、metal、xpu、bm、mlu、intel_fpga、huawei_ascend_npu、imagination_nna、rockchip_npu、mediatek_apu、huawei_kirin_npu、amlogic_npu等可以同时指定多个平台以逗号分隔优先级高的在前opt 会自动选择最佳执行方式。例如需要支持华为麒麟 NPU 时应设置为huawei_kirin_npu,arm。命令行方式等价于x2paddle --frameworkonnx --modelonnx_model.onnx --save_dirpd_model --to_liteTrue --lite_valid_placesarm --lite_model_typenaive_buffer更完整的转换说明可参考仓库中的 X2Paddle 使用指南 与 docs/user_guides/opt/x2paddleopt.md。说明Paddle Lite 对输入模型的格式有明确约定非 combined 与 combined 两种具体由 opt 工具处理详见下一节。二、模型优化用 opt 工具产出轻量可执行模型2.1 为什么必须做模型优化原始训练模型直接用于端侧推理往往不是最优的。Paddle Lite 提供多种自动优化策略量化将 FP32 权重/激活压缩为 INT8 / INT16降低体积与算力开销子图融合将多个连续算子融合为一个算子减少中间张量的内存读写混合调度在同一模型中按算子特性自动调度到不同硬件CPU / GPU / NPUKernel 优选为同一算子在不同硬件、不同数据排布下挑选最快的实现。这些优化通过 opt 工具自动完成输出一个轻量的、最优的可执行模型。opt 同时还具备算子统计与支持性判断、nb 模型可视化两项辅助能力。注意为了减少第三方库依赖、提高 Paddle Lite 预测框架的通用性在移动端使用 Paddle Lite API 需要准备Naive Buffer 存储格式的模型。对应到源码层面lite/api/paddle_api.h 中定义了LiteModelType枚举kProtobuf 0, kNaiveBufferopt 输出的.nb单文件即 Naive Buffer 格式。2.2 获取 opt 工具的三种方式方式一pip 安装 Paddle Lite推荐跨平台# 当前仓库文档标注的最新版本为 2.12 pip install paddlelite2.12 # 版本号需高于或等于 1.3.3 pip install x2paddle安装后可通过终端命令paddle_lite_opt调用支持 Mac/Ubuntu或通过 Python 脚本调用支持 Windows/Mac/Ubuntu详见 opt Python 调用文档 与 Python API 参考。执行paddle_lite_opt不带参数可查看帮助信息。方式二下载预编译可执行文件opt 是 x86 平台上的可执行文件需要在 PC 端运行支持 Linux 终端和 Mac 终端。下载方式见 预编译库下载文档 中的「opt 工具」一节。若提示无执行权限先执行chmod x ./opt。方式三源码编译./lite/tools/build.sh build_optimize_tool编译产物位于Paddle-Lite/build.opt/lite/api/opt。如果提示第三方库获取失败可以删除Paddle-Lite/third_party目录后重新执行Paddle Lite 会从国内镜像获取第三方库。在 arm64 架构的 MacOS 下编译失败时可改用arch -x86_64 ./lite/tools/build.sh build_optimize_tool或./lite/tools/build_macos.sh build_optimize_tool脚本。更详细的命令行用法参考 opt 可执行文件使用文档。2.3 功能一转化模型为 Paddle Lite 格式opt 支持以下 5 种 PaddlePaddle 模型目录格式使用--model_dir指定(1) __model__ var1 var2 ... 非 combined 形式 (2) model var1 var2 ... 非 combined 形式 (3) model.pdmodel model.pdiparams 动态图导出的 combined 形式 (4) model params combined 形式 (5) model weights combined 形式如果待优化模型是model param这类非标准格式则需要用--model_file与--param_file分别指定模型文件与参数文件位置paddle_lite_opt --model_file./model --param_file./param转化示例将mobilenet_v1转为 arm 平台的 naive_buffer 模型# 终端命令方式 paddle_lite_opt --model_dir./mobilenet_v1 \ --valid_targetsarm \ --optimize_outmobilenet_v1_opt优化后生成单文件mobilenet_v1_opt.nb。opt 完整转化命令的所有选项如下paddle_lite_opt \ --model_dirmodel_param_dir \ --model_filemodel_path \ --param_fileparam_path \ --optimize_out_type(protobuf|naive_buffer) \ --optimize_outoutput_optimize_model_dir \ --valid_targets(arm|opencl|x86|npu|xpu|huawei_ascend_npu|imagination_nna) \ --enable_fp16(true|false) \ --quant_model(true|false) \ --quant_type(QUANT_INT16|QUANT_INT8)选项说明--model_dir待优化的 PaddlePaddle 模型非 combined 形式的路径--model_file待优化的 PaddlePaddle 模型combined 形式的网络结构文件路径--param_file待优化的 PaddlePaddle 模型combined 形式的权重文件路径--optimize_out_type输出模型类型protobuf或naive_buffer。naive_buffer 是更轻量级的序列化/反序列化实现移动端预测务必选择naive_buffer。注意opt 工具文档中的默认值在不同版本间有差异务必显式指定--optimize_out优化模型的输出路径--valid_targets指定模型可执行的 backend默认arm。可同时指定多个逗号分隔优先级高的在前opt 自动选择最佳方式如huawei_kirin_npu,arm--enable_fp16是否启用 opt 中的 Float16 低精度量化提高速度、降低内存占用但精度会有一定下降--quant_model是否启用 opt 中的动态离线量化功能与 PaddleSlim 的动态离线量化功能等价--quant_type动态离线量化的量化类型QUANT_INT8或QUANT_INT16。int8 对精度略有影响、体积约减小 4 倍int16 对精度基本无影响、体积约减小 2 倍使用要点非 combined 模型设置--model_dir忽略--model_file/--param_filecombined 模型反之naive_buffer优化产物为单个.nb文件protobuf优化产物为model与params两个文件将model重命名为__model__即可用 Netron 打开查看结构opt 会自动判别模型是否为量化模型并执行相应优化。2.4 功能二统计模型算子信息、判断硬件支持情况在开发前先用 opt 评估模型在目标硬件上的支持程度可以避免部署阶段踩坑# 打印模型中包含的所有算子并判断在 valid_targets 指定的硬件平台下是否被支持 paddle_lite_opt --print_model_opstrue --model_dirmobilenet_v1 --valid_targetsarm # 打印当前 Paddle Lite 支持的所有算子信息OP 数量及每个 OP 支持的硬件平台 paddle_lite_opt --print_all_opstrue # 打印指定硬件平台如 x86下支持的所有 OP paddle_lite_opt --print_supported_opstrue --valid_targetsx86需要说明的是依据 opt 可执行文件使用文档kHost上支持的算子是纯 C 实现、不依赖任何第三方计算库的算子当在用户指定的valid_targets上找不到算子时opt 会在kHost上寻找对应实现kUnk上支持的算子是量化相关算子。这也解释了为何部分算子可以在没有专属硬件加速时回退到通用 CPU 实现从而保证模型的可用性。2.5 功能三nb 模型可视化opt 还可以加载优化后的 naive_buffer 模型并生成可视化 dot 文件帮助核对优化后的模型结构./opt --optimized_nb_model_path./mobilenet_v1_opt.nb \ --visualization_file_output_path.选项说明--optimized_nb_model_path优化之后的 nb 模型文件路径--visualization_file_output_path可视化 dot 文件的保存路径执行后会生成Block_0.dot文件再用 graphviz 的 dot 命令即可生成 pdf、png 等文件dot Block_0.dot -Tpdf -o Block_0.pdf注意请确保环境已安装 dot 可执行命令可用dot -V确认。若未安装也可以将 dot 文件内容复制到在线可视化工具中查看。三、下载或编译预测库模型优化完成后需要获取对应目标平台的预测库。Paddle Lite 为Android / iOS / ArmLinux / Windows / MacOS / Ubuntu等平台提供官方 Release 预测库优先推荐直接下载 Paddle Lite 预编译库也可根据目标平台选择源码编译。3.1 预编译库的关键参数预编译库下载文档通过以下参数组合区分不同版本选型时应逐一对齐自己的目标环境参数取值范围说明archarmv7 / armv7hf / armv8 / x86目标设备的 CPU 架构osAndroid / IOS / Linux / MacOS / Windows目标设备的操作系统toolchaingcc / clang源码编译时的编译器android_stlc_static / c_shared预测库采用的 Android STL 类型静态链接 / 动态链接with_extraON / OFF是否编译全量 OPOFF 时只编译 CV 相关基础 OPwith_cvON / OFF是否编译 CV 相关 APIwith_logON / OFF预编译库是否带有日志打印python_version2.7 / 3.5 / 3.6 / 3.7Python 版本Windows 等平台使用官方预编译库覆盖的平台与后端组合包括Androidarmv7/armv8 × clang/gcc × c_static/c_shared × with_extra/with_cv 的全组合、iOSarmv7/armv8、Linux ARMarmv7hf/armv8如 Raspberry Pi 3B、RK3399 等设备、Linux x86Ubuntu、MacOS、Windowsx64 多 Python 版本、OpenCLarmv7/armv8、昆仑芯 XPU、华为昇腾 NPU、华为麒麟 NPU、联发科 APU、颖脉 NNA 等。各版本的具体下载清单请直接查阅 release_lib.md 中的表格。3.2 源码编译如需自定义算子集、开启 Profiler 或适配特殊环境可走源码编译路线。编译脚本统一位于仓库lite/tools/目录下例如# Android ./lite/tools/build_android.sh --archarmv8 --toolchainclang full_publish # Linux x86 ./lite/tools/build_linux.sh full_publish编译前需要准备编译环境官方推荐使用 Docker环境要求与各平台编译选项详见编译环境文档与编译选项文档。此外library_tailoring 文档还介绍了依据实际模型裁剪库文件的方法配合 opt 的--record_tailoring_info选项使用。四、开发应用程序五步完成一次预测Paddle Lite 提供 C、Java、Python 三种 API核心编程模式高度一致。下面以 C API 为例展示完整的五步预测流程对应源码实现在 lite/api/paddle_api.h 中。4.1 C API 五步编程步骤 1声明MobileConfig配置模型MobileConfig是轻量级预测器的配置类它会跳过 IR 优化等不必要的阶段直接加载 opt 优化后的模型。既可以加载文件也可以从内存缓冲区加载见 paddle_api.h#include paddle_api.h using namespace paddle::lite_api; MobileConfig config; // 加载 opt 优化后的 naive_buffer 模型文件.nb config.set_model_from_file(model_file_path); // 如需从内存加载config.set_model_from_buffer(buffer, length); config.set_power_mode(LITE_POWER_HIGH); // 能耗模式大核/小核/全核/不绑定 config.set_threads(1); // 工作线程数从源码看MobileConfig继承自ConfigBase后者提供了set_threads、set_power_mode、set_opencl_tune、set_opencl_precision、set_nnadapter_device_names、set_xpu_config等一系列后端配置接口覆盖 OpenCL/GPU、XPU、NNAdapter各类 NPU等场景。步骤 2创建Predictor一行代码即可完成引擎初始化std::shared_ptrPaddlePredictor predictor CreatePaddlePredictorMobileConfig(config);CreatePaddlePredictor是模板函数根据传入的 Config 类型构建对应的预测器声明见 paddle_api.h。步骤 3准备输入通过predictor-GetInput(i)获取第 i 个输入变量Resize指定形状后用mutable_dataT()取得可写数据指针并填充值std::unique_ptrTensor input_tensor(std::move(predictor-GetInput(0))); input_tensor-Resize({1, 3, 224, 224}); auto* data input_tensor-mutable_datafloat(); for (int i 0; i ShapeProduction(input_tensor-shape()); i) { data[i] 1; // 全 1 输入示例 }Tensor类的Resize、dataT、mutable_dataT、shape()等接口定义于 paddle_api.h。如果模型有多个输入每个输入都需要准确设置 shape 和 data若输入是图片需先完成预处理再赋值。步骤 4执行预测predictor-Run();步骤 5获取输出std::unique_ptrconst Tensor output_tensor( std::move(predictor-GetOutput(0))); auto output_data output_tensor-datafloat();GetInput/GetOutput/Run均为PaddlePredictor的纯虚接口定义于 paddle_api.h任何后端预测器都遵循同一调用约定。4.2 端侧完整运行示例以 Android ARMv8 mobilenet_v1 为例仓库提供了可编译、可运行的完整 C 示例源码位于 lite/demo/cxx/mobile_light/mobilenetv1_light_api.cc完整步骤文档见 C 完整示例。1准备模型并转换wget http://paddle-inference-dist.bj.bcebos.com/mobilenet_v1.tar.gz tar zxf mobilenet_v1.tar.gz # 方式一下载 opt 可执行文件后转化 ./opt --model_dir./mobilenet_v1 \ --optimize_out_typenaive_buffer \ --optimize_out./mobilenet_v1_opt # 方式二通过 pip 安装的 paddle_lite_opt 转化 paddle_lite_opt --model_dir./mobilenet_v1 \ --optimize_out_typenaive_buffer \ --optimize_out./mobilenet_v1_opt执行成功后在同级目录生成mobilenet_v1_opt.nb。2编译示例程序下载对应预测库后在预测库解压目录下编译随库发布的 democd inference_lite_lib.android.armv8/demo/cxx/mobile_light make生成可执行文件mobilenetv1_light_api。3部署到手机并执行adb devices # 确认手机已被识别 adb push mobilenet_v1_opt.nb /data/local/tmp adb push libpaddle_light_api_shared.so /data/local/tmp adb push mobilenetv1_light_api /data/local/tmp adb shell cd /data/local/tmp export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/data/local/tmp ./mobilenetv1_light_api mobilenet_v1_opt.nb示例程序会输出 benchmark 汇总信息与输出 tensor 统计信息。从 mobilenetv1_light_api.cc 的源码可以看到该可执行文件支持的运行参数./mobilenetv1_light_api naive_buffer_model_dir raw_input_shapes repeats warmup power_mode thread_num accelerate_opencl print_output其中power_mode含义0大核高性能、1小核、2全核、3不绑定accelerate_opencl在模型可运行于 OpenCL 后端时生效1 表示启用 OpenCL kernel 缓存与调优。示例中还演示了 OpenCL 后端的标准配置流程IsOpenCLBackendValid()校验 →set_opencl_binary_path_name()缓存 kernel 二进制 →set_opencl_tune(CL_TUNE_NORMAL, ...)算法调优 →set_opencl_precision(CL_PRECISION_FP16)设置精度。4.3 Java 与 Python API三种 API 遵循相同的五步模式。Java 与 Python 的完整示例与 API 文档分别为C 完整示例、C API 参考Java 完整示例、Java API 参考Python 完整示例、Python API 参考Python 侧的核心类可参考 CxxConfig、MobileConfig、LightPredictor、Tensor、create_paddle_predictor 等文档。4.4 各硬件平台与业务场景示例Paddle Lite 针对不同硬件平台提供了完整的工程化示例可直接在仓库文档中查阅移动端通用Android apps、iOS apps、Linux appsCPU / GPU 后端Arm、x86、OpenCL、Metal各类 NPU / 加速器华为麒麟 NPU、华为昇腾 NPU、昆仑芯 XPU、昆仑芯 XTCL、高通 QNN、寒武纪 MLU、芯原 TIM-VX、Android NNAPI、联发科 APU、颖脉 NNA、Intel OpenVINO、亿智 NPU对应文件见 docs/demo_guides/ 目录此外官方还发布了基于 Paddle Lite 开发的图像分类、目标检测、口罩检测、人脸关键点、人像分割等 Android 演示 APK可在对应 demo 文档中找到运行说明便于先在真机上体验效果。五、性能与精度分析Profiler 工具完成部署后如果需要进一步了解模型在端上的运行情况Paddle Lite 提供了 Profiler 工具分为性能 Profiler与精度 Profiler两类详见 Profiler 工具文档性能 Profiler逐层耗时统计可获取 ARM CPU / x86 CPU / OpenCL 上每个 kernel 的耗时信息定位耗时瓶颈精度 Profiler逐层精度统计获取模型每个 Op 的输出 tensor 精度信息快速定位计算精度异常的 Op。5.1 性能 Profiler编译 full_publish 预测库时加入--with_profileON选项# Android ./lite/tools/build_android.sh \ --archarmv8 --toolchainclang --android_stlc_static \ --with_profileON full_publish # Linux x86 ./lite/tools/build_linux.sh --with_profileON full_publish运行示例程序后会自动打印三类统计日志Detailed Dispatch Profiler Summary单次推理的逐 OP 底层 Kernel 层运行耗时在KernelBase::Run()前后统计排除第一次计时相当于 warmupConcise Create Profiler Summary汇总统计创建 Op 的耗时从Instruction::Run()开始到KernelBase::Run()执行前排除前 10 次推理Concise Dispatch Profiler Summary汇总统计运行 Op 的耗时Kernel 层完整耗时排除前 10 次推理。输出表格包含OperatorType、KerneAttr(Place)、KernelFuncName、Avg/Min/Max(ms)、Avg(%)、GOPs、GOPS等列。其中KernelFuncName如conv1x1s1_gemm_fp32、conv_3x3s2_direct_fp32、conv_depthwise_3x3_fp32直接暴露了底层选用的 kernel 实现名根据其耗时占比即可定位性能瓶颈例如 1x1 卷积的 GEMM kernel 往往占比最高。5.2 精度 Profiler编译 full_publish 预测库时加入--with_precision_profileON选项./lite/tools/build_android.sh --with_precision_profileON full_publish # 或 ./lite/tools/build_linux.sh --with_precision_profileON full_publish运行后输出Detailed Precision Profiler Summary对每个 output tensor 提供维度/设备/数据排布/精度信息以及三个核验数值均值mean所有元素的平均值反映整体水平标准差std_deviation元素相对均值的波动程度均值 标准差即可基本确定 tensor 的正确性序列值ave_grow_rate反映元素从起始到末尾的序列变化情况当两组 tensor 均值与标准差相同但元素出现位次不同时该值不同。ave_grow_rate的计算伪代码如下依据 profiler.mdfor (size_t i 1; i output.length; i) { ave_grow_rate (output[i] - output[i - 1]) / (output[i - 1] eps); } ave_grow_rate / output.length;如需把每层输出保存到文件可在执行前设置环境变量export PADDLELITE_PRECISION_WRITE_TO_FILE1Profiler 的实现机制可参考 profiler.md 中的架构设计Op 层信息由Instruction::SetProfileRuntimeOpInfo调用OpLite-GetOpRuntimeInfo获取各算子子类如ConvOpLite重写该方法Kernel 层信息则由KernelBase::SetProfileRuntimeKernelInfo虚函数经多态调用到具体 kernel 实现最终通过profile::OpCharacter结构体在 Op 层与 Kernel 层之间传递信息。总结一条完整的端侧推理落地链路回顾整个流程Paddle Lite 的端侧推理遵循一条清晰的流水线准备模型静态图用save_inference_model、动态图用paddle.jit.save导出 PaddlePaddle 格式第三方框架模型先经 X2Paddle 转换模型优化用 opt 工具pip 安装 / 预编译二进制 / 源码编译执行量化、子图融合、混合调度、Kernel 优选输出.nb的 Naive Buffer 模型并用--print_model_ops提前确认硬件支持性获取预测库按arch / os / toolchain / android_stl / with_extra / with_cv / with_log等参数选择预编译库或使用lite/tools/下脚本源码编译开发应用用 C / Java / Python 三种 API 按「配置 Config → 创建 Predictor → 准备输入 → Run() → 读取输出」五步完成推理并按目标硬件查阅对应平台 demo调优验证用性能 Profiler 定位耗时瓶颈用精度 Profiler 校验逐层输出结合power_mode、线程数、OpenCL 精度等运行时配置进一步优化。这条链路中每一步的入口文档与示例代码都已收录在当前仓库中主流程见 docs/quick_start/tutorial.md优化与 Profiler 等扩展工具的使用细节可在 docs/user_guides/ 目录下找到对应章节源码实现则以 lite/api/paddle_api.h 与 lite/demo/cxx/ 下的示例为最佳参考。【免费下载链接】Paddle-LitePaddlePaddle High Performance Deep Learning Inference Engine for Mobile and Edge (飞桨高性能深度学习端侧推理引擎项目地址: https://gitcode.com/GitHub_Trending/pa/Paddle-Lite创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表