当前位置: 首页 > news >正文

Ubuntu20.04系统部署RetinaFace完整指南

Ubuntu20.04系统部署RetinaFace完整指南

1. 为什么选择RetinaFace做人脸检测

在实际项目中,我们经常需要快速准确地从图片或视频里找出人脸位置,还要标出眼睛、鼻子、嘴巴这些关键点。比如做门禁系统时要识别人脸,做美颜APP时要精准定位五官,或者做安防监控时要追踪多个人脸——这时候,一个既快又准的模型就特别重要。

RetinaFace就是这样一个被工业界和学术界都认可的模型。它不光能框出人脸,还能同时标出五个关键点:左右眼、鼻尖、左右嘴角。这些点对后续的人脸对齐、表情分析、3D建模都很关键。更重要的是,它在小脸、侧脸、遮挡脸这些难检场景下表现稳定,不像有些模型一遇到戴口罩或侧脸就“失明”。

我之前在一台普通服务器上试过几个主流模型,RetinaFace在WIDER FACE数据集上的硬样本(hard subset)检测率明显更高,而且推理速度也够用。如果你不是在手机端跑,而是在Ubuntu服务器这类有GPU的环境里部署,它是个很务实的选择。

这次教程会带你从零开始,在Ubuntu 20.04系统上把RetinaFace跑起来。整个过程不依赖Docker镜像,也不用编译复杂源码,所有步骤我都实测过,包括CUDA驱动怎么装、哪些Python包容易踩坑、测试图怎么选才不会报错。你只要跟着敲命令,最后就能看到一张图输入进去,立刻返回带框和关键点的标注结果。

2. 环境准备与系统检查

2.1 确认系统版本与硬件基础

首先确认你的系统确实是Ubuntu 20.04。打开终端,输入:

lsb_release -a

你应该看到类似这样的输出:

Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal

如果不是20.04,请先升级系统或重装镜像。这个版本对CUDA 11.x支持最成熟,避免很多兼容性问题。

接着检查GPU是否被系统识别:

nvidia-smi

如果显示驱动版本(比如515.65.01)和GPU型号(如RTX 3090),说明显卡驱动已就绪。如果提示“NVIDIA-SMI has failed”,说明驱动没装好,需要先安装NVIDIA官方驱动。推荐用ubuntu-drivers autoinstall命令自动安装,比手动下载.run包更稳妥。

2.2 安装CUDA与cuDNN(GPU加速核心)

RetinaFace依赖PyTorch,而PyTorch要发挥GPU性能,必须配好CUDA和cuDNN。Ubuntu 20.04官方源里CUDA版本较旧,我们直接用NVIDIA官网提供的deb包安装CUDA 11.3——这是目前与PyTorch 1.10+兼容性最好的版本。

执行以下命令:

wget https://developer.download.nvidia.com/compute/cuda/11.3.1/local_installers/cuda-repo-ubuntu2004-11-3-local_11.3.1-465.19.01-1_amd64.deb sudo dpkg -i cuda-repo-ubuntu2004-11-3-local_11.3.1-465.19.01-1_amd64.deb sudo apt-key add /var/cuda-repo-ubuntu2004-11-3-local/7fa2af80.pub sudo apt-get update sudo apt-get install -y cuda-11-3

安装完后,把CUDA路径加进环境变量。编辑~/.bashrc

echo 'export PATH=/usr/local/cuda-11.3/bin:$PATH' >> ~/.bashrc echo 'export LD_LIBRARY_PATH=/usr/local/cuda-11.3/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc source ~/.bashrc

验证CUDA是否生效:

nvcc --version

应该输出Cuda compilation tools, release 11.3, V11.3.109

接下来安装cuDNN 8.2.1(对应CUDA 11.3)。去NVIDIA官网下载cuDNN v8.2.1 for CUDA 11.3的tar包(需注册账号),上传到服务器后解压并复制文件:

tar -xzvf cudnn-11.3-linux-x64-v8.2.1.32.tgz sudo cp cuda/include/cudnn*.h /usr/local/cuda-11.3/include sudo cp cuda/lib/libcudnn* /usr/local/cuda-11.3/lib64 sudo chmod a+r /usr/local/cuda-11.3/include/cudnn*.h /usr/local/cuda-11.3/lib64/libcudnn*

最后验证cuDNN:

cat /usr/local/cuda-11.3/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

应看到#define CUDNN_MAJOR 8等信息。

2.3 创建独立Python环境

别直接用系统Python,容易污染全局环境。我们用conda创建干净环境(比venv更稳妥,尤其对CUDA相关包):

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3 $HOME/miniconda3/bin/conda init bash source ~/.bashrc conda create -n retinaface python=3.8 conda activate retinaface

激活环境后,确认Python版本:

python --version # 应为3.8.x

3. 安装依赖库与RetinaFace代码

3.1 安装PyTorch与基础库

PyTorch必须匹配CUDA版本。我们装支持CUDA 11.3的1.10.2版本:

pip3 install torch==1.10.2+cu113 torchvision==0.11.3+cu113 torchaudio==0.10.2+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html

然后装其他必需库:

pip3 install numpy opencv-python scikit-image matplotlib tqdm requests

注意:opencv-python不要装opencv-contrib-python,后者可能引发冲突;scikit-image用于图像预处理,比PIL更稳定。

3.2 获取RetinaFace官方实现

我们用bifeng84的PyTorch实现(GitHub star最多、维护活跃、文档清晰):

git clone https://github.com/biubug6/Pytorch_Retinaface.git cd Pytorch_Retinaface

这个仓库结构很清晰:models/放网络定义,data/放数据加载,utils/放工具函数,weights/放预训练权重。我们不需要训练,只用推理,所以重点在inference.py和权重文件。

3.3 下载预训练模型权重

官方提供两个常用权重:ResNet50主干(精度高)和mobilenet0.25(速度快)。我们先下ResNet50版,适合服务器部署:

mkdir weights cd weights wget https://github.com/biubug6/Pytorch_Retinaface/releases/download/1.0/Resnet50_Final.pth cd ..

如果网速慢或下载失败,可以改用国内镜像源(如清华TUNA),或者用curl -L替代wget

4. 运行模型验证与效果测试

4.1 准备测试图片

找一张含人脸的图片,最好是正面、光照均匀的。你可以用自己手机拍一张,或者从网上下载公开测试图。保存为test.jpg放在项目根目录。

如果想省事,用代码生成一张简单测试图:

import cv2 import numpy as np # 创建纯色背景 img = np.ones((480, 640, 3), dtype=np.uint8) * 230 # 画一个模拟人脸(圆圈+十字) cv2.circle(img, (320, 240), 80, (100, 150, 200), -1) # 脸轮廓 cv2.circle(img, (280, 220), 10, (50, 50, 50), -1) # 左眼 cv2.circle(img, (360, 220), 10, (50, 50, 50), -1) # 右眼 cv2.circle(img, (320, 260), 8, (100, 50, 50), -1) # 鼻子 cv2.line(img, (290, 290), (350, 290), (100, 50, 50), 3) # 嘴巴 cv2.imwrite('test.jpg', img)

运行这段代码,就会生成一张带模拟人脸的图,确保测试不依赖外部资源。

4.2 修改推理脚本适配本地环境

原仓库的inference.py默认从命令行读参数,我们稍作简化,让它直接加载本地图片。新建一个run_test.py

import torch import numpy as np import cv2 from models.retinaface import RetinaFace from utils.box_utils import decode, decode_landm from utils.nms.py_cpu_nms import py_cpu_nms import time # 加载模型 net = RetinaFace(cfg={'name': 'Resnet50', 'min_sizes': [[16, 32], [64, 128], [256, 512]], 'steps': [8, 16, 32], 'variance': [0.1, 0.1, 0.2, 0.2], 'clip': False, 'loc_weight': 2.0, 'gpu_train': True}) net = net.cuda() net.eval() # 加载权重 checkpoint = torch.load('./weights/Resnet50_Final.pth', map_location='cuda') net.load_state_dict(checkpoint) # 读取图片 img_raw = cv2.imread('./test.jpg', cv2.IMREAD_COLOR) img = np.float32(img_raw) # 预处理:缩放到640x640,归一化 im_height, im_width, _ = img.shape scale = torch.Tensor([im_width, im_height, im_width, im_height]) img -= (104, 117, 123) img = img.transpose(2, 0, 1) img = torch.from_numpy(img).unsqueeze(0) img = img.cuda() scale = scale.cuda() # 推理 with torch.no_grad(): start_time = time.time() loc, conf, land = net(img) # forward pass end_time = time.time() print(f"推理耗时: {(end_time - start_time)*1000:.1f} ms") # 后处理:解码bbox和关键点 priorbox = PriorBox(cfg={'min_sizes': [[16, 32], [64, 128], [256, 512]], 'steps': [8, 16, 32], 'clip': False}, image_size=(im_height, im_width)) priors = priorbox.forward() priors = priors.cuda() boxes = decode(loc.data.squeeze(0), priors.data, cfg['variance']) boxes = boxes * scale / resize scores = conf.squeeze(0)[:, 1] landmarks = decode_landm(land.data.squeeze(0), priors.data, cfg['variance']) landmarks = landmarks * scale / resize # NMS过滤 inds = torch.nonzero(scores > 0.5).squeeze(1) boxes = boxes[inds] landmarks = landmarks[inds] scores = scores[inds] keep = py_cpu_nms(np.hstack((boxes.cpu().numpy(), scores.cpu().numpy()[:, np.newaxis])), 0.3) boxes = boxes[keep, :] landmarks = landmarks[keep, :] scores = scores[keep] # 绘制结果 for i in range(boxes.shape[0]): box = boxes[i].cpu().numpy().astype(np.int32) cv2.rectangle(img_raw, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2) # 绘制关键点 land = landmarks[i].cpu().numpy().astype(np.int32) for j in range(0, 5): cv2.circle(img_raw, (land[j*2], land[j*2+1]), 2, (255, 0, 0), 2) # 保存结果 cv2.imwrite('result.jpg', img_raw) print("结果已保存为 result.jpg")

注意:上面代码中PriorBox类需要从utils.prior_box导入,实际使用时请参考原仓库inference.py的完整导入逻辑。为简洁起见,这里展示核心流程。

4.3 执行测试并查看结果

回到终端,运行:

python run_test.py

如果一切顺利,你会看到类似输出:

推理耗时: 42.3 ms 结果已保存为 result.jpg

打开result.jpg,应该能看到绿色矩形框住人脸,蓝色小圆点标出双眼、鼻尖、嘴角。如果框歪了或关键点偏移,大概率是图片尺寸或预处理参数不匹配,这时回看resize值是否设为640(原模型输入尺寸)。

5. 常见问题与实用技巧

5.1 “CUDA out of memory”怎么办

这是新手最常遇到的错误。根本原因是GPU显存不足。解决方法分三步:

第一,确认没有其他进程占着显存:

nvidia-smi

Processes栏有没有占用GPU的PID,用kill -9 PID结束。

第二,降低输入图片分辨率。原模型支持最大1280x720,但服务器上建议用640x480。修改run_test.py里的resize参数即可。

第三,关闭不必要的日志和调试:

import os os.environ['CUDA_LAUNCH_BLOCKING'] = "0" # 关闭同步模式,提升速度

5.2 检测不到人脸?试试这几个调整

  • 光照太暗:用OpenCV增强对比度:

    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) img_yuv = cv2.cvtColor(img_raw, cv2.COLOR_BGR2YUV) img_yuv[:,:,0] = clahe.apply(img_yuv[:,:,0]) img_raw = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
  • 人脸太小:模型对小于40x40像素的人脸检测率低。可先用双线性插值放大图片:

    img_raw = cv2.resize(img_raw, (0,0), fx=1.5, fy=1.5)
  • 置信度阈值太高:默认0.5可能漏检。把scores > 0.5改成scores > 0.3,再配合NMS阈值调到0.2。

5.3 如何批量处理图片

写个简单的循环脚本batch_infer.py

import glob import os from pathlib import Path # 获取所有jpg/png图片 image_paths = glob.glob('input/*.jpg') + glob.glob('input/*.png') os.makedirs('output', exist_ok=True) for img_path in image_paths: # 复用前面的推理逻辑 img_raw = cv2.imread(img_path) # ...(中间推理代码同上)... output_path = os.path.join('output', Path(img_path).stem + '_out.jpg') cv2.imwrite(output_path, img_raw) print(f"已处理: {img_path}")

把待处理图片放进input/文件夹,运行脚本,结果自动存到output/

6. 性能优化与部署建议

6.1 速度与精度的平衡取舍

