☰
MMDetection环境配置与模型训练实战:CUDA与PyTorch版本匹配指南
2026/10/17 4:43:24 网站建设 项目流程

2. 环境准备与版本匹配

MMDetection 的安装,第一道坎往往不是安装本身,而是环境。我见过太多人卡在 import 报错,翻来覆去查不到原因,最后发现是 CUDA 和 PyTorch 版本对不上。所以先把环境这关捋清楚,后面能省一大半的事。

2.1 系统与硬件层面的前置要求

先说结论:Linux 和 Windows 都支持,macOS 只能做 CPU 推理,没法跑 GPU 训练(M 系列芯片虽然能用 MPS 后端,但 MMDetection 对 MPS 的支持并不完整,很多算子会落到 CPU 上,速度优势体现不出来)。我的建议是,如果你想认真做训练,直接上 Linux + NVIDIA 显卡,省心。Windows 下面不是不能跑,但编译一些自定义算子时经常会碰见 MSVC 版本、路径空格这类幺蛾子,我身边好几个同事最后都换到 Ubuntu 了。

硬件方面,显存是一个很现实的问题。拿 COCO 数据集训练时,如果用的输入尺寸是 1333x800,batch size 设为 2,一张 8G 显存的卡跑 Faster R-CNN 都紧巴巴的,更别说 Cascade Mask R-CNN 这种重型模型了。如果你手里是 6G 或者 8G 的卡,建议先从两阶段检测器开始试,或者直接缩小输入尺寸、降低 batch size,先把流程跑通再追求精度。

2.2 Python 版本解析

MMDetection 的依赖链是:MMDetection 依赖 MMEngine 和 MMCV,MMCV 又依赖 PyTorch。这条链条里任何一个版本不匹配,都会在运行时冒出一堆莫名其妙的报错。

先说结论:Python 建议用 3.8 到 3.10。3.7 太老,很多新版本依赖已经不提供对应的 wheel 包了;3.11 以上则可能因为某些算子库没跟上而导致安装失败。我建议直接新建一个虚拟环境,别偷懒:

conda create -n openmmlab python=3.8 -y conda activate openmmlab

注意:如果你用的是公司内网或者服务器,没有外网权限,conda 创建环境时可能会卡在 Solving environment 这一步,这时候可以换成python -m venv配合 pip 使用,或者配置好内网镜像源再操作。

2.3 CUDA 与 PyTorch 版本匹配的黄金法则

这一节是整个安装过程中的重中之重。简单来说:PyTorch 的 CUDA 版本必须和驱动支持的 CUDA 版本兼容,但这里有个常见的误区,很多人以为驱动要装带 CUDA Toolkit 的那个版本。其实驱动本身就是兼容的,关键看 PyTorch 编译时用的 CUDA 版本。

用nvidia-smi查看驱动支持的 CUDA 版本,比如显示CUDA Version: 12.1,那说明你的驱动最高支持 CUDA 12.1。这时你就完全可以装 CUDA 11.8 或 12.1 的 PyTorch 轮子。举个例子:

# 查看驱动版本 nvidia-smi # 输出示例: # NVIDIA-SMI 525.85.12 Driver Version: 525.85.12 CUDA Version: 12.1

然后安装对应 PyTorch:

# CUDA 11.8 版本 pip install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cu118 # CUDA 12.1 版本 pip install torch==2.1.1 torchvision==0.16.1 --index-url https://download.pytorch.org/whl/cu121

这里有个实测经验:MMDetection 3.x 支持 PyTorch 1.8 到 2.x,但推荐 1.13 以上。PyTorch 太旧的话,很多新出的 CUDA 算子编译不过去,反而拖慢进度。

2.4 用一张表理清 MMCV 全家桶的关系

MMDetection 3.x 之后,官方把原来的 MMCV 拆成了两块:MMCV 和 MMEngine。很多人第一次装的时候,看到mmcv-full和mmcv两个名字直接懵掉。

这张表可以直接保存下来:

组件名作用安装方式
MMEngine训练、验证、日志、钩子等基础框架pip install mmengine
MMCV计算机视觉底层算子,如 NMS、RoIAlign、Deformable Convpip install mmcv -f 对应链接
MMDetection检测模型库,真正写代码时 import 的对象pip install mmdet

注意:这里建议装mmcv而不是mmcv-full。在 2.x 时代装的是mmcv-full,3.x 时代统一叫mmcv,不需要再区分-full后缀。如果你在网上查到的教程是 2023 年之前的,用的多半是mmcv-full,那份教程很可能已经过时了。

MMCV 的安装建议用官方预编译轮子,避免本地编译。本地编译 MMCV 极慢,我见过一台 8 核机器编译了整整一个半小时,最后还失败的情况。

pip install mmcv -f https://download.openmmlab.com/mmcv/dist/cu118/torch2.0/index.html

