siyiweigeHEW opened a new issue, #20148:
URL: https://github.com/apache/tvm/issues/20148

   
   ### Expected behavior
   
   A valid ONNX `PRelu` model whose `slope` is **lower-rank** than `X` but 
unidirectionally broadcastable (numpy trailing-dimension alignment) should be 
imported successfully by `tvm.relax.frontend.onnx.from_onnx`. The ONNX spec 
explicitly permits this — *"The shape of slope can be smaller than first input 
X; if so, its shape must be unidirectional broadcastable to X"* (see [ONNX 
PRelu spec](https://github.com/onnx/onnx/blob/main/docs/Operators.md#PRelu)). 
Such models pass `onnx.checker` and run correctly in onnxruntime and 
onnx.reference.
   
   ### Actual behavior
   
   `from_onnx` raises `ValueError: Unsupported PRelu slope shape`:
   
   ```
   ValueError: Unsupported PRelu slope shape: R.shape([64, 1, 1])
   ```
   
   raised at `python/tvm/relax/frontend/onnx/onnx_frontend.py:1154` in 
`PRelu._impl_v1` (class at line 1120). The frontend only supports:
   
   - all-ones `slope`, or rank-1 `slope` (`onnx_frontend.py:1137-1139`, 
reshaped to 1-D and applied at `axis = ndim - 1`), and
   - a same-rank `slope` with exactly **one** non-broadcast axis 
(`onnx_frontend.py:1141-1151`).
   
   Any lower-rank broadcastable `slope` (e.g. `(64, 1, 1)` for `X: (1, 64, 128, 
128)`) falls through to the unconditional `raise ValueError` at line 1154. Two 
related coverage gaps in the same method:
   
   - same-rank `slope` with **multiple** non-broadcast dims (including `slope` 
shaped identically to `X`) → `ValueError: Invalid PRelu slope shape (multiple 
non-broadcast dims)` at line 1147;
   - scalar (rank-0) `slope` → crash `IndexError: ShapeExpr index out of 
range`, because `slope_shape[0]` at line 1138 indexes an empty shape.
   
   The same model passes `onnx.checker`, runs correctly in onnxruntime (output 
shape `(1, 64, 128, 128)`), and is confirmed valid by the reference 
implementation `onnx.reference`, so the rejection is a frontend coverage gap, 
not an invalid model.
   
   ### Environment
   
   - OS: Linux
   - TVM: v0.24.dev0 (main branch, commit `262c6d2e0`, built 2026-02-11)
   - Python: 3.11
   - onnx: 1.20.1
   - onnxruntime: 1.24.1
   
   ### Steps to reproduce
   
   ```python
   """Repro: valid ONNX PRelu with lower-rank broadcastable slope is rejected 
by the
   TVM relax ONNX frontend, while onnxruntime accepts and runs it correctly.
   This is exactly the motivating case (X(1,64,128,128) + slope(64,1,1)) 
reported in
   apache/tvm #20115, triggered by a Qualcomm Real-ESRGAN export."""
   import numpy as np
   import onnx, onnxruntime
   from onnx import helper, TensorProto
   from tvm.relax.frontend.onnx import from_onnx
   
   x_shape, slope_shape = (1, 64, 128, 128), (64, 1, 1)          # slope is 
lower-rank, broadcastable
   X = helper.make_tensor_value_info("X", TensorProto.FLOAT, list(x_shape))
   Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, list(x_shape))
   node = helper.make_node("PRelu", ["X", "slope"], ["Y"])
   slope = helper.make_tensor("slope", TensorProto.FLOAT, list(slope_shape),
                              
np.random.RandomState(0).randn(*slope_shape).astype("float32").flatten().tolist())
   graph = helper.make_graph([node], "prelu", [X], [Y], initializer=[slope])
   model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
   model.ir_version = 8
   
   onnx.checker.check_model(model)                                # (1) valid 
ONNX model
   x = np.random.RandomState(1).randn(*x_shape).astype("float32")
   y = onnxruntime.InferenceSession(model.SerializeToString()).run(None, {"X": 
x})[0]
   print("onnxruntime runs OK ->", y.shape)                       # (2) 
reference impl works
   from_onnx(model, shape_dict={"X": x_shape})                    # (3) TVM 
rejects the same model
   ```
   
   Actual output:
   
   ```
   onnxruntime runs OK -> (1, 64, 128, 128)
   Traceback (most recent call last):
     ...
     File "tvm/relax/frontend/onnx/onnx_frontend.py", line 1154, in _impl_v1
       raise ValueError(f"Unsupported PRelu slope shape: {slope_shape}")
   ValueError: Unsupported PRelu slope shape: R.shape([64, 1, 1])
   ```
   
   ### Additional context
   
   - The ONNX PRelu spec states: *"The shape of slope can be smaller than first 
input X; if so, its shape must be unidirectional broadcastable to X."* It does 
**not** restrict `slope` to rank-1 or to a single non-broadcast channel axis.
   - A minimal lower-rank case (`X: (2, 3, 4, 5)`, `slope: (3, 1, 1)` → channel 
dim) reproduces the same `ValueError` with `onnx_frontend.py:1154`.
   - A broader differential survey (7 `X` shapes × every valid `slope` 
broadcast shape): of **113** legal ONNX PRelu models accepted by onnxruntime / 
`onnx.checker` / `onnx.reference`, TVM's frontend rejects **67** — lower-rank 
`slope` (32), same-rank multi-non-broadcast including `slope == X` (28), scalar 
rank-0 `slope` (7, crashing with `IndexError`). No numeric mismatch was 
observed on the 46 accepted models, so the gap is purely import coverage.
   - `relax.op.nn.prelu` can already express any single per-axis slope (the 
same-rank branch calls `nn.prelu(x, slope, axis)`), so the lower-rank case is 
expressible by computing `axis = ndim - s_ndim + relative_axis` before 
reshaping the slope, rather than rejecting the model.
   - A fix was upstreamed in apache/tvm [#20115 "[Relax][ONNX] Support 
lower-rank PRelu slopes"](https://github.com/apache/tvm/pull/20115) (merged 
2026-08-11), whose motivating case is exactly `X(1,64,128,128) + slope(64,1,1)` 
from a Qualcomm Real-ESRGAN export — confirming the bug is real and observed in 
the wild. This report covers the unfixed behavior in the v0.24.dev0 build at 
commit `262c6d2e0`.
   
   ### Triage
   
   * needs-triage
   * bug
   * relax
   * frontend/onnx
   


-- 
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]

Reply via email to