RetinaFace有两个主力版本:ResNet50和mobilenet0.25。前者在RTX 3090上约40ms/帧,后者约15ms/帧。如果你的业务对实时性要求高(比如视频流分析),建议换mobilenet版:

wget https://github.com/biubug6/Pytorch_Retinaface/releases/download/1.0/mobilenet025_Final.pth

然后修改模型加载部分:

net = RetinaFace(cfg={'name': 'mobilenet0.25', 'min_sizes': [[16, 32], [64, 128], [256, 512]], ...})

虽然精度略降(WIDER FACE hard set mAP约低1.2%),但速度提升近三倍,对大多数安防、门禁场景完全够用。

6.2 内存占用优化技巧

PyTorch默认会缓存CUDA内存,长期运行可能OOM。在脚本开头加:

import gc torch.cuda.empty_cache() gc.collect()

另外,推理时禁用梯度计算(我们已经用了torch.no_grad()),并把模型设为eval()模式,这两点能省下不少显存。

6.3 部署到生产环境的提醒

  • 不要用Jupyter跑服务:它内存管理不严格,容易泄漏。用纯Python脚本或Flask/FastAPI封装。
  • 设置超时机制:图片太大时,推理可能卡死。用signal.alarm()加超时:
    import signal def timeout_handler(signum, frame): raise TimeoutError("Inference timeout") signal.signal(signal.SIGALRM, timeout_handler) signal.alarm(10) # 10秒超时
  • 日志记录关键指标:每次推理记录耗时、检测人数、置信度均值,方便后续调优。

获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

http://www.cnnetsun.cn/news/1374593.html

相关文章:

  • 妊娠引起的肠道菌群改变驱动巨噬细胞焦亡和脓毒症炎症反应
  • C++类中 函数后面加const 是什么意思
  • MediaPipe TouchDesigner:一站式GPU加速视觉交互系统构建实战
  • 【2026年蚂蚁春招算法岗- 3月19日 -第二题- 文本数值混合特征工程】(题目+思路+JavaC++Python解析+在线测试)
  • Qwen-Image镜像实际效果:多语言混合图文(中英日)理解与统一中文输出
  • 无人机、农机与手机:GNSS相位平滑技术如何悄悄提升你身边的定位体验?
  • 从《2025 AI 应用发展报告》看行业真相:技术落地、产业格局与开发者机遇
  • Qwen3.5-9B GPU部署教程:多卡并行推理与模型分片加载实操详解
  • Nanbeige 4.1-3B实战教程:集成LangChain实现多步骤RPG任务规划与执行
  • Qwen1.5-1.8B GPTQ与Transformer架构解析:从原理到部署
  • Qwen3.5-9B开源镜像快速启动:一行命令完成GPU服务部署
  • 长晶科技推出ZBG系列3W稳压二极管,覆盖6.8V至100V宽电压范围
  • CGAN在图像翻译中的5个惊艳应用:从黑白上色到虚拟换装
  • 一数资源合集(第二辑)
  • 通义千问3-VL-Reranker-8B效果展示:智能排序让搜索更精准
  • 番茄小说下载器技术实现与多平台部署方案
  • 闲鱼运营效率倍增:自动化工具如何重构二手交易管理流程
  • 3秒破解百度网盘提取码:让资源获取从此告别繁琐搜索
  • 中国香港中文大学深圳分校全球首创视频广告植入新技术
  • 嵌入式安全通信生死线,C语言CAN FD协议栈开发必避的8个致命陷阱及FMEA验证清单
  • 基于STM32定时器外部触发模式实现高精度频率测量
  • 保姆级教学:Qwen2.5-0.5B网页版AI助手从部署到对话
  • 别再只盯着GPT了!盘点2024年那些能让你模型更‘听话’的指令调优数据集(附下载与使用心得)
  • 三月七小助手:星穹铁道自动化终极解决方案,解放你的游戏时间
  • 手机拍摄总手抖?这5款AI视频防抖App实测对比(2023最新版)
  • 中微CMS8S3680单片机在电源控制中的实战应用(附完整代码解析)
  • OpenCV实战:基于SIFT与FLANN的指纹识别系统优化
  • 突破单机限制:Nucleus Co-op开源工具实现本地多人游戏自由
  • SSE避坑指南:为什么你的Vue3应用收不到服务端推送?7个常见问题排查
  • nodejs+vue基于springboot的重庆医科大学高校学科竞赛管理系统