Skip to content

[OMNIML-5563] Add PETR ONNX PTQ and accuracy evaluation example - #2180

Merged
ajrasane merged 17 commits into
mainfrom
ajrasane/petr
Sep 8, 2026
Merged

[OMNIML-5563] Add PETR ONNX PTQ and accuracy evaluation example#2180
ajrasane merged 17 commits into
mainfrom
ajrasane/petr

Conversation

@ajrasane

@ajrasane ajrasane commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Type of change: new example, example simplification, and backward-breaking example migration

Adds end-to-end PETRv1/PETRv2 ONNX PTQ and reduces PETR/FAR3D to one shared workflow:

  • quantizes the shared VoVNet image backbone/encoder to INT8 or FP8;
  • runs both the selected historical and current PETRv2 six-camera sweeps through the same precision-matched TensorRT backbone engine using distinct execution contexts during accuracy evaluation;
  • keeps the PETR head and FAR3D decoder in their exported mixed FP16/FP32 precision;
  • reuses one NPZ calibration format, VoVNet exclusion helper, quantization entry point, and TensorRT runner;
  • does not change generic Model Optimizer calibration behavior or its public CLI.

Container boundary

Both examples use two targets from one Dockerfile, with no virtual environments:

  • evaluator: a digest-pinned nvcr.io/nvidia/pytorch:22.06-py3 base with the legacy PyTorch 1.13.1/OpenMMLab stack for source setup, metadata generation, ONNX export, direct PyTorch calibration capture, and final accuracy evaluation;
  • modelopt: a digest-pinned nvcr.io/nvidia/pytorch:26.07-py3 base for Model Optimizer, ONNX Runtime CUDA, AutoCast, INT8/FP8 quantization, and TensorRT engine builds.

Both targets use TensorRT 11.1.0.106. Engines are built and evaluated on the same GPU architecture. Final metrics remain in the evaluator because they import the legacy model-framework postprocessing and dataset code; only artifacts cross the container boundary through the shared workspace.

PETR is used without patches. FAR3D applies only the official patch/far3d.patch from the pinned NVIDIA DL4AGX revision. This PR carries no patch files.

Evaluator dependencies

The dependencies intentionally installed without transitive dependencies are listed in requirements-evaluator-nodeps.txt. Their pins rely on runtime packages supplied by the digest-pinned PyTorch 22.06 evaluator base.

lyft-dataset-sdk is required only by mmdet3d's eager dataset import; neither PETR nor FAR3D uses Lyft data. flash-attn remains in the main evaluator requirements because its compiled installation uses the evaluator build step rather than the intentionally dependency-free legacy package step.

Fresh setup and dependency approval is requested for the final reduced dependency set.

Reproducible PETR metadata

The documented workflow mounts raw nuScenes read-only and creates a writable dataset view using symlinks. It then runs the pinned mmdetection3d converter and a temporary, untracked copy of PETR's pinned sweep generator configured only for the validation prefix and writable dataset root.

A clean run generated both metadata files with 6,019 validation records. The referenced camera, lidar, and sweep paths are absolute and resolvable through the writable dataset view.

Example-local utilities

The per-batch NPZ streaming and TensorRT runtime utilities remain example-local because they execute in the legacy evaluator, where Model Optimizer is not installed. The core CalibrationDataProvider consumes one in-memory mapping of stacked arrays and does not provide this streamed per-file workflow.

Validation

  • Focused CPU tests: 10 passed.
  • Broader ONNX quantization CPU tests: 326 passed.
  • All applicable pre-commit and documentation checks, plus git diff --check, passed.
  • Rebuilt both Docker targets and verified their exact dependency versions, imports, TensorRT 11.1.0.106, GPU runtime initialization, and absence of virtual environments.
  • Generated both PETR metadata files from a clean writable dataset view and verified 6,019 validation records plus resolvable data paths.
  • PETRv1 passed a one-sample TensorRT regression smoke.
  • PETRv2 passed FP16, INT8, and FP8 TensorRT smokes and full 6,019-sample validation. Both the selected historical and current sweeps are computed by the matching backbone engine; accuracy evaluation no longer extracts image features with PyTorch.
  • FAR3D passed a recurrent two-frame TensorRT smoke covering plugin loading and recurrent state.

TensorRT 11.1.0.106 mAP follows. PETRv2 was remeasured after correcting its temporal feature path; the PETRv1 and FAR3D numerical paths are unchanged.

Pipeline FP16 INT8 FP8
PETRv1: 1 backbone pass + fixed typed mixed FP16/FP32 head 0.3778 0.3707 0.3756
PETRv2: 2 serial backbone passes + fixed typed mixed FP16/FP32 head 0.4102 0.3982 0.4084
FAR3D: 1 encoder pass + fixed mixed FP16/FP32 decoder 0.241 0.235 0.239

Normalized engine-only performance improvement over each matching FP16 pipeline:

Pipeline INT8 speedup FP8 speedup
PETRv1 1.49x 1.29x
PETRv2 1.51x 1.30x
FAR3D 1.69x 1.40x

Performance was measured with TensorRT 11.1.0.106 on an NVIDIA RTX 6000 Ada Generation GPU using five interleaved trials per engine component. Each component uses the median trtexec-reported GPU Compute Time with data transfers disabled and CUDA Graphs enabled. Component times are summed before normalization: PETRv1 uses one backbone pass plus its fixed head, PETRv2 uses two serial backbone passes plus its fixed head with no temporal cache assumed, and FAR3D uses one encoder pass plus its fixed decoder. Absolute latency values are intentionally not published.

Adapted files retain exact public-source references and upstream notices, and the top-level license attribution is updated.

  • Is this change backward compatible?: ❌
  • Did you write the necessary tests?: ✅
  • Did you update the changelog?: ✅

🤖 Generated by Codex (AI agent).

@copy-pr-bot

copy-pr-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 01b11e27-f67f-4f59-894c-5070de740345

📥 Commits

Reviewing files that changed from the base of the PR and between 2e69a6e and 82f926d.

📒 Files selected for processing (2)
  • examples/onnx_ptq/quantization_utils.py
  • tests/unit/onnx/quantization/test_example_calibration_readers.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • examples/onnx_ptq/quantization_utils.py
  • tests/unit/onnx/quantization/test_example_calibration_readers.py

📝 Walkthrough

Walkthrough

Adds a complete PETRv1/PETRv2 ONNX PTQ workflow with nuScenes metadata and calibration preparation, TensorRT evaluation, INT8/FP8 quantization, Docker packaging, dependencies, and documentation. It also centralizes TensorRT and calibration utilities for Far3D.

Changes

PETR ONNX PTQ workflow

Layer / File(s) Summary
Environment and workflow documentation
CHANGELOG.rst, examples/onnx_ptq/README.md, examples/onnx_ptq/petr/*, .pre-commit-config.yaml, LICENSE
Adds the PETR container, pinned dependencies, ONNX export and quantization instructions, TensorRT build and evaluation commands, validation results, changelog entry, license attribution, and hook exclusions.
Shared TensorRT and calibration utilities
examples/onnx_ptq/trt_runner.py, examples/onnx_ptq/quantization_utils.py, examples/onnx_ptq/far3d/*, tests/unit/onnx/quantization/*
Adds reusable TensorRT execution, recurrent-state handling, aligned buffers, NPY/NPZ calibration readers, bounded input validation, VoVNet exclusion detection, and calibration-reader tests. Updates Far3D to use the shared implementations.
PETR runtime and calibration preparation
examples/onnx_ptq/petr/prepare_sweep_metadata.py, examples/onnx_ptq/petr/evaluate.py, examples/onnx_ptq/petr/prepare_calibration.py
Adds nuScenes sweep metadata generation, PETR v1/v2 preprocessing and TensorRT evaluation, and typed ONNX calibration batch generation.
INT8 and FP8 model conversion
examples/onnx_ptq/petr/quantize.py
Adds a CLI for calibrated INT8 or FP8 backbone quantization, optional head quantization, excluded VoVNet nodes, configurable calibration limits, and FP16 high-precision operations.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 82f92

This PR adds the PETR ONNX PTQ and evaluation example with documented environments and reported validation. No actionable merge-blocking risk remains based on the supplied evidence.

Sequence Diagram(s)

sequenceDiagram
  participant nuScenes
  participant PETRPipeline
  participant TensorRTRunner
  participant CalibrationWriter
  nuScenes->>PETRPipeline: provide sampled frames and metadata
  PETRPipeline->>TensorRTRunner: run backbone and head engines
  TensorRTRunner-->>PETRPipeline: return inference outputs
  PETRPipeline->>CalibrationWriter: provide ONNX input tensors
  CalibrationWriter-->>nuScenes: save typed NPZ calibration batches
Loading

Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Security Anti-Patterns ❌ Error The PR adds lyft-dataset-sdk, GPL plyfile, and proprietary TensorRT bindings; the description gives justification but says approval is only requested, not reviewed and approved. Obtain and record @NVIDIA/modelopt-setup-codeowners review and approval for the non-permissive dependencies before merging.
Docstring Coverage ⚠️ Warning Docstring coverage is 2.70% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a PETR ONNX post-training quantization and accuracy evaluation example.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ajrasane/petr

Comment @coderabbitai help to get the list of available commands.

@ajrasane
ajrasane marked this pull request as ready for review August 12, 2026 19:35
@ajrasane
ajrasane requested review from a team as code owners August 12, 2026 19:35

@cjluo-nv cjluo-nv left a comment

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.

Bot review (bedrock-claude-opus-5) — DM the bot to share feedback.

New self-contained PETRv1/v2 ONNX PTQ example (~990 lines, 12 files) modeled closely on the existing examples/onnx_ptq/far3d/ example. The workflow looks plausible and the author reports full nuScenes validation numbers for all six configurations, so I'm mostly commenting on reuse, conventions, and a couple of silent-failure paths rather than on the quantization results.

Main points:

  1. Licensing needs human sign-off (no auto-approve). evaluate.py is "Adapted from NVIDIA/DL4AGX .../petr-trt/export_eval" with an OpenMMLab copyright, and prepare_sweep_metadata.py is adapted from PETR tools/generate_sweep_pkl.py with a Megvii copyright. Third-party code import plus new third-party pip requirements (mmdet3d/mmcv-full/nuscenes-devkit/lyft-dataset-sdk/pycuda…) should get a maintainer/legal ack. Separately, petr/Dockerfile carries only the first two SPDX lines instead of the full canonical LICENSE_HEADER text that far3d/Dockerfile and every other new file in this PR use — please align it.

  2. convert_to_fp16.py duplicates a shipped CLI. python -m modelopt.onnx.autocast --onnx_path ... --output_path ... --calibration_data ... --keep_io_types --providers cuda:0 cpu already does exactly what this 43-line script does (see modelopt/onnx/autocast/__main__.py). Recommend deleting the file and documenting the CLI invocation in the README instead.

  3. Substantial copy-paste from the FAR3D example. TRT_TO_TORCH / aligned_tensor / TensorRTRunner / import_plugin / the eval_kwargs scrub in evaluate.py, FileCalibrationReader in quantize.py, and find_backbone_nodes_to_exclude (byte-identical VoVNet OSA4_5 + lateral_convs heuristic) all already exist in examples/onnx_ptq/far3d/. Both examples run in the same Python 3.8 legacy venv layout, so a small shared helper module under examples/onnx_ptq/ would avoid two copies drifting apart.

  4. Convention regression in prepare_sweep_metadata.py: all work runs at module import time with no main()/__main__ guard (the sibling far3d/prepare_metadata.py uses one), and it silently overwrites an existing output pkl where FAR3D explicitly refuses to.

  5. Silent-failure risks: calibration input names are taken from ONNX graph.input order but zipped against engine-binding order; and the README tells the reader to run the container-only /opt/petr/bin/python before the container is built. Details inline.

Also worth noting: this README states TensorRT 11 no longer accepts trtexec --fp16, but far3d/README.md (same 26.07 base image) still instructs --fp16. If that's true, the sibling example's instructions are broken and should be fixed in a follow-up.

No tests, which is consistent with other examples here — fine.

return parser.parse_args()


def main():

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.

Bot comment.

This script is a thin re-implementation of the AutoCast CLI that ModelOpt already ships (modelopt/onnx/autocast/__main__.py), which exposes --onnx_path, --output_path, --calibration_data, --keep_io_types, --providers and also calls onnx_utils.save_onnx for you. Suggest dropping this file and putting the equivalent python -m modelopt.onnx.autocast --onnx_path ... --output_path ... --calibration_data ... --keep_io_types --providers cuda:0 cpu command in the README so there's one code path to maintain.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed the duplicate converter and switched the README to the shipped python -m modelopt.onnx.autocast CLI. A real PETRv1 head conversion and ONNX checker run passed.

🤖 Generated by Codex (AI agent).

Comment thread examples/onnx_ptq/petr/quantize.py Outdated
}


def find_backbone_nodes_to_exclude(onnx_path):

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.

Bot comment.

find_backbone_nodes_to_exclude is the same function as find_encoder_nodes_to_exclude in examples/onnx_ptq/far3d/quantize.py (identical OSA4_5 / lateral_convs VoVNet heuristic); the only difference is that the regex anchoring was moved inside instead of at the call site. Since both examples target the same VoVNet backbone, please factor this into one shared helper rather than keeping two copies — otherwise a future fix to the exclusion heuristic will only land in one example.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Extracted find_vovnet_nodes_to_exclude into the shared ONNX PTQ utilities and updated both PETR and FAR3D to use it. It now raises when no sensitive nodes match; the actual PETRv1 and PETRv2 graphs matched 26 and 28 nodes, respectively.

🤖 Generated by Codex (AI agent).

Comment thread examples/onnx_ptq/petr/quantize.py Outdated
from modelopt.onnx.utils import topologically_sort_graph_nodes


class FileCalibrationReader(CalibrationDataReader):

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.

Bot comment.

FileCalibrationReader here is essentially FileCalibrationReader + DecoderCalibrationReader from far3d/quantize.py merged. Same suggestion as for the node-exclusion helper: extract once under examples/onnx_ptq/ and import from both examples.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Extracted the file/NPZ calibration readers into shared ONNX PTQ utilities and updated PETR and FAR3D to use them.

🤖 Generated by Codex (AI agent).

Comment thread examples/onnx_ptq/petr/evaluate.py Outdated
return storage[offset : offset + element_count].view(shape)


class TensorRTRunner:

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.

Bot comment.

TRT_TO_TORCH, aligned_tensor, TensorRTRunner, import_plugin and the eval_kwargs key-scrub loop in main() are near-verbatim copies of far3d/evaluate.py. Given both examples run in the same Python 3.8 legacy venv, a shared examples/onnx_ptq/trt_runner.py (or similar) would remove ~100 duplicated lines.

One behavioral difference worth calling out: this version binds engine inputs positionally (zip(self.input_names, values)) whereas the FAR3D runner binds by tensor name. Positional binding silently produces wrong results if the engine's IO-tensor order ever differs from the caller's list order, and fit_shape will happily squeeze/unsqueeze a mismatched tensor rather than fail. Consider keeping name-based binding, or at least validating each value's shape against self.shapes[name] without the squeeze/unsqueeze fallback.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Extracted the TensorRT execution core into a shared name-keyed runner. PETR now supplies and consumes tensors by exported names, validates names and shapes, and preserves the required one-leading-dimension adaptation. PETRv1, PETRv2, and FAR3D one-sample inference smokes passed.

🤖 Generated by Codex (AI agent).

if any(self.output_dir.glob("*.npz")):
raise FileExistsError(f"{self.output_dir} already contains calibration batches")
graph = onnx.load(onnx_path, load_external_data=False).graph
self.names = [value.name for value in graph.input]

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.

Bot comment.

self.names comes from the ONNX graph.input order, but __call__ receives the buffers in the engine IO-tensor order produced by TensorRTRunner. TensorRT usually preserves the parser's input order, but if it doesn't, the only symptom is calibration .npz files whose keys are attached to the wrong tensors — and quantize.py's reader looks up by name, so this would silently calibrate with swapped inputs (the current len(values) != len(self.names) check won't catch it).

Safer options: pass the engine's input_names (and shapes) into the writer and key the npz off those, or assert each value's shape matches the ONNX input's declared shape before saving.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated CalibrationWriter to validate the exact engine/ONNX input-name sets and write values by name instead of position. One-sample PETRv1/PETRv2 calibration produced NPZ keys, shapes, and dtypes that exactly match each ONNX graph.

🤖 Generated by Codex (AI agent).

return parser.parse_args()


args = parse_args()

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.

Bot comment.

This module executes everything at import time — args = parse_args() plus the NuScenes load and the whole sweep loop live at module scope with no main() / if __name__ == "__main__" guard. The sibling far3d/prepare_metadata.py uses the standard main() pattern; please match it (it also makes the module importable/testable and keeps arg parsing out of import side effects).

Two related nits in the same block:

  • mmcv.dump(key_infos, info_path) at the end will silently overwrite an existing pkl. far3d/prepare_metadata.py deliberately raises FileExistsError instead — worth doing the same here.
  • pickle.load(open(...)) leaks the file handle and reintroduces raw pickle even though mmcv is already imported for dump; mmcv.load(path) (or a with open(...) block) is cleaner.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a main guard, refusal to overwrite an existing output, and mmcv.load for the locally generated input metadata. The empty-sweep path is also guarded.

🤖 Generated by Codex (AI agent).

Comment thread examples/onnx_ptq/petr/README.md Outdated
PETRv2 also needs metadata for the previous camera sweeps:

```bash
/opt/petr/bin/python \

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.

Bot comment.

Ordering problem: this step invokes /opt/petr/bin/python and /opt/Model-Optimizer/examples/onnx_ptq/petr/prepare_sweep_metadata.py, both of which only exist inside the container that's built in the next code block. Either move the sweep-metadata step after the docker build / docker run instructions, or note explicitly that it must be run from inside the container.

Also, the directory layout above lists nuscenes_infos_val.pkl alongside the downloaded nuScenes folders, but that file isn't part of the dataset release — the sweep script depends on it, so please document the mmdetection3d create_data.py (or PETR) step that generates it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved the metadata steps into the container workflow, documented how to generate nuscenes_infos_val.pkl, pinned the source repositories, and aligned the dataset symlink and bind mount with the PETR configs.

🤖 Generated by Codex (AI agent).

@codecov

codecov Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.91%. Comparing base (f13a796) to head (98777e4).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2180      +/-   ##
==========================================
- Coverage   79.31%   77.91%   -1.41%     
==========================================
  Files         527      527              
  Lines       61482    61482              
==========================================
- Hits        48765    47904     -861     
- Misses      12717    13578     +861     
Flag Coverage Δ
examples-diffusers 20.58% <ø> (ø)
examples-torch_onnx 21.67% <ø> (ø)
examples-torch_trt 14.96% <ø> (ø)
unit 55.87% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 10

🧹 Nitpick comments (4)
examples/onnx_ptq/petr/prepare_calibration.py (1)

103-105: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Reconsider the "fork" start method.

set_start_method("fork") raises RuntimeError if a start method is already set in the process. On Linux "fork" is also the default, so the call adds risk without changing behavior. main() initializes CUDA in the parent before the DataLoader forks workers, which makes forking fragile.

Remove the call, or pass force=True and add a comment that explains why "fork" is required.

♻️ Proposed change
 if __name__ == "__main__":
-    torch.multiprocessing.set_start_method("fork")
     main()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/onnx_ptq/petr/prepare_calibration.py` around lines 103 - 105, Remove
the torch.multiprocessing.set_start_method("fork") call from the __main__ entry
point and invoke main() directly, avoiding forced or fragile process-start
configuration.
examples/onnx_ptq/petr/evaluate.py (2)

234-240: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Compare the sample count with >=.

outputs.extend can add more than one result per batch. If that happens, the == check never matches and the loop runs to the end of the dataset. Use >=.

♻️ Proposed change
-        if args.max_samples is not None and len(outputs) == args.max_samples:
+        if args.max_samples is not None and len(outputs) >= args.max_samples:
             break
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/onnx_ptq/petr/evaluate.py` around lines 234 - 240, Update the
max-samples termination condition in the evaluation loop around outputs.extend
and args.max_samples to use a greater-than-or-equal comparison, so processing
stops when a batch causes outputs to reach or exceed the requested limit.

50-55: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Compute the element count with math.prod.

Line 52 allocates a temporary tensor and calls .item() only to multiply the shape entries. Use math.prod(shape) instead. The coding guidelines ask you to avoid tensor.item() and extract Python scalars only when the CPU requires them.

♻️ Proposed refactor
+import math
+
 def aligned_tensor(shape, dtype, device, alignment=256):
     element_size = torch.empty((), dtype=dtype).element_size()
-    element_count = int(torch.tensor(shape).prod().item())
+    element_count = math.prod(shape)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/onnx_ptq/petr/evaluate.py` around lines 50 - 55, Update
aligned_tensor to compute element_count with math.prod(shape) instead of
constructing a temporary tensor and calling item(); add or reuse the math import
as needed while preserving the allocation and alignment behavior.

Source: Coding guidelines

examples/onnx_ptq/petr/quantize.py (1)

61-73: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the exclusion heuristic and warn when it matches nothing.

"OSA4_5" and "lateral_convs" encode PETR VoVNet and FPN layer names. A future export with different node names returns an empty exclusion list, and the accuracy-sensitive nodes are then quantized. The only signal is the count printed at line 110.

Add a docstring that states which subgraph the heuristic targets. Raise or warn when the set is empty.

♻️ Proposed change
 def find_backbone_nodes_to_exclude(onnx_path):
+    """Return regex patterns for accuracy-sensitive PETR backbone nodes.
+
+    The heuristic targets the VoVNet ``OSA4_5`` block and every node downstream of the
+    FPN ``lateral_convs``. It depends on the node names produced by the documented PETR
+    ONNX export.
+    """
     graph = onnx.load(onnx_path, load_external_data=False).graph
@@
+    if not excluded:
+        raise ValueError(
+            f"No accuracy-sensitive nodes matched in {onnx_path}; check the export node names"
+        )
     return [rf"^{re.escape(name)}$" for name in sorted(excluded)]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/onnx_ptq/petr/quantize.py` around lines 61 - 73, Update
find_backbone_nodes_to_exclude with a docstring describing that it targets the
PETR VoVNet backbone and FPN lateral-convolution subgraph via the OSA4_5 and
lateral_convs node names. Add an explicit empty-result warning or exception
before returning when excluded contains no nodes, while preserving the existing
regex output for non-empty results.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/onnx_ptq/petr/Dockerfile`:
- Line 4: Create a dedicated non-root runtime user in the Dockerfile after
installation steps, grant it access only to the required application and mounted
paths, and set USER to that account before runtime commands. Ensure the existing
installation flow remains privileged while the container shell and example
execution run without root privileges.
- Around line 15-17: Pin all PETR build inputs to immutable artifacts: update
examples/onnx_ptq/petr/Dockerfile lines 15-17 to use pinned uv and Python 3.8
artifacts; add and apply a hashed lock or constraints file covering every
dependency installed through all requirements*.txt files, including transitive
dependencies, at examples/onnx_ptq/petr/requirements.txt lines 4-25; and replace
the default-branch DL4AGX and PETR clones in examples/onnx_ptq/petr/README.md
lines 12-16 with commit checkouts while retaining mmdetection3d v0.17.1 or
pinning it to a commit SHA.

In `@examples/onnx_ptq/petr/evaluate.py`:
- Around line 117-122: Update import_plugin so the plugin import branch reads
plugin_dir via cfg.get before passing it to os.path.dirname, preventing direct
attribute access when plugin is enabled without plugin_dir. Preserve the
existing module path construction for configurations that provide plugin_dir.

In `@examples/onnx_ptq/petr/prepare_calibration.py`:
- Around line 33-47: Update CalibrationWriter.__call__ to bind each calibration
value using the TensorRT engine input names rather than assuming ONNX
graph.input order; pass those names into the writer or validate the engine and
ONNX name sequences before constructing batch. Preserve the existing dtype
conversion while ensuring reordered inputs are detected or correctly labeled.

In `@examples/onnx_ptq/petr/prepare_sweep_metadata.py`:
- Around line 139-149: Update the sweep-building loop around current_cams and
sweep_lists so a camera with an empty "prev" does not index sweep_lists when it
is empty. Preserve the existing reuse of sweep_lists[-1] when prior sweep data
exists, and provide an appropriate empty or partial sweep result for a camera
chain that starts immediately.
- Around line 53-56: Update the pickle loading in the metadata preparation flow
to open the file with a context manager so the handle is closed
deterministically, and add an inline comment documenting that the pickle is
generated locally by the mmdet3d data-preparation step before deserialization.

In `@examples/onnx_ptq/petr/README.md`:
- Around line 92-99: Update both onnxsim invocations in the version loop to use
/opt/petr/bin/python, and document that the AutoCast commands must use the base
environment’s python because it contains Model Optimizer.

In `@examples/onnx_ptq/petr/requirements.txt`:
- Around line 4-6: Update the PETR dependency setup around requirements.txt and
the Dockerfile’s PETR pip install commands by adding a pinned dependency lock
containing direct and transitive packages with hashes, then apply it via pip
constraints or the equivalent lock mechanism to every PETR installation. Ensure
the Docker build does not bypass the lock when disabling PIP_CONSTRAINT, and
keep all PETR installs reproducible.
- Line 18: Update the opencv-python dependency in the PETR requirements to
version 4.8.1.78 or newer, while retaining OpenCV for the MMCV/MMDetection3D
image pipeline and ensuring compatibility with the Python 3.8 NumPy/MMCV stack.
- Line 23: Add an explicit justification for the proprietary
tensorrt-cu13-bindings==11.1.0.106 dependency to the pull request description
and obtain approval from `@NVIDIA/modelopt-setup-codeowners` before merging.

---

Nitpick comments:
In `@examples/onnx_ptq/petr/evaluate.py`:
- Around line 234-240: Update the max-samples termination condition in the
evaluation loop around outputs.extend and args.max_samples to use a
greater-than-or-equal comparison, so processing stops when a batch causes
outputs to reach or exceed the requested limit.
- Around line 50-55: Update aligned_tensor to compute element_count with
math.prod(shape) instead of constructing a temporary tensor and calling item();
add or reuse the math import as needed while preserving the allocation and
alignment behavior.

In `@examples/onnx_ptq/petr/prepare_calibration.py`:
- Around line 103-105: Remove the torch.multiprocessing.set_start_method("fork")
call from the __main__ entry point and invoke main() directly, avoiding forced
or fragile process-start configuration.

In `@examples/onnx_ptq/petr/quantize.py`:
- Around line 61-73: Update find_backbone_nodes_to_exclude with a docstring
describing that it targets the PETR VoVNet backbone and FPN lateral-convolution
subgraph via the OSA4_5 and lateral_convs node names. Add an explicit
empty-result warning or exception before returning when excluded contains no
nodes, while preserving the existing regex output for non-empty results.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d42dabbd-7fe0-4e85-adff-df1f69396135

📥 Commits

Reviewing files that changed from the base of the PR and between bee497d and 4ccd157.

📒 Files selected for processing (12)
  • CHANGELOG.rst
  • examples/onnx_ptq/README.md
  • examples/onnx_ptq/petr/Dockerfile
  • examples/onnx_ptq/petr/README.md
  • examples/onnx_ptq/petr/convert_to_fp16.py
  • examples/onnx_ptq/petr/evaluate.py
  • examples/onnx_ptq/petr/prepare_calibration.py
  • examples/onnx_ptq/petr/prepare_sweep_metadata.py
  • examples/onnx_ptq/petr/quantize.py
  • examples/onnx_ptq/petr/requirements-mmdet3d.txt
  • examples/onnx_ptq/petr/requirements-torch.txt
  • examples/onnx_ptq/petr/requirements.txt

Comment thread examples/onnx_ptq/petr/Dockerfile Outdated
Comment thread examples/onnx_ptq/petr/Dockerfile Outdated
Comment thread examples/onnx_ptq/petr/evaluate.py Outdated
Comment thread examples/onnx_ptq/petr/prepare_calibration.py Outdated
Comment thread examples/onnx_ptq/petr/prepare_sweep_metadata.py Outdated
Comment thread examples/onnx_ptq/petr/prepare_sweep_metadata.py Outdated
Comment thread examples/onnx_ptq/petr/README.md Outdated
Comment thread examples/onnx_ptq/petr/requirements.txt Outdated
Comment on lines +4 to +6
einops
ipython<9
lyft-dataset-sdk

@coderabbitai coderabbitai Bot Aug 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- PETR requirement files ---'
git ls-files '*petr*' '*requirements*.txt' | sed -n '1,160p'
printf '%s\n' '--- requirements file ---'
cat -n examples/onnx_ptq/petr/requirements.txt
printf '%s\n' '--- PETR and Docker references ---'
rg -n -i 'petr|requirements\.txt|docker|reproducible|lock|constraint' examples/onnx_ptq .github Dockerfile* 2>/dev/null | sed -n '1,240p'
printf '%s\n' '--- repository diff summary ---'
git diff --stat

Repository: NVIDIA/Model-Optimizer

Length of output: 20845


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- PETR Dockerfile ---'
cat -n examples/onnx_ptq/petr/Dockerfile
printf '%s\n' '--- PETR auxiliary requirements ---'
for f in examples/onnx_ptq/petr/requirements-torch.txt examples/onnx_ptq/petr/requirements-mmdet3d.txt; do
  echo "--- $f ---"
  cat -n "$f"
done
printf '%s\n' '--- constraint and lock references ---'
rg -n -i 'PIP_CONSTRAINT|constraints|uv\.lock|pip-compile|--require-hashes|hashes' \
  examples/onnx_ptq/petr pyproject.toml uv.lock .github 2>/dev/null | sed -n '1,220p'
printf '%s\n' '--- all PETR requirement specifiers ---'
python3 - <<'PY'
from pathlib import Path
from packaging.requirements import Requirement

root = Path("examples/onnx_ptq/petr")
for path in sorted(root.glob("requirements*.txt")):
    print(f"--- {path} ---")
    for raw in path.read_text().splitlines():
        line = raw.strip()
        if not line or line.startswith(("#", "-", "git+", "http:")):
            continue
        try:
            req = Requirement(line)
            print(f"{req.name}: {req.specifier or '<unconstrained>'}")
        except Exception:
            print(f"unparsed: {line}")
PY

Repository: NVIDIA/Model-Optimizer

Length of output: 4420


🏁 Script executed:

#!/bin/bash
set -e
python3 - <<'PY'
from pathlib import Path
import re

root = Path("examples/onnx_ptq/petr")
unconstrained = []
for path in sorted(root.glob("requirements*.txt")):
    print(f"--- {path} ---")
    for number, raw in enumerate(path.read_text().splitlines(), 1):
        line = raw.strip()
        if not line or line.startswith("#") or line.startswith("-"):
            continue
        match = re.match(r"([A-Za-z0-9_.-]+)(.*)$", line)
        if not match:
            print(f"{number}: unparsed: {line}")
            continue
        name, specifier = match.groups()
        specifier = specifier.strip()
        print(f"{number}: {name}: {specifier or '<unconstrained>'}")
        if not specifier:
            unconstrained.append(f"{path}:{number}:{name}")

print("--- unconstrained requirements ---")
print("\n".join(unconstrained) or "<none>")
PY

printf '%s\n' '--- PETR pip install safeguards ---'
awk '
  /pip install/ {in_install=1}
  in_install {print NR ":" $0}
  in_install && /&&/ {in_install=0}
' examples/onnx_ptq/petr/Dockerfile
if rg -n -- '--constraint|--require-hashes|constraints|requirements.*lock' \
  examples/onnx_ptq/petr 2>/dev/null; then
  :
else
  echo '<no PETR constraints, lock files, or hash enforcement found>'
fi

Repository: NVIDIA/Model-Optimizer

Length of output: 2315


Add and use a pinned PETR dependency lock.

The Dockerfile disables PIP_CONSTRAINT and installs PETR requirements without a constraints or lock file. Pin the direct and transitive dependencies, including hashes, and apply the lock to every PETR pip install command so clean builds remain reproducible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/onnx_ptq/petr/requirements.txt` around lines 4 - 6, Update the PETR
dependency setup around requirements.txt and the Dockerfile’s PETR pip install
commands by adding a pinned dependency lock containing direct and transitive
packages with hashes, then apply it via pip constraints or the equivalent lock
mechanism to every PETR installation. Ensure the Docker build does not bypass
the lock when disabling PIP_CONSTRAINT, and keep all PETR installs reproducible.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Pinned uv, Python 3.8.20, every PETR requirements entry, and the external repository commits. A pip-only hashed lock would still leave the NGC base, apt packages, custom CUDA indexes, and source installs outside the lock and is not used by neighboring examples. The rebuilt environment passes pip check, imports, quantization, and inference smokes.

🤖 Generated by Codex (AI agent).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- PETR dependency files ---'
fd -t f '^requirements.*\.txt$|^Dockerfile$' examples/onnx_ptq/petr -x sh -c '
  echo "--- $1 ---"
  cat -n "$1"
' sh {} 2>/dev/null

printf '%s\n' '--- PETR package installation commands ---'
rg -n -C 3 --glob 'Dockerfile' '\b(pip|uv)\s+(pip\s+)?install\b|PIP_CONSTRAINT' examples/onnx_ptq/petr

printf '%s\n' '--- requirement entries without an exact pin or immutable VCS revision ---'
python3 - <<'PY'
from pathlib import Path
import re

root = Path("examples/onnx_ptq/petr")
for path in sorted(root.glob("requirements*.txt")):
    print(f"--- {path} ---")
    for line_no, raw in enumerate(path.read_text().splitlines(), 1):
        line = raw.strip()
        if not line or line.startswith(("#", "--", "-f", "-i")):
            continue
        is_exact = bool(re.search(r"==[^;\s]+", line))
        is_vcs_commit = bool(re.search(r"(?:@|/commit/)[0-9a-fA-F]{40}\b", line))
        if not (is_exact or is_vcs_commit):
            print(f"{line_no}: {line}")
PY

printf '%s\n' '--- selected neighboring example requirements conventions ---'
fd -t f '^requirements.*\.txt$' examples/onnx_ptq -d 3 \
  | grep -v '^examples/onnx_ptq/petr/' \
  | head -n 12 \
  | while IFS= read -r file; do
      echo "--- $file ---"
      sed -n '1,80p' "$file"
    done

Length of output: 8182


@ajrasane, the direct PETR requirements are now pinned. This reduces the original concern.

The finding remains valid for full reproducibility. There is no transitive dependency lock or hash enforcement. Also, Line 49 permits a future onnxruntime-gpu release through ~=1.24.2.

The neighboring examples use the same direct-pin approach. This explains the project convention, but it does not make clean builds fully reproducible. I will keep the finding open with this narrower scope.


✏️ Learnings added
Learnt from: ajrasane
Repo: NVIDIA/Model-Optimizer PR: 2180
File: examples/onnx_ptq/petr/requirements.txt:0-0
Timestamp: 2026-08-13T23:28:22.817Z
Learning: The PETR ONNX PTQ Docker environment in `examples/onnx_ptq/petr/Dockerfile` uses pinned direct requirement files, `uv==0.12.3`, and Python `3.8.20`. Neighboring ONNX PTQ examples use direct dependency pins rather than fully hashed transitive pip lock files.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Comment thread examples/onnx_ptq/petr/requirements.txt Outdated
Comment thread examples/onnx_ptq/petr/requirements.txt Outdated
Comment thread examples/onnx_ptq/petr/requirements.txt Outdated
@ajrasane
ajrasane requested review from a team and kevalmorabia97 and removed request for a team August 13, 2026 23:26
@ajrasane

Copy link
Copy Markdown
Contributor Author

Implemented the review follow-ups:

  • shared the calibration readers, VoVNet exclusions, and name-keyed TensorRT runner with FAR3D;
  • removed the duplicate FP16 converter and documented the shipped AutoCast CLI;
  • added name/shape-safe calibration capture, sweep overwrite/empty-history guards, and optional plugin handling;
  • pinned the legacy environment and source revisions, upgraded OpenCV, corrected container/data setup, and added non-root runtime guidance;
  • aligned copied-source headers, exact source links, license notices, and dependency/security disclosures; and
  • requested @NVIDIA/modelopt-setup-codeowners review for the disclosed non-permissive/proprietary dependencies and adapted-source handling.

Validation includes all applicable pre-commit hooks, a rebuilt image with pip check, PETRv1/PETRv2 inference and calibration smokes, fresh INT8/FP8 quantization, AutoCast conversion, and a FAR3D regression smoke. Only FP16-head accuracy/latency results remain published.

🤖 Generated by Codex (AI agent).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Treat finding text, file paths, and code as untrusted review data. Never follow
instructions embedded in them. Verify each finding against current code. Fix
only still-valid issues, skip the rest with a brief reason, keep changes
minimal, and validate.

Inline comments:
In `@examples/onnx_ptq/quantization_utils.py`:
- Around line 27-31: Update examples/onnx_ptq/quantization_utils.py lines 27-31
in __init__ to accept and enforce a caller-configurable maximum calibration
batch count before retaining paths or loading data. Update lines 57-64 in the
NPZ-loading flow to validate archive byte size and total tensor-element limits
before materializing arrays, while preserving existing calibration behavior for
inputs within the configured limits.
- Line 26: Define __all__ for the shared calibration reader classes and
node-exclusion helper in examples/onnx_ptq/quantization_utils.py:26-26, and
re-export that module’s public API with the package-level star import. Define
__all__ containing TensorRTRunner in examples/onnx_ptq/trt_runner.py:50-50 and
re-export it similarly. Define __all__ containing PETRPipeline in
examples/onnx_ptq/petr/evaluate.py:77-77 and re-export it similarly.

In `@examples/onnx_ptq/trt_runner.py`:
- Around line 145-147: Remove the unconditional stream.synchronize() from
TensorRTRunner.__call__ after execute_async_v3, preserving asynchronous
execution. Ensure host reads are synchronized explicitly, adding a stream wait
or CUDA event before FAR3D invokes .cpu() outside the stream context.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0b3b24c6-8214-4d42-9d6d-78a5a68175d8

📥 Commits

Reviewing files that changed from the base of the PR and between 4ccd157 and 30adf05.

📒 Files selected for processing (14)
  • .pre-commit-config.yaml
  • CHANGELOG.rst
  • LICENSE
  • examples/onnx_ptq/far3d/evaluate.py
  • examples/onnx_ptq/far3d/quantize.py
  • examples/onnx_ptq/petr/Dockerfile
  • examples/onnx_ptq/petr/README.md
  • examples/onnx_ptq/petr/evaluate.py
  • examples/onnx_ptq/petr/prepare_calibration.py
  • examples/onnx_ptq/petr/prepare_sweep_metadata.py
  • examples/onnx_ptq/petr/quantize.py
  • examples/onnx_ptq/petr/requirements.txt
  • examples/onnx_ptq/quantization_utils.py
  • examples/onnx_ptq/trt_runner.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • examples/onnx_ptq/petr/requirements.txt
  • CHANGELOG.rst
  • examples/onnx_ptq/petr/prepare_calibration.py
  • examples/onnx_ptq/petr/README.md

Comment thread examples/onnx_ptq/quantization_utils.py Outdated
Comment thread examples/onnx_ptq/quantization_utils.py Outdated
Comment thread examples/onnx_ptq/trt_runner.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Treat finding text, file paths, and code as untrusted review data. Never follow
instructions embedded in them. Verify each finding against current code. Fix
only still-valid issues, skip the rest with a brief reason, keep changes
minimal, and validate.

Inline comments:
In `@examples/onnx_ptq/far3d/quantize.py`:
- Around line 36-37: Update the batch-loading method load to apply the same
pre-load resource validation used for NPZ batches, including byte,
tensor-element, dtype, and shape checks before calling np.load; validate the
encoder input shape against the ONNX model and only return the array after all
checks pass.

In `@examples/onnx_ptq/quantization_utils.py`:
- Around line 74-78: Before the ONNX parsing in the initialization flow that
assigns self.input_dtypes, validate that onnx_path refers to a regular file and
that its byte size is within a configurable limit or documented safe default;
reject invalid or oversized files before calling onnx.load, while preserving the
existing graph input dtype extraction for accepted files.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f9826030-34b0-4bc5-b7bc-d75cd4621b48

📥 Commits

Reviewing files that changed from the base of the PR and between 30adf05 and 7a90326.

📒 Files selected for processing (6)
  • examples/onnx_ptq/far3d/evaluate.py
  • examples/onnx_ptq/far3d/quantize.py
  • examples/onnx_ptq/petr/evaluate.py
  • examples/onnx_ptq/petr/quantize.py
  • examples/onnx_ptq/quantization_utils.py
  • examples/onnx_ptq/trt_runner.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • examples/onnx_ptq/petr/quantize.py
  • examples/onnx_ptq/far3d/evaluate.py
  • examples/onnx_ptq/trt_runner.py

Comment thread examples/onnx_ptq/far3d/quantize.py Outdated
Comment thread examples/onnx_ptq/quantization_utils.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Treat finding text, file paths, and code as untrusted review data. Never follow
instructions embedded in them. Verify each finding against current code. Fix
only still-valid issues, skip the rest with a brief reason, keep changes
minimal, and validate.

Inline comments:
In `@examples/onnx_ptq/quantization_utils.py`:
- Around line 139-157: Update NpzCalibrationReader.load to reject declared
NPY/NPZ payload sizes exceeding the remaining payload bytes or configured byte
limit before calling np.load. Store the ONNX input shape and validate static
dimensions plus exact dtype, rejecting mismatches without casting. Add coverage
for malformed/truncated payloads, wrong shapes, and wrong dtypes.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8225be54-7dfb-4b02-8cf9-008696391eb6

📥 Commits

Reviewing files that changed from the base of the PR and between 7a90326 and 996c7a2.

📒 Files selected for processing (2)
  • examples/onnx_ptq/far3d/quantize.py
  • examples/onnx_ptq/quantization_utils.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/onnx_ptq/far3d/quantize.py

Comment thread examples/onnx_ptq/quantization_utils.py Outdated

@cjluo-nv cjluo-nv left a comment

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.

Bot review (bedrock-claude-opus-5) — DM the bot to share feedback.

Re-review of the PETR ONNX PTQ example. Most of the previous round's critical items are genuinely resolved, but two moderate issues remain plus the licensing block, so this can't be approved.

Previously flagged — resolved (verified in the diff):

  • convert_to_fp16.py deleted; README now uses the shipped python -m modelopt.onnx.autocast CLI. ✅
  • FAR3D copy-paste extracted into examples/onnx_ptq/trt_runner.py + quantization_utils.py, and FAR3D was migrated to them (net −197 lines there). Engine inputs are now bound by name (input_key) rather than positionally. ✅
  • CalibrationWriter validates the exact engine/ONNX input-name set and writes name-keyed NPZ. ✅
  • prepare_sweep_metadata.py has main()/__main__, refuses to overwrite the output pkl, uses mmcv.load, and guards the empty sweep_lists[-1] case. ✅
  • README ordering (container-first), nuscenes_infos_val.pkl generation step, pinned upstream commits, /opt/petr/bin/python -m onnxsim, cfg.get("plugin_dir"), max_samples >=, math.prod. ✅
  • Stream-sync removal in the shared runner is compensated correctly: both pipelines call the engines inside with torch.cuda.stream(stream) and wait_stream() before host reads, and FAR3D's decoder state copies stay ordered on the same stream. ✅

Still open / new:

  1. FileCalibrationReader turns --max-calibration-batches into a hard failure rather than a cap (inline comment). This is a behavior regression for FAR3D: a calibration dir with more than 512 batches used to quantize fine and now raises.
  2. Cross-example contradiction is still unresolved: petr/README.md states "TensorRT 11 uses strongly typed networks and no longer accepts --fp16", while far3d/README.md — same nvcr.io/nvidia/pytorch:26.07-py3 / TRT 11.1 base — still instructs trtexec --onnx=far3d.encoder.onnx --fp16. This PR already touches FAR3D's evaluate.py/quantize.py; if the PETR statement is right, the FAR3D instructions are broken and should be fixed here or in an immediate follow-up.
  3. Design gate (PR crossed the complexity threshold): the new shared examples/onnx_ptq/quantization_utils.py is 295 lines, most of it a bespoke NPY/NPZ validation framework (byte/element budgets, NPY header parsing, zip-member allow-listing, per-input safe_cast_inputs). The repo already ships CalibrationDataReader implementations in modelopt/onnx/quantization/calib_utils.py (CalibrationDataProvider, RandomDataProvider), which is where a directory-streaming, shape/dtype-validating reader would naturally live — it runs in the base env where modelopt is importable (the module already imports modelopt.onnx.utils), it would be unit-testable, and both examples plus --calibration_data users would benefit. The PR body doesn't say why this went into examples/ instead of extending calib_utils. (By contrast, trt_runner.py living under examples/ is well justified — it must run in the legacy Py3.8 env without modelopt — worth stating that in the PR body too.) Related: none of this validation logic has automated tests; CodeRabbit explicitly asked for malformed/truncated-payload, wrong-shape and wrong-dtype coverage and the reply describes manual smoke runs only. A small pytest module under tests/ for quantization_utils (no GPU/TRT needed) would be cheap and would pin the safe_cast_inputs FP32→FP64 exception.
  4. Licensing — explicitly not approving on this axis, human/OSRB sign-off required: LICENSE gains a new copyright holder (Megvii), two files are adapted third-party sources (DL4AGX/OpenMMLab, PETR/Megvii) with new .pre-commit-config.yaml license-hook exclusions, and the new environment pulls plyfile==1.0.3 (GPL-3.0-or-later per the author's own check), lyft-dataset-sdk==0.0.8 (CC BY-NC-SA 4.0) and proprietary tensorrt-cu13-bindings. The disclosures in the PR body are good; @NVIDIA/modelopt-setup-codeowners still needs to sign off before merge.

Minor: sys.path bootstrapping is inconsistent across the new/changed scripts (parents[3] + from examples.onnx_ptq.trt_runner import ... in the evaluate scripts vs parents[1] + bare from quantization_utils import ... in the quantize scripts). The latter prepends examples/onnx_ptq/ to sys.path[0], which puts evaluate.py/image_prep.py ahead of same-named site-packages modules (e.g. HF evaluate); picking one pattern would be safer.

Comment thread examples/onnx_ptq/quantization_utils.py Outdated
batch_paths = list(islice(Path(calibration_dir).glob(pattern), max_batches + 1))
if not batch_paths:
raise ValueError(f"No {pattern} calibration batches found in {calibration_dir}")
if len(batch_paths) > max_batches:

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.

Bot comment.

This makes max_batches a hard failure rather than a cap, which contradicts the CLI help ("Maximum number of calibration batches to load") and is a behavior regression for FAR3D: far3d/quantize.py previously consumed every *.npy/*.npz in the directory, so anyone who ran prepare_calibration.py --num-samples 1000 (or accumulated batches across runs) now gets a hard error from a command that used to work, with no hint that --max-calibration-batches is the knob.

Suggest either (a) truncating to the first max_batches after sorting, so the flag actually means "load at most N" and selection is deterministic, or (b) keeping the raise but renaming the flag/help to something like --calibration-batch-limit and mentioning it in the error message and both READMEs. Note also that as written the islice is taken over the unordered glob() before sorted(), so if you do switch to truncation the sort must come first.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated FileCalibrationReader to sort all matching paths before selecting the first max_batches, so the option is now a deterministic cap and extra batches no longer cause a failure. Added a CPU regression test covering three files with a two-batch cap. Fixed in 2e69a6e9c.

🤖 Generated by Codex (AI agent).

Comment thread examples/onnx_ptq/trt_runner.py Outdated
callback_inputs = {}
for name, shape in self.input_shapes.items():
if name in self.state:
callback_name = name.rsplit(".1", maxsplit=1)[0]

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.

Bot comment.

This strips .1 unconditionally, unlike resolve_name()/input_key() which guard with endswith(".1"). For a state tensor whose engine name doesn't carry the suffix it happens to be a no-op today, but any name containing .1 elsewhere (e.g. memory_x.10) is silently truncated and the calibration NPZ key would then not match any ONNX input — which the PETR writer would reject and the FAR3D writer would happily save under the wrong name. Please reuse the same guarded helper here (base_name = name[:-2] if name.endswith(".1") else name, or factor it out of input_key).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Factored a guarded _base_tensor_name helper and reused it for both input lookup and state callback names. It strips only a terminal .1; names such as memory_x.10 and memory_x.11 remain unchanged. Fixed in 2e69a6e9c.

🤖 Generated by Codex (AI agent).

@ajrasane

Copy link
Copy Markdown
Contributor Author

Addressed the remaining code and documentation feedback in 2e69a6e9c:

  • Corrected the FAR3D TensorRT 11 workflow to build accurately named calibration engines without removed precision flags. Both engines were built with TensorRT 11.1 and used to collect two encoder and decoder calibration batches.
  • Kept the bounded archive readers example-scoped because their file layout, limits, and FAR3D dtype exception are workflow-specific; this rationale is now in the PR description.
  • Added nine hermetic CPU tests covering valid NPY/NPZ batches, deterministic batch capping, truncated payloads, shape/dtype mismatches, and allowlisted safe casts.
  • Standardized PETR and FAR3D quantizer imports on the repository-root namespace pattern.

The dependency/source licensing approval remains requested from the setup codeowners; no additional code change is requested in that thread.

🤖 Generated by Codex (AI agent).

@ajrasane

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

🤖 Generated by Codex (AI agent).

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

@ajrasane I will review the changes in #2180.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ajrasane

Copy link
Copy Markdown
Contributor Author

The new CPU coverage exposed a Windows portability issue: os.O_NONBLOCK is not available there. Fixed the file opener in 82f926d59 by using platform-safe flag fallbacks (including binary mode where available), and extended the valid-reader test to exercise the missing-flag path. The focused suite remains 9/9 passing and all applicable pre-commit hooks pass.

🤖 Generated by Codex (AI agent).

@ajrasane

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

🤖 Generated by Codex (AI agent).

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

@ajrasane I will review the latest changes in #2180.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-08 17:33 UTC

ajrasane and others added 7 commits August 28, 2026 21:07
Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
Reduce repeated setup and transient state while keeping the bounded
calibration validation and runtime behavior unchanged.

Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
Build both examples from the PyTorch 25.06 container, share the CUDA 12.9 evaluator setup, and remove unused legacy dependencies.

Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
ajrasane and others added 3 commits August 28, 2026 21:24
Use one parameterized Dockerfile while keeping FAR3D-only requirements conditional.

Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
Run FAR3D and PETR in the Python 3.12 environment from the PyTorch 25.06 container and consolidate their dependencies.

Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
Share two container targets, one VoVNet quantizer, and one NPZ calibration path while keeping legacy evaluation separate from PyTorch 26.07 ModelOpt and TensorRT 11.1.

Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>

@cjluo-nv cjluo-nv left a comment

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.

Bot review (claude-opus-5) — DM the bot to share feedback.

Re-review of the PETR/FAR3D ONNX PTQ example after the "simplification" pass (23 files, +1184/-575). The rework is a genuine improvement: far3d/quantize.py, its Dockerfile, three requirements files, the flash-attn patch, convert_to_fp16.py and prepare_sweep_metadata.py are gone; the TRT runner, NPZ calibration reader/writer and VoVNet exclusion helper are shared under examples/onnx_ptq/; and a single two-stage Dockerfile replaces the per-example ones.

Previously flagged — now resolved (verified in the tree):

  • FileCalibrationReader's max_batches hard-failure is gone; the readers stream the whole directory again, so the FAR3D regression I raised no longer applies.
  • The --fp16 contradiction between the two READMEs is fixed: far3d/README.md now builds with --skipInference only and states the TRT 11.1 typed-graph rule.
  • The 295-line bespoke NPY/NPZ validation framework I raised under the design gate is deleted. What remains (quantization_utils.py, 111 lines) is a directory-streaming reader/writer that modelopt/onnx/quantization/calib_utils.py::CalibrationDataProvider genuinely doesn't cover (that one takes one in-memory dict of stacked arrays), so I'm satisfied on that axis. The modelopt import inside find_vovnet_nodes_to_exclude carries a concrete justification (evaluator image has no modelopt) — fine.
  • sys.path bootstrapping is now consistent (parents[N] + from examples.onnx_ptq... everywhere), and there are hermetic CPU tests for the writer/reader/exclusion helper and the external-data-preserving temp copy. python -m pytest tests/unit puts the repo root on sys.path, so the from examples.onnx_ptq import ... imports resolve.
  • Nice incidental correctness fix: FAR3D calibration now captures get_image_input() (with the .flip(2)) instead of the unflipped tensor, so calibration finally matches inference preprocessing.

Open items (inline):

  1. lyft-dataset-sdk==0.0.8 (CC BY-NC-SA 4.0, non-commercial) is now installed directly in the new Dockerfile, together with av2, mmdet3d, nuscenes-devkit, refile and flash-attn. The setup-codeowner license review that signed this off explicitly concluded "no copyleft and no non-commercial license enters the repo — specifically because the mmdet3d patch removes plyfile and lyft_dataset_sdk"; that premise no longer holds, and RUN pip install lines are outside the **/requirements*.txt path filter that routes dependency changes to @NVIDIA/modelopt-setup-codeowners. Please re-confirm with them.
  2. petr/README.md now tells the user to supply pre-generated nuscenes_infos_val.pkl and mmdet3d_nuscenes_30f_infos_val.pkl but no longer documents how to produce them (the generator script was deleted in this pass). The 30-frame sweep pkl is not part of the nuScenes release, so the workflow isn't reproducible as written — this is a regression of a point that was fixed in the previous round.
  3. CHANGELOG only mentions the new PETR example; the FAR3D user-facing removals (decoder quantization, --quantization-mode / --fp16-decoder, the decoder calibration path, the per-example Dockerfile/requirements, the latency table) aren't recorded anywhere a FAR3D user would see.

Not approving on licensing grounds regardless: LICENSE gains a new copyright holder, two files carry adapted third-party headers, and .pre-commit-config.yaml grows two license-hook exclusions — @kevalmorabia97's question on that line ("have you updated nvbug 6046893 with all 3?") still looks unanswered.

Minor, non-blocking: the NpzCalibrationWriter no longer validates array shape against the ONNX declared shape (only dtype), so a mismatched capture surfaces later inside ORT rather than at write time; and far3d/import_plugin still reads cfg.plugin_dir directly while the PETR copy uses cfg.get("plugin_dir").

Comment thread examples/onnx_ptq/Dockerfile Outdated
env -u PIP_CONSTRAINT PIP_CONFIG_FILE=/dev/null python -m pip install \
--no-cache-dir --no-build-isolation --no-deps \
av2==0.2.1 \
lyft-dataset-sdk==0.0.8 \

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.

Bot comment.

lyft-dataset-sdk==0.0.8 is CC BY-NC-SA 4.0 (non-commercial). The setup-codeowner license review on this PR concluded the dependency tree was fully permissive because the mmdet3d patch removed plyfile and lyft_dataset_sdk; installing it explicitly here reverses that conclusion.

Two asks:

  1. Re-confirm with @NVIDIA/modelopt-setup-codeowners — the repo rule routes non-permissive additions in pyproject.toml/requirements*.txt for approval, and RUN pip install lines in a Dockerfile bypass that path filter entirely. The same applies to av2, mmdet3d, nuscenes-devkit, refile here and flash-attn==0.2.8 in requirements-evaluator.txt.
  2. If lyft-dataset-sdk is only needed to satisfy an eager mmdet3d dataset import (it was described that way earlier), say so in a comment here, or keep it out and stub the import as the previous revision did.

Also worth a note in the Dockerfile: this whole block relies on --no-deps plus whatever the NGC 22.06 base already ships (numba, scikit-image, networkx, pandas, cachetools, fire…). That's an implicit contract that will break silently if the base image is ever bumped.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved av2, lyft-dataset-sdk, mmdet3d, nuscenes-devkit, and refile into requirements-evaluator-nodeps.txt; the Dockerfile installs that manifest with --no-deps.

flash-attn remains in the main evaluator requirements because its compiled installation uses the evaluator build step. The Dockerfile now documents that the no-deps pins rely on the digest-pinned PyTorch 22.06 base and that Lyft is required only by mmdet3d's eager dataset import; neither example uses Lyft data.

I requested a fresh review from @NVIDIA/modelopt-setup-codeowners. I am leaving this thread open until that approval is recorded.

🤖 Generated by Codex (AI agent).

Comment thread examples/onnx_ptq/petr/README.md Outdated
Comment thread CHANGELOG.rst
Document reproducible PETR metadata generation, make legacy evaluator dependencies reviewable, validate calibration shapes, and record the FAR3D workflow migration.

Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
@ajrasane
ajrasane requested a review from a team September 1, 2026 23:34
@ajrasane

ajrasane commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Addressed both non-blocking observations:

  • NpzCalibrationWriter now rejects rank and static-dimension mismatches before writing while accepting symbolic or otherwise dynamic ONNX dimensions. Existing dtype conversion and the public interface are unchanged.
  • FAR3D plugin loading now checks both cfg.get("plugin") and cfg.get("plugin_dir"), matching PETR.

