Far3D is the state of the art for camera only 3D object detection on the NuScenes dataset. It achieves this by using a 2D detector to initialize 3D adaptive queries which are then cross attended across camera views using perspective aware feature aggregation. This repository implements the changes and tools necessary to deploy a Far3D model using TensorRT on NVIDIA DRIVE Orin.
(Image taken from the Far3D repo)
[2025-03-19]Added support for a mixed precision decoder in TensorRT 10+ which reduces latency by more than 40% with marginal accuracy loss.[2025-04-23]Added support for post training quantization for the encoder which reduces latency by an additional 35% with marginal accuracy loss.
Repository preparation Please execute the following commands to download this repository and apply patches.
git clone http://github.com/NVIDIA/DL4AGX
cd DL4AGX
git submodule update --init --recursive
cd AV-Solutions/far3d-trt/dependencies/Far3D
git apply ../../patch/far3d.patchIn all future instructions, AV-Solutions/far3d-trt will be considered the root of the workspace.
Build the docker environment to be used for exporting the model
cd docker && docker build . -t far3d --network=hostCopy your Far3D config and weights into the workspace. Please also download the pretrained weights and put them in the weights folder.
Before proceeding, please download and extract the argoverse2 validation dataset, preprocessing of the data will be done inside of the container with the installed dependencies.
Run the docker container with GPU access, and the argoverse2 dataset mount location:
docker run -it --network=host --gpus=all --shm-size=80G --privileged \
-v /data/av2:/data/av2 \
-v $(pwd)/../:/workspace far3dThe above container will be referred to as the export container.
The folder structure inside of the export container should be as follows with the mounted argoverse dataset prior to preprocessing:
📦 /workspace/far3d-trt
┗ data
┣ 📂av2
┃ ┣ 📂val
┃ ┃ ┣ 📂scene0
┃ ┃ ┣ 📂scene ...
┃ ┃ ┗ 📂sceneN
┣ 📜decoder_input.pkl
┣ 📜encoder_input.pkl
┗ 📜model_input.pkl
Now preprocess the dataset to generate metadata files from av2 annotations with the following commands inside the export container:
python3 dependencies/Far3D/tools/create_infos_av2/create_av2_infos.py
python3 dependencies/Far3D/tools/create_infos_av2/gather_argo2_anno_feather.pyAfter the above steps, the file structure should be as follows:
📦 /workspace/far3d-trt
┗ data
┣ 📂av2
┃ ┣ 📂val
┃ ┃ ┣ 📂scene0
┃ ┃ ┣ 📂scene ...
┃ ┃ ┗ 📂sceneN
┃ ┣ 📜av2_val_infos.pkl
┃ ┗ 📜val_anno.feather
┣ 📜decoder_input.pkl
┣ 📜encoder_input.pkl
┗ 📜model_input.pkl
Use the following command to export the model to onnx, modifying the config and weights parameters accordingly.
export PYTHONPATH=$(pwd)/dependencies/Far3D/
python3 tools/export_onnx.py dependencies/Far3D/projects/configs/far3d.py weights/iter_82548.pthThe above workflow will produce a "far3d.encoder.onnx" and a "far3d.decoder.onnx" file in the root of the workspace.
To further reduce latency, we demonstrate how to perform post training quantization on the image encoder to enable INT8 inference. Use the following command to quantize the encoder, modifying the config and onnx path parameters accordingly. The below command will sample 500 batches at an interval of one sample per 20 batches from the validation set for calibration.
export PYTHONPATH=$(pwd)/dependencies/Far3D/
python3 tools/quantize_onnx.py dependencies/Far3D/projects/configs/far3d.py far3d.encoder.onnx --num_samples=500 --sample_skip_interval=20The above command will produce a post training quantized 'far3d.encoder.int8.onnx' along with quantization data 'far3d.encoder.int8.onnx.data' and 'far3d.encoder.int8.onnx_data' for TensorRT to consume.
This model has been tested on NVIDIA DRIVE Orin with TensorRT 8.6 and TensorRT 10.9. To get access to these versions of TensorRT, please refer to details on the NVIDIA DRIVE site. These versions of TensorRT comes with a compatible version of MultiScaleDeformableAttention (MSDA) inside the default libnvinfer_plugins.so library which enables the Far3D transformer decoder.
Far3D TensorRT engine files can be generated with trtexec on the target device:
trtexec --onnx=far3d.encoder.onnx --saveEngine=far3d.encoder.fp16.engine --fp16
# Since we've performed explicit quantization to this model, everything that is quantized will execute in INT8, the fp16 flag here enables fp16 and fp32
# precision for all other layers, thus enabling TensorRT to perform more optimizations.
trtexec --onnx=far3d.encoder.int8.onnx --saveEngine=far3d.encoder.int8.engine --fp16
# The stongly typed onnx file is still compatible with TensorRT 8.6 as a weakly typed fp32 model with no loss in accuracy.
trtexec --onnx=far3d.decoder.onnx --saveEngine=far3d.decoder.fp32.engine
# stronglyTyped is a feature of TensorRT 10+ and thus the following will not work for 8.6
trtexec --onnx=far3d.decoder.onnx --saveEngine=far3d.decoder.fp16.engine --stronglyTyped
The strategy used here to enable FP16 in the decoder is to keep all operations on features in FP16 and to keep all operations on points and intrinsics in FP32. The reason for this is that the intrinsic matrices are sensitive to casting to FP16, and that the matrix multiplications involved with point projection are prone to overflowing FP16 precision. Both of these operations are on small amounts of data while the operations on features are much less error prone to lower precision. The strongly typed network feature that was introduced in TensorRT 10+ enables precise precision control of operations and tensors which we use to achieve a significant reduction in latency while maintaining the necessary precision for sensitive operations and tensors.
The following command can be used to verify TensorRT model performance on the complete argoverse validation set using TensorRT python bindings. This needs to be done from inside the export container due to a dependency on MMCV for dataloading and preprocessing.
python3 tools/test_tensorrt.py dependencies/Far3D/projects/configs/far3d.py far3d.encoder.fp16.engine far3d.decoder.fp16.engineThe example C++ inference application expects binary dumps on disk, this data can be extracted with the following command executed from the export container:
python3 tools/extract_data.py dependencies/Far3D/projects/configs/far3d.pyThe above command needs the Far3D configuration file to ensure data is loaded consistently with how it was exported to ensure a correct performance evaluation. It will produce a dump of data for the first scene in argoverse2 into the data folder as well as data/filelist.txt which instructs the c++ inference application which frames to run inference on.
We recommend using the following NVIDIA DRIVE docker image drive-agx-orin-linux-aarch64-sdk-build-x86:6.0.10.0-0009 as the cross-compile environment, this container will be referred to as the build container.
To launch the docker on the host x86 machine, you may run:
docker run --gpus all -it --network=host --rm \
-v $(pwd)/../:/workspace \
nvcr.io/drive/driveos-sdk/drive-agx-orin-linux-aarch64-sdk-build-x86:latestTo gain access to this image please join the DRIVE AGX SDK Developer Program.
The C++ inference application has a dependency on Eigen3 which can be installed from apt with the following:
apt-get install libeigen3-devThe C++ inference application follows standard cmake practices, it can be built as follows:
mkdir build
cd build
cmake ../inference_app -DTENSORRT_ROOT=/data/TensorRT -DTARGET=orin
make -jThe above will generate a libfar3d.so shared library and a main inference application. It is recommended to network mount this workspace to your NVIDIA DRIVE Orin to enable data sharing. The main inference application can be run as follows from the Orin device, selecting from FP16 or FP32 for decoder precision:
./build/main far3d.encoder.fp16.engine far3d.decoder.{decoder_precision}.engine data/filelist.txtIt will produce ${prefix}_bboxes.bin, ${prefix}_labels.bin, and ${prefix}_scores.bin which can be loaded by numpy in the following step for validation; as well as several visualizations of detections such as the following:

The first sequence of argoverse can be tested with the following command from the export container:
python3 tools/evaluate_inference_app_output.py dependencies/Far3D/projects/configs/far3d.pyThe above command expects your config file as an input to configure dataloading, it then will read the first sequence of data and evaluate model performance on it by loading the binary blobs generated in the last step.
These results are based on the pretrained reference model (config) with a VoV-99 backbone at 960x640 input resolution. Latency measurements were collected on a DRIVE Orin-X platform.
| Precision | Framework | GPU Compute Time (median, ms) | Accuracy (mAP) |
|---|---|---|---|
| FP32 encoder + FP32 decoder | Pytorch 1.13.1 | 730.0 | 0.241 |
| FP32 encoder + FP32 decoder | TensorRT 8.6 | 538.5 | 0.233 |
| FP16 encoder + FP32 decoder | TensorRT 8.6 | 367.4 | 0.233 |
| FP16 encoder + FP16 decoder | TensorRT 10.9 | 203.9 | 0.232 |
| INT8 encoder + FP16 decoder | TensorRT 10.9 | 132.3 | 0.230 |
