Skip to content

Fix KITTI eval and checkpoint loading on numpy>=2 / torch>=2.6 - #1773

Open
blancnight2 wants to merge 1 commit into
open-mmlab:masterfrom
blancnight2:fix/numpy2-numba-and-torch26-compat
Open

blancnight2 wants to merge 1 commit into
open-mmlab:masterfrom
blancnight2:fix/numpy2-numba-and-torch26-compat

Conversation

@blancnight2

@blancnight2 blancnight2 commented Sep 1, 2026 •

Copy link
Copy Markdown

What

Two independent compatibility fixes needed to run OpenPCDet on current toolchains
(numpy >= 2.0, torch >= 2.6). Both currently block evaluation out of the box.

1. rotate_iou.py — drop the numba dependency

The numba.cuda kernel used by the KITTI evaluator fails type inference on recent
numba releases combined with numpy >= 2.0, raising Signature mismatch from
FixupArgs. The workaround circulating in the issue tracker is to pin
numpy==1.23, which is not viable on newer toolchains (and conflicts with other
packages in a modern CUDA 12.x environment).

Instead of pinning numpy back, this PR removes the numba.cuda GPU-kernel path from KITTI evaluation (the part that breaks); the CPU @numba.jit functions in eval.py are untouched and continue to work by reimplementing rotate_iou_gpu_eval as a thin PyTorch
wrapper around the project's own compiled boxes_overlap_bev_gpu op
(pcdet/ops/iou3d_nms). That op is already a hard dependency of OpenPCDet, so
no new dependency is introduced — one is removed.

Geometry equivalence. The original code builds corners and rotates them by
[[cos, sin], [-sin, cos]], which is R(-angle), whereas boxes_overlap_bev_gpu
rotates by R(heading). Setting heading = -angle (with dx = x_d, dy = y_d)
makes the two rectangles identical, so the returned intersection area matches.

2. detector3d_template.py — weights_only=False

torch 2.6 flipped the default of torch.load to weights_only=True. OpenPCDet
checkpoints contain more than plain tensors, so loading them now fails. This PR
passes weights_only=False explicitly at the two checkpoint load sites.

Verification

rotate_iou_gpu_eval was checked against an independent shapely reference that
reimplements the original corner convention, over random boxes and all four
criterion values:

criterion meaning max abs error
-1 IoU (inter / union) 9.0e-07
0 inter / area(boxes) 1.3e-06
1 inter / area(query_boxes) 6.2e-07
other raw intersection area 6.9e-05 (area units)

i.e. float32 round-off. End-to-end, PointPillars trained for 80 epochs evaluates
normally on KITTI val with this evaluator (3D AP R40 — Car 85.59 / 75.60 / 72.76,
Pedestrian 50.79 / 43.75 / 39.12, Cyclist 79.72 / 62.05 / 57.71).

Environment

Ubuntu 20.04 (WSL2), torch 2.11.0+cu128, CUDA 12.8, RTX 5070 (sm_120), numpy 2.2,
spconv-cu124.

Notes

  • device_id is now honoured (tensors are placed on cuda:device_id) instead of
    being ignored.
  • The deprecated torch.cuda.FloatTensor(...) constructor is avoided.
  • The evaluator now requires the compiled iou3d_nms op at eval time. This is
    already required to run any detector in OpenPCDet, so it should not be a new
    constraint in practice — happy to guard it behind a try/except with a clear
    error message if maintainers prefer.

Two independent compatibility fixes needed to run OpenPCDet on current
toolchains:

1. rotate_iou.py: the numba.cuda kernel fails type inference
   ("Signature mismatch" raised from FixupArgs) on recent numba
   releases combined with numpy >= 2.0. Replace it with a thin PyTorch
   wrapper around the project's own compiled boxes_overlap_bev_gpu op.
   This removes the numba requirement for KITTI evaluation entirely
   rather than pinning numpy back to <2.

   The rectangle geometry is reproduced exactly by setting
   heading = -angle: the original code rotates local corners by
   [[cos,sin],[-sin,cos]] = R(-angle), while boxes_overlap_bev_gpu
   rotates by R(heading).

   Verified against an independent shapely reference that implements
   the original corner convention, over random boxes and all four
   criterion values: max abs error 9.0e-07 (IoU), 1.3e-06 and 6.2e-07
   (the two ratio criteria), 6.9e-05 (raw intersection area, in area
   units) -- i.e. float32 round-off.

2. detector3d_template.py: torch 2.6 flipped the default of torch.load
   to weights_only=True, which breaks loading OpenPCDet checkpoints
   since they contain more than plain tensors. Pass weights_only=False
   explicitly at the two checkpoint load sites.
@blancnight2

Copy link
Copy Markdown
Author

Two clarifications after re-reading my own description.

1. Scope of the numba change. To be precise, this removes the numba.cuda
GPU-kernel path
from KITTI evaluation, not numba altogether. eval.py still uses
CPU @numba.jit(nopython=True) in five places and those are unaffected — only the
CUDA kernel hits the type-inference regression (Signature mismatch from
FixupArgs). Apologies for the overstatement in the description; I have corrected
it there as well.

For reference, the failure is limited to evaluation — training and inference never
touch this code path. The weights_only change in (2) is broader: it affects any
checkpoint load, including resuming training, test.py, and the demo scripts.

2. The same kernel is duplicated elsewhere. The identical numba.cuda
implementation of rotate_iou_gpu_eval also lives in
pcdet/datasets/once/once_eval/iou_utils.py (lines ~277-341), so ONCE evaluation
should fail the same way on numpy >= 2. I left it untouched because I have no ONCE
data to validate the change against, and I did not want to ship an unverified edit.
Happy to apply the same fix there if maintainers want it in this PR, or to leave it
for a separate one.

That makes three implementations of rotated-rectangle intersection in the repo:
the two numba copies above, and the compiled C++/CUDA boxes_overlap_bev_gpu in
pcdet/ops/iou3d_nms that this PR reuses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant