wuyii8941 opened a new issue, #19693:
URL: https://github.com/apache/tvm/issues/19693
## Expected behavior
ONNX `NonMaxSuppression` declares `max_output_boxes_per_class`,
`iou_threshold`, and `score_threshold` as scalar tensors. By long-standing
convention (and ORT's behavior), both **0-D scalars** (shape `[]`) and **1-D
single-element tensors** (shape `[1]`) are accepted. Many ONNX exporters emit
shape `[1]`.
## Actual behavior
The TVM frontend crashes during conversion:
```
TypeError: only 0-dimensional arrays can be converted to Python scalars
```
This is a NumPy 2.x stricter cast — calling `int(np.array([3]))` now raises
`TypeError`, whereas NumPy 1.x silently accepted it.
## Reproduction
```python
import numpy as np
import onnx
from onnx import helper, TensorProto, numpy_helper
import onnxruntime as ort
from tvm.relax.frontend.onnx import from_onnx
boxes = helper.make_tensor_value_info("boxes", TensorProto.FLOAT, [1, 5, 4])
scores = helper.make_tensor_value_info("scores", TensorProto.FLOAT, [1, 1,
5])
Y = onnx.ValueInfoProto(); Y.name = "selected"
inits = [
numpy_helper.from_array(np.array([3], dtype=np.int64), "max_output"),
# shape [1]
numpy_helper.from_array(np.array([0.5], dtype=np.float32), "iou"),
# shape [1]
numpy_helper.from_array(np.array([0.0], dtype=np.float32), "score_thr"),
# shape [1]
]
node = helper.make_node("NonMaxSuppression",
["boxes", "scores", "max_output", "iou",
"score_thr"],
["selected"])
g = helper.make_graph([node], "g", [boxes, scores], [Y], initializer=inits)
m = helper.make_model(g, opset_imports=[helper.make_opsetid("", 18)])
boxes_v = np.array([[[0., 0., 1., 1.],
[0., 0.1, 1., 1.1],
[0., -0.1, 1., 0.9],
[0., 10., 1., 11.],
[0., 10.1, 1., 11.1]]], dtype=np.float32)
scores_v = np.array([[[0.9, 0.75, 0.6, 0.95, 0.5]]], dtype=np.float32)
print("ORT:", ort.InferenceSession(m.SerializeToString()).run(None,
{"boxes": boxes_v, "scores": scores_v})[0])
# ORT: [[0 0 3] [0 0 0]]
inf = onnx.shape_inference.infer_shapes(m)
mod = from_onnx(inf) # TypeError: only 0-dimensional arrays can be
converted to Python scalars
```
## Root cause
`python/tvm/relax/frontend/onnx/onnx_frontend.py`,
`NonMaxSuppression._impl_v10`:
```python
if max_output_boxes_per_class is not None and
isinstance(max_output_boxes_per_class, relax.Constant):
max_output_boxes_per_class =
int(max_output_boxes_per_class.data.numpy()) # NumPy 2.x: TypeError on shape
[1]
...
if iou_threshold is not None and isinstance(iou_threshold, relax.Constant):
iou_threshold = float(iou_threshold.data.numpy())
# same
...
if score_threshold is not None and isinstance(score_threshold,
relax.Constant):
score_threshold = float(score_threshold.data.numpy())
# same
```
`int()` / `float()` on a NumPy ndarray no longer auto-flattens; this raises
`TypeError` on any non-0-D tensor.
## Suggested fix
Use `.item()` (which accepts both 0-D and 1-element tensors of any rank):
```python
max_output_boxes_per_class =
int(max_output_boxes_per_class.data.numpy().item())
iou_threshold = float(iou_threshold.data.numpy().item())
score_threshold = float(score_threshold.data.numpy().item())
```
The same pattern (`int(constant.data.numpy())` / `float(...)`) appears in
several other converters and should be audited; e.g., `TopK` had a similar
problem fixed by #19573.
## Impact
Any ONNX model that emits NMS thresholds as shape-`[1]` tensors fails to
import. ONNX exporters from torchvision, MMDetection, YOLO-family
object-detection pipelines commonly produce shape-`[1]` here.
Unrelated to (but distinct from) #19544 which addresses the
`max_output_boxes_per_class = 0` semantics.
## Environment
- TVM: latest `main` (commit b172d5ea3)
- Python: 3.11
- NumPy: 2.4.4
- ONNX Runtime: 1.24.4
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]