以上链接的写法要对应你实际的 CUDA 和 PyTorch 版本。如果版本对不上,编译时你会看到类似Undefined symbols的报错,查半天都不一定能定位到。

3. MMDetection 本体安装的完整流程

环境准备好以后,MMDetection 的安装就很简单了。但为了照顾第一次接触 OpenMMLab 生态的朋友,我还是按完整步骤来写,每一步都说明为什么这样做。

3.1 从源码安装还是 pip 安装

MMDetection 官方提供两种方式:

  • pip install mmdet直接安装稳定版,适合只想调用现成模型做推理的用户
  • 从 GitHub 拉源码git clone后运行pip install -v -e .可编辑安装,适合要改核心代码、加自定义模型或 debug 源码的用户

我的建议是:入门阶段直接 pip 安装即可。因为 MMDetection 的复现能力已经很强,写训练脚本时只需要改配置文件,基本用不着动源码。等到后面你要自定义 head、加 loss 或者改 hook 时,再换成源码安装也不迟。

如果你还是想用源码安装,步骤是:

git clone https://github.com/open-mmlab/mmdetection.git cd mmdetection pip install -v -e .

这里-e表示可编辑模式,即源码改了什么,import 时立刻生效,不用重新装一遍。这个模式在开发时的体验非常好,我常用它来给模型加自定义 loss,改完直接重新跑训练就行。

3.2 验证安装是否成功的三个命令

很多教程教你装完以后python -c "import mmdet",只要不报错就算成功。但说实话,这种验证太粗糙了。至少应该做到以下三步:

# 第一步:确认 import 成功 python -c "import mmdet; print(mmdet.__version__)" # 第二步:确认 mmcv 和 torch 版本匹配 python -c "import mmcv; print(mmcv.__version__)" # 第三步:确认 CUDA 环境可用 python -c "import torch; print(torch.cuda.is_available())"

第三步尤其重要。很多人 import 全部正常,一跑训练就报CUDA error: no kernel image is available for execution on the device,原因就是 PyTorch 编译时的 CUDA 版本高于驱动所支持的版本。如果torch.cuda.is_available()返回False或报错,不要继续往后走,回头检查驱动和 PyTorch 版本。

提示:在 Linux 服务器上,用nvidia-smi和python -c "import torch; print(torch.version.cuda)"对比两个 CUDA 版本号,是最快的排查方法。

3.3 一个最小推理 Demo

装完之后,为了确认整个链路真的通了,我最喜欢跑一个官方自带的推理脚本。不需要训练权重,直接用demo目录下的脚本和预训练模型就能测出来:

python demo/image_demo.py demo/demo.jpg configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py \ --weights https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \ --device cuda:0

注意上面的模型权重链接用了 2.x 时代的旧地址,在 3.x 版本里已经失效了。正确做法是去 Model Zoo 页面下载对应的.pth文件,或者直接用官网脚本里的默认链接。如果链接失效,可以在终端里看到 HTTP 404 的报错,这会浪费你不少时间。

如果推理脚本跑起来以后,能看到一张标注好检测框的图片,那环境就是真的通了,可以进入下一步:跑训练流程。

4. 实操环节:如何运行一次完整的训练

到这里,你的 MMDetection 已经能跑推理了。但装环境的意义往往是为了训练自己的数据集,这一步也是很多人最容易卡住的地方——不是环境问题,而是数据集格式和配置文件的问题。我来拆开讲。

4.1 数据集目录结构

MMDetection 的训练数据用的是 COCO 格式,这是目标检测领域最通用的标注格式。即使你手里的数据不是 COCO 标准,也得先转成这个格式。

一个标准的 COCO 格式数据集目录长这样:

data/ ├── coco/ │ ├── annotations/ │ │ ├── instances_train2017.json │ │ └── instances_val2017.json │ ├── train2017/ │ │ ├── 000000000001.jpg │ │ └── ... │ └── val2017/ │ ├── 000000000042.jpg │ └── ...

如果你用的是自定义数据集,我建议直接用一些标注工具导出 COCO 格式,而不是自己手写 JSON。手写标注文件很容易在类别 id 上出错,比如 COCO 的类别 id 从 1 开始计数,而很多工具的背景类别是 0,一个不留神就会导致训练 loss 直接崩到 NaN。

4.2 配置文件的关键参数解读

MMDetection 的核心玩法就是改配置文件。以faster-rcnn_r50_fpn_1x_coco.py为例,你需要关注以下内容:

  • num_classes:必须改成你自己的类别数。如果是单类目标检测,这里要填 1;如果是 3 类,就填 3。注意背景类不算在里面。
  • data_root:指向你的数据集目录,比如/home/user/data/coco。
  • batch_size:samples_per_gpu这个参数代表每张卡每步训练的图片数。显存不够就调小,比如 2、1。
  • max_epochs:1x约等于 12 个 epoch,代表 12 个 epoch 的训练进度计划。如果数据量小,可以改成20x或50x,但要注意学习率调整策略也要一并改,否则后期 loss 难收敛。

