Paddle-Lite 端侧 C++ Demo 完全指南:基于 adb 的 Android 模型验证与部署流程
Paddle-Lite 端侧 C Demo 完全指南基于 adb 的 Android 模型验证与部署流程【免费下载链接】Paddle-LitePaddlePaddle High Performance Deep Learning Inference Engine for Mobile and Edge (飞桨高性能深度学习端侧推理引擎项目地址: https://gitcode.com/GitHub_Trending/pa/Paddle-Lite本篇技术指南基于 Paddle-Lite 仓库 lite/demo/cxx/README.md 编写完整讲解如何通过 shell 端adb在 Android 手机上编译、运行 Paddle-Lite 官方 C Demo快速验证模型在端侧的正确性与性能。读完本文你将掌握轻量级 APILight API与全量 APIFull API两种预测方式的选型与调用、mobilenetv1 分类、SSD/YOLOv3 目标检测、人脸口罩检测、含 CV 预处理库单测共 6 类官方 Demo 的完整落地流程并能结合仓库源码理解其底层实现原理为后续在 Android App 中正式部署模型铺平道路。1. 概述与前置准备这些 C Demo 通过 shell 端即电脑终端 adb在安卓手机上直接执行核心目的是快速验证模型的正确性在手机端跑通模型、确认输出符合预期之后再在 Android App 中调用 Paddle-Lite 完成正式部署。这种先命令行验证、后 App 集成的方式可以极大缩短端侧调试周期避免在 App 工程中反复折腾。运行这些 Demo 需要准备两样东西一台可以编译 Paddle-Lite 的电脑具体环境配置可参考 docs/source_compile/compile_env.rst推荐使用 Docker 环境可避免本机依赖污染。一台 armv7 或 armv8 架构的安卓手机安装好 adb并确保电脑和手机可以通过 adb 正常连接adb devices能看到设备。Paddle-Lite 预测库的获取有两种途径任选其一自行编译参考 docs/source_compile/linux_x86_compile_android.rst 编译 Android 版本预测库直接下载从 Paddle-Lite release 界面下载已经编译好的 release 库文件包并参考 docs/quick_start/release_lib.md 了解其目录结构与使用方式。编译好的 release 包如inference_lite_lib.android.armv8内部包含demo/cxx目录与仓库 lite/demo/cxx 下的结构一致官方 Demo 源码、Makefile 均已内置可直接进入对应目录编译。下文涉及的 6 个 Demo 为轻量 API 分类 Demo、全量 API 分类 Demo、物体分类 Demo、SSD 目标检测 Demo、YOLOv3 目标检测 Demo、人脸识别与口罩佩戴判断 Demo以及含 CV 预处理库的模型单测 Demo。2. 编译并运行轻量级 APILight APIDemo轻量级 API 是 Paddle-Lite 推荐的部署方式先用 opt 工具把训练模型离线转换为 Paddle-Lite 专用格式naive_buffer.nb文件再通过轻量 API 直接加载.nb文件进行预测。由于免去了运行时在线转换加载与预测耗时均更优。2.1 编译可执行文件在inference_lite_lib.android.armv8/demo/cxx/mobile_light目录下执行cd inference_lite_lib.android.armv8/demo/cxx/mobile_light make -j编译产出可执行文件mobilenetv1_light_api。对应的源码位于 lite/demo/cxx/mobile_light/mobilenetv1_light_api.cc其核心流程为构造MobileConfig→CreatePaddlePredictorMobileConfig(config)创建预测器 → 填充输入 →predictor-Run()→ 读取输出。测试代码中输入的是一张全 1 数据input_data[i] 1.f仅用于验证流程正确性实际部署时请替换为真实预处理后的图像数据。2.2 下载模型并使用 opt 转换下载原始 Paddle 模型mobilenet_v1 分类模型wget http://paddle-inference-dist.bj.bcebos.com/mobilenet_v1.tar.gz tar zxf mobilenet_v1.tar.gz使用 opt 工具进行模型转换具体用法参考 docs/user_guides/model_optimize_tool.md。推荐从 Paddle-Lite release 界面下载 opt 工具注意 opt 工具版本必须与预测库版本保持一致。假定转换后的模型为mobilenet_v1.nb。opt 工具同时也提供命令行二进制形式转换命令可参考./opt --model_dirmobilenet_v1 --optimize_out_typenaive_buffer --optimize_outmobilenet_v1 # 优化后模型为 mobilenet_v1.nb更多 opt 用法可查看仓库文档 docs/user_guides/opt/opt_bin.md 与 docs/user_guides/opt/opt_python.md。2.3 通过 adb 推送并在手机端执行adb push mobilenetv1_light_api /data/local/tmp/ adb push mobilenet_v1.nb /data/local/tmp/ adb push ../../../cxx/lib/libpaddle_light_api_shared.so /data/local/tmp/ adb shell chmod x /data/local/tmp/mobilenetv1_light_api adb shell export LD_LIBRARY_PATH/data/local/tmp/:$LD_LIBRARY_PATH /data/local/tmp/mobilenetv1_light_api /data/local/tmp/mobilenet_v1.nb说明需要将动态库libpaddle_light_api_shared.so与可执行文件、模型一并 push 到手机并通过LD_LIBRARY_PATH指定动态库搜索路径chmod x赋予执行权限如果是在 Docker 中编译而 Docker 无法直连手机可将测试所需文件和库拷贝到 Docker 外部再执行上述命令。运行成功后控制台会输出预测结果前 10 个类别的预测概率。2.4 从源码看 Light API 的可调参数从 mobilenetv1_light_api.cc 的main函数可以看出该可执行文件支持最多 8 个命令行参数依次为参数说明默认值naive_buffer_model_dir.nb模型路径必填raw_input_shapes输入 shape如1,3,224,224多输入用:分隔1,3,224,224repeats重复推理次数10warmup预热次数10power_mode0大核高性能1小核2全部核3不绑定0thread_num线程数1accelerate_opencl仅当模型可在 OpenCL 后端运行时生效1 开启 OpenCL kernel 缓存与调优1print_output1 表示将输出张量逐元素打印到 stdout0源码还展示了 OpenCL 后端相关的进阶配置IsOpenCLBackendValid检查 GPU 后端是否可用set_opencl_binary_path_name指定 kernel 二进制缓存路径set_opencl_tune(CL_TUNE_NORMAL, ...)选择调优级别set_opencl_precision(CL_PRECISION_FP16)指定 FP16 精度。若 OpenCL 不可用程序会输出*** nb model will be running on cpu. ***提示并回退到 CPU 执行。完整 OpenCL 部署可参考 docs/demo_guides/opencl.md。3. 编译并运行全量 APIFull APIDemo全量 APICxxConfigCreatePaddlePredictorCxxConfig支持在线对原始模型进行转换直接加载 Paddle 原始模型__model__/__params__或合并格式在运行时完成优化后再预测。由于在线转换耗时较久Paddle-Lite 推荐首选 opt 工具离线转换 轻量 API 部署的组合。全量 API 更多用于调试或需要动态改变模型结构的场景。注当编译模式为tiny_publish时release 包中将不包含该 Demo需使用full_publish编译模式才会产出。3.1 编译与运行cd inference_lite_lib.android.armv8/demo/cxx/mobile_full wget http://paddle-inference-dist.bj.bcebos.com/mobilenet_v1.tar.gz tar zxvf mobilenet_v1.tar.gz make adb push mobilenet_v1 /data/local/tmp/ adb push mobilenetv1_full_api /data/local/tmp/ adb push ../../../cxx/lib/libpaddle_full_api_shared.so /data/local/tmp/ adb shell chmod x /data/local/tmp/mobilenetv1_full_api adb shell export LD_LIBRARY_PATH/data/local/tmp/:$LD_LIBRARY_PATH /data/local/tmp/mobilenetv1_full_api --model_dir/data/local/tmp/mobilenet_v1 --optimized_model_dir/data/local/tmp/mobilenet_v1.opt运行成功后在控制台输出预测结果前 10 个类别的预测概率。同样地测试文件中输入数据为全 1实际部署请替换为真实数据Docker 编译无法连手机时将所需文件和库拷贝到 Docker 外部再测试。3.2 从源码看 Full API 的命令行参数对应源码 lite/demo/cxx/mobile_full/mobilenetv1_full_api.cc 基于 gflags 解析参数参数类型说明--model_dirstring未合并uncombined格式的模型目录路径--model_file/--param_filestring合并combined格式的模型文件与参数文件--optimized_model_dirstring优化后模型的输出目录--prefer_int8_kernelbool是否优先使用 int8 kernel默认 false--power_modeint320POWER_HIGH1POWER_LOW2POWER_FULL3NO_BIND默认 3--threadsint32线程数默认 1--warmupint32预热次数默认 10--repeatsint32重复次数默认 100--use_gpubool是否使用 OpenCL 后端默认 false源码中的关键点通过config.set_valid_places(valid_places)声明候选执行后端列表开启 GPU 时会依次放入多组 OpenCLPlace含TARGET(kOpenCL)、FP16/FP32 精度、kImageDefault/kImageFolder/kNCHW数据布局否则仅放入TARGET(kARM)predictor-SaveOptimizedModel(FLAGS_optimized_model_dir, LiteModelType::kNaiveBuffer)会在线把优化后的模型保存为.nb文件——这正是 Full API 相比 Light API 的差异点它把 opt 的转换能力内置到了运行时。源码注释特别警告SaveOptimizedModel必须在Run()之前调用因为部分 kernel 的PrepareForRun可能修改参数值。4. 编译并运行物体分类 Demomobile_classify与前两个 Demo 不同物体分类 Demo 是面向真实图像的它会用 OpenCV 读取图片、做完整预处理并输出带类别名的 Top-K 结果最贴近实际业务场景。4.1 编译cd inference_lite_lib.android.armv8/demo/cxx/mobile_classify make编译产出mobile_classify可执行文件。4.2 下载模型与测试数据wget http://paddle-inference-dist.bj.bcebos.com/mobilenet_v1.tar.gz tar zxf mobilenet_v1.tar.gz wget https://paddle-inference-dist.cdn.bcebos.com/PaddleLite/cxx_demo/test_data.tgz tar zxf test_data.tgztest_data.tgz内含测试图片test.jpg与类别标签文件label.txt。4.3 模型转换./opt --model_dirmobilenet_v1 --optimize_out_typenaive_buffer --optimize_outmobilenet_v1 # 优化后模型为 mobilenet_v1.nb--optimize_out_typenaive_buffer即产出轻量 API 所需的.nb格式。4.4 推送并执行adb push ../../../cxx/lib/libpaddle_light_api_shared.so /data/local/tmp/ adb push mobile_classify /data/local/tmp/ adb shell chmod x /data/local/tmp/mobile_classify adb push test_data /data/local/tmp/ adb push mobilenet_v1.nb /data/local/tmp/ adb shell export LD_LIBRARY_PATH/data/local/tmp/:$LD_LIBRARY_PATH /data/local/tmp/mobile_classify /data/local/tmp/mobilenet_v1.nb /data/local/tmp/test_data/test.jpg /data/local/tmp/test_data/label.txt运行成功后输出预测结果前 5 个类别的概率。4.5 可选参数topk 与输入尺寸查看前 10 个类别在命令末尾追加topk值即可adb shell export LD_LIBRARY_PATH/data/local/tmp/:$LD_LIBRARY_PATH /data/local/tmp/mobile_classify /data/local/tmp/mobilenet_v1.nb /data/local/tmp/test_data/test.jpg /data/local/tmp/test_data/label.txt 10切换其他模型并指定输入尺寸追加model_dir及其模型输入大小格式为topk 宽 高adb shell export LD_LIBRARY_PATH/data/local/tmp/:$LD_LIBRARY_PATH /data/local/tmp/mobile_classify /data/local/tmp/mobilenet_v1.nb /data/local/tmp/test_data/test.jpg /data/local/tmp/test_data/label.txt 10 224 2244.6 从源码看图像预处理链路对应源码 lite/demo/cxx/mobile_classify/mobile_classify.cc 展示了完整的图像 → 张量预处理流程这部分是端侧视觉类应用的通用范式cv::cvtColor将 BGR 图转为 RGBcv::resize缩放到模型输入尺寸convertTo(CV_32FC3, 1/255.f)归一化到[0,1]调用neon_mean_scale完成减均值、除方差并通过 NEON 内联汇编float32x4_t、vld3q_f32、vst1q_f32等将 NHWC 布局转换为 NCHW 布局同时做 4 路向量化加速。默认均值means {0.485f, 0.456f, 0.406f}、方差scales {0.229f, 0.224f, 0.225f}ImageNet 统计值print_topk使用std::partial_sort计算 Top-K并配合label.txt输出类别名与置信度。该 Demo 同时展示了MobileConfig的最小用法set_model_from_file指定.nb模型 →CreatePaddlePredictorMobileConfig→GetInput(0)/Resize/mutable_datafloat→Run()→GetOutput(0)。5. 编译并运行 SSD 目标检测 DemoSSD Demo 将检测框、类别、置信度直接绘制到测试图片上并保存结果图可直观验证检测模型的正确性。cd inference_lite_lib.android.armv8/demo/cxx/ssd_detection make -j adb push ../../../cxx/lib/libpaddle_light_api_shared.so /data/local/tmp/ adb push ssd_detection /data/local/tmp/ adb shell chmod x /data/local/tmp/ssd_detection wget https://paddle-inference-dist.bj.bcebos.com/mobilenetv1-ssd.tar.gz tar zxvf mobilenetv1-ssd.tar.gz adb push mobilenetv1-ssd /data/local/tmp adb push test.jpg /data/local/tmp/ # 请自己准备ssd模型的测试图片 adb shell export LD_LIBRARY_PATH/data/local/tmp/:$LD_LIBRARY_PATH /data/local/tmp/ssd_detection /data/local/tmp/mobilenetv1-ssd /data/local/tmp/test.jpg adb pull /data/local/tmp/test_ssd_detection_result.jpg ./运行成功后ssd_detection目录下会生成目标检测结果图像test_ssd_detection_result.jpg。从源码看检测输出后处理对应源码 lite/demo/cxx/ssd_detection/ssd_detection.cc 展示了端侧目标检测的标准后处理SSD 模型的输出按每 6 个 float 为一组data 6组织依次为class_id类别索引、prob置信度、以及归一化后的x, y, w, hdata[2]..data[5]需乘以原图宽高还原为像素坐标阈值0.6f用于过滤低置信度框detect_object中还会用cv::Rect(0,0,cols,rows)对检测框做越界裁剪内置 VOC 20 类 background 共 21 个类别名class_names[]使用cv::rectangle、cv::putText将结果绘制到图上最终cv::imwrite保存为图片名_ssd_detection_result.jpg。预处理方面该 Demo 使用均值/方差{0.5f, 0.5f, 0.5f}输入尺寸固定为300×300同样基于 NEON 完成 NHWC→NCHW 转换。6. 编译并运行 YOLOv3 目标检测 DemoYOLOv3 Demo 与 SSD Demo 流程一致仅模型与后处理不同cd inference_lite_lib.android.armv8/demo/cxx/yolov3_detection make -j adb push ../../../cxx/lib/libpaddle_light_api_shared.so /data/local/tmp/ adb push yolov3_detection /data/local/tmp/ adb shell chmod x /data/local/tmp/yolov3_detection wget https://paddle-inference-dist.bj.bcebos.com/mobilenetv1-yolov3.tar.gz tar zxvf mobilenetv1-yolov3.tar.gz adb push mobilenetv1-yolov3 /data/local/tmp adb push test.jpg /data/local/tmp/ # 请自己准备yolov3模型的测试图片 adb shell export LD_LIBRARY_PATH/data/local/tmp/:$LD_LIBRARY_PATH /data/local/tmp/yolov3_detection /data/local/tmp/mobilenetv1-yolov3 /data/local/tmp/test.jpg adb pull /data/local/tmp/test_yolov3_detection_result.jpg ./运行成功后yolov3_detection目录下会生成目标检测结果图像test_yolov3_detection_result.jpg。从源码 lite/demo/cxx/yolov3_detection/yolov3_detection.cc 可以看到其内置了 COCO 80 类类别名person、bicycle、car、dog…后处理同样按固定步长解析输出并进行阈值过滤与坐标还原最后将结果绘制并保存。7. 人脸识别与佩戴口罩判断 Demomask_detection该 Demo 串联了人脸检测 口罩佩戴判断两个模型先用pyramidbox_lite人脸检测模型定位人脸再用人脸区域作为输入交给mask_detector口罩判断模型分类。官方已提供两种使用方式直接下载编译好的 Demo 包或从源码编译。7.1 方式一下载编译好的 Demo 包直接执行下载压缩包mask_demo_v2.6.tgzPaddle-Lite 2.6 版本内含编译好的可执行文件、模型文件、测试图片、Paddle-Lite 2.6 版本动态库解压到本地。官方声明该 Demo 已在 Paddle-Lite 2.6 和 2.8 版本上验证可准确执行。电脑连接安卓手机后在电脑 shell 端进入mask_demo目录执行sh run.sh脚本会自动完成push 文件到手机端 → 执行口罩检测 → pull 结果图片。执行后在电脑端查看test_img_result.jpg即为口罩检测结果。7.2 方式二从源码编译 Demo 并执行第一步准备编译环境。参考 docs/source_compile/compile_env.rst。第二步拉取 Paddle-Lite 代码并切换到 2.6 版本分支git clone https://github.com/PaddlePaddle/Paddle-Lite.git cd Paddle-Lite git fetch origin release/v2.6:release/v2.6 git checkout release/v2.6第三步编译预测库。进入 Paddle-Lite 根目录执行详细编译方法参考 docs/source_compile/linux_x86_compile_android.rst./lite/tools/build.sh \ --arm_osandroid \ --arm_abiarmv8 \ --arm_langgcc \ --android_stlc_static \ --build_extraON \ --with_logON \ full_publish第四步编译 Demo 可执行文件。进入 Demo 编译目录执行脚本脚本会编译可执行文件并将可执行文件、预测库、模型、图片统一收集到mask_demo目录cd build.lite.android.armv8.gcc/inference_lite_lib.android.armv8/demo/cxx/mask_detection sh prepare.sh仓库中对应脚本为 lite/demo/cxx/mask_detection/prepare.sh其工作内容一目了然设置NDK_ROOT环境变量 →make -j编译 → 创建mask_demo目录并拷贝run.sh、mask_detection可执行文件、libpaddle_light_api_shared.so→ 自动下载mask_models_img.tar.gz及两个模型的.nb文件pyramidbox_lite_fp32_for_cpu_v2_10_rc.tar.gz、mask_detector_fp32_128_128_for_cpu_v2_10_rc.tar.gz并重命名。第五步运行。手机连接电脑后进入mask_demo目录执行sh run.sh查看生成的test_img_result.jpg。lite/demo/cxx/mask_detection/run.sh 的核心命令为adb push ../mask_demo /data/local/tmp/ adb shell cd /data/local/tmp/mask_demo export LD_LIBRARY_PATH...:${LD_LIBRARY_PATH} \ ./mask_detection pyramidbox_lite_v2_10_rc_opt2.nb mask_detector_v2_10_rc_opt2.nb mask_models_img/test_img.jpg adb pull /data/local/tmp/mask_demo/test_img_result.jpg .7.3 使用 PaddleHub 模型替换除了官方模型也可以通过 PaddleHub 下载人脸检测与口罩佩戴判断模型再经 opt 转换后替换mask_demo目录下的模型文件import paddlehub as hub pyramidbox_lite_mobile_mask hub.Module(namepyramidbox_lite_mobile_mask) pyramidbox_lite_mobile_mask.processor.save_inference_model(dirnametest_program)上述代码会将模型保存在test_program目录人脸检测与口罩佩戴判断模型分别存储在pyramidbox_lite和mask_detector子目录中其中的__model__是模型结构文件、__param__是权重文件。从 PaddleHub 下载的是预测模型需使用 Paddle-Lite 的 opt 工具转换为.nb格式后再替换。7.4 关键超参数shrink 与 detect_threshold源码 lite/demo/cxx/mask_detection/mask_detection.cc 中暴露了两个可自由配置的常量位于人脸检测与口罩判断的推理循环里缩放因子shrink默认 0.4用于把输入图片按比例缩小后再送入人脸检测模型s_width width * shrink。缩放因子越大模型运行速度越慢检测准确率越高反之速度更快但可能漏检小脸。检测阈值detect_threshold默认 0.7人脸框置信度阈值if (outptr[1] detect_threshold)。阈值越高人脸筛选越严格检测出的人脸框可能越少调低可召回更多人脸但可能引入误检。实际调优时应根据目标设备算力与场景如人流密度、口罩合规率在精度与速度之间权衡。8. 编译含 CV 预处理库的模型单测 Demotest_cvtest_cvDemo 用于验证Paddle-Lite CV 图像预处理库图像缩放、颜色转换、旋转等与模型的联合推理其独立说明见 lite/demo/cxx/test_cv/README.md。cd ../test_cv wget http://paddle-inference-dist.bj.bcebos.com/mobilenet_v1.tar.gz tar zxvf mobilenet_v1.tar.gz ./model_optimize_tool optimize model make adb push test_model_cv /data/local/tmp/ adb push test.jpg /data/local/tmp/ adb push labels.txt /data/local/tmp/ adb push ../../../cxx/lib/libpaddle_full_api_shared.so /data/local/tmp/ adb shell chmod x /data/local/tmp/test_model_cv adb shell export LD_LIBRARY_PATH/data/local/tmp/:$LD_LIBRARY_PATH /data/local/tmp/test_model_cv /data/local/tmp/mobilenetv1opt2 /data/local/tmp/test.jpg /data/local/tmp/labels.txt注意此处使用libpaddle_full_api_shared.so全量库且模型需经本地工具转换为mobilenetv1opt2目录格式。运行成功后在控制台输出预测结果前 10 个类别的预测概率。该目录下的源码 lite/demo/cxx/test_cv/test_model_cv.cc 与 lite/demo/cxx/test_cv/test_img_prepross.cc 演示了 CV 库预处理与 Full API 推理的组合调用方式可作为带图像预处理的完整推理流水线参考模板。9. 通用编译机制Makefile 体系说明上述所有 Android Demo 共用的编译基础设施在 lite/demo/cxx/Makefile.def 与 lite/demo/cxx/makefiles 目录中每个 Demo 均提供Makefile.android.armv7与Makefile.android.armv8两份 Makefile如 makefiles/mobile_light/Makefile.android.armv8通过ARM_ABI arm8或arm7切换目标架构Makefile.def会根据NDK_ROOT环境变量自动探测 NDK 版本grep -Eo android-ndk-r[0-9]{2}并据此选择编译器NDK r18 及以下使用aarch64-linux-android-g/arm-linux-androideabi-ggcc 工具链r19 使用 clangaarch64-linux-android21-clang/armv7a-linux-androideabi16-clang链接选项默认使用共享库-lpaddle_light_api_sharedMakefile 注释中同时说明了如何切换到静态库libpaddle_api_light_bundled.a需在源码中放开paddle_use_ops.h/paddle_use_kernels.h的 include以避免unsupport ops or kernels链接错误armv7 编译默认开启-mfpuneon -mfloat-abisoftfp所有目标默认-fopenmp多线程、-fPIEAndroid 要求 PIE 可执行文件。10. 小结从 Demo 验证到 App 部署结合 lite/demo/cxx/README.md 与上述源码分析可以总结出一条清晰的端侧部署路径准备环境搭建可编译 Paddle-Lite 的环境推荐 Docker准备 armv7/armv8 安卓手机并通过 adb 连接获取预测库自行编译docs/source_compile/linux_x86_compile_android.rst或直接下载 release 包转换模型使用与预测库同版本的 opt 工具将原始 Paddle 模型转换为.nb格式docs/user_guides/model_optimize_tool.md验证正确性编译并运行上述任一 C Demo在 shell 端确认预测结果Top-K 概率、检测框、口罩结果等符合预期App 集成验证通过后将 Light API 调用逻辑迁移到 Android App 中正式部署。对于有更复杂交互诉求如图像实时采集、OpenGL 渲染的移动端场景可进一步参考仓库的 docs/demo_guides/android_app_demo.md 与 docs/demo_guides/arm_cpu.md这些文档展示了 Android App 级别的集成方案与本文的 shell 端验证 Demo 形成互补。总体而言lite/demo/cxx 目录下的这 6 类 Demo 覆盖了分类、检测、人脸/口罩识别等最常见端侧任务是学习 Paddle-Lite 双 API 用法、验证模型正确性、快速原型验证的第一手教材。【免费下载链接】Paddle-LitePaddlePaddle High Performance Deep Learning Inference Engine for Mobile and Edge (飞桨高性能深度学习端侧推理引擎项目地址: https://gitcode.com/GitHub_Trending/pa/Paddle-Lite创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考