news 2026/9/19 3:02:06

从零跑通BEVFormer:AutoDL上Nuscenes数据集训练全流程指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零跑通BEVFormer:AutoDL上Nuscenes数据集训练全流程指南

自动驾驶纯视觉感知这几年卷得厉害,BEVFormer算是绕不开的一个经典方案。但真正动手在AutoDL上把它跑起来,很多人第一步就被环境、数据、显存这些坎拦住了。我这次从零开始,把Nuscenes数据集完整训练BEVFormer的全流程走了一遍,踩了不少坑,也总结出一套能在AutoDL上快速复现的可靠路径,分享出来给后面要入坑的朋友参考。

先说清楚这套方案能解决什么问题:AutoDL平台按小时计费,GPU资源灵活,非常适合做BEVFormer这种大模型的训练验证;但平台自带环境是通用镜像,要跑BEVFormer,还得自己处理数据格式、依赖版本、训练配置这些细节。这篇文章覆盖从数据集申请下载、环境搭建、配置文件修改到完整训练、报错排查的整个过程,适合已经跑通基础目标检测、准备转入BEV感知方向的研究生或算法工程师。

1. 整体思路与方案选型

1.1 为什么选AutoDL作为训练平台

BEVFormer训练对硬件要求不低,Nuscenes全量数据集单卡训练,显存基本要24GB以上,如果本地没有多卡A100或者RTX 3090/4090,光准备机器就是一笔不小的开销。AutoDL这类云GPU平台的优势在于可以按需租用,训练完就释放,成本相对可控。

我在AutoDL上选择的是RTX 4090(24GB显存)规格的实例,搭配平台提供的PyTorch 2.0 + CUDA 11.8基础镜像。之所以不选A100,一方面是因为4090性价比更高,另一方是因为BEVFormer官方实现基于mmdetection3d框架,对GPU型号并没有特殊依赖,24GB显存跑base版本足够,不需要上80GB的大卡。

1.2 环境版本组合的底层逻辑

BEVFormer最麻烦的地方在于依赖版本耦合非常紧,尤其是mmcv、mmdet、mmseg、mmdet3d这四件套的版本必须严格对齐,版本不匹配会直接导致导入报错或算子编译失败。我最终采用的版本组合如下:

依赖包版本说明
Python3.83.10以下兼容性最好
PyTorch1.13.1官方推荐版本
CUDA11.7与PyTorch配套
mmcv-full1.7.0必须1.6以上,BEVFormer用到了其中的Deformable Attention
mmdet2.28.13.x版本接口变动太大,不推荐
mmseg0.30.0和mmdet版本配套
mmdet3d1.0.0rc6官方分支指定版本

这个组合不是我拍脑袋定的,BEVFormer官方仓库的requirements.txt里写得很清楚,但直接pip install大概率会装上最新版本导致冲突。稳妥做法是先创建conda环境,再按固定顺序安装,后面第3章会详细说。

1.3 方案对比:从头训练还是加载预训练权重

这个问题我纠结了很久。BEVFormer有两种启动方式:一种是完全从头训练,另一种是加载官方提供的nuScenes预训练权重继续训练或微调。从实验角度看,如果只是为了验证代码能跑通、熟悉训练流程,从头训练几百个iteration就够了;如果要做精度对比或下游任务,建议直接加载预训练权重。

我在AutoDL上先做了200 iter的冒烟测试确认流程无问题,再启动完整训练。这样能避免数据或配置问题在长训练跑到一半才暴露,白白烧掉几十个小时的GPU费用。

2. 环境搭建与依赖安装避坑要点

2.1 conda环境创建与PyTorch安装

AutoDL镜像自带conda,我建议创建一个独立环境,不要污染基础环境。

# 创建conda环境 conda create -n bevformer python=3.8 -y conda activate bevformer # 安装PyTorch 1.13.1 + CUDA 11.7 pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 --extra-index-url https://download.pytorch.org/whl/cu117

这里注意不要用AutoDL自带的PyTorch 2.0镜像,因为后续编译mmcv-full时可能出现算子兼容性问题。实测下来PyTorch 1.13.1是BEVFormer全链路最稳的版本,这也是官方CI测试用的版本。

2.2 mmcv-full编译的两种方式与取舍

mmcv-full是BEVFormer里最关键的依赖,负责提供CUDA算子。BEVFormer官方要求mmcv-full版本在1.6.0以上,我用的是1.7.0。安装有两种方式:

方式一:直接安装预编译包(推荐)

pip install mmcv-full==1.7.0 -f https://download.openmmlab.com/mmcv/dist/cu117/torch1.13.1/index.html

这种方式不需要本地编译,几分钟就能装完。前提是PyTorch和CUDA版本要和链接里的对应。

方式二:源码编译安装(备用方案)

如果预编译包安装后出现算子缺失问题,比如ImportError: libcudart.so.11.0: cannot open shared object file,则需要源码编译:

git clone https://github.com/open-mmlab/mmcv.git -b v1.7.0 cd mmcv MMCV_WITH_OPS=1 pip install -e .

源码编译耗时视机器性能而定,AutoDL上大约20到40分钟。这里要提醒的是,编译前确认gcc版本不低于7.0,否则会报internal compiler error

2.3 mmdet、mmseg、mmdet3d安装顺序

三个包安装顺序不能乱,因为mmdet3d的安装会依赖mmdet和mmseg,且版本必须匹配。我按以下顺序执行:

# 先安装mmdet和mmseg pip install mmdet==2.28.1 mmseg==0.30.0 # 再安装mmdet3d,从源码安装指定版本 git clone https://github.com/open-mmlab/mmdetection3d.git -b v1.0.0rc6 cd mmdetection3d pip install -e .

这里的坑在于,如果先装mmdet3d再装mmdet,pip会主动把mmdet升级到3.x版本,导致BEVFormer无法启动。装完后建议用pip list验证一下四个核心包的版本都符合上表。

2.4 其他依赖与常见编译报错

BEVFormer还依赖一些其他库,比如timmeinopsnumpy等。有一个关键点:numpy版本必须锁定在1.23.5以下,新版numpy在PyTorch 1.13下会出现module 'numpy' has no attribute 'bool'一类的报错。执行:

pip install numpy==1.23.5 timm einops yapf==0.40.1

另外还有一个很隐蔽的坑:mmdet3d 1.0.0rc6在编译时会检查torchvision的版本,如果版本过高会出现AssertionError: TorchVision not found之类误报。上面安装的0.14.1版本是安全的。

3. Nuscenes数据集获取与处理全流程

3.1 数据下载:官方渠道与磁盘空间规划

Nuscenes完整数据集比较大,包含1000个场景,每个场景约20秒,总共约300GB以上。在AutoDL上下载时,要格外注意两点:第一是AutoDL系统盘一般只有50GB,数据必须放到数据盘(一般挂载在/root/autodl-tmp),第二是数据下载速度受官网限制,从官网直接下载非常慢。

建议先在本地官网注册并申请下载权限,然后获取下载链接,再到AutoDL上用wgetaria2c并行下载。整个数据集包括:

数据内容大小说明
trainval约70GB训练集和验证集图像
test约46GB测试集图像(可选)
CAN bus约9GB车辆CAN总线数据
map约7GB高精地图扩展包
标注文件约8GBjson标注

如果只是做训练验证,trainval加上map和CAN bus就够用了,test可以不下载。我在AutoDL数据盘上预留了300GB空间,实际使用约120GB,包括后续生成的中间文件。

3.2 数据集目录结构规范

Nuscenes数据必须按照mmdet3d规定的目录结构存放,否则后续生成info文件时找不到路径。规范结构如下:

nuscenes/ ├── maps/ ├── samples/ ├── sweeps/ ├── v1.0-trainval/ ├── can_bus/ ├── lidarseg/ └── (test目录可选)

下载完成后,先建立一个软链接指向你的数据目录,方便多个项目共用同一份数据:

mkdir -p data/nuscenes ln -s /root/autodl-tmp/nuscenes data/nuscenes

3.3 使用官方工具生成pkl标注文件

mmdet3d训练需要把Nuscenes的json标注转换成pkl格式,这里用到的工具是官方仓库里的create_data.py。在BEVFormer仓库的tools目录下执行:

python tools/create_data.py nuscenes \ --root-path ./data/nuscenes \ --out-dir ./data/nuscenes \ --extra-tag nuscenes \ --version v1.0-trainval \ --canbus ./data/nuscenes

