This is an automated email from the ASF dual-hosted git repository.
mshr pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push:
new 993c785bad [ONNX] Handle Gelu approximate attribute from Opset 20
(#18773)
993c785bad is described below
commit 993c785bad1429abb6c2d45a3bd60a2c93ece9f3
Author: Harikrishna KP <[email protected]>
AuthorDate: Wed Feb 18 09:24:38 2026 +0530
[ONNX] Handle Gelu approximate attribute from Opset 20 (#18773)
## Description
Fixes #18750
The ONNX frontend `Gelu` converter was hardcoded to always emit
`R.nn.gelu`, ignoring the `approximate` attribute introduced in ONNX
Opset 20. When a model uses `approximate="tanh"`, TVM would silently
produce incorrect results by applying the exact erf-based Gelu instead
of the tanh approximation.
## Changes
Added `_impl_v20` to the `Gelu` converter class that checks the
`approximate` attribute:
- `approximate="tanh"` → routes to `relax.op.nn.gelu_tanh`
- `approximate="none"` (default) → routes to `relax.op.nn.gelu`
The existing `_impl_v1` is left untouched for backward compatibility
with the Microsoft onnxruntime contrib opset. The version dispatch
mechanism will automatically select `_impl_v20` for Opset 20+ models.
## Testing
- The change is a straightforward attribute check that routes to an
already-existing and tested operator (`R.nn.gelu_tanh`).
- No new dependencies introduced.
---------
Signed-off-by: Mr-Neutr0n <[email protected]>
---
python/tvm/relax/frontend/onnx/onnx_frontend.py | 16 +++++++++++++++-
tests/python/relax/test_frontend_onnx.py | 8 ++++++++
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/python/tvm/relax/frontend/onnx/onnx_frontend.py
b/python/tvm/relax/frontend/onnx/onnx_frontend.py
index 5f7c2ab752..a9334b98b1 100644
--- a/python/tvm/relax/frontend/onnx/onnx_frontend.py
+++ b/python/tvm/relax/frontend/onnx/onnx_frontend.py
@@ -1181,15 +1181,29 @@ class LeakyRelu(OnnxOpConverter):
class Gelu(OnnxOpConverter):
- """Operator converter for Gelu from Microsoft onnxruntime contrib opset.
+ """Operator converter for Gelu.
+
+ Supports both Microsoft onnxruntime contrib opset and ONNX Opset 20+.
gelu(x) = 0.5x(1 + erf(x/sqrt(2)))
+
+ When approximate="tanh" (ONNX Opset 20):
+ gelu(x) = 0.5x(1 + tanh(sqrt(2/pi)(x + 0.044715x^3)))
"""
@classmethod
def _impl_v1(cls, bb, inputs, attr, params):
return relax.op.nn.gelu(inputs[0])
+ @classmethod
+ def _impl_v20(cls, bb, inputs, attr, params):
+ approximate = attr.get("approximate", b"none").decode("utf-8")
+ if approximate == "tanh":
+ return relax.op.nn.gelu_tanh(inputs[0])
+ if approximate == "none":
+ return relax.op.nn.gelu(inputs[0])
+ raise ValueError(f"Unsupported approximate mode for Gelu:
{approximate}")
+
class FastGelu(OnnxOpConverter):
"""Operator converter for FastGelu from Microsoft onnxruntime contrib
opset.
diff --git a/tests/python/relax/test_frontend_onnx.py
b/tests/python/relax/test_frontend_onnx.py
index 2cdf7e9b74..255a025602 100644
--- a/tests/python/relax/test_frontend_onnx.py
+++ b/tests/python/relax/test_frontend_onnx.py
@@ -923,6 +923,14 @@ def test_gelu():
verify_unary("Gelu", [32, 32], domain="com.microsoft")
+def test_gelu_approximate():
+ """Test Gelu with approximate attribute from ONNX Opset 20."""
+ # Test Gelu with approximate="tanh"
+ verify_unary("Gelu", [32, 32], attrs={"approximate": "tanh"}, opset=20)
+ # Test Gelu with approximate="none" (default, same as standard Gelu)
+ verify_unary("Gelu", [32, 32], attrs={"approximate": "none"}, opset=20)
+
+
def test_bias_gelu():
verify_binary("BiasGelu", [32, 32], [32], [32, 32], domain="com.microsoft")