Skip to content

Add fuse_gelu pass to fuse erf-based GELU into a Gelu op - #320

Open
take-cheeze wants to merge 1 commit into
onnx:mainfrom
onnxsim:claude/gelu-fusion-90s0no
Open

Add fuse_gelu pass to fuse erf-based GELU into a Gelu op#320
take-cheeze wants to merge 1 commit into
onnx:mainfrom
onnxsim:claude/gelu-fusion-90s0no

Conversation

@take-cheeze

Copy link
Copy Markdown
Member

Mirror onnxslim's GELU fusion: match the exact GELU decomposition 0.5 * x * (1 + erf(x / sqrt(2))), spelled as Div -> Erf -> Add -> Mul -> Mul, and rewrite it to a single standard-domain Gelu operator.

Operand ordering of the two commutative multiplications (and of the addition) is accepted in either direction; the non-commutative division requires x to be the numerator. The intermediate nodes must be single-use so the leftover decomposition becomes dead code. Constants are matched whether they are initializers or Constant nodes. Since the standard-domain Gelu op was introduced in opset 20, the fusion is gated on opset >= 20 to keep the resulting model valid.

Tests cover both operand orderings, the low-opset no-op case, and a real-world graph produced by torch.onnx (exported at opset 17 as the erf decomposition, version-converted to 20, then fused). The torch test is gated on torch being importable and skips gracefully if the exporter is unavailable or emits a different structure.

Claude-Session: https://claude.ai/code/session_01EEN9xE3D2ePRzBwU1fsu3F

Mirror onnxslim's GELU fusion: match the exact GELU decomposition
0.5 * x * (1 + erf(x / sqrt(2))), spelled as Div -> Erf -> Add -> Mul ->
Mul, and rewrite it to a single standard-domain Gelu operator.

Operand ordering of the two commutative multiplications (and of the
addition) is accepted in either direction; the non-commutative division
requires x to be the numerator. The intermediate nodes must be
single-use so the leftover decomposition becomes dead code. Constants
are matched whether they are initializers or Constant nodes. Since the
standard-domain Gelu op was introduced in opset 20, the fusion is gated
on opset >= 20 to keep the resulting model valid.

Tests cover both operand orderings, the low-opset no-op case, and a
real-world graph produced by torch.onnx (exported at opset 17 as the
erf decomposition, version-converted to 20, then fused). The torch test
is gated on torch being importable and skips gracefully if the exporter
is unavailable or emits a different structure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EEN9xE3D2ePRzBwU1fsu3F
Signed-off-by: take-cheeze <takechi101010@gmail.com>
@take-cheeze
take-cheeze requested review from a team as code owners July 26, 2026 03:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants