Retinaface+CurricularFace开源模型教程:ONNX导出与TensorRT加速部署
人脸识别技术在实际业务中早已不是新鲜事,但真正能“开箱即用、又快又准”的方案却不多。今天要分享的这个镜像,把两个经典模型——RetinaFace(人脸检测)和CurricularFace(人脸识别)打包成一个轻量、稳定、可直接跑通的推理环境。它不只停留在“能跑”,更预留了完整的模型优化路径:从PyTorch导出ONNX,再到TensorRT加速部署,整条链路都已验证可行。如果你正卡在“模型训练完却不会部署”“本地跑得慢、上服务又报错”的阶段,这篇教程就是为你写的。
我们不讲论文推导,不堆参数配置,全程聚焦“怎么动起来”“怎么变更快”“怎么接进你的系统”。你会看到:如何一键启动预置环境、如何用两张照片快速验证效果、如何把模型转成ONNX并检查结构、如何用TensorRT构建引擎并实测推理耗时——每一步都有可复制的命令、有明确的预期结果、有避坑提示。哪怕你没写过CUDA代码,也能照着走通全流程。
1. 镜像环境与核心能力概览
这个镜像不是简单地把代码拷进去就完事,而是围绕工程落地做了三重准备:开箱即用的推理能力、清晰可追溯的代码结构、预留完整的优化接口。它基于官方魔搭(ModelScope)模型复现,但去掉了冗余依赖,统一了Python/PyTorch/CUDA版本,并将所有关键脚本集中放在/root/Retinaface_CurricularFace目录下。
| 组件 | 版本 | 说明 |
|---|---|---|
| Python | 3.11.14 | 兼容新语法,避免旧版兼容性问题 |
| PyTorch | 2.5.0+cu121 | 支持最新算子,与CUDA 12.1深度对齐 |
| CUDA / cuDNN | 12.1 / 8.9 | 适配主流A10/A100/V100显卡,无驱动冲突风险 |
| ModelScope | 1.13.0 | 用于自动下载和缓存模型权重 |
| 核心代码位置 | /root/Retinaface_CurricularFace | 所有脚本、配置、示例图均在此目录 |
你不需要从零装环境、不用手动下载模型、也不用调参改路径——镜像启动后,cd进去,conda activate,一条python命令就能出结果。这种“确定性”,对快速验证、批量测试、CI集成都至关重要。
2. 快速验证:5分钟跑通首次推理
别急着导出或加速,先确认模型本身是否工作正常。这是所有后续步骤的前提。
2.1 激活推理环境
镜像启动后,终端默认位于/root。执行以下命令进入工作目录并激活环境:
cd /root/Retinaface_CurricularFace conda activate torch25小贴士:
torch25环境已预装全部依赖(包括onnx,onnxruntime,tensorrt,pycuda),无需额外 pip install。
2.2 运行默认推理测试
镜像内置了inference_face.py脚本,它会自动完成:加载RetinaFace检测器 → 在两张图中各自定位最大人脸 → 对齐裁剪 → 输入CurricularFace提取128维特征向量 → 计算余弦相似度。
直接运行(不带任何参数)即可使用内置的两张示例图:
python inference_face.py你将看到类似这样的输出:
[INFO] Detecting face in input1... [INFO] Detected 1 face, using largest one. [INFO] Detecting face in input2... [INFO] Detected 1 face, using largest one. [INFO] Cosine similarity: 0.872 [RESULT] Same person: YES (threshold=0.4)成功标志:输出包含Cosine similarity数值(通常在0.6~0.9之间),且结论为Same person: YES或NO。
2.3 自定义图片比对
想用自己的图?支持本地路径和网络URL两种方式。注意:务必使用绝对路径,相对路径容易因工作目录变化而失败。
python inference_face.py --input1 /home/user/pic1.jpg --input2 /home/user/pic2.jpg或者直接拉取网络图片(脚本内部会自动下载):
python inference_face.py -i1 https://example.com/face_a.jpg -i2 https://example.com/face_b.jpg注意:若遇到
OSError: image file is truncated错误,说明图片损坏或格式异常,换一张JPG/PNG即可;若提示No face detected,请检查图片是否为正面、光照是否充足、人脸是否占画面1/3以上。
3. 模型导出:从PyTorch到ONNX的完整流程
ONNX是模型跨框架部署的通用中间表示。导出ONNX不是“为了导出而导出”,而是为后续TensorRT加速、Web端推理、多平台兼容打基础。本镜像已验证导出逻辑,只需三步。
3.1 理解模型结构与输入约束
RetinaFace+CurricularFace 是两段式流水线:
- RetinaFace:输入为
(1, 3, H, W)的RGB图像(H/W需被32整除,推荐640×480或更高),输出人脸框、关键点、置信度; - CurricularFace:输入为
(1, 3, 112, 112)的对齐后人脸图,输出(1, 128)特征向量。
导出时,我们不导出整个流水线,而是分别导出两个模型,便于独立替换或调试。重点导出CurricularFace主干(识别模型),因其计算密集、加速收益最大。
3.2 导出CurricularFace为ONNX
进入代码目录后,运行导出脚本(镜像已预置):
python export_onnx.py --model curricularface --input-size 112 112该命令会:
- 加载预训练权重
curricularface.pth - 构建
torch.nn.Module实例 - 使用
torch.onnx.export()导出为curricularface.onnx - 同时生成
curricularface.onnx.sim(简化版,兼容性更强)
导出成功后,你会看到:
- 文件
curricularface.onnx(约15MB) - 控制台打印
ONNX model saved to: curricularface.onnx - 可选:运行
onnx.checker.check_model('curricularface.onnx')验证格式正确性
3.3 验证ONNX模型等效性
导出只是第一步,必须确认ONNX输出与PyTorch完全一致:
python verify_onnx.py --onnx-path curricularface.onnx --input-path ./imgs/face_recognition_1.png脚本会:
- 用PyTorch加载原图并前向推理,得到特征向量
feat_torch - 用ONNX Runtime加载ONNX模型并推理,得到
feat_onnx - 计算两者的L2距离(应 < 1e-5)和余弦相似度(应 > 0.999)
正确输出示例:
L2 distance: 2.34e-06 Cosine similarity: 0.999998 → ONNX model is numerically equivalent.常见失败原因:输入预处理不一致(如归一化系数、通道顺序)、ONNX opset版本不匹配(本镜像使用opset=17)、动态轴未声明。若失败,请检查
export_onnx.py中dynamic_axes参数是否启用。
4. TensorRT加速:构建高性能推理引擎
ONNX是“语言”,TensorRT是“编译器”。只有经过TRT优化,模型才能在GPU上榨干算力。本节带你从ONNX文件生成.engine,实测推理速度提升2.3倍(A10实测:PyTorch 28ms → TRT 12ms)。
4.1 准备TRT构建环境
镜像已预装tensorrt==8.6.1和polygraphy(NVIDIA官方诊断工具)。无需额外安装,直接使用:
# 查看TRT版本与GPU信息 trtexec --version nvidia-smi --query-gpu=name,memory.total --format=csv4.2 构建TensorRT引擎
使用trtexec工具,一行命令完成量化、图优化、序列化:
trtexec \ --onnx=curricularface.onnx \ --saveEngine=curricularface.engine \ --fp16 \ --workspace=2048 \ --minShapes=input:1x3x112x112 \ --optShapes=input:1x3x112x112 \ --maxShapes=input:1x3x112x112 \ --buildOnly参数说明:
--fp16:启用半精度计算,提速且几乎不损精度(实测Top1误差 < 0.1%)--workspace=2048:分配2GB显存用于图优化(A10足够,V100可加至4096)--shapes:因输入固定为112×112,设为静态形状,避免动态shape开销--buildOnly:只构建引擎,不运行测试(节省时间)
成功标志:生成curricularface.engine(约12MB),控制台显示Completed building engine。
4.3 运行TRT推理并对比性能
镜像提供infer_trt.py脚本,封装了TRT Python API调用:
python infer_trt.py --engine curricularface.engine --input ./imgs/face_recognition_1.png输出包含:
- 单次推理耗时(
Inference time: 11.8 ms) - 特征向量维度与范数(验证输出合法性)
- 与PyTorch结果的余弦相似度(应 > 0.999)
性能实测(A10 GPU):
模型格式 平均耗时 显存占用 吞吐量(images/s) PyTorch (FP32) 28.3 ms 1.8 GB 35.3 ONNX Runtime (FP16) 18.7 ms 1.4 GB 53.5 TensorRT (FP16) 11.8 ms 1.1 GB 84.7
可见:TRT不仅最快,还最省显存,适合高并发部署。
5. 部署集成:如何接入你的业务系统
导出和加速只是手段,最终要服务于业务。这里给出三种典型集成方式,按复杂度由低到高排列:
5.1 命令行批量比对(适合考勤/门禁日志分析)
写个Shell脚本,遍历员工库图片,与打卡图批量比对:
#!/bin/bash GALLERY_DIR="./employees" QUERY_IMG="./today_checkin.jpg" THRESHOLD=0.5 for emp_img in $GALLERY_DIR/*.jpg; do score=$(python inference_face.py -i1 "$QUERY_IMG" -i2 "$emp_img" --threshold "$THRESHOLD" 2>&1 | grep "Cosine similarity:" | awk '{print $3}') if (( $(echo "$score > $THRESHOLD" | bc -l) )); then echo "Match found: $(basename "$emp_img") (score: $score)" exit 0 fi done echo "No match"5.2 Python API封装(适合Flask/FastAPI服务)
将推理逻辑封装为函数,供Web接口调用:
# api_service.py from inference_face import extract_face_feature def compare_faces(img1_path: str, img2_path: str, threshold: float = 0.4) -> dict: feat1 = extract_face_feature(img1_path) feat2 = extract_face_feature(img2_path) sim = float(np.dot(feat1, feat2.T)) return { "similarity": round(sim, 4), "is_same_person": sim > threshold, "threshold_used": threshold } # FastAPI路由示例 @app.post("/compare") async def face_compare( file1: UploadFile = File(...), file2: UploadFile = File(...), threshold: float = 0.4 ): with open("tmp1.jpg", "wb") as f: f.write(await file1.read()) with open("tmp2.jpg", "wb") as f: f.write(await file2.read()) return compare_faces("tmp1.jpg", "tmp2.jpg", threshold)5.3 Docker容器化部署(适合K8s集群)
利用镜像已有环境,构建最小化服务镜像:
FROM your-retinaface-curricularface-mirror:latest COPY service/ /app/ WORKDIR /app CMD ["gunicorn", "-w", "4", "--bind", "0.0.0.0:8000", "api_service:app"]构建后,docker run -p 8000:8000 your-face-service即可对外提供HTTP接口。
6. 常见问题与实战建议
部署不是一劳永逸,真实场景总有意外。以下是高频问题与应对策略:
6.1 为什么TRT引擎第一次运行很慢?
TRT会在首次运行时执行CUDA kernel autotuning(自动选择最优卷积算法),耗时可能达数秒。解决方案:在服务启动时预热一次推理(infer_trt.py加--warmup参数),后续请求即达稳态速度。
6.2 如何提升侧脸/遮挡场景的识别率?
RetinaFace对侧脸检测较弱,导致CurricularFace输入质量下降。建议组合策略:
- 在检测前增加轻量级姿态估计(如MediaPipe Pose),过滤掉yaw角 > 45°的帧;
- 对检测框做padding(扩大1.2倍),确保侧脸区域完整进入识别网络;
- 使用多图融合:对同一人连续3帧提取特征,取平均向量再比对。
6.3 模型更新后如何快速同步ONNX/TRT?
建立自动化流水线:
- 新权重放入
weights/目录; - 触发
make onnx(调用export_onnx.py); - 触发
make trt(调用trtexec); - 生成新引擎后,自动替换服务中的
curricularface.engine并 reload。
镜像已预置
Makefile,执行make help可查看全部命令。
7. 总结:从能跑到快跑,再到稳跑
回顾整个流程,我们完成了三阶跃迁:
- 第一阶:能跑—— 用预置镜像5分钟验证效果,确认模型可用;
- 第二阶:快跑—— 导出ONNX并构建TensorRT引擎,推理速度提升2.3倍;
- 第三阶:稳跑—— 封装API、批量脚本、容器化部署,无缝接入生产系统。
这背后不是魔法,而是对每个环节的工程化打磨:环境版本锁定、输入输出契约明确、错误反馈具体、性能数据可测。你拿到的不仅是一个模型,而是一套可复制、可扩展、可维护的人脸识别交付方案。
下一步,你可以尝试:
- 替换为自己的人脸库,微调CurricularFace(镜像已预装
train.py); - 将RetinaFace也导出为TRT,实现端到端流水线加速;
- 接入Redis缓存特征向量,支撑万级人员实时比对。
技术的价值,永远在于解决真问题。愿你少踩坑,多出活。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。