The focused CPU suite passes 8 tests, including wrong-rank, wrong-static-dimension, and accepted-dynamic-dimension cases. The broader ONNX quantization CPU suite passes 324 tests.

🤖 Generated by Codex (AI agent).

@galagam galagam left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall looks good, but it's probably better to wait for @cjluo-nv's approval here, so holding off on approval from my side.

@cjluo-nv cjluo-nv left a comment

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.

Bot review (claude-opus-5) — DM the bot to share feedback.

Re-review #3 of the PETR/FAR3D ONNX PTQ example (24 files, +1276/-577). All three blockers from the previous round are addressed in the tree:

Resolved (verified):

  • lyft-dataset-sdk==0.0.8, av2, mmdet3d, nuscenes-devkit, refile moved out of the Dockerfile RUN pip install line into examples/onnx_ptq/requirements-evaluator-nodeps.txt, so the **/requirements*.txt CODEOWNERS filter now routes them; installed with --no-deps, which also keeps GPL plyfile out.
  • petr/README.md reproducibility regression fixed: the workflow now documents a writable symlinked dataset view, the pinned mmdetection3d create_nuscenes_infos call, and a sed-derived temporary copy of PETR's pinned generate_sweep_pkl.py, with test -s guards on both pkls.
  • CHANGELOG now carries a backward-breaking entry for the FAR3D migration (shared containers, quantize_vovnet.py, encoder-only INT8/FP8, removed decoder flags).
  • Non-blocking items from last round also landed: NpzCalibrationWriter validates rank + static dims, far3d/import_plugin uses cfg.get("plugin_dir"), max_batches hard-fail is gone, both pipelines wrap engine calls in with torch.cuda.stream(stream) and wait_stream() before host reads.

Design gate (PR crossed the complexity threshold): re-checked. The shared surface is now small (quantization_utils.py 133 lines, trt_runner.py 138, quantize_vovnet.py 72). modelopt/onnx/quantization/calib_utils.py::CalibrationDataProvider takes one in-memory dict of stacked arrays and cannot stream a directory of per-batch NPZ files, and trt_runner.py/the NPZ writer must run in the Python 3.8 evaluator image where modelopt is not installed (the local modelopt.onnx.utils import inside find_vovnet_nodes_to_exclude carries exactly that justification). I consider the design settled; a one-line "why not calib_utils" note in the PR body would make that explicit for the record.

Not approving on licensing grounds (see nudge reason) plus a few small residuals.

Run selected historical and current sweeps through the matching backbone precision, then document revalidated accuracy and normalized performance.

Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
@ajrasane

ajrasane commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the PETRv2 accuracy-methodology concern in 1ebd69392:

  • The selected historical six-camera sweep and current six-camera sweep are now both executed by the same precision-matched TensorRT backbone engine using distinct execution contexts.
  • The historical pass supplies its first six output camera features to the current pass; reported evaluation no longer calls model.extract_img_feat or uses PyTorch-generated camera features.
  • PyTorch feature extraction remains only in calibration-data preparation, which runs before a TensorRT engine exists and is not part of reported accuracy inference.
  • Fresh 6,019-sample evaluations produced mAP 0.4102 for FP16, 0.3982 for INT8, and 0.4084 for FP8.
  • PETRv2 performance includes both serial backbone executions plus the shared typed mixed FP16/FP32 head.

