-
Notifications
You must be signed in to change notification settings - Fork 525
[OMNIML-5562] Add FAR3D ONNX PTQ and accuracy evaluation example #2012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ajrasane
wants to merge
16
commits into
main
Choose a base branch
from
ajrasane/onnx_eval
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
da22292
Add FAR3D ONNX PTQ example
ajrasane 47337f5
Use one container for FAR3D workflow
ajrasane 0ff65a4
Simplify FAR3D container dependencies
ajrasane 869e38a
Quantize FAR3D decoder by default
ajrasane a799d6f
Add FAR3D FP8 quantization support
ajrasane 1bb48a2
Simplify FAR3D exclusion traversal
ajrasane 979e588
Add FAR3D example to changelog
ajrasane 1808c72
Anchor FAR3D node exclusions
ajrasane b6b5f9d
Move FAR3D mmcv import to module scope
ajrasane 7988f96
Add FAR3D TensorRT accuracy results
ajrasane 83aa262
Update FAR3D TensorRT results
ajrasane 6de498f
Document FAR3D decoder accuracy guidance
ajrasane 7cad7c9
Address FAR3D review feedback
ajrasane a216c03
Update FAR3D to PyTorch 26.07 container
ajrasane b2222a0
Rename FAR3D FlashAttention compatibility patch
ajrasane 089ea57
Clarify FAR3D TensorRT environments
ajrasane File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # TensorRT 11.1 from the base image builds and runs the FAR3D engines. | ||
| FROM nvcr.io/nvidia/pytorch:26.07-py3 | ||
|
|
||
| ENV LD_LIBRARY_PATH=/usr/local/cuda/compat/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64 | ||
|
|
||
| RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ | ||
| libgl1 \ | ||
| libglib2.0-0 && \ | ||
| rm -rf /var/lib/apt/lists/* | ||
|
|
||
| ENV UV_PYTHON_INSTALL_DIR=/opt/python | ||
|
|
||
| RUN python -m pip install --no-cache-dir uv && \ | ||
| uv python install 3.8 && \ | ||
| uv venv --seed --python 3.8 /opt/far3d | ||
|
|
||
| COPY examples/onnx_ptq/far3d/requirements*.txt /tmp/far3d-requirements/ | ||
| RUN env -u PIP_CONSTRAINT /opt/far3d/bin/python -m pip install --no-cache-dir \ | ||
| -r /tmp/far3d-requirements/requirements-torch.txt && \ | ||
| env -u PIP_CONSTRAINT /opt/far3d/bin/python -m pip install --no-cache-dir \ | ||
| -r /tmp/far3d-requirements/requirements.txt && \ | ||
| env -u PIP_CONSTRAINT /opt/far3d/bin/python -m pip install --no-cache-dir \ | ||
| --no-build-isolation \ | ||
| -r /tmp/far3d-requirements/requirements-mmdet3d.txt && \ | ||
| mkdir -p /opt/far3d/lib/python3.8/site-packages/tensorrt && \ | ||
| cp /opt/far3d/lib/python3.8/site-packages/tensorrt_bindings/__init__.py \ | ||
| /opt/far3d/lib/python3.8/site-packages/tensorrt/__init__.py && \ | ||
| cp /opt/far3d/lib/python3.8/site-packages/tensorrt_bindings/tensorrt.so \ | ||
| /opt/far3d/lib/python3.8/site-packages/tensorrt/tensorrt.so | ||
|
|
||
| COPY . /opt/Model-Optimizer | ||
| RUN cd /opt/Model-Optimizer && \ | ||
| env -u PIP_CONSTRAINT python -m pip install --no-cache-dir \ | ||
| -e ".[onnx]" \ | ||
| "onnxruntime-gpu[cuda,cudnn]~=1.24.2" \ | ||
| "tensorrt-cu12-libs==10.11.0.33" | ||
|
|
||
| # The TensorRT EP in ONNX Runtime 1.24 requires TensorRT 10 during decoder quantization. | ||
| ENV ORT_TRT10_LIB_PATH=/usr/local/lib/python3.12/dist-packages/tensorrt_libs | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| # FAR3D ONNX PTQ and Argoverse 2 evaluation | ||
|
|
||
| This example quantizes the FAR3D image encoder and decoder to INT8 or FP8 with Model Optimizer and evaluates the complete pipeline on the Argoverse 2 validation set. It follows the [NVIDIA DL4AGX FAR3D workflow](https://github.com/NVIDIA/DL4AGX/tree/master/AV-Solutions/far3d-trt). | ||
|
|
||
| FAR3D uses a legacy PyTorch/MMCV environment that is incompatible with the current Model Optimizer Python dependencies. The provided image uses `nvcr.io/nvidia/pytorch:26.07-py3` with TensorRT 11.1 for engine build and evaluation, and isolates the legacy FAR3D packages in a Python 3.8 virtual environment. The TensorRT EP in ONNX Runtime 1.24 requires CUDA 12 and TensorRT 10.11 compatibility libraries during decoder quantization; these libraries are not used to build or run the TensorRT 11.1 engines. | ||
|
|
||
| ## 1. Prepare FAR3D and Argoverse 2 | ||
|
|
||
| Clone DL4AGX, initialize its submodules, and apply its FAR3D patch: | ||
|
|
||
| ```bash | ||
| git clone https://github.com/NVIDIA/DL4AGX.git | ||
| cd DL4AGX | ||
| git submodule update --init --recursive | ||
| cd AV-Solutions/far3d-trt/dependencies/Far3D | ||
| git apply ../../patch/far3d.patch | ||
| git apply /path/to/Model-Optimizer/examples/onnx_ptq/far3d/far3d_optional_flash_attn.patch | ||
| cd ../.. | ||
| ``` | ||
|
|
||
| The second patch makes the unused CUDA 11-only FlashAttention implementation optional; the reference configuration uses MMCV `MultiheadAttention`. | ||
|
|
||
| Download the [Argoverse 2 sensor validation set](https://www.argoverse.org/av2.html), the [reference FAR3D checkpoint](https://github.com/NVIDIA/DL4AGX/tree/master/AV-Solutions/far3d-trt#pytorch-model-to-onnx), and its configuration. The remaining commands assume: | ||
|
|
||
| ```text | ||
| far3d-trt/ | ||
| ├── data/av2/val/ | ||
| ├── dependencies/Far3D/projects/configs/far3d.py | ||
| └── weights/iter_82548.pth | ||
| ``` | ||
|
|
||
| Build the example image from the Model Optimizer checkout: | ||
|
|
||
| ```bash | ||
| docker build \ | ||
| -f /path/to/Model-Optimizer/examples/onnx_ptq/far3d/Dockerfile \ | ||
| -t far3d-modelopt \ | ||
| /path/to/Model-Optimizer | ||
| ``` | ||
|
|
||
| Start the image and mount the FAR3D checkout: | ||
|
|
||
| ```bash | ||
| docker run --rm -it --network=host --gpus=all --shm-size=80G --privileged \ | ||
| -v /data/av2:/data/av2 \ | ||
| -v /path/to/far3d-trt:/workspace/far3d-trt \ | ||
| far3d-modelopt | ||
| ``` | ||
|
|
||
| Use `/opt/far3d/bin/python` for data preparation, export, and evaluation. It selects the isolated legacy FAR3D environment: | ||
|
|
||
| ```bash | ||
| export PYTHONPATH=/workspace/far3d-trt/dependencies/Far3D | ||
| cd /workspace/far3d-trt | ||
| /opt/far3d/bin/python /opt/Model-Optimizer/examples/onnx_ptq/far3d/prepare_metadata.py data/av2 | ||
| ``` | ||
|
|
||
| ## 2. Export the ONNX models | ||
|
|
||
| ```bash | ||
| /opt/far3d/bin/python tools/export_onnx.py \ | ||
| dependencies/Far3D/projects/configs/far3d.py \ | ||
| weights/iter_82548.pth | ||
| ``` | ||
|
|
||
| This produces `far3d.encoder.onnx` and `far3d.decoder.onnx`. | ||
|
|
||
| ## 3. Prepare calibration batches | ||
|
|
||
| Build temporary engines from the exported models. They run the reference pipeline while collecting representative encoder and decoder inputs: | ||
|
|
||
| ```bash | ||
| trtexec \ | ||
| --onnx=far3d.encoder.onnx \ | ||
| --saveEngine=far3d.encoder.fp16.engine \ | ||
| --fp16 \ | ||
| --skipInference | ||
| trtexec \ | ||
| --onnx=far3d.decoder.onnx \ | ||
| --saveEngine=far3d.decoder.fp16.engine \ | ||
| --stronglyTyped \ | ||
| --skipInference | ||
| ``` | ||
|
|
||
| Extract 512 batches sampled every 20 frames from the Argoverse 2 validation loader: | ||
|
|
||
| ```bash | ||
| /opt/far3d/bin/python /opt/Model-Optimizer/examples/onnx_ptq/far3d/prepare_calibration.py \ | ||
| dependencies/Far3D/projects/configs/far3d.py \ | ||
| data/far3d_calibration \ | ||
| --encoder-engine far3d.encoder.fp16.engine \ | ||
| --decoder-engine far3d.decoder.fp16.engine \ | ||
| --num-samples 512 \ | ||
| --sample-skip-interval 20 | ||
| ``` | ||
|
|
||
| The calibration directory contains separate `encoder/` and `decoder/` batches. Decoder batches include the image features, camera geometry, and temporal state seen by the reference decoder. | ||
|
|
||
| ## 4. Quantize the models | ||
|
|
||
| Use the base Python environment for Model Optimizer: | ||
|
|
||
| ```bash | ||
| LD_LIBRARY_PATH="${ORT_TRT10_LIB_PATH}:${LD_LIBRARY_PATH}" \ | ||
| python /opt/Model-Optimizer/examples/onnx_ptq/far3d/quantize.py \ | ||
| --encoder-onnx far3d.encoder.onnx \ | ||
| --decoder-onnx far3d.decoder.onnx \ | ||
| --calibration-dir data/far3d_calibration | ||
| ``` | ||
|
|
||
| Both models use max calibration. INT8 is the default; use `--quantization-mode fp8` to produce `far3d.encoder.fp8.onnx` and `far3d.decoder.fp8.onnx` instead. FP8 deployment requires an FP8-capable GPU. | ||
|
|
||
| The quantizer preserves the accuracy-sensitive exclusions used by the DL4AGX reference: the `OSA4_5` block and nodes downstream of `lateral_convs` remain in high precision. | ||
|
|
||
| To keep the decoder in its original mixed FP16/FP32 precision, add `--fp16-decoder`; decoder calibration batches are not required in that mode. This flag can be combined with either quantization mode. | ||
|
|
||
| Build both engines in the same container. Serialized TensorRT engines are not portable across TensorRT versions or GPU architectures. | ||
|
|
||
| Set the precision to the quantization mode used above: | ||
|
|
||
| ```bash | ||
| precision=int8 # Use fp8 for FP8 models. | ||
| trtexec \ | ||
| --onnx=far3d.encoder.${precision}.onnx \ | ||
| --saveEngine=far3d.encoder.${precision}.engine \ | ||
| --stronglyTyped \ | ||
| --skipInference | ||
| trtexec \ | ||
| --onnx=far3d.decoder.${precision}.onnx \ | ||
| --saveEngine=far3d.decoder.${precision}.engine \ | ||
| --stronglyTyped \ | ||
| --skipInference | ||
| ``` | ||
|
|
||
| When using `--fp16-decoder`, build `far3d.decoder.onnx` as `far3d.decoder.fp16.engine` instead. | ||
|
|
||
| ## 5. Evaluate accuracy | ||
|
|
||
| ```bash | ||
| precision=int8 # Use fp8 for FP8 models. | ||
| /opt/far3d/bin/python /opt/Model-Optimizer/examples/onnx_ptq/far3d/evaluate.py \ | ||
| dependencies/Far3D/projects/configs/far3d.py \ | ||
| far3d.encoder.${precision}.engine \ | ||
| far3d.decoder.${precision}.engine | ||
| ``` | ||
|
|
||
| Use `--max-samples N` for an inference smoke test. Dataset metrics are skipped when only part of the validation set is processed. | ||
|
|
||
| ## Results on Argoverse 2 validation set | ||
|
|
||
| The following historical results use TensorRT 10.11.0.33 on an NVIDIA RTX 6000 Ada Generation GPU. Model quantization uses PyTorch 2.8.0a0 from the 25.06 PyTorch container, while the FAR3D export and evaluation environment uses PyTorch 1.13.1. Accuracy is measured over all 23,522 validation frames after calibration with 512 batches sampled every 20 frames. These numbers are not directly reproducible with the current 26.07/TensorRT 11.1 image; rerun the workflow to measure the current toolchain. | ||
|
|
||
| | Encoder precision | Decoder precision | Framework | GPU compute time (ms) | Accuracy (mAP) | | ||
| | --- | --- | --- | ---: | ---: | | ||
| | FP32 | FP32 | TensorRT 10.11 | 92.5 | 0.241 | | ||
| | FP16 | FP32 | TensorRT 10.11 | 47.8 | 0.241 | | ||
| | FP16 | FP16 | TensorRT 10.11 | 45.0 | 0.241 | | ||
| | INT8 | FP16 | TensorRT 10.11 | 24.6 | 0.236 | | ||
| | FP8 | FP16 | TensorRT 10.11 | 31.5 | 0.241 | | ||
|
|
||
| Quantizing the decoder to INT8 or FP8 produced severe accuracy degradation in this evaluation and is not recommended. Keep the decoder in its original mixed FP16/FP32 precision. | ||
|
|
||
| GPU compute time is the sum of the encoder and decoder median times reported by `trtexec`, with host-to-device and device-to-host transfers disabled. Results depend on the TensorRT version and GPU architecture and are not directly comparable with the DRIVE Orin-X measurements in the [DL4AGX reference](https://github.com/NVIDIA/DL4AGX/tree/master/AV-Solutions/far3d-trt#results-on-argoverse2-validation-set). |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we using python 3.8? ModelOpt requires 3.10+ (and soon 3.11+) and 3.8 will most likely fail