这一步生成的文件包括:

  • nuscenes_infos_train.pkl:训练集所有帧的传感器标注信息
  • nuscenes_infos_val.pkl:验证集标注信息
  • nuscenes_dbinfos_train.pkl:用于data augmentation的数据库信息
  • nuscenes_infos_test.pkl:测试集信息(如果下载了test数据)
  • nuscenes_infos_train_mono3d.coco.json:单目3D标注格式,BEVFormer不强制使用,但可以顺带生成

生成过程大约需要30到60分钟,取决于数据盘IO性能。如果中途报缺失文件,多半是下载时漏了某个子目录,回到3.1检查。

3.4 数据加载验证:确认pkl文件可正确读取

在正式训练之前,先验证数据是否能被正确加载。我写了一个简单的测试脚本:

import pickle with open('./data/nuscenes/nuscenes_infos_train.pkl', 'rb') as f: data = pickle.load(f) print(len(data['infos'])) # 训练集大约28130条 sample = data['infos'][0] print(sample['lidar_path']) print(sample['cam_sweeps'].keys())

如果正常输出路径和相机sweep的键名,说明数据文件没问题。这里如果报KeyError: 'cam_sweeps',说明你用的create_data.py版本和BEVFormer仓库不一致,需要从BEVFormer官方仓库里拉取对应的data_converter脚本。

4. 配置文件修改与训练启动

4.1 配置文件结构与关键参数解读

BEVFormer的训练配置在projects/configs/bevformer/目录下,核心文件是bevformer_base.py。这个文件是继承结构,先加载基础配置,再叠加数据集和模型配置。看懂这个文件是调通训练的前提。

几个关键参数的作用如下:

参数名默认值作用
voxel_size[0.512, 0.512, 8]体素分辨率,影响BEV网格大小
point_cloud_range[-51.2, -51.2, -5, 51.2, 51.2, 3]感知范围,正负51.2米
bev_h/bev_w200 / 200BEV特征图尺寸
num_query900可学习query数量
num_classes10检测类别数,Nuscenes是10类
use_emaFalse是否启用指数滑动平均
save_epoch1每隔多少个epoch保存一次ckpt

训练策略方面,BEVFormer base版本默认训练24个epoch,学习率初始为2e-4,采用了余弦退火调度。如果只想验证流程,建议直接把total_epochs改成1,log_config的间隔调小到每10次迭代打印一次。

4.2 针对单卡训练的资源配置调整

AutoDL租用单张4090时,不能直接用官方默认的多卡配置,需要手动调整以下参数:

# 在bevformer_base.py中修改 data = dict( samples_per_gpu=1, # 单卡batch size设为1,4090 24GB只能跑1 workers_per_gpu=4, ) optimizer = dict( type='AdamW', lr=2e-4, paramwise_cfg=dict(custom_keys={'backbone': dict(lr_mult=0.1)}), )

batch size是最关键的,BEVFormer的显存占用大头在BEV特征图和可变形注意力模块上,24GB显存跑batch size=1已经是极限,如果想跑大batch,需要A100 80GB或者多卡并行。

另外,由于用了单卡,需要去掉配置文件里的find_unused_parameters相关设置,并确保gpu_ids为[0]:

gpu_ids = [0]

4.3 启动完整训练:命令与日志分析

环境配置无误后,进入BEVFormer仓库根目录,执行训练命令:

cd /root/autodl-tmp/BEVFormer python tools/train.py projects/configs/bevformer/bevformer_base.py \ --work-dir ./work_dirs/bevformer_base \ --gpus 1

启动后观察日志输出,重点看以下几个方面:

  • 模型结构加载:确认各模块参数量,总参数量约69MB(BEVFormer-Base),如果显示为0或无法加载多为依赖缺失
  • 数据集初始化:正常情况下会输出Loading 28130 annotations之类信息,耗时约10分钟
  • 显存占用:用nvidia-smi实时查看,训练稳定后显存应在20-23GB之间,如果超24GB就会OOM

正常启动后,日志每10步输出一次loss,期望数值在初始阶段大约5到8之间,随着训练逐渐下降。如果初始loss直接飙升到几百,优先检查学习率是否过大或数据label是否有问题。

4.4 checkpoint保存与中断恢复

长训练过程中因网络抖动、机器抢占等原因导致中断是很常见的事。BEVFormer支持从ckpt恢复训练:

python tools/train.py projects/configs/bevformer/bevformer_base.py \ --work-dir ./work_dirs/bevformer_base \ --resume-from ./work_dirs/bevformer_base/epoch_10.pth

这里建议把AutoDL的自动快照功能打开,但快照只保存系统盘,数据盘里的数据不受影响。如果实例被释放了,重新创建一个同配置实例、挂载同一数据盘,再手动把代码和work_dir同步过来即可,不需要重新处理数据。

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

5.1 显存不足导致OOM

OOM是最常见的问题,尤其是在生成BEV特征时。报错通常长这样:

RuntimeError: CUDA out of memory. Tried to allocate 2.00 GiB (GPU 0; 23.70 GiB total capacity; ...)

排查顺序:先用nvidia-smi看显存是否被其他进程占用,然后用fuser -v /dev/nvidia*杀掉多余进程;如果确认是训练本身超限,依次尝试以下方案:

  • samples_per_gpu从1改为1且开启cudnn.benchmark=False
  • 降低bev_hbev_w到150×150(这是最后手段,会牺牲精度)
  • 检查mmcv-full是否开启了磁盘缓存,MKL_SERVICE_FORCE_INTEL=1等环境变量有时能小幅降低显存

4090在batch size=1下基本能跑满24GB,如果还OOM,优先怀疑是不是其他地方改了配置文件导致特征图尺寸变大。

5.2 加载预训练权重时的shape mismatch

使用官方提供的BEVFormer预训练模型做微调时,经常遇到以下报错:

size mismatch for img_backbone.backbone.conv1.weight: copying a param with shape torch.Size([64, 3, 7, 7]) from checkpoint, the shape in current model is torch.Size([128, 3, 7, 7])

这个原因是预训练模型的backbone输入通道数(3通道RGB图)和配置文件里的num_cams或图像尺寸设置不一致。遇到这个情况,用tools/convert_bevformer_checkpoints.py脚本转换权重,或者直接忽略backbone权重只加载neck和head部分:

load_from = 'path/to/checkpoint.pth' # 在配置文件中加一行 load_from = None # 改为None表示不加载预训练权重

如果是刻意忽略backbone,用mmcv.runnerload_checkpoint接口并设置strict=False即可。

5.3 CUDA算子版本相关报错

BEVFormer的核心算子Deformable Attention在mmcv-full里编译,如果版本不对,会出现:

ModuleNotFoundError: No module named 'mmcv.ops.multi_scale_deformable_attn'

这是mmcv-full没有正确编译GPU算子导致的。解决方法是执行3.2节的源码编译方式,确认编译日志中出现Compiling ops... done字样。还有一种情况是mmcv和mmcv-full装重了,需要先卸载再安装:

pip uninstall mmcv mmcv-full -y pip install mmcv-full==1.7.0 -f https://download.openmmlab.com/mmcv/dist/cu117/torch1.13.1/index.html

5.4 训练结束后评估精度异常