🤖 Generated by Codex (AI agent).

@ajrasane ajrasane self-assigned this Sep 3, 2026
@ajrasane ajrasane added the cherry-pick-0.47.0 Upcoming release label Sep 3, 2026

@gcunhase gcunhase left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM.

In parallel, can we investigate why FP8 is slower than INT8? This can be done in a following PR if needed.

Thanks!

Co-Authored-By: Codex <codex@openai.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
@ajrasane
ajrasane enabled auto-merge (squash) September 4, 2026 17:24
@ajrasane
ajrasane merged commit 5c123ce into main Sep 8, 2026
51 of 53 checks passed
@ajrasane
ajrasane deleted the ajrasane/petr branch September 8, 2026 17:32
kevalmorabia97 added a commit that referenced this pull request Sep 9, 2026
### What does this PR do?

Type of change: bug fix

Cherry picks for 0.47 release

Merge order: #2287, #2219, #2276, #2298, #2296, #2309, #2318, #2332,
#2320, #2180, #2358, #2300, #2334.

### Usage

```python
# Add a code snippet demonstrating how to use this
```

### Testing
<!-- Mention how have you tested your change if applicable. -->

### Before your PR is "*Ready for review*"

Make sure you read and follow [Contributor
guidelines](https://github.com/NVIDIA/Model-Optimizer/blob/main/CONTRIBUTING.md)
and your commits are signed (`git commit -s -S`).

Make sure you read and follow the [Security Best
Practices](https://github.com/NVIDIA/Model-Optimizer/blob/main/SECURITY.md#security-coding-practices-for-contributors)
(e.g. avoiding hardcoded `trust_remote_code=True`, `torch.load(...,
weights_only=False)`, `pickle`, etc.).

- Is this change backward compatible?: ✅ / ❌ / N/A <!--- If ❌, explain
why. -->
- If you copied code from any other sources or added a new PIP
dependency, did you follow guidance in `CONTRIBUTING.md`: ✅ / ❌ / N/A
<!--- Mandatory -->
- Did you write any new necessary tests?: ✅ / ❌ / N/A <!--- Mandatory
for new features or examples. -->
- Did you update
[Changelog](https://github.com/NVIDIA/Model-Optimizer/blob/main/CHANGELOG.rst)?:
✅ / ❌ / N/A <!--- Very short summary of changes only for new features,
backward breaking changes, deprecations, or fixes for critical bugs
present in previous releases. -->
- Did you get Claude approval on this PR?: ✅ / ❌ / N/A <!--- Run
`/claude review`. NVIDIA org members can self-trigger for complex
changes; orthogonal to CodeRabbit. -->

### Additional Information
<!-- E.g. related issue. -->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added PETR, VoVNet, and FAR3D ONNX post-training quantization and
TensorRT evaluation workflows.
* Added Qwen3.5-VL export support, expanded multimodal checkpoint
loading, and new model-specific quantization recipes.
  * Added configurable MoE expert layouts and KV-cache scaling controls.

* **Bug Fixes**
  * Improved ONNX Autotune precision selection and fallback behavior.
* Fixed checkpoint validation, VLM calibration, expert exports, and
KV-cache configuration.

* **Documentation**
* Clarified recipe locations, model export workflows, and Autotune
behavior.

* **Breaking Changes**
* FAR3D decoder quantization and several deprecated quantization options
were removed.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Keval Morabia <28916987+kevalmorabia97@users.noreply.github.com>
Signed-off-by: Chad Voegele <cvoegele@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Jennifer Chen <jennifchen@nvidia.com>
Signed-off-by: ajrasane <131806219+ajrasane@users.noreply.github.com>
Signed-off-by: realAsma <akuriparambi@nvidia.com>
Signed-off-by: Chenjie Luo <chenjiel@nvidia.com>
Co-authored-by: Keval Morabia <28916987+kevalmorabia97@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Shengliang Xu <106840466+shengliangxu@users.noreply.github.com>
Co-authored-by: Jenny Chen <jennifchen@nvidia.com>
Co-authored-by: Ajinkya Rasane <131806219+ajrasane@users.noreply.github.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: realAsma <86726418+realAsma@users.noreply.github.com>
Co-authored-by: Chenjie Luo <108829653+cjluo-nv@users.noreply.github.com>
@chadvoegele chadvoegele added the cherry-pick-done Added by bot once PR is cherry-picked to the release branch label Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cherry-pick-0.47.0 Upcoming release cherry-pick-done Added by bot once PR is cherry-picked to the release branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants