Home

Awesome

CenterPoint : An Lidar Object Detection & Tracking project implemented by TensorRT

The project implement CenterPoint by TensorRT, where CenterPoint is an 3D object detection model using center points in the bird eye view. Code is written according to the project

Besides, it is running inference on WaymoOpenSet

Setup

The project has been tested on Ubuntu18.04 and Ubuntu20.04, It mainly relies on TensorRT and cuda as 3rd-party package, with the following versions respectively:

vTensorRT : 8.0.1.6

vCuda : 11.3

This project has provided the baseline onnx models trained with this config in models. If you want to export your own models, we assume you have had CenterPoint project installed, you can setup local det3d environment

cd /PATH/TO/centerpoint/tools 
bash setup3.sh

Preperation

Export as onnx models

To export your own models, you can run

python3 export_onnx.py \
--config waymo_centerpoint_pp_two_pfn_stride1_3x.py \
--ckpt your_model.pth \
--pfe_save_path pfe.onnx \
--rpn_save_path rpn.onnx

Here we extract two pure nn models from the whole computation graph---pfe and rpn, this is to make it easier for trt to optimize its inference engines, and we use cuda to connect these nn engines.

Generate TensorRT serialized engines

Actually you can directly create trt engines from onnx models and skip this step, however a more ideal way is to load your previously saved serialize engine files.

You can run

python3 create_engine.py \
--config waymo_centerpoint_pp_two_pfn_stride1_3x.py \
--pfe_onnx_path pfe.onnx \
--rpn_onnx_path rpn.onnx \
--pfe_engine_path pfe_fp.engine \
--rpn_engine_path rpn_fp.engine

By default this will generate fp16-engine files.

Work with int8

There are two ways to make quantization according to Nvidia: Explicit & Implicit Quantization

To make explicit quant, you can go to TensorRT/bin and make ./trtexec --onnx=model.onnx --int8 --saveEngine=model.engine you will need to compile tensorrt from source code

To make implicit quant, you need previously generate calibration files, we assume you have waymo_openset downloaded and have converted into the desired data formation according to this

python3 generate_calib_data.py \
--config waymo_centerpoint_pp_two_pfn_stride1_3x.py \
--ckpt your_model.pth \
--calib_file_path your_calib_files

Then refer to the code we provide by

python3 create_engine.py \
--config waymo_centerpoint_pp_two_pfn_stride1_3x.py \
--pfe_onnx_path pfe.onnx \
--rpn_onnx_path rpn.onnx \
--pfe_engine_path pfe_quant.engine \
--rpn_engine_path rpn_quant.engine \
--quant \
--calib_file_path your_calib_files \
--calib_batch_size 10

Run inference

After preperation, you may then build tensorrt project by executing the following commands:

cd /PATH/TO/centerpoint
mkdir build && cd build
cmake .. && make

If you want to create engine from onnx files, you can do infer by

./build/centerpoint \
--pfeOnnxPath=models/pfe_baseline32000.onnx \
--rpnOnnxPath=models/rpn_baseline.onnx \
--savePath=results \
--filePath=/PATH/TO/DATA \
--fp16

Or load engine files directly

./build/centerpoint \
--pfeEnginePath=pfe_fp.engine \
--rpnEnginePath=rpn_fp.engine \
--savePath=results \
--filePath=/PATH/TO/DATA \
--loadEngine

where filePath refers to input bin files generated by tools/generate_input_data.py.

You can also download seq1 directly to fastly test your model, see here in Baidu Cloud Disk :

link:https://pan.baidu.com/s/1Ua9F3eFflA9Gckpa9U-1Eg  passwd:08s6

Computation Speed

Acceleration is the main aim we want to archieve, and therefore we do most of computation(including preprocess & postprocess) on GPU. The below table gives the average computation speed (by millisecond) of every computation module, and it is tested on RTX3080, with all the 39987 waymo validation samples. the below table summarizes the computation speed.

PreprocessPfeInferVoxelAssignRpnInferPostprocess
fp32+gpupre+gpupost1.738.470.3625.02.01
fp16+gpupre+gpupost1.615.880.176.892.37
fp16+cpupre+gpupost9.26.140.427.142.10
int8(minmax)+gpupre+gpupost1.618.230.175.253.21
int8(entropy)+gpupre+gpupost1.417.450.174.652.11
int8(explicit)+gpupre+gpupost2.28.00.178.182.59

