Lift-Splat-Shoot 复现
我理解的复现,就是把代码跑通,完整训练一遍,然后测试,争取达到论文里报告的效果。虽然大部分工作复现出来可能都到不了论文里的性能,比较玄学。
概述
Lift-Splat-Shoot (LSS) 是 BEV 方法的开山之作,作者来自 NVIDIA。该方法是一个纯视觉的感知方法,用来做 BEV 分割任务的,但是其架构和思路可以推广到其他感知任务。
思路:等我看懂了再补吧……
代码简介
原代码仓库:https://github.com/nv-tlabs/lift-splat-shoot
我 fork 的仓库:https://github.com/Eslzzyl/lss
LSS 的代码简直是自动驾驶感知方法里的一股清流。
现在的大多数方法都是用 mmdet3d 改的,mmdet3d 相对比较成熟,如果熟悉这个框架改起来当然容易,但 mmdet3d 的环境太难配了,python pytorch cudatoolkit setuptools mmengine mmcv mmdet nuscenes-devkit mmdet3d 这几个包(以及它们的一大堆依赖)的版本互相牵扯,坑非常多;而且这个框架比较复杂,对初学者不是很友好;最难顶的是这些方法绝大多数都是用自己魔改的 mmdet3d 代码库,很多要自己编译 CUDA 算子,又牵扯到 gcc 和 nvcc,问题繁多。
LSS 的代码则是直接在 nuscenes-devkit 的基础上自己写了数据加载、模型结构和训练流程,整体上还是比较复合标准的 PyTorch 训练 pipeline 的,依赖也很少,对像我这样的小白来说比较容易理解。
再加上 LSS 是一个纯视觉的方法,不需要做 Fusion、模态对齐之类的,结构就更简单。这份代码实测可以用最新版本的工具链来训练,详见环境配置部分。
LSS 代码库只有 6 个主要的 Python 文件:
main.py
,程序入口train.py
,训练脚本data.py
,建立在 nuscenes-devkit 基础上的数据加载代码models.py
,模型代码tools.py
,实用工具explore.py
主要是模型验证和可视化代码
环境配置
我配置的环境如下:
- Python 3.12
- Pytorch 2.4.1
- torchvision
- 自己改的 nuscenes-devkit,兼容 Python 3.12
以下是具体配置过程。
创建虚拟环境
建议使用 conda 创建虚拟环境。
conda create -n lss python=3.12
conda activate lss
安装 PyTorch 和 torchvision
本文假定读者已经安装了 NVIDIA 显卡驱动和 CUDA 工具包,示例版本是 12.1。LSS 不需要自行编译 CUDA 算子。
# 此处遵循 PyTorch 官网指南安装最新版本的 pytorch 和 torchvision 即可
conda install pytorch torchvision pytorch-cuda=12.1 -c pytorch -c nvidia
安装 nuscenes-devkit
# 克隆我修改的 nuscenes-devkit
git clone https://github.com/Eslzzyl/nuscenes-devkit.git
cd nuscenes-devkit
# 安装。nuscenes-devkit 的依赖将被自动安装。
pip install -v -e ./setup
安装 LSS 的依赖
# 克隆我修改的 LSS 代码
git clone https://github.com/Eslzzyl/lss.git
cd lss
# 安装依赖
pip install -r requirements.txt
环境配置到此完成。没有恼人的版本不兼容问题,不需要执行任何编译操作。
训练
我尝试了在两套环境上训练 LSS:
- 8 卡 2080Ti(11G),96G内存,双路 Xeon Gold 5118 CPU,共 24 核
- 单卡 4090(24G),41G内存,Xeon w7-3465x CPU,9核(这个是在 docker 容器里面跑的,所以没法用到所有的内存和 CPU)
LSS 代码里设定是 nuScenes trainval 上跑 10000 个 epoch,应该是随便给了一个比较大的数,然后看收敛了就停下来。我改成 1000 了,在环境 1 训练完需要大概 3 天,环境 2 是 6 天。但是环境 1 因为后面内存爆了就停下来了。这里要引以为鉴,nuScenes 上开多个 worker 加载数据非常消耗内存,可用的内存一定要和卡数匹配。
幸运的是,LSS 的数据加载部分没有内存泄露的问题。这个方向有很多代码的数据加载是有内存泄漏的,根本跑不完整个训练过程。
(环境 2)查看 TensorBoard 的日志,基本上到第 20k 个 step 模型就已经收敛,IOU 来到 0.28 左右。此时距离模型开始训练过去了两个小时。
# 在执行下面的命令启动训练之前,先修改 train.sh 中的超参数,确保适合自己的硬件配置,不会导致内存或显存溢出。
bash train.sh
验证
其实就是在 nuScenes 的验证集上跑一遍验证过程,这个和训练过程中的验证是完全一样的。
bash eval.sh
程序将报告 IoU 指标,我这里测的是 0.28 左右。就像上面说的,训练开始不久后验证的 IoU 指标就达到了这个值。
可视化
bash visual.sh
将产生许多张图片,这是其中一张。
总结
LSS 的代码是很值得借鉴的,干净利落,没有太多的封装。