这里有个新手常踩的坑:只改了num_classes,忘了改模型 head 中的num_classes。在 MMDetection 3.x 中,这个参数分散在多个地方,比如roi_head里的bbox_head和mask_head(如果是 Mask R-CNN)。最好的办法是在配置文件里用_base_继承后,重新model = dict(roi_head=dict(bbox_head=dict(num_classes=你的类别数))),这样能一次性覆盖所有 head 的类别数。

4.3 训练命令与日志观察

配置改好以后,训练命令本身很简单:

python tools/train.py configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py

但要真正判断训练是否正常,你需要观察几个关键指标:

  • loss_rpn_cls:RPN 分支的分类损失,正常来说应该逐步降低。
  • loss_cls:最终检测头的分类损失。
  • loss_bbox:回归损失。如果这个值突然变成inf或者NaN,基本可以断定是学习率过大,或者标注框出现了 0 尺寸(比如某个 bounding box 的宽或高为 0)。
  • lr:每轮迭代打印的学习率,确认它是按照调度策略在变化。

日志里如果出现nan或inf,第一反应不是调参,而是检查数据:用可视化脚本把标注画到原图上,看看是不是有错标。我处理过不下 5 次 NaN loss 的问题,最后原因全是标注文件有脏数据。

4.4 测试与评估

训练完成后,出一张 mAP 报告是必须的:

python tools/test.py configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py \ work_dirs/faster-rcnn_r50_fpn_1x_coco/epoch_12.pth \ --eval bbox

--eval bbox会输出 COCO 格式的 AP 结果,包含AP@IoU=0.50:0.95、AP@IoU=0.50、AP@IoU=0.75等指标。如果你自己的任务对定位精度要求高,可以重点看AP@IoU=0.75;如果只关心粗定位,看AP@IoU=0.50就够了。

5. 常见问题与排查技巧实录

这一部分是我个人实际踩坑的总结,很多问题看起来不复杂,但解决起来绕了远路。统一整理成速查表,方便你直接对照排查。

5.1 问题速查表

现象可能原因解决方案
ModuleNotFoundError: No module named 'mmcv'MMCV 未安装,或安装在别的环境检查当前环境pip list,重新安装 mmcv 对应版本
ImportError: cannot import name 'Config' from 'mmcv'MMCV 版本过旧,还在 1.x 时代升级到最新版 mmcv,或者改用 mmengine 中的 Config
CUDA error: no kernel image is availablePyTorch 的 CUDA 版本高于驱动支持版本降低 PyTorch 的 CUDA 版本,或升级显卡驱动
RuntimeError: Attempting to deserialize object on a CUDA device加载了 GPU 训练的权重到 CPU 环境加载权重时加map_location='cpu'
训练时 loss 为 NaN标注有脏数据、学习率过大、BN 的 momentum 过小可视化检查标注,降低 lr,或改momentum为0.01
安装过程卡死,pip 长时间无响应网络问题,或者本地编译 MMCV 太慢换镜像源,或直接用预编译的 MMCV 轮子

5.2 多卡训练时常见的坑

多卡训练是很多刚上手的人容易出问题的地方。首先要保证启动命令带了CUDA_VISIBLE_DEVICES指定可见的卡号:

CUDA_VISIBLE_DEVICES=0,1,2,3 bash tools/dist_train.sh configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py 4

这里4是卡的数量,不是卡编号。如果你只有 2 张卡,就写2,否则进程会一直等不到足够的卡。

另一个多卡训练常遇见的坑是:每张卡的 batch size 和总 batch size 的关系。配置文件里的samples_per_gpu是单卡的值,总 batch size =samples_per_gpu * 卡数。如果你想让总 batch size 保持 8,用 4 卡训练,samples_per_gpu就设成 2;用 2 卡训练,samples_per_gpu就设成 4。学习率需要根据总 batch size 适当调整,一般线性缩放,但我见过很多人直接用默认 lr 也不出问题,因为 COCO 上的 0.02 本来就是一个相对保守的值。

5.3 到底要不要编译 CUDA 算子

很多人在安装 MMCV 时会纠结要不要用MMCV_WITH_OPS=1编译算子。我的经验是:能不用就不用。预编译轮子已经覆盖了绝大多数常用算子,如nms、roi_align、deformable_conv2d等。只有当你用了官方预编译没覆盖的 CUDA 算子或者自定义算子时,才需要本地编译。

如果你确实需要编译,务必注意两点:

  • 确保当前环境能访问到nvcc,即 CUDA Toolkit 真的装了
  • 编译前不要忘了设置环境变量FORCE_CUDA=1,否则可能出现“看起来编译了,实际上没用 GPU”的情况

