专栏感知手把手教你利用算法工具链训练、量化、编译、可视化J6参考算法BEVFormer

手把手教你利用算法工具链训练、量化、编译、可视化J6参考算法BEVFormer

默认166402024-08-06
962
5

写在前面:

关于OE包内参考算法的使用,地平线已经释放了大量文档指导用户完成各类模型的训练、校准、量化、定点过程,但其中有些细节可能会对不是特别熟悉算法工具链的客户造成困扰,本文档致力于消除参考算法使用过程中所有可能存在的模糊操作,引导初学者快速上手参考算法,在实操中树立信心、激发学习兴趣。

1 环境部署

1.1 开发机准备

为了顺利地使用工具链,地平线建议您选择的开发机应满足以下要求:

硬件/操作系统要求CPUCPU I3以上或者同级别E3/E5的处理器内存16G或以上级别GPUCUDA11.8、驱动版本Linux:>= 510.39.01*

(推荐驱动版本Linux:520.61.05)

适配显卡包括但不限于:

1. GeForce RTX 3090

2. GeForce RTX 2080 Ti

3. NVIDIA TITAN V

4. Tesla V100S-PCIE-32GB

5. A100系统原生Ubuntu 22.04

1.2 Docker容器部署

地平线要求的Docker基础环境如下,请提前在您的宿主机上完成安装:

完成Docker基础环境安装后,还需要将无root权限的用户添加到Docker用户组中。参考命令如下:


拉取docker镜像,并下载OE开发包,将OE开发包和Nuscenes数据集挂载到docker容器中。参考命令如下:

注意,“--gpus”参数一定要设置为all,代表着在容器内能使用开发机所有的GPU,“--shm-size”一定要修改,不然默认共享内存仅为64MB。

2 数据集准备

2.1 数据集下载

进入nuscenes官网,根据提示完成账户的注册,下载Full dataset(v1.0)、CAN bus expansion和Map expansion(v1.3)、nuScenes-lidarseg这四个项目下的文件。下载后的压缩文件为:

Full dataset(v1.0)包含多个子数据集,如果不需要进行v1.0-trainval数据集的浮点训练和精度验证,可以只下载v1.0-mini数据集进行小场景的训练和验证。

2.2 Full dataset版本数据集打包和meta文件夹构建

2.2.1 数据集打包

将下载完成的v1.0-trainval01_blobs.tar~v1.0-trainval10_blobs.tar、nuScenes-lidarseg-all-v1.0.tar.bz2、v1.0-trainval_meta.tar、nuScenes-map-expansion-v1.3.zip和can_bus.zip进行解压,解压后的目录如下所示:

进入 horizon_model_train_sample/scripts 目录,使用以下命令将训练数据集和验证数据集打包,格式为lmdb。如果将上述nuscenes文件夹放到上述目录内,下面WORKSPACE可替换为`pwd`。

打包结束生成目录如下所示。

  • --src-data-dir为解压后的nuscenes数据集目录;

  • --target-data-dir为打包后数据集的存储目录;

  • --version 选项为["v1.0-trainval", "v1.0-test", "v1.0-mini"],如果进行全量训练和验证设置为v1.0-trainval,如果仅想了解模型的训练和验证过程,则可以使用v1.0-mini数据集;v1.0-test数据集仅为测试场景,未提供注释。

  • 全量的nuscenes数据集较大,打包时间巨长,如果仅仅作为学习使用mini版就好。

2.2.2 meta文件夹构建

  • 在tmp_data/nuscenes 下创建meta文件夹,如果使用--version = "v1.0-mini",将解压后的v1.0-mini文件夹拷贝到tmp_data/nuscenes/meta 文件夹内,如果使用--version = "v1.0-trainval",将解压后的v1.0-trainval文件夹拷贝到tmp_data/nuscenes/meta 文件夹内;
  • 将解压后的maps文件夹拷贝到tmp_data/nuscenes/meta 文件夹内;
  • 将解压后的lidarseg文件夹拷贝到tmp_data/nuscenes/meta 文件夹内。

如果使用--version = "v1.0-trainval",此时tmp_data的目录结构为:

2.3 Mini dataset版本数据集打包和meta文件夹构建

如果需要使用mini数据集,在BEVFormer对应的config文件"bevformer_tiny_resnet50_detection_nuscenes"中,需要更改以下配置:

float_trainer/predictor、calibration_trainer/predictor、qat_trainer/predictor、int_infer_predictor/int_infer_trainer的version:数据集的版本,选项为["v1.0-trainval", "v1.0-test", "v1.0-mini"],选择"v1.0-mini"。

2.3.1 数据集打包

如果下载的是Full dataset(v1.0)中的Mini、CAN bus expansion和Map expansion(v1.3)、nuScenes-lidarseg这四个项目下的文件,将下载完成的v1.0-mini.tgz、nuScenes-lidarseg-all-v1.0.tar.bz2、nuScenes-map-expansion-v1.3.zip和can_bus.zip进行解压,解压后的目录如下所示:

进入 horizon_model_train_sample/scripts 目录,使用以下命令将训练数据集和验证数据集打包,格式为lmdb。如果将上述nuscenes文件夹放到上述目录内,下面WORKSPACE可替换为`pwd`。

打包结束生成目录如下所示。

  • --src-data-dir为解压后的nuscenes数据集目录;

  • --target-data-dir为打包后数据集的存储目录;

  • --version 选项为["v1.0-trainval", "v1.0-test", "v1.0-mini"],如果进行全量训练和验证设置为v1.0-trainval,如果仅想了解模型的训练和验证过程,则可以使用v1.0-mini数据集;v1.0-test数据集仅为测试场景,未提供注释。

  • 全量的nuscenes数据集较大,打包时间巨长,如果仅仅作为学习使用mini版就好。

2.3.2 meta文件夹构建

  • 在tmp_data/nuscenes 下创建meta文件夹,如果使用--version = "v1.0-mini",将解压后的v1.0-mini文件夹拷贝到tmp_data/nuscenes/meta 文件夹内,如果使用--version = "v1.0-trainval",将解压后的v1.0-trainval文件夹拷贝到tmp_data/nuscenes/meta 文件夹内;
  • 将解压后的maps文件夹拷贝到tmp_data/nuscenes/meta 文件夹内;
  • 将解压后的lidarseg文件夹拷贝到tmp_data/nuscenes/meta 文件夹内。

如果使用--version = "v1.0-mini",此时tmp_data的目录结构为:

3 权重文件准备

如果不想重复BEVFormer模型的训练、校准、量化、定点过程,可从scripts/configs/bev/README.md内下载BEVFormer的权重文件,用于浮点模型精度验证、Calibration模型精度验证、量化模型精度验证、定点模型精度验证、仿真上板精度验证,或可视化定点模型对于单帧的检测效果,权重文件的下载命令参考:
将权重文件拷贝到scripts/tmp_models/文件夹内,此时tmp_models的目录结构为:

如果想完整复现BEVFormer模型的训练、校准、量化、定点过程,可在数据集和Config文件配置完成后,按照第4、5、6部分的指导进行。

4 Config文件配置

config内容较多,对于用户来说,需要关注的主要有以下参数:

  • device_ids:配置为本机支持的GPU,根据开发环境进行配置;

  • ckpt_dir:权重路径配置;

  • data_rootdir:打包数据集路径配置;

  • meta_rootdir:meta文件所在的路径;

  • float_trainer/predictor、calibration_trainer/predictor、qat_trainer/predictor、int_infer_trainer/int_infer_predictor的checkpoint_path:权重路径配置;

  • float_trainer/predictor、calibration_trainer/predictor、qat_trainer/predictor、int_infer_predictor/int_infer_trainer的version:数据集的版本,选项为["v1.0-trainval", "v1.0-test", "v1.0-mini"]。

上述checkpoint_path和version需要根据数据集的版本和使用需求修改。

5 浮点模型训练和精度验证

5.1 浮点模型训练

config文件中的参数配置完成后,使用以下命令训练浮点模型(如果训练浮点模型,需要使用完整数据集而非mini):

float训练后模型ckpt的保存路径为config配置的ckpt_callback中save_dir的值,默认为ckpt_dir。

5.2 浮点模型精度验证

浮点模型训练完成以后,可以使用以下命令验证已经训练好的浮点模型精度:

验证完成后,会在终端打印浮点模型在验证集上检测精度,如下所示:


6 模型量化和编译

完成浮点训练后,还需要进行量化训练和编译,才能将定点模型部署到板端。地平线对该模型的量化采用horizon_plugin框架,经过Calibration+QAT量化训练后,使用compile的工具将量化模型编译成可以上板运行的hbm文件。

6.1 Calibration

模型完成浮点训练后,便可进行 Calibration。calibration在forward过程中通过统计各处的数据分布情况,从而计算出合理的量化参数。 通过运行下面的脚本就可以开启模型的Calibration过程:

6.2 Calibration 模型精度验证

Calibration完成以后,可以使用以下命令验证经过calib后模型的精度:

验证完成后,会在终端输出calib模型在验证集上检测精度。

6.3 量化模型训练

Calibration完成后,就可以加载calib权重开启模型的量化训练。 量化训练其实是在浮点训练基础上的finetue,具体配置信息在config的qat_trainer中定义。量化训练的时候,初始学习率设置为浮点训练的十分之一,训练的epoch次数也大大减少。和浮点训练的方式一样,将checkpoint_path指定为训好的calibration权重路径。

通过运行下面的脚本就可以开启模型的qat训练:

6.4 量化模型精度验证

Calibration完成以后,可以使用以下命令验证经过calib后模型的精度:

验证完成后,会在终端输出calib模型在验证集上检测精度,格式见2.3。

6.5 导出定点模型

完成量化训练后,便可以开始导出定点模型。可以通过下面命令来导出:

6.6 定点模型精度验证

指定calibration-checkpoint后,通过运行以下命令进行量化模型的精度验证:

qat模型的精度验证对象为插入伪量化节点后的模型(float32);quantize模型的精度验证对象为定点模型(int8),验证的精度是最终的int8模型的真正精度,这两个精度应该是十分接近的。

6.7 量化模型编译

在量化训练完成之后,可以使用compile_perf.py脚本将量化模型编译成可以板端运行的hbm模型,同时该工具也能预估在BPU上的运行性能,compile_perf脚本使用方式如下:

opt为优化等级,取值范围为0~3,数字越大优化等级越高,编译时间更长,但部署性能更好。

compile_perf脚本将生成.html文件和.hbm文件(compile文件目录下),.html文件为BPU上的运行性能,.hbm文件为上板实测文件。

运行后,ckpt_dir的compile目录下会产出以下文件:

7 模型推理效果可视化

如果你希望可以看到训练出来的模型对于单帧的检测效果,我们的tools文件夹下面同样提供了预测及可视化的脚本,你只需要运行以下脚本即可,可视化结果将会在save-path路径下输出。

但在此之前你需要在/script中组织你的tmp_orig_data文件夹,文件夹目录为:

imgs为同一时刻下6个相机输出的图片;

其中homo文件夹内的ego2global.npy、ego2img.npy分别是上述图像对应的自车坐标系到世界坐标系、自车坐标系到像素坐标系的homo矩阵,尺寸分别为(4,4)和(6,4,4)。

上述信息可通过一下脚本生成:


可视化示例如下:

感知
社区征文技术深度解析
+8
评论1
0/1000
  • Lby
    Lv.1

    你好,nuScenes-lidarseg-all-v1.0.tar.bz2解压出来的

    v1.0-trainval下有category.json和lidarseg.json

    与v1.0-trainval放到一个目录下会覆盖v1.0-trainval原有的category.json和lidarseg.json

    而trainval和lidarseg两者的category.json和lidarseg.json是不一样的,lidarseg内文件size更大。所以覆盖了会对trainval的全量数据造成影响吗?

    2024-08-13
    0
    4
    • Lby回复Lby:

      纠正下错误,trainval数据集v1.0-trainval没有lidarseg.json。但category.json(4.7kb)会被nuScenes-lidarseg-all-v1.0.tar.bz2下v1.0-trainval的category.json(8.1kb)覆盖

      2024-08-13
      0
    • 默认16640回复Lby:

      好的,感谢提醒和补充!


      2024-08-22
      0
    • vilon888回复Lby:

      hihi, 完全按照帖子做了,原始nuscenes 数据目录严格按照贴子,,但任然报错:

      2024-10-31 05:47:55,174 INFO [nuscenes_dataset.py:2814] Node[0] process sample cef5745a54e24c7a9111d449e336b4ed ...

      Process ForkProcess-2:

      Traceback (most recent call last):

       File "/usr/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap

        self.run()

       File "/usr/lib/python3.10/multiprocessing/process.py", line 108, in run

        self._target(*self._args, **self._kwargs)

       File "/usr/local/lib/python3.10/dist-packages/hat/data/datasets/data_packer.py", line 39, in _read_worker

        raise e

       File "/usr/local/lib/python3.10/dist-packages/hat/data/datasets/data_packer.py", line 34, in _read_worker

        block = packer.pack_data(idx)

       File "/usr/local/lib/python3.10/dist-packages/hat/data/datasets/nuscenes_dataset.py", line 2916, in pack_data

        data_meta = self.dataset[idx]

       File "/usr/local/lib/python3.10/dist-packages/hat/data/datasets/nuscenes_dataset.py", line 2617, in __getitem__

        return self._gen_info(self.samples[index])

       File "/usr/local/lib/python3.10/dist-packages/hat/data/datasets/nuscenes_dataset.py", line 2829, in _gen_info

        self._gen_occ_gt(scene, sample_info)

       File "/usr/local/lib/python3.10/dist-packages/hat/data/datasets/nuscenes_dataset.py", line 2422, in _gen_occ_gt

        occ_labels = np.load(occ_gt_path)

       File "/usr/local/lib/python3.10/dist-packages/numpy/lib/npyio.py", line 390, in load

        fid = stack.enter_context(open(os_fspath(file), "rb"))

      FileNotFoundError: [Errno 2] No such file or directory: '/data/horizon_j6/data/nuscenes_srcdata/nuscenes/occ3d/gts/scene-0273/cef5745a54e24c7a9111d449e336b4ed/labels.npz'

      2024-10-31 05:47:55,275 INFO [nuscenes_dataset.py:2814] Node[0] process sample 2e3374eb19ee46e09fd0fa90281fbc7d ...

      感觉这个pack过程还用到occ 3d的gts, 难道执行这个脚本前,需要执行摸个occ 3d gts生成脚本吗?

      看call stack,这个已经是hat库里面的调用了,

      2024-10-31
      0
    • 未见青山老回复vilon888:

      OCC数据下载步骤:

      1. 在README 的 Download 一节,下载对应版本(mini or trainval)的数据。

      2. 将下载的 gts.tar.gz 解压到 nuscene/occ3d 目录下。

      2024-10-31
      0