最近有个朋友找我吐槽,说mmdet3d环境配置折腾了他整整两天,最后在一堆“CUDA版本不对”“mmcv编译失败”的报错里差点把电脑重装了。我说这太正常了,这个工具箱的依赖链有点长,PyTorch、mmcv、mmdet、mmseg、mmdet3d,一串名字看着就头大,版本之间还互相卡脖子,配环境的时间经常比跑模型的时间还长。
这篇内容就是来帮你把这段弯路走直的。我会以一套我自己实测过的组合为例,把 mmdet3d 环境配置从头到尾讲清楚——包括为什么要按这个顺序装、版本怎么匹配、装完怎么验证、跑 demo 报错怎么排查。适合正准备入坑 3D 目标检测、被环境折磨得想弃坑的同学,也适合已经配好环境但想了解背后版本逻辑、避免以后升级踩雷的朋友。
1. 动手之前,先把版本匹配这件事想明白
1.1 mmdet3d 依赖了什么
先搞清楚我们到底在装什么。mmdet3d 是 OpenMMLab 系列下的 3D 目标检测工具箱,主打自动驾驶场景里的点云检测、单目 3D 检测、多模态检测这些任务。它的定位是“3D 检测的集成框架”,常用算法比如 PointPillars、SECOND、CenterPoint、PV-RCNN 都有官方实现,预训练权重也齐全,拿来跑实验和复现论文都很方便。
但它不是孤零零的,整个 OpenMMLab 家族是一套层层嵌套的结构:
- PyTorch 是地基,负责张量计算和 GPU 加速;
- mmcv-full / mmcv 是核心库,提供所有 OpenMMLab 项目公用的底层组件,比如 I/O 操作、自定义算子、训练回调;
- mmdet 是 2D 检测库,mmdet3d 里很多 2D 相关的网络结构、检测头直接复用它的实现;
- mmseg 是分割库,部分多任务模型或多模态融合方案里会用到;
- 最后才是 mmdet3d 本身。
中间的 mmdet 和 mmseg 相当于“桥梁”,把 mmcv 的能力翻译成检测和分割任务能用的模块。所以这些包的版本必须放到一起看,单独升级任何一个都可能把整条链搞崩。
1.2 版本矩阵:别信“最新版”,信“配套版”
说到版本匹配,这是 mmdet3d 环境配置里最劝退的地方,也是最值得先说清楚的。不同时期的 mmdet3d 对 PyTorch 和 mmcv 的要求完全不同,用错组合最常见的表现是:安装全部成功、import 也不报错,但一跑训练就提示算子不存在,或者直接 CUDA error。
我按自己的实践分成两个典型配置档位,都是验证过的组合:
| 组件 | 旧版稳定组合(推荐新手) | 新版组合(功能更全) |
|---|---|---|
| 操作系统 | Ubuntu 20.04 / 22.04 | Ubuntu 20.04 / 22.04 |
| Python | 3.8 | 3.8 |
| CUDA Toolkit(本地) | 11.7 | 11.7 |
| PyTorch | 1.13.1 | 2.0.1 |
| torchvision | 0.14.1 | 0.15.2 |
| mmcv-full | 1.7.0 | 2.1.0 |
| mmdet | 2.25.0 | 3.2.0 |
| mmsegmentation | 0.30.0 | 1.2.2 |
| mmdet3d | 1.0.0rc6 | 1.4.0 |
先说明一点:上面是“配套”关系,不是“最新”关系。很多新手喜欢装最新的 mmdet3d + 最新的 mmcv,结果发现新版代码改了接口,老教程全失效。如果你是照着网上的老博客配环境,建议优先选旧版稳定组合,因为网上绝大多数的踩坑记录和 demo 教程都基于这个档位。如果你的任务需要新算法的实现,再考虑新版组合。
为什么 Python 推荐 3.8?因为 mmcv 在 Python 3.10 以上的环境里源码编译容易碰到容器工具链兼容问题,3.8 是最省心的。至于 CUDA,11.7 是兼容性最好的版本,PyTorch 官方各版本的预编译包基本都有对应的选择,驱动只要支持 11.7 以上就没问题。
注意:这里说的 CUDA 分两种。一个是驱动附带的 CUDA Driver,一个是每个虚拟环境里给 PyTorch 用的 CUDA Toolkit。PyTorch 是自带 CUDA runtime 的,也就是说,并不是"系统装了什么 CUDA,PyTorch 就用什么",而是看安装 PyTorch 时指定的 cu117 / cu118 后缀。很多人误以为必须装完整的 CUDA Toolkit 才能用 GPU,其实驱动到位、PyTorch 选对版本就够了。
为什么强调先定版本矩阵再动手?因为 mmcv 的安装有两种路径:一种是直接下载官方预编译好的 wheel,速度快,但不指定版本的话容易装成mmdet3d不兼容的版本;另一种是 pip 拉源码本地编译,能用的前提是你的 PyTorch、CUDA 和编译器环境都对得上。版本矩阵不定,你连该走哪条路都不知道。
2. 环境搭建实操:从新建虚拟环境到全部装完
2.1 用 conda 建一个干净的虚拟环境
很多人图省事直接 pip install 装进 base 环境,这是后面哭的一大来源。因为 OpenMMLab 系列依赖很多,跟你其他项目很容易冲突。我强烈建议用 Miniconda 管理,每个项目一个独立环境,哪怕哪天 mmdet3d 环境坏掉了,直接删掉重建就行,不会牵连其他项目。
创建环境并激活:
conda create -n mmdet3d python=3.8 -y conda activate mmdet3d这里把环境名取成 mmdet3d,方便记忆。激活之后,建议顺手把 pip 源改成国内镜像(清华源或阿里源都行),后面的安装会快很多:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple注意:conda 的源也建议调整一下,否则创建环境时解析依赖可能慢到怀疑人生。但 conda 源配置就不展开讲了,网上教程很多,配好之后创建环境的体验会好很多。
2.2 PyTorch 与 CUDA 的匹配细节
PyTorch 的安装顺序一定要排在 mmcv 之前,因为 mmcv 的编译和预编译包检测都会读取 PyTorch 的版本信息。
在旧版稳定组合下,我用的安装命令是:
pip install torch==1.13.1 torchvision==0.14.1 --index-url https://download.pytorch.org/whl/cu117cu117这个后缀很关键,表示这个 PyTorch 预编译包内置了 CUDA 11.7 运行时。你也可以选择 cu118 甚至 cu121,但要保证后面 mmcv 的预编译版本也对应同一套 CUDA 版本。跨版本组合,比如 PyTorch 内置 CUDA 11.7,但 mmcv 拿的是 cu118 的包,就会出现“torch.cuda.is_available() 返回 True,但模型一跑就报 CUDA error”的问题。
装完先做个快速验证:
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"正常输出:
1.13.1 True如果这里输出的是 False,先别往下装 mmcv,停下来排查:
- 执行
nvidia-smi,看驱动是否正常显示; - 确认 PyTorch 安装的版本名里带的是 cu117 而不是 cpu;
- 如果是笔记本双显卡,检查是不是跑到了核显上。
注意:
nvcc -V显示的 CUDA 版本是系统里编译工具的版本,而torch.version.cuda才是 PyTorch 自带的 CUDA 版本。两者不一致非常正常,不必纠结,只要 nvidia-smi 能看到 GPU、torch.cuda.is_available() 是 True,就能用。
2.3 mmcv / mmdet / mmseg / mmdet3d 的安装顺序与命令
PyTorch 就绪后,接下来是重头戏。很多人一上来就pip install mmdet3d,结果要么装到了不兼容的版本,要么编译到一半崩掉。正确姿势是严格按依赖顺序装:mmcv → mmdet → mmseg → mmdet3d。
mmcv 的安装是这套环境里最容易翻车的一步。强烈建议用官方预编译 wheel,而不是源码编译:
pip install mmcv-full==1.7.0 -f https://download.openmmlab.com/mmcv/dist/cu117/torch1.13/index.html这行命令会读取当前环境的 PyTorch 版本(1.13.1)和 CUDA 版本(11.7),从 OpenMMLab 的服务器上拉取对应的预编译包。如果不加-f参数直接 pip install mmcv-full,它默认去 PyPI 拉包,大概率拉到一个通用版本,然后本地编译,耗时又容易失败。
接下来装 mmdet 和 mmseg:
pip install mmdet==2.25.0 pip install mmsegmentation==0.30.0这两个包安装一般不会出幺蛾子,注意版本别装成 3.x 的新版就行,新版接口有较大改动,配 1.0.0rc6 的 mmdet3d 会报错。
最后装 mmdet3d 本体。建议以源码方式安装,方便后续调试和查看源码:
git clone https://github.com/open-mmlab/mmdetection3d.git cd mmdetection3d git checkout v1.0.0rc6 pip install -e .git checkout v1.0.0rc6这一步很多人会忽略。默认仓库 master 分支已经是最新的 1.4.0 甚至更高,按上面那个配套矩阵,就应该切回旧版稳定组合对应的 tag。如果不切,后面 import 阶段就等着看一堆缺依赖的报错吧。
pip install -e .会以可编辑模式安装,即在当前目录下直接使用源码。这个模式的好处是改代码不用重新安装,但对新手来说无所谓,用pip install .也可以。
全部装完后,一个完整的验证命令:
python -c "import mmcv; import mmdet; import mmseg; import mmdet3d; print(mmcv.__version__); print(mmdet.__version__); print(mmseg.__version__); print(mmdet3d.__version__)"如果输出如下,说明环境基本就绪:
1.7.0 2.25.0 0.30.0 1.0.0rc6提示:这里每 import 一个包都要等几秒钟,因为 OpenMMLab 系列在 import 时会注册大量模块。第一次跑验证命令如果卡了几十秒,属于正常现象,别误以为死循环。
2.4 升级版:新版组合的差异点
如果你决定采用新版组合(mmdet3d 1.4.0 + mmcv 2.1.0),安装命令有一些变化:
- 不再有 mmcv-full 这个包名,统一叫 mmcv;
- mmdet 和 mmsegmentation 的版本也不同,需要装 3.2.0 和 1.2.2;
- mmdet3d 也不要 checkout v1.0.0rc6,而是保持 master 分支或 checkout v1.4.0。
pip install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cu117 pip install mmcv==2.1.0 -f https://download.openmmlab.com/mmcv/dist/cu117/torch2.0/index.html pip install mmdet==3.2.0 pip install mmsegmentation==1.2.2新版组合的坑在于教程少、社区解决方案还不那么丰富。如果你刚入门,我不建议用新版,先用旧版把流程跑通,理解每个组件的角色,后面迁移到新版会容易很多。
3. 验证环境与第一个 Demo 跑通
3.1 逐项验证:不只是 import 不报错
环境装完,很多人到import mmdet3d不报错就以为大功告成了,开始下数据集、准备训练。实际上 import 成功只能说明依赖链是齐的,不等于 GPU 算子也正常。我建议按下面这个顺序逐项验证:
第一步,确认 PyTorch 的 GPU 可用性:
python -c "import torch; assert torch.cuda.is_available(); print(torch.cuda.get_device_name(0))"第二步,确认 mmcv 的 CUDA 算子可用性。mmcv 的预编译包自带很多自定义算子,可以用下面这个命令验证:
python -c "from mmcv.ops import nms; import torch; boxes = torch.rand(10, 4).cuda(); scores = torch.rand(10).cuda(); print(nms(boxes, scores, 0.5))"如果能正常输出结果,说明 mmcv 的 CUDA 扩展没问题。这条验证很值得做,因为很多人的环境 import 没问题,但跑训练时nms相关算子直接崩,就是因为这里出了岔子。
第三步,用官方 demo 跑一次推理。mmdet3d 仓库里自带 demo 脚本和一小组样例点云数据:
cd mmdetection3d python demo/pcd_demo.py demo/data/kitti/kitti_000008.bin demo/data/kitti/pointpillars_secfpn_8x2_160e_kitti-3d-3class.py checkpoints/hv_pointpillars_secfpn_6x8_160e_kitti-3d-3class_20220301_150405-b4c9c5c5.pth --out-dir demo/output脚本需要对应数据集的 config 文件和 pretrain 权重,权重从 OpenMMLab 官网模型库下载对应文件即可。跑通这步就能看到点云可视化结果,也会要求安装 open3d:
pip install open3d如果你不想下载 KITTI 数据集,直接用 demo/data/kitti 下自带的几帧点云就行,够验证环境了。
3.2 跑通 demo 但看不到结果,一定是这三个原因
我见过不少人卡在这一步:demo 命令行没报错,但可视化窗口一闪而过,或者直接黑屏。逐个排查:
- 如果代码跑到可视化阶段报
ModuleNotFoundError: open3d,直接 pip install open3d 即可,注意 open3d 版本不要太新,0.17 以下比较稳妥; - 如果你是在服务器上跑,没有显示器,需要在代码里把 open3d 的可视化模式改为 headless,或者把可视化结果渲染到图片输出;
- 如果可视化窗口卡住不动,多半是 open3d 和当前的 OpenGL 环境冲突,可以试试用
mesa-libGL之类的软件渲染库,或者干脆跳过可视化、以输出推理结果文件为准。
实际上,验证环境不一定非要看到可视化窗口。demo 脚本在推理后会保存一个输出 pkl 或图片级结果文件,只要文件生成且内容不对空,就可以判定环境是可用的。可视化的意义更多是让你直观感受模型效果。
4. 常见报错与排查速查
4.1 高频报错一表对照
配置 mmdet3d 环境的过程中,会遇到的报错翻来覆去就那么几类。我把它们汇总成了一张速查表,按出现频率排序,后面的详细分析只挑最值得说的两个展开:
| 报错/现象 | 根本原因 | 解决办法 |
|---|---|---|
ModuleNotFoundError: No module named 'mmcv' | 当前环境没装 mmcv,或装的是 mmcv 的另一个版本 | 先conda activate mmdet3d,确认在虚拟环境里执行 import |
ImportError: libcudart.so.11.0: cannot open shared object file | 环境里缺少 CUDA 动态库路径 | 确认 PyTorch 版本对应的 CUDA,必要时在~/.bashrc中设置LD_LIBRARY_PATH |
AttributeError: module 'mmcv' has no attribute 'nms' | mmcv 和 mmdet 版本不配套 | 检查版本矩阵,按推荐组合重新安装 |
CUDA error: no kernel image is available for execution on the device | PyTorch 的 CUDA 版本与 GPU 算力不兼容 | 检查显卡算力,装对应 CUDA 版本的 PyTorch |
| 编译 mmcv 时内存不足 / OOM | 编译算子需要较大内存 | 加MAX_JOBS=2降低并行编译线程数 |
AttributeError: module 'setuptools' has no attribute 'dist' | setuptools 版本与 Python 3.8 冲突 | pip install setuptools==59.5.0 |
undefined symbol: _ZN6caffe...一类的编译链接错误 | mmcv 源码编译时检测到的 PyTorch 头文件与运行时版本不一致 | 统一 PyTorch 的安装方式,避免混合 pip 和 conda 安装的 PyTorch |
| import mmdet3d 时卡住不动 | OpenMMLab 系列注册模块较多,首次加载较慢 | 等待几秒到几十秒,可用python -c单条命令验证是否卡死 |
4.2 最容易卡死人的两个坑
第一个坑是 mmcv 源码编译失败。很多人因为懒得指定-f参数,直接pip install mmcv-full,结果 pip 找不到匹配的预编译 wheel,自动退化为源码编译。源码编译要下载 OpenMMLab 的源码,然后调用 nvcc 和 gcc 编译数百个融合算子,耗时四十分钟到一个小时很常见,期间任何一步编译器报错都会导致整个装包失败。
启动源码编译后,报错的典型场景包括:
- gcc 版本过低,部分 C++17 特性不支持;
- CUDA 编译器 nvcc 和你本地安装的 CUDA Toolkit 版本不一致;
- 编译过程中内存不足,进程被系统杀掉。
解决办法有两个方向:一是回到预编译 wheel 路线,记得加上-f https://download.openmmlab.com/mmcv/dist/cu117/torch1.13/index.html这个参数;二是要编译的话,先把 gcc 升级到 7.5 以上,然后设置环境变量MAX_JOBS=2限制并发数,避免内存被打满。
第二个坑是 PyTorch 和 CUDA 版本“半匹配”状态。具体表现是torch.cuda.is_available()返回 True,但实际运行模型时出现CUDA error: no kernel image。这是什么情况?说明 PyTorch 自带的 CUDA runtime 版本高于你显卡驱动支持的版本。比如你的显卡驱动只支持到 CUDA 11.2,但你装了 cu117 的 PyTorch,那么运行时的 CUDA API 是能调用的,但具体 kernel 无法在设备上执行。
排查方式也很简单:
nvidia-smi看右上角的 “CUDA Version”,比如显示 11.4,就表示你的驱动最高支持 CUDA 11.4。这时候如果 PyTorch 是 cu117 的,就属于跨版本了。解决方式是下载驱动更新,或者改装 cu113 / cu111 这样的 PyTorch 版本。
注意:新版驱动通常向下兼容,所以从 CUDA 11.7 降到 11.3 安装 PyTorch 是可行的,不用换驱动;但如果 PyTorch 需要的 CUDA 高于驱动支持的最高版本,就必须要换驱动,没有别的办法。
4.3 用了 conda 自带 CUDA Toolkit,还是报错?
有一种常见情况是:为了保险起见,用conda install cudatoolkit=11.7在环境里装了一份 CUDA Toolkit,然后发现nvcc -V有输出,但还是各种报错。
原因在于 PyTorch 的 CUDA 运行时库并不是从 conda 的 cudatoolkit 目录里找的,而是从torch/lib目录下加载的(里面自带 libcudart.so、libnvToolsExt.so 等)。也就是说,conda 里的 cudatoolkit 对 PyTorch 而言是多余的,它们之间互不干扰。真正会被系统找库的,是在源码编译 mmcv 的时候——那时 nvcc 需要从 cudatoolkit 里找编译工具。
如果你遇到源码编译阶段找不到nvcc的报错,再检查一下这个环境变量:
export CUDA_HOME=$CONDA_PREFIX或者在~/.bashrc里写上 conda 环境里 cuda 的路径:
export CUDA_HOME=/path/to/miniconda3/envs/mmdet3d如果 CUDA_HOME 没有指向正确的路径,nvcc 编译阶段就会直接退出,mmcv 装不上。
5. 装完环境之后:数据准备与训练前的一点点提醒
5.1 数据集格式转换:KITTI 不是直接能用的
环境配好、demo 能跑之后,下一步通常就是跑自己的数据或者公开数据集。以 KITTI 为例,很多人以为从官网下载原始数据就能直接训练,跑起来才发现 mmdet3d 需要的是 kitti_format 的中间格式,以及对应的 .pkl 索引文件。
mmdet3d 官方仓库提供了数据转换脚本:
python tools/create_data.py kitti --root-path ./data/kitti --out-dir ./data/kitti --extra-tag kitti这个脚本的作用是把原始点云、标注框、标定参数整理成 mmdet3d 规定的目录和 pkl 文件。pkl 文件里记录的是每个样本的点云路径、标注框坐标、类别、标定矩阵等信息,训练时 DataLoader 直接读取 pkl 就能组织 training 和 validation 样本。
如果你不转换格式就直接训练,会报类似FileNotFoundError: kitti_infos_train.pkl的错误。这不是环境问题,而是数据处理流程没走全。
5.2 第一次训练如何选择 config
mmdet3d 配置好之后,你想跑某个算法,不需要从零写模型代码,直接用官方 config 文件即可。比如 PointPillars 算法的配置在configs/pointpillars/下,里面有基于不同数据集(KITTI、nuScenes、Waymo)的一堆配置。
新手第一次训练,我建议注意两点:
第一,先把 config 里的samples_per_gpu调小一些,默认的 4 或者 8 在显存小的卡上很容易 OOM。调到 2 或 1 先确认能正常启动训练,再逐步加回去。
第二,检查 pretrained 路径。config 里的 load_from 字段指向预训练权重,如果你没下载这个文件,就把 load_from 注释掉或改成 None,否则代码会尝试加载不存在的文件然后报错。
第一次训练成功启动后,建议先训练个几十个 iteration 就 Ctrl+C 停掉,确认 loss 正常下降、日志文件有输出、可视化目录里生成了图片,再放心跑完整训练。
写在最后
这半年我给好几台机器配过 mmdet3d 环境,配的次数多了之后总结出一个体会:环境配置问题本质上是版本管理问题,不是代码问题。只要先把 PyTorch 和 CUDA 的对应关系定死,再沿着 mmcv → mmdet → mmseg → mmdet3d 的顺序装,中途每一步都做一次 import 验证和 GPU 算子验证,整个过程反而比想象中省心。
还有一个实用的小技巧:每次环境装到一个阶段,就把当前环境的完整信息快照保存下来:
conda env export > environment.yaml pip freeze > requirements.txt万一哪天不小心把环境搞坏了,或者要换机器重配,一份 environment.yaml 就能复现出完全一样的环境。我在吃过一次“重装三天”的亏之后,现在每配一台新机器都会做这个操作。希望上面这些内容也能帮你少走几步弯路。