Skip to content

Fix SkipLayerNormalization fusion for residual Add outputs - #33611

Open
Harshal Dharpure (hdharpure9922) wants to merge 2 commits into
microsoft:mainfrom
hdharpure9922:fix-skiplayernorm-fusion-safety
Open

Harshal Dharpure (hdharpure9922) wants to merge 2 commits into
microsoft:mainfrom
hdharpure9922:fix-skiplayernorm-fusion-safety

Conversation

@hdharpure9922

Copy link
Copy Markdown
Contributor

This change fixes an ORT fusion issue where Add + LayerNormalization could be fused into SkipLayerNormalization even when the Add output was still being used elsewhere or was exposed as a graph output. In those cases, the fusion was not safe and could lead to backend load failures, including with OpenVINO.

The fix adds a guard to ensure fusion only happens when the residual Add output can be safely removed. If the output is still needed, the original graph is preserved.

Context

This issue was reported in intel#748 with GPT-like ONNX models failing to load on OpenVINOExecutionProvider when SkipLayerNormalization was present. The root cause was an overly aggressive ORT fusion that generated an invalid SkipLayerNormalization pattern while the residual tensor was still live.

What changed
Skip fusion when the residual Add output has multiple consumers.
Skip fusion when the residual Add output is a graph output.
Added regression tests covering both scenarios.

Copilot AI balanced review requested due to automatic review settings October 26, 2026 12:51
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@hdharpure9922 Harshal Dharpure (hdharpure9922) changed the title Fix SkipLayerNormalization fusion safety for residual consumers Fix SkipLayerNormalization fusion for residual Add outputs Oct 26, 2026
@hdharpure9922

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree company="Intel"

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Four biased test cases have incorrect Add counts, and the multiple-consumer condition lacks focused regression coverage.

2 open issues
What changed in this PR

This PR makes the Python transformer optimizer preserve Add + LayerNormalization when the residual output is still needed, avoiding multi-output SkipLayerNormalization patterns associated with the reported OpenVINO load failure.

Changes:

  • Skip fusion when the residual Add has multiple consumers or produces a graph output.
  • Update six existing graph-output tests to expect the unfused pattern.
File Description
onnxruntime/​test/​python/​transformers/​test_skip_layer_norm_fusion.py Updates graph-output cases to expect retained Add and LayerNormalization nodes.
onnxruntime/​python/​tools/​transformers/​fusion_skiplayernorm.py Adds an early return for live residual outputs and removes multi-output fusion handling.

Review effort: Balanced

"Add": 0,
"LayerNormalization": 0,
"SkipLayerNormalization": 1,
"Add": 1,

if residual_add_has_multiple_consumers:
outputs_to_keep.extend([add.output[0]])
return

This branch has not been deployed

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