先讲个真实经历。我自己刚入门3D目标检测那会儿,照着网上几篇老教程搭环境,OpenPCDet、MMDetection3d、Det3d三个框架来回装了四遍,最后被同一个坑折磨到怀疑人生:CUDA版本和PyTorch对不上,一跑就报找不到算子的错误。后来我把安装顺序、版本搭配、编译细节全部重新梳理了一遍,才算真正把这三套环境都跑通。这篇东西不是官方文档翻译,是我反复踩坑后整理出来的实操记录,适合想在Linux服务器上把OpenPCDet、MMDetection3d、Det3d全部或部分搭起来的人。它会告诉你怎么少走弯路,也会把那些文档里没写清楚的版本匹配问题一次性讲明白。
1. 环境搭建前的全局规划
1.1 先搞清楚三套框架的底层关系
很多人一上来就急着git clone,然后按README一顿操作,结果编译到一半就开始报错。3D目标检测环境不是装个pip包就完事的,它和2D检测最大的区别在于多了很多自定义的CUDA算子,比如稀疏卷积、RoI池化、体素化这些操作,都需要在编译时把你的GPU架构考虑进去。OpenPCDet、MMDetection3d、Det3d这三个框架,底层全都依赖PyTorch,但各自又封装了不同的扩展库:OpenPCDet依赖spconv,MMDetection3d依赖mmcv系列,Det3d则是一套更早期的自定义build流程。
这三套框架的定位也不一样。OpenPCDet主打点云检测,PointPillars、PV-RCNN、CenterPoint这些经典模型都有现成实现,代码结构清晰,适合做算法对比实验;MMDetection3d是OpenMMLab生态的一部分,不仅支持点云,还支持多模态数据融合,模型库很全,适合做统一训练和评测;Det3d是比较早的框架,很多论文的baseline代码都基于它,虽然更新慢,但在复现某些经典论文时绕不开。
所以我的建议是:不要把三个框架强行装进同一个环境里,那样大概率会陷入依赖冲突的泥潭。用conda虚拟环境隔离,每个框架各住一个房间,互不打扰。这也是后面所有步骤的前提。
1.2 版本匹配是环境搭建的生死线
环境搭建里最常见的错误,就是盲目装最新版。你要知道,3D检测框架的版本兼容性非常脆弱,PyTorch、CUDA、spconv、mmcv这四者的版本必须严丝合缝。一个粗略的匹配关系可以参考下面这张表:
| 框架 | 推荐Python | 推荐PyTorch | CUDA版本 | 关键扩展库 |
|---|---|---|---|---|
| OpenPCDet | 3.8 | 1.10.0 | 11.3 | spconv-cu113 |
| MMDetection3d (1.0rc系列) | 3.8 | 1.10.0 | 11.3 | mmcv-full 1.7.0 |
| Det3d (早期仓库) | 3.7 | 1.7.1 | 11.0/11.1 | numba + 自编译算子 |
这个表不是一个死规定,但它代表了我实测下来比较稳的一组组合。为什么要卡这么老?因为像spconv 2.x版本是明确绑定了PyTorch和CUDA编译环境的,你换一个PyTorch小版本,可能就得编译半天甚至直接编译失败。mmcv也类似,它需要跟PyTorch和CUDA严格对齐,否则会报“mmcv not compiled with CUDA”这类错误。
先别急着照着装。你要做的第一件事是确认GPU驱动支持的最高CUDA版本,运行:
nvidia-smi看到右上角的CUDA Version,比如12.0或者11.4,那是驱动最高支持的版本,不代表你必须在容器里装这么高的CUDA。你可以选择向下兼容的CUDA 11.3来安装。只要驱动版本不低于目标CUDA版本就行。
1.3 用conda虚拟环境隔离不同框架
我特别建议每个框架都建一个独立的conda环境,名字叫pcdet、mmdet3d、det3d,一目了然。这样即使某个环境的依赖被搞崩了,删掉重来也很快。
conda create -n pcdet python=3.8 -y conda activate pcdet创建环境时把Python版本选定,后面就不要轻易动了。Python 3.8是一个兼容性非常好的版本,spconv、mmcv、numba对它的支持都比较成熟,建议作为默认选择。使用Python 3.10以上版本的话,很多编译老项目反而会遇到C++标准库API变换的问题。
还有一个容易被忽略的点:不要在conda环境里混用pip和conda的包,尤其是torch和cudatoolkit系列。要么全都走conda安装,要么全都走pip,混装容易出现两个版本同时存在的情况。Python包的优先级是鱼龙混杂的,到时候排查起来相当痛苦。
2. OpenPCDet环境搭建实操
2.1 依赖安装顺序:先PyTorch,再spconv,最后装OpenPCDet
OpenPCDet的安装顺序其实是很有讲究的,官方文档只给了个setup.py develop,但实际上你如果没有提前装好spconv,后面编译pcdet时一定会报错。
我当时的安装步骤是这样的:
conda create -n pcdet python=3.8 -y conda activate pcdet # 安装 PyTorch 1.10.0 + CUDA 11.3 pip3 install torch==1.10.0 torchvision==0.11.0 torchaudio==0.10.0 --extra-index-url https://download.pytorch.org/whl/cu113 # 安装 spconv 2.x pip install spconv-cu113 # 克隆 OpenPCDet git clone https://github.com/open-mmlab/OpenPCDet.git cd OpenPCDet pip install -r requirements.txt python setup.py develop这里有个很重要的点:pip install spconv-cu113会安装spconv 2.x版本,但这个wheel是编译好了的,它会自动匹配你环境中已有的PyTorch版本。如果你先装了spconv,再装PyTorch,可能会出现版本对不上的问题。所以我每次都是先确保PyTorch能用,再看spconv。
python setup.py develop是源码开发模式,它会编译OpenPCDet里的C++和CUDA扩展。这个过程通常要几分钟,如果机器配置低可能需要十几分钟。编译前建议检查一下g++版本:
g++ --version如果gcc版本太低,编译时会报错“internal compiler error”,那时候不要慌,先升级一下基础编译工具链:
sudo apt update && sudo apt install g++-8 -y export CXX=g++-82.2 数据准备:KITTI数据集目录结构
OpenPCDet默认使用KITTI数据集,但官方不会直接给你下载数据脚本,你需要自己去KITTI官网下载以下几部分:calib、velodyne、label_02、image_02以及ImageSets。下载完后,把它们组织成下面这样的结构:
OpenPCDet/ ├── data/ │ └── kitti/ │ ├── ImageSets/ │ ├── training/ │ │ ├── calib/ │ │ ├── label_2/ │ │ ├── velodyne/ │ │ └── image_2/ │ └── testing/ │ ├── calib/ │ └── velodyne/如果你数据文件放在别的目录,可以用软链接把它链进来:
cd OpenPCDet/data/kitti ln -s /path/to/velodyne/ velodyne ln -s /path/to/calib/ calib目录建好后,还要生成训练所需的infos文件和gt_database文件。这一步很多人会漏掉,直接跑训练就报文件找不到。
python -m pcdet.datasets.kitti.kitti_dataset create_kitti_infos tools/cfgs/dataset_configs/kitti_dataset.yaml这个命令会读取你data/kitti目录下的数据,并生成kitti_infos_train.pkl、kitti_infos_val.pkl、kitti_dbinfos_train.pkl等文件。生成完以后,你再用demo.py测试一下环境是否正常。
2.3 验证环境:用demo脚本跑一个PointPillars
环境搭好了,数据也有了,怎么判断是否成功?我习惯直接用官方pre-trained模型跑一下demo,能出结果就说明环境基本没问题。
python demo.py --cfg_file tools/cfgs/kitti_models/pointpillar.yaml --ckpt pointpillar_7728.pth --data_path /path/to/000000.bin如果你没有预训练权重,可以先去OpenPCDet官方Model Zoo下载pointpillar的pth文件。demo跑通后会在输出目录生成可视化结果文件(比如pcd的预测结果),说明spconv、点云预处理、网络推理链路都正常。这时候再进训练环节,心态就踏实很多。
3. MMDetection3d环境搭建实操
3.1 MMCV全家桶版本对齐
MMDetection3d的安装比OpenPCDet复杂一点,因为它依赖整个OpenMMLab家族:mmcv-full、mmdet、mmsegmentation、mmdet3d,这四个包的版本必须互相兼容。如果你从官方GitHub拉最新代码,然后直接pip install -e .,大概率会因为mmcv版本不兼容而错过一堆算子。
我当时用的是1.0.0rc6版本,配套的是mmcv-full 1.7.0、mmdet 2.28.2、mmsegmentation 0.30.0。这套组合在PyTorch 1.10 + CUDA 11.3下运行稳定。安装命令如下:
conda create -n mmdet3d python=3.8 -y conda activate mmdet3d pip3 install torch==1.10.0 torchvision==0.11.0 torchaudio==0.10.0 --extra-index-url https://download.pytorch.org/whl/cu113 pip install openmim mim install mmcv-full==1.7.0 pip install mmdet==2.28.2 mmsegmentation==0.30.0 git clone https://github.com/open-mmlab/mmdetection3d.git cd mmdetection3d git checkout v1.0.0rc6 pip install -e .为什么要用mim而不是直接pip install mmcv-full?因为mmcv-full有很多预编译wheel,mim会根据你当前的PyTorch和CUDA版本自动推荐合适的安装源,这比自己找下载链接靠谱得多。如果你自己pip,可能装到CPU版本的mmcv-full,运行时会报“mmcv not compiled with CUDA enabled”。
3.2 编译细节:gcc版本和CUDA算子
MMDetection3d里很多模型都会用到mmcv提供的CUDA算子,比如voxelization、grid_sample、ball_query等。如果你在mmcv-full安装时选的是源码编译,那就要确保环境里的gcc版本与PyTorch编译时保持一致。PyTorch 1.10在Ubuntu 18.04上要求gcc至少7.5,在Ubuntu 20.04上则建议使用gcc-9。太小或太大,编译时会出现奇怪的模板报错。
这个环节我吃过一个亏:系统默认gcc是11,PyTorch是9,结果编译mmcv时一路爆红,最后把gcc切到9才过。切换命令如下:
sudo apt install gcc-9 g++-9 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 100 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 100如果你不想折腾系统gcc,也可以用conda安装一个独立编译器:
conda install gxx_linux-64不过要注意,这样装完的编译器可能在环境切换后路径不对,需要手动设置万能and环境变量。我自己的经验是:能用系统gcc-9就用系统gcc-9,最省事。
3.3 用create_data.py生成KITTI中间文件
MMDetection3d的数据准备方式和OpenPCDet不太一样。它把KITTI数据整理成一个pkl文件,然后训练时从pkl里读取标注和点云路径。
python tools/create_data.py kitti --root-path ./data/kitti --out-dir ./data/kitti --extra-tag kitti这个命令会在data/kitti目录下生成kitti_infos_train.pkl、kitti_infos_val.pkl、kitti_dbinfos_train.pkl等文件,并且会把点云数据预处理成相应的格式。同样,你需要先把KITTI的原始目录结构放好,包括ImageSets、training、testing等。
生成完pkl之后,可以用一个快速测试来判断环境是否真正可用:
python tools/test.py configs/pointpillars/hv_pointpillars_secfpn_6x8_160e_kitti-3d-car.py --work-dir work_dirs --eval mAP如果这个命令能正常跑起来并输出mAP结果,哪怕精度不高,也说明整个数据加载、模型计算、后处理流程都通了。如果连这个都跑不过,那就先不要急着练自己的模型,回头查环境问题。
4. Det3d环境搭建与踩坑记录
4.1 Det3D和前面两套框架的差异
Det3d这个框架,很多人一听名字就以为是OpenPCDet的前身或者某个模块,其实它是另一套独立的早期开源代码。它和OpenPCDet、MMDetection3d最大的区别是:没有统一管理算子的集中编译流程,很多细节上的依赖需要自己手动处理。
如果你是为了复现某些论文里的baseline,Det3d绕不开。但说实话,它的环境搭建比前面两个都要磨人,因为它依赖的numba、scipy这些包版本非常敏感,稍微新一点就会报错。我在搭建时使用的Python是3.7,搭配numba 0.48和scipy 1.4.1,这才稳定通过了numba的JIT编译。
4.2 依赖安装和源码编译
安装命令大概长这样:
conda create -n det3d python=3.7 -y conda activate det3d pip install torch==1.7.1 torchvision==0.8.2 pip install numba==0.48.0 scipy==1.4.1 pip install pybind11 onnx onnxruntime pip install opencv-python pillow tensorboardX tensorboard pip install shapely six git clone <det3d仓库地址> cd det3d python setup.py build develop值得提醒的是,这个仓库的requirements.txt可能不全,它的文档也没怎么写清楚。我当时是装完上述依赖后,在import时还报缺了其他小包,再一个个补上的。比如可能缺sklearn、pandas这些,用pip install scikit-learn pandas补一下就好。
编译过程中,det3d会编译一些C++/CUDA算子,比如voxelization、rpn head里的自定义层。如果你的GPU较新,比如Ampere架构,并且使用的是CUDA 11.3,个别算子可能会编译失败。这时候可以尝试改用更老的CUDA 11.0,或者调整一些PyTorch的C++扩展接口。这也是这个框架更挑环境的主要原因。
4.3 跑通demo的注意事项
Det3d的数据读取格式比较老,KITTI数据目录里每个序列的训练和验证划分,它不像OpenPCDet那样直接读pkl,很多时候需要在config里指定数据路径,而且它还可能要求你有完备的pkl文件,一个是kitti_infos_train.pkl,一个是kitti_infos_val.pkl。
如果你已经用OpenPCDet或MMDetection3d生成过KITTI的pkl文件,理论上可以试着复用,但要注意字段名可能对不上。我当时是直接用仓库自带的prepare_data脚本重新生成了一遍,虽然慢,但至少不会因为字段缺失而卡住。
跑demo时,先确定你下载的预训练模型和代码版本匹配。Det3d仓库里有些模型权重是用老版本PyTorch保存的,可能需要在加载时加map_location或者设置python_version标志。如果遇到加载键名缺失,多半是网络定义改了,需要检查代码版本。
5. 三大框架通用问题排查与避坑
5.1 版本冲突自查清单
环境搭建的报错五花八门,但大部分可以归为几类。下面这个表格是我自己在排查问题时的心得,可以直接拿来对照。
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| import torch时直接报CUDA error | 驱动没有正确识别GPU | nvidia-smi看显卡状态 |
| 编译spconv时报未定义引用 | PyTorch与CUDA版本不匹配 | 确认PyTorch是否是cu113版 |
| 运行mmcv时报not compiled with CUDA | mmcv-full装成了CPU版本 | 用mim重装mmcv-full |
| numpy相关错误,比如np.int不存在 | numpy版本过高,移除了旧接口 | pip install numpy==1.23.5 |
| 训练时显存很快爆炸 | 数据加载预处理不当或batchsize过大 | 调整数据加载器的workers |
| 数据集加载报路径不存在 | 目录软链接没有建好 | 到data/kitti下ls -l看链接 |
| 编译时gcc报错 | gcc版本和PyTorch不一致 | 切换到gcc-9 |
其中numpy版本问题最隐蔽。很多3D检测代码还在使用np.int、np.float这样的旧写法,在numpy 1.24以后这些接口都被移除了,一跑就报AttributeError。我后来统一在环境里限制numpy版本为1.23.5,问题就消失了。
5.2 我踩过的几个坑和破局方法
第一个坑是乱升级PyTorch。有一次我在OpenPCDet环境里执行了conda update --all,结果torch被自动升级,spconv编译好的库全失效了,import时报错“undefined symbol: _ZN6caffe...”。后来我给conda指定了torch版本,才恢复。所以环境装好后,尽量用conda export把版本锁住,不要随便更新。
第二个坑是软链接路径写错。KITTI目录下的velodyne、calib、label_2这些目录名,必须和代码里一致。我一开始链接成了trainning这种少一个i的目录,结果训练脚本一直报错找不到文件。看似小问题,实际排查花了我一个多小时。
第三个坑是训练时内存不够。3D目标检测的点云数据预处理通常会把整个点云加载进内存,如果同时加载太多线程,容易把内存吃满。我把num_workers降低到4,并且每次只加载一个epoch的数据,速度虽然慢了点,但至少不崩了。
5.3 运行效率和磁盘规划
KITTI数据集不算特别大,但如果要训练多个模型,生成的过程文件会非常多,尤其是gt_database、infos文件,加起来能到几十GB。建议把数据目录放在空间充裕的盘上,用软链接链接到仓库里。
另外,编译OpenPCDet和mmcv这种带大量自定义算子的库时,临时文件可能会占满/tmp目录。如果服务器/tmp空间小,可以把TMPDIR变量指向一个大目录:
export TMPDIR=/data/tmp这个操作我在训练服务器上实测很有用,能少很多莫名其妙的编译失败。
6. 环境搭建之后我用下来的几点体会
现在回头看,三套框架我都跑过一遍,最终的感受是:如果你只想快速上手验证一个点云检测模型,OpenPCDet是最省心的;如果你需要同时做多模态融合、多种评测指标对比,MMDetection3d的生态优势很明显;Det3d更适合用来读代码、复现历史论文,真到生产应用,维护成本很高。
环境搭建这件事,本质上是在处理各种版本间的依赖关系,没有一套万能组合能覆盖所有场景。我习惯每次装完一个环境,在conda环境里执行一次:
conda list --explicit > environment_backup.txt这样即使后来系统重装,也能根据备份把环境一波拉回来。另外,我还会在项目根目录写一个requirements_fixed.txt,把关键包的版本号都钉死,方便同事克隆相同环境。
如果你正在准备入坑3D目标检测,我建议先别急着把三个框架都装齐,先选定一个你最想复现的模型和对应的框架,跑通一条完整链路,再考虑扩展。不然一上来就面对三套环境的编译问题,很容易劝退。祝你的环境一次过,跑出来的模型点云框又准又稳。