DeepStream-3D 多模态 BEVFusion 设置#

该管线高效处理来自 6 个摄像头和 1 个激光雷达的数据,利用预训练的 PyTorch BEVFusion 模型。此模型针对 NVIDIA GPU 进行了优化,使用了 TensorRT 和 CUDA,正如 CUDA-BEVFusion 项目所展示的那样。为了增强集成,基于 PyTriton 的多模态推理模块 (triton-lmm) 简化了 Python BEVFusion 模型的整合。该管线无缝地使用 ds3d::datatfiler 通过 gRPC 进行 triton 推理。最终,用户可以通过检查带有 6 个摄像头视角的 ds3d::datamap 来可视化结果。该管线还将激光雷达数据和 3D 边界框投影到每个视角中。此外,相同的激光雷达数据在顶视图和侧视图中都经过周全的可视化,以增强理解。

DeepStream 3D Lidar BEVFusion pipeline overview

要运行演示,您需要运行两个进程,可以在同一台机器上或不同的机器上。

  • 运行 tritonserver 以启动 pytriton 托管的 BEVFusion 模型。 此模型需要 GPU 计算能力为 8.0 或更高版本的 x86 平台。

  • 运行 DS3D 传感器融合 3D 检测管线以从 Triton 服务器请求推理。 该管线可以在任何 x86 或 Jetson 平台上运行。

先决条件#

  • 必须安装以下开发包。

    • GStreamer-1.0

    • GStreamer-1.0 基础插件

    • GLES 库

    • libyaml-cpp-dev

  • 本地下载并安装 DeepStream SDK

Triton Server 的依赖项在构建 DeepStream Triton BEVFusion 容器期间自动安装。检查依赖项在

/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-3d-lidar-sensor-fusion/bevfusion/bevfusion.Dockerfile

注意

如果在容器外部运行脚本,或者遇到文件读/写权限错误,请使用 sudo -E 运行命令。

开始入门#

要开始入门,请导航到以下目录

# run the following commandline outside of the container.
$ export DISPLAY=0.0 # set the correct display number if DISPLAY is not exported
$ xhost +
$ cd /opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-3d-lidar-sensor-fusion
$ sudo chmod -R a+rw . # Grant read/write permission for all of the files in this folder

注意

除非另有说明,否则以下所有 BEVFusion 设置的命令行都在容器外部运行

在带有独立 GPU 的 X86 上准备 DeepStream Triton BEVFusion 容器和模型#

构建 deepstream-triton-bevfusion [x86] 的 Docker 目标镜像#

构建名为 deepstream-triton-bevfusion:{DS_VERSION_NUM} 的 docker 目标镜像。确保 DeepStream 版本号 {DS_VERSION_NUM} 大于或等于 7.0。

运行以下脚本以在 DeepStream Triton 基础镜像之上构建目标镜像

# The following commands are require to enable Docker-in-Docker functionality if anyone want to run
# DeepStream docker inside another docker.
# Please start the container using a command like the following, adding your own parameters as needed:
# docker run --gpus all -it --rm --net=host --privileged \
#      -v /usr/bin/docker:/usr/bin/docker \
#      -v /usr/libexec/docker:/usr/libexec/docker \
#      -v /var/run/docker.sock:/var/run/docker.sock \
#      -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY nvcr.io/nvidia/deepstream:{xx.xx.xx}-triton-multiarch
$ bevfusion/docker_build_bevfusion_image.sh nvcr.io/nvidia/deepstream:{xx.xx.xx}-triton-multiarch

注意

将 {xx.xx.xx} 替换为大于或等于 7.0 的版本号。最新的基础镜像可以在以下位置找到:https://catalog.ngc.nvidia.com/orgs/nvidia/containers/deepstream

下载 CUDA-BEVFusion 模型并构建 TensorRT 引擎文件 [x86]#

从 CUDA-BEVFusion 下载模型块,并使用 trtexec 将一些 ONNX 模型块转换为具有 INT8 精度的 TensorRT 引擎文件。用户需要指定一个主机目录来存储模型。该脚本会将此目录挂载到目标容器以准备模型文件。

首先,请访问 NVIDIA-AI-IOT/Lidar_AI_Solution 以获取有关如何直接下载模型的最新说明。然后将您下载的 model.zip 移动到 bevfusion/model_root 目录,然后再构建模型。

要将您下载的模型移动到默认文件位置

$ mkdir bevfusion/model_root
$ sudo cp {PATH TO YOUR model.zip DOWNLOAD} /opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-3d-lidar-sensor-fusion/bevfusion/model_root/model.zip

然后基于目标 Docker 镜像运行以下脚本

$ bevfusion/docker_run_generate_trt_engine_models.sh bevfusion/model_root

所有模型都可以在主机目录 bevfusion/model_root 中找到。

