Aharrypotter opened a new pull request, #20115: URL: https://github.com/apache/tvm/pull/20115
## Summary This PR extends the Relax ONNX `PRelu` converter to support lower-rank slope tensors that ONNX aligns to the trailing dimensions of the input. The gap was exposed by Qualcomm's Real-ESRGAN-General-x4v3 export. Its activation input has shape `[1, 64, 128, 128]`, while its slope has shape `[64, 1, 1]`. This is valid ONNX unidirectional broadcasting, but the current converter rejects it because the two ranks differ. ## Goal Import legal lower-rank ONNX `PRelu` slopes when they can be represented by Relax's one-dimensional `nn.prelu` slope and an adjusted axis. ## What changed - Align lower-rank slopes to the trailing input dimensions. - Translate the slope's non-broadcast dimension to the corresponding Relax input axis. - Keep rejecting slopes with multiple non-broadcast dimensions, which cannot be represented by the current Relax `nn.prelu` operator. - Handle rank-zero slopes without indexing an empty shape. - Add structural and ONNX Runtime-backed numerical regression coverage. ## Design For a slope with at most one non-broadcast dimension, let `relative_axis` be that dimension in the slope. ONNX trailing-dimension alignment maps it to: ```text axis = input_rank - slope_rank + relative_axis ``` For the motivating shape pair: ```text input: [1, 64, 128, 128] slope: [64, 1, 1] aligned slope: [1, 64, 1, 1] Relax axis: 1 ``` The converter then reshapes the slope to `[64]` and emits `R.nn.prelu(..., axis=1)`. ## Updated converter behavior | ONNX slope shape | Behavior | | --- | --- | | Rank-zero or all-one shape | Reshape to a one-element vector | | Rank-one shape | Preserve the existing final-axis behavior | | Lower/equal rank with one non-broadcast dimension | Align to trailing input dimensions and emit the corresponding Relax axis | | Multiple non-broadcast dimensions | Continue to raise an explicit unsupported-shape error | ## Safety checks - Existing scalar, one-dimensional, and same-rank structural cases remain covered. - The new structural case checks input `[1, 32, 16, 16]`, slope `[32, 1, 1]`, and Relax `axis=1`. - The new numerical case compares TVM with ONNX Runtime using channel-specific negative slopes. - The full Relax ONNX frontend test file passes in the validation environment, apart from five pre-existing Float8 baseline cases that were excluded explicitly. ## Out of scope / non-goals - Supporting arbitrary slopes with multiple non-broadcast dimensions. - Changing Relax `nn.prelu` semantics or legalization. - Adding the external Real-ESRGAN model to the TVM test suite. ## Results The pinned Real-ESRGAN-General-x4v3 ONNX model contains 33 `PRelu` nodes. With this change it imports, compiles for the C target, and runs end to end: ```text input: [1, 3, 128, 128] output: [1, 3, 512, 512] max abs error: 4.0531158447265625e-06 versus ONNX Runtime ``` ## Tests - `pre-commit run --files python/tvm/relax/frontend/onnx/onnx_frontend.py tests/python/relax/test_frontend_onnx.py` - Focused H20 run: `2 passed, 498 deselected` - Relax ONNX frontend H20 run: `482 passed, 9 skipped, 5 deselected, 4 xfailed` - Pinned Real-ESRGAN-General-x4v3 end-to-end C-target validation against ONNX Runtime ## References - [ONNX PRelu specification](https://onnx.ai/onnx/operators/onnx__PRelu.html) - [Qualcomm Real-ESRGAN-General-x4v3](https://huggingface.co/qualcomm/Real-ESRGAN-General-x4v3/tree/e12a7dcde3df0cf4315c648e0b5e4ca4f43d6904) - [Previous Relax ONNX PRelu support](https://github.com/apache/tvm/pull/18658) -- 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]
