Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ repos:
examples/llm_eval/lm_eval_hf.py|
examples/llm_eval/mmlu.py|
examples/llm_eval/modeling.py|
examples/onnx_ptq/far3d/evaluate.py|
examples/llm_qat/train.py|
examples/llm_sparsity/weight_sparsity/finetune.py|
examples/specdec_bench/specdec_bench/models/specbench_medusa.py|
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Experimental
- **Multi-Latent Attention (MLA)**, such as DeepSeek — MLA latent ranks are not pruned.
- **Latent MoE**, such as Nemotron-3-Super — ``hidden_size`` pruning resizes the latent projections while the MoE latent dim itself is not pruned.
- Add Minitron pruning support for the language model part of vision-language models (e.g. Qwen3.5-VL, Gemma3-VL) via ``examples/megatron_bridge/prune_minitron.py``. The language model is pruned while the vision tower is left intact and the full VLM is saved back; ``hidden_size`` is not pruned if it is shared with the vision projector. Pruning importance is estimated from image-text calibration (the full VLM forward over vision-conditioned activations) by default, or from a text dataset for text-only ablations.
- Add an end-to-end FAR3D ONNX PTQ example with calibration data generation, INT8 and FP8 quantization, TensorRT engine building, and Argoverse 2 accuracy evaluation. See `examples/onnx_ptq/far3d/README.md <https://github.com/NVIDIA/Model-Optimizer/tree/main/examples/onnx_ptq/far3d>`_ for details.
- Add PTQ support for the language model part of vision-language models (e.g. Qwen3.5-VL, Gemma3-VL) via ``examples/megatron_bridge/quantize.py``. Only the language model is quantized (vision tower + projector left in full precision) and the full VLM is saved as a Megatron checkpoint. The calibration modality is inferred from ``--calib_dataset_name``: an image-text dataset drives the full VLM forward (vision-conditioned activations), while a text dataset runs text-only calibration of the language model. Image-text calibration shards across data-parallel ranks (context parallelism is supported only for text-only calibration). HuggingFace unified export of a quantized VLM is not yet supported.
- Add Megatron-Bridge distillation and QAD support for the language model part of vision-language models (e.g. Qwen3.5-VL, Gemma3-VL) via ``examples/megatron_bridge/distill.py``.
- Add NVFP4 Four-Over-Six (4/6) weight quantization (``mtq.NVFP4_FOUR_OVER_SIX_CFG``): MSE weight calibration picks, per block, between an M=6 and an M=4 dynamic range (the choice is folded into the FP8 per-block scales), with the ``four_over_six: true`` flag normalizing those scales by 256 (vs 448) for M=4 headroom. Supported via ``mtq.quantize`` and HF / Megatron export only -- **not** ``mtq.compress``, which does not preserve the per-block M=4/M=6 choice
Expand Down
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ the following copyright holders, licensed under the Apache License, Version 2.0
Copyright 2023 Rohan Taori, Ishaan Gulrajani, Tianyi Zhang, Yann Dubois, Xuechen Li
Copyright (c) 2024 Heming Xia
Copyright 2025 The Qwen team, Alibaba Group and the HuggingFace Inc. team
Copyright (c) OpenMMLab. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not
use these files except in compliance with the License. You may obtain a copy
Expand Down
4 changes: 4 additions & 0 deletions examples/onnx_ptq/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ The top5 accuracy of the model is <accuracy score between 0-100%>
Inference latency of the model is <X> ms
```

### FAR3D 3D object detection

The [FAR3D example](./far3d/) demonstrates an end-to-end workflow that exports and quantizes the FAR3D ONNX image encoder, builds TensorRT engines, and evaluates 3D object detection mAP on the Argoverse 2 validation set.

## Advanced Features

### Per node calibration of ONNX models
Expand Down
80 changes: 80 additions & 0 deletions examples/onnx_ptq/far3d/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# 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.

FROM nvcr.io/nvidia/pytorch:25.06-py3

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we using 1 year old docker?


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

RUN env -u PIP_CONSTRAINT /opt/far3d/bin/python -m pip install --no-cache-dir \
torch==1.13.1+cu117 \
torchvision==0.14.1+cu117 \
--extra-index-url https://download.pytorch.org/whl/cu117

RUN env -u PIP_CONSTRAINT /opt/far3d/bin/python -m pip install --no-cache-dir \
"numpy<1.24" \
opencv-python==4.5.5.64 \
yapf==0.32.0 \
mmcv-full==1.7.0 \
-f https://download.openmmlab.com/mmcv/dist/cu117/torch1.13.0/index.html

RUN env -u PIP_CONSTRAINT /opt/far3d/bin/python -m pip install --no-cache-dir \
av2==0.2.1 \
einops \
"ipython<9" \
kornia==0.6.12 \
mmdet==2.28.2 \
mmsegmentation==0.30.0 \
onnx \
onnx-graphsurgeon==0.6.1 \
onnxruntime \
onnxsim \
refile \
tensorrt-cu12-bindings==10.11.0.33 \
--extra-index-url https://pypi.nvidia.com && \
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

RUN env -u PIP_CONSTRAINT /opt/far3d/bin/python -m pip install --no-cache-dir \
"setuptools<81" && \
env -u PIP_CONSTRAINT /opt/far3d/bin/python -m pip install --no-cache-dir \
--no-build-isolation \
mmdet3d==1.0.0rc6

COPY . /opt/modelopt

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use /opt/Model-Optimizer naming? Thats the convention we use in other places also (e.g. Megatron-Bridge)

RUN env -u PIP_CONSTRAINT python -m pip install --no-cache-dir \
Comment on lines +69 to +70

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we instead do pip install -e .[onnx] here?

lief \
ml_dtypes \
omegaconf \
"onnx-graphsurgeon>=0.6.1" \
"onnx~=1.21.0" \
"onnxruntime-gpu~=1.24.2" \
onnxscript \
"onnxslim>=0.1.76" \
"setuptools>=80" && \
env -u PIP_CONSTRAINT python -m pip install --no-cache-dir --no-deps -e /opt/modelopt
Comment on lines +31 to +80

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you move all requirements.txt and install from it instead of mentioning in dockerfile so nspect scanning can detect these dependencies

158 changes: 158 additions & 0 deletions examples/onnx_ptq/far3d/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# 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:25.06-py3` for the complete workflow and isolates the legacy FAR3D packages in a Python 3.8 virtual environment.

## 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_pytorch_25_06.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/modelopt/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/modelopt/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
python /opt/modelopt/examples/onnx_ptq/far3d/quantize.py \
far3d.encoder.onnx \
far3d.decoder.onnx \
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/modelopt/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 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.

| Encoder precision | Decoder precision | Framework | GPU compute time (ms) | Accuracy (mAP) |
| --- | --- | --- | ---: | ---: |
| INT8 | INT8 | TensorRT 10.11 | 25.4 | 0.124 |
| FP8 | FP8 | TensorRT 10.11 | 31.2 | 0.000 |
| FP8 | FP16 | TensorRT 10.11 | 31.5 | 0.241 |

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).
Loading
Loading