编译过程中如果看到fatal error: cuda_runtime_api.h: No such file or directory,说明 CUDA 路径没找到,可能需要手动指定:

export CUDA_HOME=/usr/local/cuda

5.4 我踩过的三个隐蔽的坑

最后聊三个不太容易排查、但一旦遇上非常折磨人的问题。

第一个是配置文件缓存问题。MMDetection 3.x 在跑过一次训练后,会在work_dirs里生成一个并合并过的完整配置存档。当你后续改了_base_里的配置,再跑tools/train.py时,如果用法不当,可能没真正用上你的新配置,而是还在用缓存。解决方法是训练前删掉work_dirs下的旧文件,或者看一眼终端日志里打印出来的配置是不是你预期的那份。

第二个是路径分隔符在 Windows 下的表现。如果你在 Windows 上跑,配置文件里的路径最好统一用正斜杠/或者用os.path.join生成,别直接在 .py 里拼反斜杠,不然会在mmcv底层路径处理时报No such file or directory。

第三个是预训练权重自动下载太慢。每次修改模型结构重新训练时,MMDetection 默认会自动下载对应骨干网络的 ImageNet 预训练权重。如果网络不好,会一直卡在下载环节。我的做法是提前手动下载好.pth文件,然后在配置文件里指定:

model = dict( backbone=dict( init_cfg=dict(type='Pretrained', checkpoint='/path/to/resnet50-19c8e357.pth')))

这样不仅快,还能避免服务器没外网权限时反复超时的窘境。

6. 基于实际场景的选型建议

聊完安装和训练,再补充一点我自己在实践中总结的选型经验。经常有人问:好不容易装好了,到底该跑哪个模型?这里给几类典型需求做个简单对照。

6.1 轻量级部署场景选型

如果你是要部署到边缘设备、手机端或者嵌入式平台,那重量级的 Cascade R-CNN 肯定不合适。我建议优先考虑:

  • RTMDet:MMDetection 3.x 主推的实时检测模型,部署友好,精度和速度的平衡点非常好。
  • YOLOX:如果你更熟悉 YOLO 系列,MMDetection 里也有 YOLOX 的实现,能直接复用这套训练和部署链路。
  • FCOS:单阶段无锚框检测器,结构简洁,训练速度也快。

这些模型在 COCO 上的精度可能不如两阶段大模型,但部署时的推理速度和显存占用优势非常明显。

6.2 高精度场景选型

如果对精度要求极高,不关心速度,优先考虑:

  • Cascade Mask R-CNN:级联结构能逐步提升 IoU 阈值,在高 IoU 指标上有明显优势。
  • DINO:基于 DETR 系列的最新成果,在 COCO 上刷新过不少次 SOTA,但对显存和训练时间的要求也更高。
  • Mask2Former:如果你同时要做实例分割和全景分割,这个模型在统一框架上做得非常好。

这些模型的训练时间通常以天为单位,需要你有足够的 GPU 资源和耐心。

6.3 实际项目里我常用的一个组合

下面给一个我实际做项目时的经验组合,供参考:

任务:工业质检中的缺陷检测 数据类型:单类缺陷,小目标,2000张图 推荐配置: 模型:RTMDet-s backbone:默认 训练:50 epoch,batch size 8(需要在多卡或大显存下) 增强:随机翻转 + 多尺度训练(scale jitter) 部署:TensorRT FP16

这个组合在速度和精度上比较均衡,单卡的 8G 显存也能跑得动,适合快速验证和项目交付。

7. 写在最后的实际体会

装 MMDetection 这件事,看起来只是敲几行命令,但背后藏着版本依赖和深度学习环境管理的整个逻辑。我当年第一次装的时候,也经历过编译到凌晨、报错到怀疑人生的阶段。后来总结出两个最简单有效的原则:一是所有东西都尽量用官方预编译版本,二是每次只变更一个版本变量。

如果你在安装过程中卡住了,不要急着搜报错原文,先用pip list把当前环境里的核心包版本全部查一遍,对照一下 torch、mmcv、mmdet、mmengine 的版本关系。一般来说,90% 的问题都能在这一步定位到。剩下的 10%,再去看官方文档的 Issue 区或者 FAQ,基本都能解决。

另外一个小技巧,安装完以后,不管最后跑成什么样,都建议把环境用conda env export > environment.yaml导出一份。这样就算以后换机器,也能用一份文件把环境完整还原回来。这个习惯救了我不止一次。

如果你接下来准备训练自己的数据集,我的建议是从一个超小型的 Demo 数据开始,哪怕是 10 张图,先跑通整套流程,确认数据格式、标签、评估环节都没问题,再上全部数据。很多问题在 10 张图上暴露出来,远比你在 5000 张图上折腾一整天要划算得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询