训练24个epoch后在验证集上评估,如果mAP非常低(比如不到0.1),而loss已经收敛,问题多半出在数据加载或后处理上。排查方向有:

  • 确认test配置里的ann_file指向的是nuscenes_infos_val.pkl,而不是训练集
  • 确认class_names顺序和Nuscenes官方顺序一致(默认顺序是car, truck, trailer, bus, construction_vehicle, bicycle, motorcycle, pedestrian, barrier, traffic_cone
  • 确认是否加载了ema权重,BEVFormer官方实验里开启EMA后精度更高

我在调试时发现一个隐蔽问题:验证时NMS阈值设太高(0.7以上),导致大量预测框被滤除,mAP掉得厉害。把nms_iou_thr调到0.5后恢复了正常水平。

5.5 常见问题速查表

症状原因解决方案
启动即报No module named 'mmcv.ops'mmcv-full未正确编译源码重编译mmcv-full
size mismatch加载权重失败配置文件与ckpt结构不一致设置strict=Falseconvert脚本
CUDA OOMbatch size过大或显存被占用调小batch,清理进程
numpy bool报错numpy版本过新锁定numpy==1.23.5
训练loss为NaN学习率过大或数据有脏值降低lr,检查标注有无无穷值
验证时KeyError: 'pts_bbox'mmdet3d版本与配置文件不匹配升级/降级mmdet3d到rc6
pkl文件加载慢磁盘IO瓶颈数据放到SSD数据盘,不要放系统盘

6. 训练效率优化与后续扩展建议

6.1 开启混合精度训练

BEVFormer base版本使用FP32训练,24GB显存只能跑batch size=1,但开启AMP(自动混合精度)后,显存占用可以降到18GB左右,还能小幅提升训练速度。配置文件里增加:

fp16 = dict(loss_scale='dynamic')

但需要确认模型中有部分算子不支持FP16,尤其是multi_scale_deformable_attn,实测下来BEVFormer官方代码是支持AMP的,只是精度会有轻微波动。对实验验证场景完全够用。

6.2 使用分布式训练加速

AutoDL上可以租用多卡实例,比如4×4090。修改启动命令:

bash tools/dist_train.sh projects/configs/bevformer/bevformer_base.py 4 \ --work-dir ./work_dirs/bevformer_base

同时把配置里的data.samples_per_gpu改成1,这样总batch size变为4。BEVFormer官方在8卡A100上训练24个epoch大约需要40小时,单张4090上要明显更久,多卡能缩短到可控范围。代价是loss曲线可能会略有波动,这是正常的。

6.3 数据增强与超参数微调实验

如果想进一步提升模型效果,可以从几个方向入手:

  • use_cbgs=True:开启类别平衡采样,对Nuscenes这种类别分布不均的数据集有明显增益
  • rotate_prev_bev:对上一帧BEV特征做随机旋转,增强时序鲁棒性
  • 增大num_query从900到1200:能提升密集场景下的小目标召回率,但显存会增加

做实验时建议用--auto-resume配合的可视化工具追踪不同配置在验证集上的NDS(nuScenes检测分数)和mAP曲线,只留最优配置做长训练。

6.4 部署到真实场景的路径

训练完模型之后,如果要做实车或实机部署,BEVFormer官方TensorRT转换需要把模型导出为ONNX再转engine。需要注意的是BEVFormer包含了时序融合的buffer,导出时需要把use_temporal标志位设成False或固定bev_embedding维度。这块相对复杂,建议先跑通pytorch推理,再考虑TensorRT优化。我在实际部署时发现Nuscenes训练出的模型在real-world数据上泛化性需要评估,建议针对目标场景采集数据做finetune。

根据我的经验,如果在AutoDL上从零开始,环境搭建大约2小时,数据处理1到2小时,冒烟测试半小时,后续全量训练就是时间问题。关键是把环境版本锁死、数据目录规范处理好,后面踩坑的概率会大幅下降。这套流程我已经跑通多次,希望对准备入坑BEVFormer的朋友有帮助。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 3:00:13

从零搭建灵活区域定义:GeoJSON、Leaflet与PostGIS实战

做过一段时间地图相关的业务系统,你会发现“区域”这个词真的很微妙。最初可能只是想在地图上画个范围,圈一下配送区域、门店服务范围或者设备管理辖区,觉得无非是拉几个点、连成一个多边形的事。但真正上线跑起来,需求就开始“活…

作者头像 李华
网站建设 2026/9/19 2:58:32

LaTeX转Word公式乱码与排版崩溃全解析:Pandoc与ai2word实战横评

学术写作圈子里有个老生常谈的痛点:论文用 LaTeX 写完了,投稿系统或者导师偏偏要 Word 版本。公式一多,转换就是灾难现场——行内公式变成图片、编号错乱、特殊符号直接变问号,更别提那些带自定义宏的模板,转完基本等于…

作者头像 李华
网站建设 2026/9/19 2:58:32

MySQL报错1093:同表更新子查询的成因与解法

好几次在线上环境排查数据订正任务,都撞见同一个报错:ERROR 1093 (HY000): You cant specify target table tb for update in FROM clause。第一次遇到是在一个给用户打分的存储过程里,日志刷了几百条这个错误,任务直接中断。后来…

作者头像 李华
网站建设 2026/9/19 2:58:10

H5华容道游戏开发实战:数据结构、碰撞检测与拖拽交互

最近在做一个华容道题材的H5小游戏,从规则建模到拖拽交互再到自动求解,把整个开发流程完整趟了一遍。这个东西看着简单,真正上手做才发现,光是棋子的数据结构和移动判定就能绕进去半天。这篇文章整理一下我实际用到的设计思路、代…

作者头像 李华
网站建设 2026/9/19 2:55:45

Continue 下拉框没有 deepseek-v4-pro?TaoToken 这样改 config.json

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华