从“装不上”到“跑通demo”:MMDetection 完整安装手记(环境篇)
如果你照着网上某些教程装 MMDetection,大概率会在某个pip install的瞬间开始怀疑人生:报错一个接一个,版本对不上,编译不过去,好不容易装上又在 import 的时候崩了。这套框架本身很强大,但安装门槛也确实劝退了不少刚开始接触目标检测的人。
这篇文章是我自己反复装环境之后整理出来的完整笔记。不是那种“复制粘贴三行命令就算完事”的教程,而是把整个安装链路拆开讲清楚:为什么需要这样装、哪些环节最容易翻车、不同安装方式分别适合什么情况、以及我在多台机器上踩过的坑和最终的排查流程。如果你正在准备做目标检测相关的项目,或者只是想先把手里的 GPU 机器变成能跑 demo 的测试环境,这篇应该能帮你少走不少弯路。
1. 别急着动手装:先搞清楚 MMDetection 的依赖链路
MMDetection 不是孤零零的一个包,它下面挂着三样东西:PyTorch、MMCV 和(如果你要训练模型)各种各样的后端算子。这三者之间存在严格的版本配套关系,装错一个,后面全盘皆输。很多人上来就pip install mmdet,结果要么编译报错,要么import mmcv的时候直接给你吐一屏红字。这不算你操作有问题,而是没有理解这条依赖链。
先说最底层的 PyTorch。MMDetection 是跑在 PyTorch 之上的,PyTorch 的版本又由你的 CUDA 驱动和 Python 版本决定。这三个东西层层嵌套,形成了一个"版本锁链"。官方文档里给出的支持范围大概是 Python 3.7 以上、PyTorch 1.6 到 2.x 不等。但你要注意,"支持"和"跑得顺"是两回事,我实测下来最省心的组合是 Python 3.8 或 3.10、PyTorch 1.13 或 2.1、MMCV 2.x 对应的配套版本。这个组合在编译算子和跑训练时都比较稳,问题最少。
然后是 MMCV。它分两个大系列:老的mmcv-full和新的mmcv(2.x 版本之后不再区分-full,直接叫mmcv)。MMDetection 3.x 依赖的是新版 MMCV,所以网上那些还教人装mmcv-full的教程基本都过时了。MMCV 的作用是把很多高频的 CUDA 算子预编译好,比如 NMS、ROIAlign、deformable conv 等等。如果 torch 和 CUDA 版本不匹配,MMCV 装不上,MMDetection 导入时就会报ModuleNotFoundError: mmcv或者干脆是RuntimeError: undefined symbol。
这套链路里还有一个经常被忽略的点:nvidia-smi显示的 CUDA 版本和实际运行时的 CUDA 版本不是一回事。前者是显卡驱动支持的 CUDA 最高版本,后者是 PyTorch 在编译和运行时使用的 CUDA 运行时版本。很多人在nvidia-smi里看到 CUDA 12.2,就觉得"那我应该装 CUDA 12.2 的 PyTorch",这是没有必要的——你真正需要匹配的是 PyTorch 编译时用的 CUDA 版本,而这个完全可以通过装驱动时附带的运行时版本来满足。通俗点说,显卡驱动是"地基",PyTorch 自带的那套 CUDA 工具库是"楼层",楼层只要不超过地基的承重上限就行,不需要完全一致。
这一节想强调的就一个核心观点:MMDetection 安装成功与否,九成取决于你 PyTorch 和 MMCV 有没有形成配套关系,而不是取决于你翻了哪个教程、用了哪条命令。版本匹配搞清楚了,后面所有步骤都会非常顺。
2. 环境准备:Python、CUDA 驱动与 PyTorch 的版本匹配公式
2.1 先摸清你机器上的底牌
动手装之前,我建议你先在终端里敲几条命令,把家底盘清楚:
nvidia-smi # 查看显卡驱动版本和最高支持的 CUDA 版本 python --version # 查看当前 Python 版本 conda --version # 确认 conda 是否可用如果你和我一样习惯用conda管理环境,那么建议专门为 MMDetection 新建一个环境,不要图省事装在 base 里。不同项目对 PyTorch 版本的要求可能不一样,把环境隔离好可以避免"改一个项目、炸掉另一个项目"的惨剧:
conda create -n mmdet python=3.10 -y conda activate mmdetPython 版本我推荐 3.10。为什么不是最新的 3.12?因为目前很多配套库(尤其是一些老版本 MMCV 依赖的编译工具)对 3.12 的支持还不完善,而 3.8 又稍微老了一点,3.10 刚好处于一个中间态,兼容性和性能都能兼顾。
2.2 PyTorch 选型:用官方命令,别用默认源
PyTorch 的安装是整个环境里最关键的一步,也是最容易出问题的一步。如果直接用pip install torch,大概率会从 PyPI 默认源装到 CPU 版或 CUDA 版本较低的一个,导致 GPU 完全用不上。正确做法是到 PyTorch 官方网站生成与你机器匹配的安装命令,你只需要选好操作系统、包管理器(pip 或 conda)和 CUDA 版本。
这几条是我在多台机器上实测比较稳的组合,整理成表格方便你对照选型:
| 显卡驱动支持的 CUDA 版本 | 推荐 PyTorch 版本 | 配套命令示例 |
|---|---|---|
| 11.7 及以上 | 1.13.1 | pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 --extra-index-url https://download.pytorch.org/whl/cu117 |
| 11.8 及以上 | 2.0.1 | pip install torch==2.0.1+cu118 torchvision==0.15.2+cu118 --extra-index-url https://download.pytorch.org/whl/cu118 |
| 12.1 及以上 | 2.1.2 | pip install torch==2.1.2+cu121 torchvision==0.16.2+cu121 --extra-index-url https://download.pytorch.org/whl/cu121 |
装完之后立刻验证一下 GPU 环境是否正常:
python -c "import torch; print('t_cuda:', torch.__version__); print('cuda_available:', torch.cuda.is_available()); print('device_name:', torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'CPU')"看到cuda_available: True,说明 PyTorch 已经能正常调用 GPU。如果这里就是False,多半是 PyTorch 选型错了或者驱动版本不对,赶紧回头修,别急着往下走——这一步不通过,后面 MMDetection 永远装不好。
2.3 一个容易被绕进去的坑:nvcc 和 nvidia-smi 版本对不上
这是个很经典的问题。装 PyTorch 的过程中,你可能会发现nvcc -V显示的 CUDA 版本和nvidia-smi显示的不一样,就开始怀疑是不是装错了。实际上这很正常:nvidia-smi显示的是显卡驱动支持的最高 CUDA 版本,本质是"驱动的一个属性";而nvcc显示的是你当前环境里有没有安装 CUDA 工具包、装的是哪个版本。PyTorch 自带 CUDA 运行时,不依赖全局的 CUDA 工具包,所以哪怕你没有单独安装 CUDA,只要驱动版本够新,PyTorch 依然能正常跑 GPU 运算。看到版本号不一样,不用慌。
3. 从 pip 到源码编译:三种安装方式的完整对比与实测
3.1 用 mim 安装:最省心、官方推荐
MMDetection 官方现在最推荐的方式是用mim(OpenMMLab 家的一站式安装工具)。这个工具会自动帮你检查并安装匹配的 MMCV 版本,省掉了很多手动对版本的步骤:
pip install openmim mim install mmengine mim install mmcv mim install mmdet注意这里的顺序:先mmengine(这是新版 MMDetection 的运行底座,负责配置解析、模型注册、日志等基础设施),再mmcv,最后mmdet。虽然文档上写了可以一行mim install mmdet直接让依赖自动带上,但实践下来,分开装每一步更可控,出了问题也容易定位。
mim的好处是它会自动看当前 Python 和 PyTorch 环境,从预编译的 whl 包里找到匹配的版本,基本不需要本地编译,速度很快。我给它打九十分,扣掉的十分是因为它对网络环境要求比较高,部分镜像源如果配置不当,还是会拉取到错误版本。
3.2 直接 pip install:可行,但要注意依赖解析的脾气
如果你不想用mim,用 pip 也是可以的,但需要手动指定 MMCV 的版本,否则 pip 有可能给你装一个太新的 MMCV,导致冲突。我推荐的命令组合:
pip install mmengine pip install mmcv==2.1.0 -f https://download.openmmlab.com/mmcv/dist/cu121/torch2.1/index.html pip install mmdet-f后面的链接指向 MMCV 预编译包的索引页,告诉 pip 去哪里找对应 CUDA 和 torch 的编译版本。这个索引页是分版本管理的,你需要根据自己的 PyTorch 版本去调整路径。比如 PyTorch 2.0.1 加 CUDA 11.8 就对应cu118/torch2.0。这种方式的好处是更透明,你能明确知道装的是哪个版本的 MMCV。
不过 pip 有一个脾气:它倾向于解析出"当前环境下所有包都兼容"的方案,有时候会自作主张把 torch 降级或者升级。所以我强烈建议在虚拟环境里操作,而且装完第一步、验证完 GPU 之后再装第二步。
3.3 源码编译:什么时候才需要走这一路
以源码方式安装的适用场景很明确:你需要修改 MMDetection 或 MMCV 的源代码。比如做学术研究时想自己改一个算子、调试某个模块内部逻辑,或者你需要某个最新特性但官方版本还没发正式包。
源码安装的步骤是:
git clone https://github.com/open-mmlab/mmdetection.git cd mmdetection pip install -v -e .-v是开启详细日志输出,-e是开发模式,这样你对源码做的改动会即时生效。但源码编译会触发编译器去构建一些自定义算子,所以你的机器上得有可用的 C++ 编译环境(Linux 上一般自带 gcc,Windows 需要装 Visual Studio 的编译工具链),整个过程耗时也比较长。
我的建议是:不要一上来就源码安装。先用mim或 pip 把环境跑通,确认 demo 能出结果;确认你需要动源码了,再拉源码编一次也不迟。反过来,要是第一步就编译失败,排查的问题会非常复杂,新手很容易直接崩溃。
4. 安装只是开始:验证安装和跑通第一个 Demo 的完整过程
4.1 环境自检三步法
装完之后,先不要急着跑训练,按下面的顺序做个三步自检:
第一步,确认 MMDetection 能正常导入:
python -c "import mmdet; print('mmdet_version:', mmdet.__version__)" python -c "import mmcv; print('mmcv_version:', mmcv.__version__)" python -c "import mmengine; print('mmengine_version:', mmengine.__version__)"第二步,确认 MMCV 的 CUDA 算子能被调用。这一步很多人会漏掉,因为import mmcv成功不代表 CUDA 算子没有问题:
python -c "from mmcv.ops import nms; import torch; boxes = torch.tensor([[1,1,3,3],[2,2,4,4]], dtype=torch.float32).cuda(); scores = torch.tensor([0.9, 0.8], dtype=torch.float32).cuda(); print(nms(boxes, scores, iou_threshold=0.5))"如果能正常打印出结果,说明 NMS 这类基础算子在你的 GPU 上可以运行,MMCV 这一层算是通了。如果这里报undefined symbol或加载错误,回忆一下是不是 PyTorch 和 MMCV 版本没有配套,直接去装对应的 MMCV 版本。
第三步,下载官方预训练模型并跑一次推理。这一步能验证完整链路:
mim download mmdet --config 对应配置文件 --dest ./checkpoints python demo/image_demo.py 测试图片路径 对应配置文件 --weights 权重路径 --device cuda:0要注意的是,官方 demo 脚本支持中文路径可能有问题,建议测试图片和输出目录都用纯英文路径。好记性不如烂笔头,我把这三步经常会遇到的问题和对应排查方向整理成表格,存着以后方便查:
| 检查项 | 报错特征 | 常见原因 | 排查方向 |
|---|---|---|---|
import mmdet | No module named mmdet | 没装成功或装错环境 | 检查当前 conda 环境名、pip list 是否能看到 mmdet |
from mmcv.ops import nms | CUDA error: no kernel image | PyTorch 和 MMCV 的 CUDA 版本不对 | 重装与 torch 匹配的 MMCV 版本 |
demo/image_demo.py | KeyError: 配置字段不存在 | mmdet 版本与配置文件的版本不匹配 | 用mim download自动下载配套配置 |
| demo 推理 | 显存不足 OOM | 默认 batch 配置太高或没有指定 GPU | 在命令里加--device cuda:0,必要时减小输入图片尺寸 |
4.2 第一次跑居然就爆显存,别慌
我第一次跑 demo 的时候,挑了一张 1080p 的街景图,结果直接CUDA out of memory。后来发现是因为 demo 脚本默认用了 batch size 为 1,而口罩检测这类模型在推理时如果开启了很多后处理分支,显存开销会被放大。解决办法很简单:换一张小图,或者加--max-num参数限制实例数量,实在不行就先把图片缩放后再输入。这个不算 bug,更多是配置和资源的不匹配。
跑通了 demo,你会看到终端输出一张标了检测框的图片。到这一步,你的安装才算真正闭环了。后面的操作,无论是训练自己的数据还是调参,都是在这个基础上展开的。
5. 四种高频报错的全链路排查:从现象到根因,不是直接换命令
5.1 场景一:编译到一半出现ninja: build stopped: subcommand failed
这种报错在源码安装和手动装 mmcv 时尤其常见。乍看之下是 ninja(一个编译加速工具)的问题,但根因往往不是 ninja 本身,而是某个算子源码编译失败。最常见的原因是 GPU 算力太低,例如老旧的架构,新版 PyTorch 和 MMCV 已经抛弃了对它的支持。
排查链路是这样的:
- 先看完整报错,不要看最后一行就完事。往上翻,找到第一个红色或者
error:开头的行,那里才写着真正的编译错误。 - 如果是
Unsupported gpu architecture 'compute_XX',说明显卡架构太老,需要手动指定编译参数,把TORCH_CUDA_ARCH_LIST环境变量改成你显卡对应的算力,比如 7.5 或 8.6。 - 如果错误是缺头文件,说明系统缺少依赖,需要先装
ninja-build gcc g++这些编译工具。 - 如果前面都查不出问题,那就把预编译包拿过来用,绕开源码编译这条路。
5.2 场景二:ModuleNotFoundError: No module named 'mmcv._ext'
这是最经典的 MMCV 报错之一,基本可以锁定为 MMCV 安装方式不对。MMCV 的官方 whl 包分为 CPU 版和 GPU 版,如果你在用 GPU 训练时命令里带上了+cpu的包,那么import时就会报缺少 CUDA 扩展。
排查链路:先执行pip show mmcv,看它安装的版本号里是否带+cpu。如果是,卸载后重装指定 CUDA 版本的包。另外,MMDet 对 MMCV 的版本只接受全量版,不接受 CPU 版。这是新手非常容易踩的坑,也是我把mim放在首选位置的原因:mim会根据当前 torch 的 CUDA 类型自动选对应的包。
5.3 场景三:下载模型权重一直超时或速度极慢
这不是安装环境的问题,而是网络带宽和源站所在地的锅。官方权重文件托管在海外服务器上,国内访问时经常会出现超时。之前帮一个同学排查,他下载mask_rcnn的权重整整挂了三个小时,最后报错超时,心态直接崩了。
排查链路:
- 优先检查文件名是否完整,权重文件是否存在。
- 如果下载不动,果断换思路:用
mim download配合--dest参数,让工具帮你处理下载逻辑,它内部带了重试和断点续传能力。 - 再不行就找一个网络情况更好的时段,或者在代码层面用
load_from指定本地路径,先跳过下载步骤完成验证。
5.4 场景四:ImportError: libGL.so.1: cannot open shared object file
这个报错经常出现在运行 demo 的时候,因为很多后续的图像处理会用到 OpenCV 的底层库,而某些精简版的系统镜像里缺少libgl相关的共享库。这是系统依赖缺失,不是 Python 包的问题。
解决办法是补齐系统依赖,或者在虚拟环境里安装opencv-python-headless这种不需要图形界面的版本,替换掉opencv-python。如果你只需要跑推理和训练,不涉及实时显示,用 headless 版本更省心。如果你需要在服务器上做可视化(比如把检测结果画在图片上),那最好同时装libgl1和libglib2.0-0。
6. 装好之后的工作目录规划与常用命令备忘
6.1 目录怎么安排
环境装好只是第一步,真正让开发效率提高的是目录规划。我现在在每台新机器上都会保持一套统一结构:
~/workspace/mmdetection/ ├── checkpoints/ # 存放预训练权重 ├── configs/ # 存放实验配置文件 ├── data/ # 数据集软链接或实际文件 ├── work_dirs/ # 训练输出,日志、权重、可视化结果 └── tools/ # 自己写的辅助脚本为什么要单独建checkpoints目录?因为 MMDetection 在训练时会根据配置文件里的load_from参数去加载预训练权重,而权重文件通常很大,不能放在项目目录里随代码反复拷贝。用软链接把数据集和权重指到固定位置,可以避免多项目之间重复复制大文件。
6.2 常用的几条命令,存进备忘录
- 训练模型:
python tools/train.py 配置文件 --work-dir work_dirs/experiment_name - 测试模型:
python tools/test.py 配置文件 权重路径 --out results.pkl - 推理单张图片:
python demo/image_demo.py 图片 配置文件 权重路径 - 查看模型参数量和计算量:
python tools/get_flops.py 配置文件
配置文件是一切的核心,改参数之前最好先复制一份,不要直接在屋主的文件上动刀。我在刚开始做实验的时候,经常因为改了原配置忘了备份,结果后面所有实验都共用了同一份被篡改的配置,alias 都没人分辨得出来。
6.3 为下一回做准备:数据集格式与标注格式
很多人装完环境、跑通 demo 之后,会想马上用自定义数据集训练。这里提前打个预防针:MMDetection 的数据集格式是 COCO 格式或自定义的标注格式,你需要提前把标注文件转换好。不要等到训练的时候才去查格式文档,那就来不及了。
这篇先聊到环境这里,下一步的内容就可以直接进入数据集准备和自定义模型的训练流程,到时候我们再继续往深处挖。如果你在安装阶段卡住了,照着前面说的排错思路一步步走,应该都能解决;实在不行,把完整报错信息复制出来逐行看,往往谜底就在谜面上。