基于 TensorRT 7 API 的 RetinaFace 人脸检测部署:tensorrtx/retinaface 完整实战指南

发布时间:2026/10/4 1:43:16
基于 TensorRT 7 API 的 RetinaFace 人脸检测部署:tensorrtx/retinaface 完整实战指南 人工智能深度学习计算机视觉【免费下载链接】tensorrtxImplementation of popular deep learning networks with TensorRT network definition API项目地址https://gitcode.com/gh_mirrors/te/tensorrtx点击查看免费下载本文以 retinaface/README.md 为主线结合 retina_r50.cpp、decode.cu、retinaface_trt.py 等源码系统讲解如何在 tensorrtx 仓库中用 TensorRT 网络定义 API 搭建 RetinaFaceResNet50 / MobileNet0.25 两种骨干推理引擎涵盖权重转换、FP16/INT8 精度配置、C 与 Python 双端推理以及后处理解码原理。读完本文你可以独立完成 RetinaFace 的 TensorRT 引擎生成、序列化与部署并掌握其自定义解码插件与 INT8 标定的实现细节。一、项目背景tensorrtx 中的 RetinaFacetensorrtx 仓库使用TensorRT 网络定义 API而非 ONNX/UFF 解析器逐层重建常见深度学习网络retinaface目录即是对人脸检测模型 RetinaFace 的完整移植原始 PyTorch 实现来自biubug6/Pytorch_Retinaface作者 fork 出wang-xinyu/Pytorch_Retinaface并额外添加了genwts.py用于把 PyTorch 权重导出为 TensorRT 所需的.wts文本权重文件当前分支使用TensorRT 7 API编写retina_r50.cpp中createEngine、addConvolutionNd、addPluginV2等均为 TRT 7 风格接口仓库另有一个基于 TensorRT 4 的旧分支trt4分支下的retinaface支持两种骨干网络ResNet-50对应retina_r50.cpp权重Resnet50_Final.pth与 MobileNet0.25对应retina_mnet.cpp权重mobilenet0.25_Final.pth二者共享同一套 FPN SSH 检测头 解码插件结构。二、源码结构与完整推理流水线retinaface目录下关键文件及职责如下文件职责decode.h定义输入尺寸INPUT_H480、INPUT_W640、Detection结构体及DecodePlugin插件类声明decode.cuDecode 插件的 CUDA Kernel 实现在 GPU 上完成先验框解码、置信度计算与关键点回归retina_r50.cppResNet-50 骨干的完整网络构建、引擎序列化-s与推理-d主程序retina_mnet.cppMobileNet0.25 骨干的对应实现common.hpp图像预处理、NMS、权重加载、BatchNorm 折叠为 Scale 层等公共函数calibrator.h / calibrator.cppINT8 熵校准器Int8EntropyCalibrator2实现retinaface_trt.pyPython 推理封装反序列化 engine 并完成前后处理CMakeLists.txt编译decodeplugin动态库及两个可执行文件整条推理流水线为图像预处理letterbox 缩放 128 灰边填充→ ResNet-50/MobileNet0.25 骨干 → FPN 特征融合 → SSH 上下文模块 → Bbox/Class/Landmark 三个检测头 → Decode 插件先验框解码→ CPU 端 NMS → 绘制结果。网络完全由 TensorRT API 手工搭建不经过任何模型解析器。三、输入尺寸、输出格式与核心配置宏3.1 输入与输出张量输入/输出规格定义在两处输入尺寸定义在 decode.hINPUT_H 480、INPUT_W 640注释明确要求H、W 必须能被 32 整除因为下采样到 1/8、1/16、1/32 三个尺度输入张量名为data形状{3, INPUT_H, INPUT_W}CHW输出张量名为prob由 decode.cu 决定输出维度。输出尺寸由 retina_r50.cpp 中的公式给出OUTPUT_SIZE (H/8 * W/8 H/16 * W/16 H/32 * W/32) * 2 * 15 1代入 480×640 即(60×80 30×40 15×20) × 30 1 189001。其含义为三个尺度上每个特征点对应 2 个 anchor每个 Detection 记录 15 个 float4 个 bbox 坐标 1 个置信度 10 个关键点坐标首元素output[0]存放检测数量。对应的Detection结构体decode.hstruct alignas(float) Detection { float bbox[4]; // x1, y1, x2, y2 float class_confidence; // 分类置信度 float landmark[10]; // 5 个关键点坐标 };3.2 编译期宏配置README 列出的全部可配置宏集中在 retina_r50.cpp 文件顶部#define USE_INT8 // 精度开关USE_INT8 / USE_FP16 / USE_FP32 三选一 #define DEVICE 0 // GPU id #define BATCH_SIZE 1 // 批大小 #define CONF_THRESH 0.75 // 置信度阈值绘图时过滤 #define IOU_THRESH 0.4 // NMS 的 IoU 阈值宏位置默认值说明USE_FP16/USE_INT8/USE_FP32retina_r50.cpp/retina_mnet.cpp顶部retina_r50默认USE_INT8retina_mnet默认USE_FP16精度三选一只能启用其一USE_INT8需要 GPU 支持 Fast INT8 且需要标定数据DEVICE同上0指定 CUDA 设备 idmain中通过cudaSetDevice(DEVICE)生效BATCH_SIZE同上1引擎批大小推理时同一张图会被复制 BATCH_SIZE 份送入CONF_THRESH同上0.75最终绘制的置信度下限低于此值的检测框被跳过IOU_THRESH同上0.4传入 NMS 的 IoU 阈值INPUT_H/INPUT_Wdecode.h480/640网络输入分辨率必须能被 32 整除在 retina_r50.cpp 中精度选择直接映射为 Builder 配置#if defined(USE_FP16) config-setFlag(BuilderFlag::kFP16); #elif defined(USE_INT8) std::cout Your platform support int8: builder-platformHasFastInt8() std::endl; assert(builder-platformHasFastInt8()); config-setFlag(BuilderFlag::kINT8); Int8EntropyCalibrator2 *calibrator new Int8EntropyCalibrator2( 1, INPUT_W, INPUT_H, ./widerface_calib/, r50_int8calib.table, INPUT_BLOB_NAME); config-setInt8Calibrator(calibrator); #endif可见 INT8 模式会断言平台支持platformHasFastInt8()并注册一个以./widerface_calib/为标定图片目录、缓存表名为r50_int8calib.table的熵校准器。四、第一步从 PyTorch 权重导出 retinaface.wtsREADME 的 Run 流程第一步是从 PyTorch 实现生成.wts权重文件git clone https://github.com/wang-xinyu/Pytorch_Retinaface.git # 下载权重文件 Resnet50_Final.pth放到 Pytorch_Retinaface/weights 目录 cd Pytorch_Retinaface python detect.py --save_model # 保存 PyTorch 模型权重 python genwts.py # 生成 retinaface.wts # 会在当前目录生成 retinaface.wts要点.wts是 tensorrtx 系列通用的轻量权重格式首行是权重块数量随后每行依次为权重名称、元素个数十进制与十六进制数据解析逻辑见 common.hpp 的loadWeights导出后的retinaface.wts必须放到本仓库retinaface目录下因为 retina_r50.cpp 硬编码从../retinaface.wts相对路径加载权重若使用 MobileNet0.25 骨干则用mobilenet0.25_Final.pth走完全相同的流程生成retinaface.wts其余步骤与retina_r50几乎一致。五、第二步构建、序列化引擎与 C 推理5.1 编译将retinaface.wts放入tensorrtx/retinaface后git clone https://gitcode.com/gh_mirrors/te/tensorrtx cd tensorrtx/retinaface mkdir build cd build cmake .. makeCMakeLists.txt 会完成三件事用cuda_add_library(decodeplugin SHARED .../decode.cu)编译libdecodeplugin.so链接nvinfer与cudart这是 Decode 插件的运行时库推理前必须保证其已生成编译retina_r50源码 calibrator.cpp retina_r50.cpp编译retina_mnet同样依赖decodeplugin并链接 OpenCV、nvinfer、cudart。5.2 序列化与推理sudo ./retina_r50 -s # build and serialize model to file i.e. retina_r50.engine wget https://github.com/Tencent/FaceDetection-DSFD/raw/master/data/worlds-largest-selfie.jpg sudo ./retina_r50 -d # deserialize model file and run inference程序仅接受一个命令行参数retina_r50.cpp-s走APIToModel()→createEngine()构建网络并序列化将二进制 engine 写入retina_r50.engine-d从retina_r50.engine反序列化引擎读取worlds-largest-selfie.jpg执行推理。推理主流程retina_r50.cpp值得注意的细节图像预处理调用 common.hpp 的preprocess_img按长边等比缩放、短边用128 灰边填充到 480×640送入网络前做减均值归一化BGR 三通道分别减去104.0 / 117.0 / 123.0与 PyTorch 训练设置一致doInference中为输入输出分别分配 CUDA 显存通过cudaMemcpyAsynccontext.enqueue完成异步推理推理耗时以微秒为单位打印代码中循环执行 1000 次取耗时方便做性能测量输出经过 common.hpp 的nms()按置信度降序排序、贪心 IoU 抑制后置信度大于CONF_THRESH的框用绿色矩形绘制5 个关键点用不同颜色的圆点标注最终保存为0_result.jpg。retina_mnet的用法完全相同仅需先用mobilenet0.25_Final.pth生成retinaface.wts并运行./retina_mnet。六、核心原理Decode 插件与先验框解码RetinaFace 的输出头Bbox 4 维、Class 2 维、Landmark 10 维经拼接后解码工作全部下沉到自定义 CUDA 插件Decode_TRT中完成避免在 CPU 上逐个解码带来开销。6.1 网络侧的三路输入在 retina_r50.cpp 中三个尺度分别生成BboxHead2 * 4个通道2 个 anchor × 4 坐标ClassHead2 * 2个通道2 个 anchor × 2 类face/backgroundLandmarkHead2 * 10个通道2 个 anchor × 5 点 × 2 坐标。随后通过addConcatenation把每个尺度的三路输出拼成一个张量再经插件注册表查找Decode_TRT版本1创建插件auto creator getPluginRegistry()-getPluginCreator(Decode_TRT, 1); IPluginV2 *pluginObj creator-createPlugin(decode, pfc); ITensor* inputTensors[] {cat1-getOutput(0), cat2-getOutput(0), cat3-getOutput(0)}; auto decodelayer network-addPluginV2(inputTensors, 3, *pluginObj); decodelayer-getOutput(0)-setName(OUTPUT_BLOB_NAME); network-markOutput(*decodelayer-getOutput(0));插件声明与注册见 decode.hDecodePluginCreator通过REGISTER_TENSORRT_PLUGIN宏注册。6.2 GPU Kernel 的解码逻辑插件核心是 decode.cu 的CalDetectionkernel。forwardGpu以步长 8/16/32 依次处理三个特征尺度对应 anchor 基础尺寸逐级 ×416 → 64 → 256见 decode.cu。每个特征点上执行置信度计算对两个类别分数做 softmax 变体conf2 exp(conf2) / (exp(conf1) exp(conf2))低于 0.02 的候选直接跳过decode.cu并用atomicAdd统计最终检测数先验框生成prior ((x0.5)/w, (y0.5)/h, anchor*(k1)/W, anchor*(k1)/H)decode.cubbox 解码中心坐标使用方差 0.1、宽高使用方差 0.2 的反向解码公式随后还原为x1,y1,x2,y2并乘以输入分辨率decode.cu关键点解码5 个关键点双眼、鼻尖、双嘴角同样以 0.1 方差解码并换算回像素坐标decode.cu。解码后的数据直接以Detection结构体逐条写入输出缓冲区首元素为检测数量后续每 15 个 float 对应一个检测结果——这也是 Cnms()与 Python 端post_process能直接解析的基础。七、Python 推理封装README 第 4 步提供了基于 TensorRT Python API 的推理封装 retinaface_trt.py前置条件安装python-tensorrt、pycuda等依赖已生成retina_r50.engine且libdecodeplugin.so已编译完成。运行方式python retinaface_trt.py脚本的核心流程retinaface_trt.py用ctypes.CDLL(build/libdecodeplugin.so)加载自定义插件库使引擎反序列化时能找到Decode_TRT插件Retinaface_trt类读取build/retina_r50.engine分配分页锁定内存cuda.pagelocked_empty与显存缓冲preprocess_image与 C 版一致长边缩放 (128,128,128)填充到 480×640、减(104,117,123)均值、HWC→CHW→NCHWinfer通过cuda.memcpy_htod_asynccontext.execute_asynccuda.memcpy_dtoh_async异步推理post_process解析输出读取output[0]检测数 → 按 15 维切分 → 阈值过滤 → 用torchvision.ops.nms做 NMS → 把填充区域坐标还原到原图每个检测框绘制矩形与 5 个关键点结果保存为output_原文件名默认输入zidane.jpg脚本还演示了用threading.Thread并发调用infer同一 PyCUDA context 内 push/pop 切换可作为多线程推理的参考模板。八、INT8 量化部署README 单独一节给出 INT8 量化的完整流程结合 calibrator.h 可理解其实现准备标定图片从训练集随机挑选上千张图片即可人脸检测场景建议来自 WiderFace也可下载 README 提供的widerface_calib标定图片包GoogleDrive 或百度网盘提取码a9wh解压将标定图片目录解压到retinaface/build下即./widerface_calib/与 retina_r50.cpp 中的路径硬编码一致切换精度在retina_r50.cpp顶部把USE_INT8设为启用状态#define USE_INT8重新make重新序列化并测试再次执行./retina_r50 -s生成 INT8 引擎然后./retina_r50 -d验证精度。实现层面Int8EntropyCalibrator2calibrator.h派生自nvinfer1::IInt8EntropyCalibrator2采用Entropy Calibrator 2kENTROPY_CALIBRATION_2算法每次getBatch从img_files_中读取一个 batch 的图片并缩放到输入尺寸标定结果写入缓存表r50_int8calib.tablereadCalibrationCache/writeCalibrationCache使二次构建可复用缓存、跳过重新标定。由于retina_r50.cpp默认启用USE_INT8若你首次构建还没有标定数据记得先切换为USE_FP16或USE_FP32。九、自定义与扩展要点修改输入分辨率只需改动 decode.h 的INPUT_H/INPUT_W要求能被 32 整除注意同时更新 Python 端 retinaface_trt.py 中手写的INPUT_H/INPUT_W更换 GPU修改DEVICE宏多卡机器上可通过cudaSetDevice(DEVICE)定位目标卡调整批大小修改BATCH_SIZE后重新-s序列化需注意当前推理代码在多 batch 时是将同一张图复制多份输入retina_r50.cpp若要处理不同图片需自行改造数据装载精度与阈值调优CONF_THRESH/IOU_THRESH可按场景调节Decode 插件内 0.02 的低置信度预筛decode.cu会影响最终检测数量上限BN 折叠实现所有 BatchNorm 层在 common.hpp 的addBatchNorm2d中通过scale/shift/power三个权值折叠进IScaleLayer这是纯 API 建网省去 BN 层、提升运行效率的关键技巧其他 tensorrtx 模型也普遍复用该模式。十、延伸阅读构建脚本与依赖见 retinaface/CMakeLists.txtOpenCV、CUDA、nvinfer及aarch64嵌入式平台路径分支权重加载与图像预处理细节见 retinaface/common.hppINT8 标定器实现见 retinaface/calibrator.h 与 retinaface/calibrator.cpp仓库总览与更多模型部署说明见根目录 README.md 及tutorials/目录下的系列文档安装、性能测量、INT8/FP16 支持检查等。赞分享人工智能深度学习计算机视觉【免费下载链接】tensorrtxImplementation of popular deep learning networks with TensorRT network definition API项目地址https://gitcode.com/gh_mirrors/te/tensorrtx点击查看免费下载相关推荐RetinaFace人脸检测终极指南PyTorch实战与快速部署RetinaFace人脸检测终极指南PyTorch实战与快速部署 RetinaFace人脸检测技术是当前最先进的人脸识别解决方案之一这个基于PyTorch的Pandoc JATS/BITS 索引元素解析指南从 index-group 到 Native AST 的完整映射Pandoc JATS/BITS 索引元素解析指南从 index group 到 Native AST 的完整映射 本文以 pandoc 仓库中的 golde人工智能深度学习计算机视觉RetinaFace深度学习模型部署实战指南5步快速上手人脸检测想要在Python项目中快速集成高精度的人脸检测功能吗RetinaFace深度学习模型正是你需要的解决方案作为基于PyTorch实现的先进人脸检测算法Re上一篇OpenAI 流式响应实战Python 里把等待压到首字符下一篇OpenCore Legacy Patcher 2.5 实操笔记老 Mac 升级 macOS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考