启动用于 BEVFusion 模型的 Tritonserver [x86]#

启动带有 localhost:8001 的 Tritonserver 以服务 BEVFusion 模型。从之前的步骤中指定模型根目录。该脚本将启动 triton_lmm Python 模块,以使用 NVIDIA Triton-python 后端服务 BEVFusion 模型。运行以下脚本以启动服务器

$ bevfusion/docker_run_triton_server_bevfusion.sh bevfusion/model_root

[已弃用] 作为使用 Tritonserver 的替代方案,您可以启动 PyTriton 服务器来托管 BEVFusion 模型。请注意,Triton-python 的性能平均而言优于 PyTriton,因为它支持仅 GPU 数据缓冲区,但 PyTriton 仍然与 DS3D 管线兼容。

要启动 PyTriton 服务器,请运行以下脚本

$ bevfusion/docker_run_pytriton_server_bevfusion.sh bevfusion/model_root

下载测试数据并启动 DS3D BEVFusion 管线#

将 NuScenes 子集数据集下载到主机目录 data/nuscene,并将数据集挂载到目标容器中以启动 BEVFusion 管线。该脚本将自动检查并下载数据集。nuscene 用于 DS3D bevfusion 的数据集托管在 GitHub Deepstream 参考应用

bevfusion/docker_run_ds3d_sensor_fusion_bevfusion_pipeline.sh 脚本将自动检查并将数据集下载到主机目录 ‘data/nuscene’。

如果您想手动下载并解压缩数据集,请运行以下脚本

$ export NUSCENE_DATASET_URL="https://github.com/NVIDIA-AI-IOT/deepstream_reference_apps/raw/DS_7.1/deepstream-3d-sensor-fusion/data/nuscene.tar.gz"
$ mkdir -p data && curl -o data/nuscene.tar.gz -L ${NUSCENE_DATASET_URL}
$ tar -pxvf data/nuscene.tar.gz -C data/

注意

nuscene 数据集受非商业用途许可协议约束。请参阅使用条款:<https://www.nuscenes.org/terms-of-use>

有 2 个 BEVFusion 配置文件,具有相同的管线,但具有不同的 3D 渲染选项。- ds3d_lidar_plus_multi_cam_bev_fusion.yaml 将每个摄像头和激光雷达数据渲染到多视图窗口中,同时将激光雷达数据和检测到的 3D 边界框投影到每个摄像头的视图中,以演示激光雷达数据对齐。- ds3d_lidar_plus_multi_cam_bev_fusion_with_label.yaml 将每个摄像头和激光雷达数据渲染到多视图窗口中,同时将检测到的 3D 边界框和标签投影到每个摄像头的视图中。

在以下测试中将这两个配置文件相互替换,以查看差异。

对于 x86:#

如果数据集不在 data/nuscene 中,该脚本将首先检查并下载数据集。

$ export NUSCENE_DATASET_URL="https://github.com/NVIDIA-AI-IOT/deepstream_reference_apps/raw/DS_7.1/deepstream-3d-sensor-fusion/data/nuscene.tar.gz"

运行脚本下载数据集并启动管线演示

$ bevfusion/docker_run_ds3d_sensor_fusion_bevfusion_pipeline.sh \
  ds3d_lidar_plus_multi_cam_bev_fusion.yaml

或者

$ bevfusion/docker_run_ds3d_sensor_fusion_bevfusion_pipeline.sh \
  ds3d_lidar_plus_multi_cam_bev_fusion_with_label.yaml

CTRL + C 终止。

对于远程机器上的 Tritonserver:#

如果 tritonserver 在与 ds3d 管线不同的远程机器/容器上运行,请务必更新 model_config_files/config_triton_bev_fusion_infer_grpc.pbtxt 中的本地 gRPC 配置文件,以使用运行 tritonserver 的远程机器的 IP 地址而不是 localhost

  • 更新本地客户端机器上的配置文件。

    grpc {
      url: "[tritonserver_ip_address]:8001"
      enable_cuda_buffer_sharing: false
    }
    
  • 取消注释 bevfusion/docker_run_ds3d_sensor_fusion_bevfusion_pipeline.sh 中的以下行以使用您的本地配置

    MOUNT_OPTIONS+=" -v ./:${TARGET_WORKSPACE}"
    
  • 在本地机器上运行脚本

    $ bevfusion/docker_run_ds3d_sensor_fusion_bevfusion_pipeline.sh ds3d_lidar_plus_multi_cam_bev_fusion.yaml
    

    或者

    $ bevfusion/docker_run_ds3d_sensor_fusion_bevfusion_pipeline.sh ds3d_lidar_plus_multi_cam_bev_fusion.yaml nvcr.io/nvidia/deepstream:{xx.xx.xx}-triton-multiarch
    
    Users can replace yaml config file to ``ds3d_lidar_plus_multi_cam_bev_fusion_with_label.yaml`` for tests as well.
    

对于 Jetson 设备:#

$ bevfusion/docker_run_ds3d_sensor_fusion_bevfusion_pipeline.sh ds3d_lidar_plus_multi_cam_bev_fusion.yaml nvcr.io/nvidia/deepstream:{xx.xx.xx}-triton-multiarch
$ bevfusion/docker_run_ds3d_sensor_fusion_bevfusion_pipeline.sh ds3d_lidar_plus_multi_cam_bev_fusion_with_label.yaml nvcr.io/nvidia/deepstream:{xx.xx.xx}-triton-multiarch

CTRL + C 终止。

用法:#

  • 在 x86 上启动 tritonserver BEVFusion 模型

$ bevfusion/docker_run_triton_server_bevfusion.sh bevfusion/model_root

命令行将 docker-run deepstream-triton-bevfusion 容器以启动 tritonserver 并侦听端口 8001 以进行 grpc 推理请求/响应。

  • 在容器内部启动 DS3D BEVFusion 推理和渲染管线

# run the following commandline inside of the container.
$ deepstream-3d-lidar-sensor-fusion -c ds3d_lidar_plus_multi_cam_bev_fusion.yaml
  • 如何从 nuscene 更新摄像头内参/外参

按照后续步骤运行 triton_lmm/helper/nuscene_data_setup.py 以打印校准数据,并将其更新到 ds3d-sensor-fusion 配置文件中。有关详细信息,请参阅 DS3D BEVFusion 的数据集生成

IoT 消息传递:#

  • 按照 Kafka 快速入门 设置 Kafka 服务器并创建主题 quick-test 以进行消息传递测试。

$ docker run -p 9092:9092 apache/kafka:3.7.0 # start kafka server with port 9092
$ bin/kafka-topics.sh --create --topic quick-test --bootstrap-server localhost:9092 # creat topic 'quick-test'
  • 安装 kafka 后,用户可以按照以下说明检查结果。

$ bin/kafka-console-consumer.sh --topic quick-test --bootstrap-server localhost:9092 # see fusion ds3d messaging results.
  • 在 deepstream triton 容器内部启动 DS3D BEVFusion 推理和 kafka 消息传递管线

# run the following commandline inside of the container.
$ deepstream-3d-lidar-sensor-fusion -c ds3d_lidar_plus_multi_cam_bev_fusion_iot.yaml
# edit ds3d_lidar_plus_multi_cam_bev_fusion_iot.yaml, search ds3d_fusion_msg_broker block
# update payload-type=1 for minimum 3D bbox; 2 for lidar data with protobuf

从源代码构建:#

  • 要在容器内部编译示例应用 deepstream-3d-lidar-sensor-fusion

$ make
$ sudo make install (sudo not required in the case of docker containers)

注意

要编译源代码,请使用 sudo -E 或 root 权限运行 make。

DS3D BEVFusion 管线的 NuScenes 数据集设置#

