资讯动态

MMDetection3D安装实战:从环境配置到PointPillars训练全流程

发布时间:2026/10/20 6:26:22 来源:尧图企业网站定制
做3D目标检测的人几乎绕不开MMDetection3D这套工具。它能帮你把常见的点云检测模型比如PointPillars、CenterPoint、SECOND直接拿来训练也能处理图像和点云融合的数据。说直白点它是目前把训练、验证、可视化串起来最顺手的工具箱之一不需要自己从头搓数据加载和评估代码。不过很多人第一次装上它的时候卡得最久的就是环境——PyTorch版本、CUDA版本、编译工具链、还有各种依赖包之间的匹配关系稍微错一个组合编译直接报错。这篇文章我按自己实际操作的顺序把安装到跑通的整个流程讲清楚每一步会给可复现的命令和参数也把那些文档上没写明白的坑都挑出来。1. 为什么选择MMDetection3D先搞清它能干哪些活1.1 从任务范围看这个工具箱的边界MMDetection3D本质上是把2D目标检测中那套模块化思路搬到了三维空间所以你能在上面找到非常熟悉的骨架backbone、neck、head、数据管线、训练器、评估器全部拆成独立模块。它支持的任务大致分三类纯LiDAR点云检测输入是激光雷达扫出来的点云输出是每个目标的3D框位置、大小、类别和朝向。这是最常用的场景。图像与点云融合检测图像和点云同时输入利用图像的纹理信息辅助点云检测适合光照变化大、点云稀疏的场景。点云分割对每个点做语义分类属于另一条分支模型如PointNet等也有覆盖。数据集方面KITTI、nuScenes、Waymo、SUN RGB-D、ScanNet、S3DIS这些主流3D数据集都有现成的数据转换脚本。这意味着你不需要自己写解析器把原始数据按约定放进目录跑一次create_data就能生成训练需要的索引文件。模型覆盖量也比较可观。从早期的VoxelNet、SECOND到PointPillars这种大一统方案再到CenterPoint、PV-RCNN、3DSSD这类性能型模型单目3D检测也带了FCOS3D、PGD、ImVoxelNet。我第一次用的时候最大的感受是不用再为了每个模型装一套不同风格的代码仓库了所有模型共用一套评估逻辑和可视化工具这在对比实验时太重要了。1.2 动手前想清楚的三件事如果你刚开始接触先别急着装环境把下面三件事想清楚能省很多冤枉路。第一是硬件。3D检测对显存的要求比2D高得多因为点云体素化之后是一个四维张量通道、深度、高度、宽度或者反过来中间特征图的体积涨得很快。我的经验是8GB显存只够跑batch size为1到2的小模型比如PointPillars还能勉强转起来想跑CenterPoint、PV-RCNN至少要16GB以上。除非你只做推理不做训练否则显卡选择上别太省。第二是数据。绝大多数算法默认数据格式是KITTI风格就算你用nuScenes或者自己采集的数据最后也会被转换成类似KITTI的标注和标定文件结构。所以在安装之前最好先确认自己的数据能不能落到这个格式里。很多人在环境装好后卡在数据上一卡就是好几天。第三是模型选择。如果你只是验证流程PointPillars是最合适的——结构简洁、训练快、显存占用低而且它的体素化思想贯穿了很多后续模型。先拿它跑通整个流程再去折腾别的模型心里会踏实很多。2. 把版本组合先锁死再开始装MMDetection3D2.1 版本对应关系这套组合最稳MMDetection3D有两个大版本路线。老版本是0.x依赖mmcv-full和mmdet 2.x装起来最大的痛点是spconv编译新版本是1.x依赖mmcv、mmengine和mmdet 3.x官方也支持了pip直接安装整体清爽很多。我建议新用户直接走1.x路线。下面是实测下来最省心的一套组合如果你之前没装过任何深度学习框架照这个来基本不会踩雷。组件推荐版本说明Python3.83.6太老3.10以上部分算子编译容易报错PyTorch1.12.1和CUDA 11.3搭配稳定且算子兼容性好CUDA Toolkit11.3不需要装最新版关键看PyTorch的wheel匹配mmcv1.6.2必须严格匹配PyTorch/CUDA组合mmdet / mmengine随pip自动装1.x项目会通过requirements自动带上GCC5.4以上编译C和CUDA算子时必需这里有个特别容易误解的地方nvidia-smi显示的CUDA驱动版本和nvcc --version显示的CUDA Toolkit版本不是一回事。PyTorch编译时用的是Toolkit不是Driver。你可以先执行下面三条命令确认当前机器状态python -c import torch; print(torch.__version__, torch.version.cuda) nvcc --version gcc --version如果nvcc命令找不到说明系统里只有显卡驱动没装CUDA Toolkit后面编译肯定会失败。这属于系统环境问题不是MMDetection3D的问题但很多人会在这里耗掉半天。2.2 conda环境创建到源码安装的完整命令下面这套流程我在多台机器上都跑过只要版本一致基本能一次过。# 1. 创建独立环境不要用base环境 conda create -n mmdet3d python3.8 -y conda activate mmdet3d # 2. 安装PyTorch注意指定CUDA版本 pip install torch1.12.1 torchvision0.13.1 --index-url https://download.pytorch.org/whl/cu113 # 3. 用mim安装mmcv它会自动匹配当前环境的torch/cuda pip install -U openmim mim install mmcv1.6.2 # 4. 克隆MMDetection3D源码建议切到release标签 cd ~/workspace git clone 官方仓库地址/mmdetection3d.git cd mmdetection3d git checkout v1.1.1 # 5. 安装依赖并执行本地开发安装 pip install -r requirements.txt pip install -e .第5步的pip install -e .会做两件事一是自动拉取mmdet、mmengine这类依赖二是本地编译项目里的C/CUDA算子。编译的时候屏幕会滚一大段日志看到Successfully built mmdet3d之类的提示才算结束。第一次编译可能要五到十分钟中间看起来像卡住了其实是正常的别去强杀进程。这里列出三个小经验mmcv不要用pip install mmcv直接装会装成CPU版本后面跑GPU会报算子不存在的错。用mim装最稳。如果之前装过老版本先把环境里残留的mmcv-full卸载干净它和mmcv不能共存。不要用Python 3.10以上版本试老版本distutils模块的变动会让很多编译脚本直接失败折腾起来很费劲。2.3 装完先跑个Demo验证环境安装成功不等于能用最直接的验证方式有两个。最快的是在Python里import一下确认核心包能被找到且版本正确python -c import mmdet3d; print(m1det3d.__version__)如果这一步报ModuleNotFoundError说明pip install -e .没有真正生效检查一下当前环境是否还是mmdet3d以及是否在源码目录下执行过安装。完整一点的验证是跑官方Demo。仓库里自带了demo用的KITTI点云文件你只需要下载一个PointPillars的预训练权重然后执行python demo/pcd_demo.py demo/data/kitti/kitti_000008.bin \ configs/pointpillars/pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py \ 权重文件路径 \ --out_dir demo_output跑完会在demo_output里生成带预测框的可视化文件。这一步能通说明算子编译、权重加载、后处理整个链路都是好的可以放心进入数据准备环节。3. 安装过程最硬核的几个编译坑逐个说清楚3.1 CUDA和GCC导致的经典编译报错编译阶段最常见的报错可以归成三类我分别说下当时的现场和解决办法。第一类报错里带cuda_runtime.h: No such file or directory。这说明系统里只装了显卡驱动没有装CUDA Toolkit。PyTorch的wheel虽然自带了运行时库但源码编译需要完整的Toolkit头文件。解决办法是去CUDA Toolkit的下载页面选对操作系统版本装上之后把下面两行写进~/.bashrcexport PATH/usr/local/cuda-11.3/bin:$PATH export CUDA_HOME/usr/local/cuda-11.3然后source ~/.bashrc再重新编译。注意路径里的11.3要换成你实际安装的版本目录名。第二类报错出现nvcc fatal: unsupported option或者gcc: error: unrecognized command line option。这通常是GCC版本太新和CUDA Toolkit内置的nvcc不兼容。CUDA 11.3那块对GCC 10以上的支持其实不好编译老一点的项目时将默认GCC降到9是比较稳妥的做法。sudo apt install gcc-9 g-9 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 sudo update-alternatives --install /usr/bin/g g /usr/bin/g-9 90第三类编译过程中出现undefined reference to cudaMemcpy之类的链接错误。这多半是CUDA的库路径没对上。除了确认CUDA_HOME之外还要检查/usr/local/cuda/lib64是否存在并且把export LD_LIBRARY_PATH/usr/local/cuda-11.3/lib64:$LD_LIBRARY_PATH也加上。多数时候这类报错是环境变量不全导致的不真是代码问题。3.2 Python版本和依赖包残留问题我见过太多人卡在这块并不是MMDetection3D本身难装而是Python环境太杂。首先是Python版本。1.x的MMDetection3D在Python 3.8下最稳我建议不要用3.9或3.10去试。遇到过一位朋友用Python 3.10装老版本报错AttributeError: module distutils has no attribute version这种问题一般跟编译脚本里调用了新版Python已废弃的distutils接口有关。与其到处打补丁不如退回3.8重新建环境十分钟的事。其次是依赖包残留。如果你之前装过mmcv-full、mmdet之类的建新环境时别图省事复制base环境。我见过有人环境里同时存在mmcv和mmcv-full两个包导致import时加载错版本算子行为完全不对。干净环境重装永远比排查残留快。最后是pip缓存。有几次我改了mmcv版本后重装结果还是老版本后来发现是pip缓存了旧wheel。用下面命令可以强制从源上重新拉pip install --no-cache-dir -U openmim mim install mmcv1.6.2 --no-cache-dir这一节总结成一句话安装阶段90%的问题源于版本组合和环境残留跟代码本身关系不大。遇到看不懂的报错先检查环境再怀疑代码。4. KITTI数据准备与infos文件生成一步都不要错4.1 原始数据目录按这个结构放好KITTI是3D检测领域绕不过去的基准数据集MMDetection3D的数据转换脚本也是照它的规范写的。官方提供的图片、点云、标定、标注文件是分开下载的你需要把它们组织成下面这个结构data/kitti/ ├── ImageSets/ │ ├── train.txt │ ├── val.txt │ └── test.txt ├── training/ │ ├── image_2/ # 左目彩色图 │ ├── velodyne/ # 激光雷达点云bin文件 │ ├── label_2/ # 3D标注文本 │ └── calib/ # 相机/雷达标定文件 └── testing/ ├── image_2/ ├── velodyne/ └── calib/重点说几个细节ImageSets里的train.txt和val.txt是样本编号列表每行六个字符比如000000。这个文件KITTI官网提供下载别自己随便生成否则会出现训练集和验证集重叠的问题。training/velodyne下是.bin文件不是pcd或las格式。如果你自己采集点云要先转成KITTI这种连续float32的二进制格式每四个float为一组x, y, z, reflectance。标注文件是纯文本每行描述一个目标类别、截断程度、遮挡程度、2D框、3D框尺寸、朝向、置信度等。换模型改配置时class_names必须和你标注里的类别名完全对应否则要么不读目标要么训练时全体漏掉。如果是在服务器上操作我习惯把原始数据放在机械硬盘然后用软链接指向data/kitti目录这样能省下复制的时间。4.2 用create_data.py生成训练索引目录结构就绪之后运行下面这条命令生成训练要用的pkl索引文件python tools/create_data.py kitti \ --root-path ./data/kitti \ --out-dir ./data/kitti \ --extra-tag kitti \ --workers 8它做的事情主要有两步读取ImageSets里的划分文件把所有样本的路径、标注、标定信息打包成pkl文件针对训练集生成gt_database也就是把每个目标的点云片段单独抽出来存好供训练时的数据增强策略使用。跑完之后在data/kitti下应该能看到kitti_infos_train.pkl kitti_infos_val.pkl kitti_infos_test.pkl kitti_gt_database_3class.pkl如果生成过程中报找不到文件基本都是路径问题。一个常见现象是--root-path写的是相对路径但当前工作目录和源码目录不一致。我建议始终用绝对路径或者先cd mmdetection3d再执行命令。4.3 数据准备阶段的三个坑第一个坑是漏下载。KITTI数据是多个zip分片比如点云文件有时候拆了好几个包漏了其中一个就会在生成pkl时报文件不存在或者训练到某一帧突然报错。我的做法是解压后在training/velodyne里数一下文件数量和官网上标注的帧数对上再继续。第二个坑是标定文件格式。KITTI的calib目录下每个样本有一个calib文本文件里面是P0到P3相机内参、相机外参、激光雷达到相机的变换矩阵。很多自研数据预处理不小心把矩阵顺序写错导致投影结果完全不对。如果后面发现2D框和点云重叠位置对不上回来看这里。第三个坑是类别名。KITTI原始标注里有Van、Truck这些常见类别但MMDetection3D的PointPillars三分类配置只保留Car、Pedestrian、Cyclist。create_data脚本会按配置过滤类别如果你自己写转换脚本而没有过滤训练时类别不匹配会直接抛异常。5. 完整跑通一个PointPillars训练、评估、可视化5.1 训练配置文件里真正要改的几个参数很多新手一打开配置文件就晕因为里面的嵌套字典一层套一层。其实对一个单卡用户来说真正需要关注的参数也就这几个。以pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py这个配置为例文件名本身透露了很多信息8xb6表示8张卡、每张卡batch size为6160e表示训练160个epoch。单卡用户如果不改一张24GB的卡也跑不动因为等效batch size是48。配置里找这几个地方改# 点云范围单位是米 point_cloud_range [-50, -50, -5, 50, 50, 3] # 体素尺寸 voxel_size [0.16, 0.16, 4] # 训练和测试时的类别 class_names [Car, Pedestrian, Cyclist] # 数据路径 data_root data/kitti/point_cloud_range定义了模型关注的空间范围超过这个范围的雷达点会被丢到体素外边直接忽略。范围越大视野越广但会导致每个非空体素的特征统计更稀疏计算量也更大。voxel_size是体素化的最小单元。[0.16, 0.16, 4]的意思是横向和纵向0.16米一格竖直方向4米一整个Z轴范围。Z方向粗是因为KITTI点云的Z轴分布相对集中再细分收益不大。训练和测试的batch size配置可以这样改train_dataloader dict( batch_size2, num_workers2, ... )第一次跑通建议把batch_size改成2epochs从160改成20不是为了追求精度而是为了快速验证全链路。我在第一次调模型时踩过一个坑用完整配置跑了一天到第30个epoch才发现数据路径写错了所有样本都读的是同一个文件白白浪费算力。5.2 单卡与多卡训练命令单卡训练直接用train.pypython tools/train.py configs/pointpillars/pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py \ --work-dir ./work_dirs/pointpillars_kitti \ --cfg-options train_dataloader.batch_size2 train_dataloader.num_workers2--work-dir用来指定权重和日志输出目录。训练开始后大约几秒你就会在终端看到滚动日志包括loss、学习率、每次迭代消耗的时间。如果想看更直观的曲线可以在另一个终端里启动tensorboard --logdir ./work_dirs --port 6006多卡训练用官方脚本把卡数换成你机器的实际数量bash tools/dist_train.sh configs/pointpillars/pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py 8 \ --work-dir ./work_dirs/pointpillars_kitti多卡训练前要确认torch.distributed的初始化和环境变量能正常工作。一个很容易漏的点是多卡训练时的batch size是每张卡各自承担的配置里写8xb6就是每张卡68张卡合计48。如果你只有两张卡想等效差不多的总batch可以写成每卡12但显存得够。训练中断了也不用从头来直接加一个--resume参数会自动读取work_dirs里最新的权重续跑。这个我在长训练中用了很多次非常可靠。5.3 测试评估与点云预测可视化训练完成后权重文件会存在work_dirs/epoch_20.pth之类的位置。测试命令也很直接python tools/test.py configs/pointpillars/pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py \ ./work_dirs/pointpillars_kitti/epoch_20.pth \ --eval mAP \ --out results.pkl其中--eval mAP会在跑完全部验证集后打印出每个类别的平均精度。--out results.pkl会把每帧的预测框和分数存下来方便后面离线分析。如果想直接看可视化结果可以在测试时加上--show-dir参数或者用下面的思路写个小脚本读取pkl画框。这里给出用open3d画预测框的示例代码核心是读取点云和预测框参数import open3d as o3d import numpy as np import pickle # 读取点云 points np.fromfile(demo/data/kitti/kitti_000008.bin, dtypenp.float32).reshape(-1, 4)[:, :3] pcd o3d.geometry.PointCloud() pcd.points o3d.utility.Vector3dVector(points) # 读取pkl结果结构一般是每帧dict的列表 with open(results.pkl, rb) as f: preds pickle.load(f) # 对每个预测框画一个3D包围盒 for pred in preds: boxes pred[boxes_3d] scores pred[scores_3d] labels pred[labels_3d] for box, score, label in zip(boxes, scores, labels): if score 0.3: continue center box[:3] dims box[3:6] yaw box[6] # 构造朝向角后的3D框 rot_matrix np.array([ [np.cos(yaw), -np.sin(yaw), 0], [np.sin(yaw), np.cos(yaw), 0], [0, 0, 1] ]) h, w, l dims # KITTI顺序是height, width, length corners np.array([ [-l/2, -w/2, -h/2], [l/2, -w/2, -h/2], [l/2, w/2, -h/2], [-l/2, w/2, -h/2], [-l/2, -w/2, h/2], [l/2, -w/2, h/2], [l/2, w/2, h/2], [-l/2, w/2, h/2] ]) corners corners rot_matrix.T center # 画8条边和6个面这里只画出8条边示意 lines [[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]] line_set o3d.geometry.LineSet() line_set.points o3d.utility.Vector3dVector(corners) line_set.lines o3d.utility.Vector2iVector(lines) line_set.paint_uniform_color([1, 0, 0]) o3d.visualization.draw_geometries([pcd, line_set])注意KITTI框的尺寸顺序和别的数据集不一样这个代码是按KITTI的height, width, length写的换数据集时要先确认格式。5.4 评估指标mAP怎么读才不白跑对于KITTI数据集最终打印出来的日志往往长这样Car AP_easy: -1.00 AP_moderate: -1.00 AP_hard: -1.00头几次看到-1.00先别慌要么是类别名没对上要么是评估参数里没有正确设置eval_metric。KITTI的评估需要你指定使用哪个版本的AP方法常见的是AP_R40也就是在精确率-召回率曲线上做40点插值求平均。不同论文之间比指标如果插值点数不同数值会有明显差异所以对比别人的结果前先确认评估方式一致。KITTI官方把评测结果按难度分成三档难度含义关注程度easy目标高度大于40像素完全可见参考moderate目标高度大于25像素遮挡程度低排名和对比主要看这个hard目标高度大于25像素遮挡程度较高综合能力参考自动驾驶场景里一般只看moderate档的AP。跑完一个模型后我通常会同时记录mAP、每帧推理时间、显存占用三个数据这样换模型时才不会只看一个维度做决策。5.5 一点个人实操心得最后分享一个我实际踩了两次的坑训练时损失一直在降但验证集mAP始终不动。排查了很久发现是数据增强把点云坐标做了随机翻转但对应的朝向角标注没有同步做变换导致模型学到的框朝向和真实标注互相冲突。这个问题的根源不是MMDetection3D而是数据管线的前后一致性没有检查。所以拿到任何新数据先拿出几张图做可视化把标注框和点云叠在一起看一眼再上训练这比损失曲线可靠得多。如果遇到编译阶段反复报错我的建议就一句话不要试图在现在的坏环境里打补丁直接回到“Python 3.8 PyTorch 1.12 CUDA 11.3 mmcv 1.6.2”这个组合重新建环境。我在多台机器上测试过这套组合从克隆源码到跑通Demo通常两个小时以内能完成省下的时间比纠结版本值得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