Note that fp16 or int8 may be mixed up with fp32, we have no control over which tensor shall be int8, fp16 or fp32, it's dominated by tensorrt. We can see that fp16 mode runs much faster than fp32 mode, and gpu preprocess runs much faster than that of cpu, because in cuda, we runs in a pointwise-multithread-way, while in cpu, points are preprocessed in a for-loop-manner.

Metrics

You can run cd tools && python3 waymo_eval.py --cpp_output --save_path ../results to compute evaluation metrics, we set score threshould as 0.2, 2D iou threshuold as [0.7,0.5] for vehicle and pedestrian as is shown in waymo openset, below we can see the evaluation results:

Vehicle_level2/mAPVehichle_level2/mAPHvehicle_level2 Recall@0.95Pedestrian_level2/mAPPedestrian_level2/mAPHPedestrian_level2 Recall@0.95
fp32+cpupre+cpupost0.78140.72400.39660.68370.56680.3739
fp32+gpupre+gpupost0.80390.79470.57310.67230.55880.2310
fp16+gpupre+gpupost0.80380.79450.57300.66710.55410.2301
int8+gpupre+gpupost0.58270.56150.40610.06340.04560.0

Below are the old metrics, it is computed by 3D iou with threshould [0.5,0.5] for vehicle and pedestrian, however the conclusions are the same.

Vehicle_level2/mAPVehichle_level2/mAPHvehicle_level2 Recall@0.95Pedestrian_level2/mAPPedestrian_level2/mAPHPedestrian_level2 Recall@0.95
torchModel0.60190.50270.02410.55450.53770.0547
fp32+cpupre+gpupost0.60190.50270.02410.55460.53780.0548
fp16+cpupre+gpupost0.60240.50300.02400.55450.53780.0542
fp16+gpupre+gpupost0.62070.51730.23270.57880.56240.2984
int8(minmax)+gpupre+gpupost0.34700.28890.00.32220.30650.0
int8(entropy)+gpupre+gpupost0.13960.10490.00140.15500.14520.0008
int8(explicit)+gpupre+gpupost0.46420.38230.02880.42480.41120.0201

From the above metrics, we can see that

  1. fp16 model almostly performs as well as fp32 model, despite it runs much faster.
  2. float model+cpupre+gpupost achieves the same result as original torch model, because the way they preprocess points are same, while gpu preprocess performs better. Because points in multithread are orderless, for a voxel that contains more points than given threshould, it makes unbiased subsampling.detailed reason see here
  3. int8 mode can't achieve the same results as float mode, and implicit calibration performs worse than explicit calib, we choose 1000 samples to make calibration and batch size is set 10, maybe samples are insufficient. However explicit calib model runs slower than implicit ones.

Online Tracking and Visualization

We use rivz to visualize perception results, to setup catkin workspace, you can go to tools/catkin_ws, run

bash catkin_make.sh
source devel/setup.bash

You need to config your file paths in tools/catkin_ws/src/waymo_track/src/waymo_track.py. Then you can open another two terminals, one type in roscore, another one type in rviz to show results(you can directly load default.rviz in catkin_ws), in your original terminal, go to catkin_ws, run rosrun waymo_track waymo_track.py, you should see the detection or tracking results in rviz window.

Detection & tracking result shows below:

float detection & tracking

<img src='doc/fp_det.gif' style=' width:400px;height:270 px'/> <img src='doc/fp_track.gif' style=' width:400px;height:270 px'/>

implicit quantization & explicit quantization (tracking)

<img src='doc/entropy_track.gif' style=' width:400px;height:270 px'/> <img src='doc/explicit_track.gif' style=' width:400px;height:270 px'/>

What has been done?

To futher learn the detailed computation graph of CenterPoint, please refer to the following picture. graph

Acknowledgements

This project refers to some codes from:

CenterPoint

TensorRT

CenterPoint-PointPillars

SORT

Contact

Hao Wang by christian.wong423@gmail.com