示例数据集可从 GitHub Deepstream 参考应用 获取,选自官方 NuScenes 数据集 (https://www.nuscenes.org/),并根据 Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License (“CC BY-NC-SA 4.0”) 获得许可。

此 DS3D BEVFusion 演示使用来自 NuScenes 场景 cc8c0bf57f984915a77078b10eb33198 (名称:scene-0061)的数据,其中包含 39 个样本。

DS3D BEVFusion 的数据集生成#

用户可以修改脚本 triton_lmm/helper/nuscene_data_setup.py,以从不同的 NuScenes 场景生成用于 DS3D 传感器融合用例的数据。

从 nuscene 样本生成数据集#

要重现示例数据并获取校准矩阵,请按照以下命令操作

$ export TARGET_WORKSPACE=/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-3d-lidar-sensor-fusion
$ cd ${TARGET_WORKSPACE}
$ mkdir -p dataset/nuscene data
$ docker run --rm --net=host \
  -v ./dataset/nuscene:${TARGET_WORKSPACE}/dataset/nuscene \
  -v ./data:${TARGET_WORKSPACE}/data \
  -w ${TARGET_WORKSPACE} --sig-proxy --entrypoint python3 deepstream-triton-bevfusion:xxx \
  python/triton_lmm/helper/nuscene_data_setup.py  --data_dir=dataset/nuscene \
  --ds3d_fusion_workspace=${TARGET_WORKSPACE} --print_calibration

注意

将 deepstream-triton-bevfusion:xxx 替换为最新的 DeepStream 版本号(例如,7.0)

解释

  • 前两行将环境变量 TARGET_WORKSPACE 设置为 deepstream-3d-lidar-sensor-fusion 示例代码的位置,然后将目录更改为该位置。

  • 第三行在目标工作区内创建名为 dataset/nuscenedata 的目录。

  • docker run 命令在 Docker 容器内执行 nuscene_data_setup.py 脚本。

    • 选项

      • --rm:在容器完成后移除容器。

      • --net=host:允许容器使用主机网络。

      • -v:挂载卷以在主机和容器之间共享数据。

      • -w ${TARGET_WORKSPACE}:设置容器内的工作目录。

      • --sig-proxy:启用容器内信号的处理。

      • --entrypoint python3:设置容器的入口点以运行 python3

  • 该命令将主机系统中的 dataset/nuscenedata 目录挂载到容器中,然后使用以下参数执行 nuscene_data_setup.py

    • --data_dir=dataset/nuscene:指定包含 NuScenes 数据集的目录。

    • --ds3d_fusion_workspace=${TARGET_WORKSPACE}:设置 DS3D 传感器融合数据的目标工作区。

    • --print_calibration:指示脚本打印校准数据。

注意

deepstream-triton-bevfusion:xxx 替换为最新的 DeepStream 版本号(例如,7.0)。

该脚本将原始 NuScenes 数据下载到 dataset/nuscene 目录中,然后将其转换为 DS3D 传感器融合所需的格式,并将转换后的数据存储在 ${TARGET_WORKSPACE}/data/nuscene 目录中。

DS3D 传感器融合的校准数据生成#

  • 先前命令中的 --print_calibration 参数输出以下校准数据,

    • 摄像头内参矩阵 (4x4)。

    • 摄像头到激光雷达外参矩阵 (4x4)。

    • 激光雷达到摄像头外参矩阵 (4x4)。

    • 激光雷达到图像矩阵 (4x4)

如何使用其他 nuScenes 场景样本:#

您可以将不同的 nuScenes 场景数据集无缝集成到 deepstream-3d-sensor-fusion 管线中,确保针对您的特定用例进行精确校准。

如果您希望在 nuScenes 数据集中使用替代场景样本来设置演示,请按照以下步骤操作

  • nuscene_data_setup.py 脚本更新为不同的场景编号,并为 ds3d-sensor-fusion 生成所需的样本数据格式。在容器内运行相同的命令行。

$ export TARGET_WORKSPACE=/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-3d-lidar-sensor-fusion
$ cd ${TARGET_WORKSPACE}
$ python3 python/triton_lmm/helper/nuscene_data_setup.py  --data_dir=dataset/nuscene \
--ds3d_fusion_workspace=${TARGET_WORKSPACE} --print_calibration
  • 将新的校准数据更新到 DS3D 传感器融合管线配置文件中

    • 从配置文件 ds3d_lidar_plus_multi_cam_bev_fusion.yaml 中更新 ds3d::datafilter lidar_alignment_filter 中的内参和外参校准矩阵。

    • 每个 cam_intrinsiclidar_to_cam_extrisic 都需要 shape: 3x4row_major: True 的矩阵,用户需要从之前的命令行日志输出中复制前 3x4 矩阵。

  • 在启动 tritonserver 之前,将新的校准数据更新到 triton-lmm。

    • 更新 python/triton_lmm/server/pytriton_server.py 以获取所有必需的矩阵。

  • 重启 tritonserver,请参阅 启动用于 BEVFusion 模型的 Tritonserver [x86] 中的说明

  • 重启 ds3d sensorfusion 管线,请参阅 下载测试数据并启动 DS3D BEVFusion 管线 中的说明

引用#

@inproceedings{liu2022bevfusion,
   title={BEVFusion: Multi-Task Multi-Sensor Fusion with Unified Bird's-Eye View Representation},
   author={Liu, Zhijian and Tang, Haotian and Amini, Alexander and Yang, Xingyu and Mao, Huizi and Rus, Daniela and Han, Song},
   booktitle={IEEE International Conference on Robotics and Automation (ICRA)},
   year={2023}
}
@article{nuscenes2019,
  title={nuScenes: A multimodal dataset for autonomous driving},
  author={Holger Caesar and Varun Bankiti and Alex H. Lang and Sourabh Vora and
          Venice Erin Liong and Qiang Xu and Anush Krishnan and Yu Pan and
          Giancarlo Baldan and Oscar Beijbom},
  journal={arXiv preprint arXiv:1903.11027},
  year={2019}
}
@article{fong2021panoptic,
  title={Panoptic nuScenes: A Large-Scale Benchmark for LiDAR Panoptic Segmentation and Tracking},
  author={Fong, Whye Kit and Mohan, Rohit and Hurtado, Juana Valeria and Zhou, Lubing and Caesar, Holger and
          Beijbom, Oscar and Valada, Abhinav},
  journal={arXiv preprint arXiv:2109.03805},
  year={2021}
}