Skip to content

Support fuse bn into ConvTranspose. - #316

Open
take-cheeze wants to merge 5 commits into
onnx:mainfrom
take-cheeze:claude/onnx-optimizer-patch-u030ld
Open

Support fuse bn into ConvTranspose. #316
take-cheeze wants to merge 5 commits into
onnx:mainfrom
take-cheeze:claude/onnx-optimizer-patch-u030ld

Conversation

@take-cheeze

Copy link
Copy Markdown
Member

Based and fixes #106

Summary

This PR extends the fuse_bn_into_conv optimization pass to support fusing BatchNormalization nodes into ConvTranspose operations, in addition to the existing Conv support.

Key Changes

  • Extended pattern matching: Updated patternMatchPredicate to recognize both Conv and ConvTranspose operations followed by BatchNormalization
  • Weight layout handling: Modified modify_conv to accept an is_conv parameter that accounts for the different weight tensor layouts:
    • Conv: weight shape is (out_channels, in_channels/group, kH, kW) with output channels on axis 0
    • ConvTranspose: weight shape is (in_channels, out_channels/group, kH, kW) with output channels on axis 1
  • Axis-aware broadcasting: Updated the unsqueeze dimension calculation to correctly broadcast the per-output-channel scale factor along the appropriate axis (axis 0 for Conv, axis 1 for ConvTranspose)
  • Grouped ConvTranspose safety: Added a check to skip fusion for grouped ConvTranspose operations where the axis-1 size differs from the channel count, preventing miscompilation
  • Added test coverage: Included test_fuse_bn_into_conv_transpose_simple to verify the fusion works correctly with distinct input/output channel counts

Implementation Details

  • The fix addresses a previous assertion failure (conv_W.sizes()[0] == C) that occurred when attempting to fuse BatchNormalization into ConvTranspose with mismatched input/output channel counts
  • Uses std::iota and erase to generate the correct unsqueeze dimensions dynamically based on the operation type
  • Added #include <numeric> for std::iota support

https://claude.ai/code/session_01Fquk8PCqZ2T26G6CwLAuDn

wenyuchi.wyc and others added 5 commits March 6, 2023 19:30
Signed-off-by: wenyuchi.wyc <wenyuchi.wyc@alibaba-inc.com>
Signed-off-by: Takeshi Watanabe <take-cheeze@users.noreply.github.com>
Extend the fuse_bn_into_conv pass to fold BatchNormalization into a
preceding ConvTranspose, and fix the channel-axis bug from PR onnx#106 that
crashed on real models.

ConvTranspose weight is laid out as (in_channels, out_channels, kH, kW),
transposed relative to Conv's (out_channels, in_channels, kH, kW). The
BatchNormalization channel count matches the output channels, so the
per-channel scale must be checked and broadcast against axis 1 for
ConvTranspose (axis 0 for Conv). Using axis 0 unconditionally triggered
the reported `conv_W.sizes()[0] == C` assertion failure whenever
in_channels != out_channels. Mismatched shapes (e.g. grouped
ConvTranspose) now skip the fusion instead of asserting.

The added test uses distinct in/out channel counts so it actually
exercises the corrected axis.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuHDzT8V8x1FbThhpWG6ad
Signed-off-by: take-cheeze <takechi101010@gmail.com>
@take-cheeze
take-cheeze requested review from a team as code owners July 23, 2026 16:55
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.

3 participants