siyiweigeHEW opened a new pull request, #20147:
URL: https://github.com/apache/tvm/pull/20147

   
   Fixes: #20146
   
   ## Summary
   
   The Relax ONNX frontend mishandles `Mean` / `Sum` / `Min` / `Max` nodes whose
   inputs are all constants (model initializers): a **single** constant input
   returns a 0-d scalar (e.g. the *global* mean `3.5` for a `(2, 3)` input)
   instead of the input unchanged, and **multiple** constant inputs raise
   `TypeError: only integer scalar arrays can be converted to a scalar index`.
   onnxruntime returns correct results in both cases.
   
   ## Root cause
   
   `MultiInputBase._impl_v1`'s constant-fold path at
   `python/tvm/relax/frontend/onnx/onnx_frontend.py:2456-2459` called
   
   ```python
   output = cls.numpy_op(*np_inputs)
   ```
   
   For `Mean` / `Sum` / `Min` / `Max`, `numpy_op` is `np.mean` / `np.sum` /
   `np.min` / `np.max`. These numpy reductions reduce their **first** argument 
and
   interpret the 2nd and later positional arguments as the `axis` parameter, 
not as
   additional data tensors. So `np.mean(x)` reduces the whole tensor to a 0-d
   scalar, and `np.mean(a, b, ...)` passes an array into `axis` → TypeError.
   
   ## Fix
   
   Mirror the non-constant path: broadcast each constant to the common shape,
   stack along a new leading axis, then reduce along it.
   
   ```python
   input_shapes = [inp.ty.shape for inp in inputs]
   target_shape = tuple(
       int(dim)
       for dim in functools.reduce(compute_broadcast_shape, input_shapes)
   )
   stacked = _np.stack(
       [_np.broadcast_to(x, target_shape) for x in np_inputs], axis=0
   )
   output = cls.numpy_op(stacked, axis=0)
   ```
   
   A single constant input then reduces a `(1, *shape)` stack along axis 0, 
which
   is the identity — matching the ONNX semantics. (`relax.Constant` shape 
elements
   are `tvm.tir.IntImm`, so they are converted to plain ints for 
`np.broadcast_to`.)
   
   ## Validation
   
   Differential test: Relax (build + `VirtualMachine`) vs onnxruntime (and
   `onnx.reference`) on the same model, comparing output shapes and max |diff|.
   
   | Case | onnxruntime | TVM | max\|diff\| | Result |
   |---|---|---|---|---|
   | Mean, single const `(2,3)` | `(2, 3)` | `(2, 3)` | 0.00e+00 | OK |
   | Mean, single const `(5,)` | `(5,)` | `(5,)` | 0.00e+00 | OK |
   | Mean, single const scalar `()` | `()` | `()` | 0.00e+00 | OK |
   | Mean, two consts `(2,3)` | `(2, 3)` | `(2, 3)` | 0.00e+00 | OK |
   | Mean, two consts `(2,3,4)` | `(2, 3, 4)` | `(2, 3, 4)` | 0.00e+00 | OK |
   | Mean, const broadcast `(2,3)+(3,)` | `(2, 3)` | `(2, 3)` | 0.00e+00 | OK |
   | Mean, 3 consts broadcast `(2,3)+(3,)+(2,1)` | `(2, 3)` | `(2, 3)` | 
2.38e-07 | OK |
   | Sum, two consts `(2,3)` | `(2, 3)` | `(2, 3)` | 0.00e+00 | OK |
   | Min, consts int64 `(2,3)` | `(2, 3)` | `(2, 3)` | 0.00e+00 | OK |
   | Max, single const int32 `(2,3)` | `(2, 3)` | `(2, 3)` | 0.00e+00 | OK |
   | Mean, non-const broadcast `(2,3)+(3,)` | `(2, 3)` | `(2, 3)` | 0.00e+00 | 
OK |
   | Mean, mixed const + graph input | `(2, 3)` | `(2, 3)` | 0.00e+00 | OK |
   
   The two failing cases from the issue now match onnxruntime exactly:
   
   ```
   onnxruntime -> (2, 3) [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
   TVM        -> (2, 3) [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
   [two inputs] onnxruntime -> (2, 3) [6.0, 7.0, 8.0, 9.0, 10.0, 11.0]
   [two inputs] TVM        -> (2, 3) [6.0, 7.0, 8.0, 9.0, 10.0, 11.0]
   ```
   
   Run:
   
   ```bash
   python results/TVM/deepseek-v4-flash/prove_hum/onnx_Mean/5修复_差分验证.py
   ```
   
   ## Files changed
   
   - `python/tvm/relax/frontend/onnx/onnx_frontend.py` — 
`MultiInputBase._impl_v1`
     constant-fold path: broadcast + stack + reduce along the leading axis 
instead
     of `numpy_op(*np_inputs)` (fixes `Mean` / `Sum` / `Min` / `Max`).
   


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