onnx / onnx/optimizer

[BUG] Pass "fuse_bn_into_conv" causes output mismatch

Open
#255 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
834
Forks
109
Avg merge
6h 55m
Merged PRs (30d)
2

Description

Pass "fuse_bn_into_conv" causes output mismatch

Issue
Applying only the fuse_bn_into_conv pass with onnxoptimizer 0.3.19 changes numerical outputs. The original model is numerically stable with the provided oracle inputs, but the optimized graph deviates immediately after this single pass.

Environment

  • Ubuntu 20.04
  • Python 3.10
  • onnx==1.19.0
  • onnxruntime==1.23.2
  • onnxoptimizer==0.3.19 (latest)

Repro steps (run from this folder)

  1. Download and unzip the attached archive below, then cd into the extracted directory

fuse_bn_into_conv_repro.tar.gz

tar -xzvf fuse_bn_into_conv_repro.tar.gz
cd fuse_bn_into_conv_repro
  1. Create a Python environment (Python 3.10) and install dependencies:
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -r requirements.txt
  1. Optimize the case with only fuse_bn_into_conv (writes model.opt.onnx next to model.onnx):
  • python optimize_model.py --case ./case_00057_seed20702402
  1. Differential test original vs optimized outputs using the stored oracle inputs:
  • python diff_test.py --case ./case_00057_seed20702402

Observed results

  • case_00057_seed20702402: overall max_abs=3.815e-06, max_rel=2.780e-07; detailed per-output diff below.

Expected
fuse_bn_into_conv should be semantics-preserving. Applying only this pass should not change any output values. Please investigate why the optimized graph diverges and whether the pass is incorrectly folding batch norm parameters into convolutions for this model.

Differential Test Output Details

  1. case_00057_seed20702402
Case: case_00057_seed20702402
  output[0]: max_abs=9.537e-07, max_rel=9.442e-08, shape=(2, 1, 1, 1)
  output[1]: max_abs=3.815e-06, max_rel=2.780e-07, shape=(2, 1, 4, 3)
  output[2]: max_abs=7.153e-07, max_rel=2.719e-07, shape=(2, 1, 1, 1)
  output[3]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(2, 2, 2, 1, 1)
  output[4]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(2, 2, 2, 16)
  output[5]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(2, 2, 2, 2, 1)
  output[6]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(2, 2, 16)
  output[7]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(2, 2, 1)
  output[8]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(2, 16)
  output[9]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(1, 16)
  output[10]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(1,)
  output[11]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(1, 16)
  output[12]: max_abs=0.000e+00, max_rel=0.000e+00, shape=()
  output[13]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(1, 16)
  output[14]: max_abs=0.000e+00, max_rel=0.000e+00, shape=()
  output[15]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(1,)
  output[16]: max_abs=0.000e+00, max_rel=0.000e+00, shape=(16, 44)
Overall: max_abs=3.815e-06, max_rel=2.780e-07

Attachments

  • README.md (this document)
  • requirements.txt (dependency versions)
  • optimize_model.py (runs only fuse_bn_into_conv and saves model.opt.onnx)
  • diff_test.py (runs original vs optimized with oracle inputs and reports max_abs/max_rel)
  • case_00057_seed20702402/ (contains model.onnx and oracle.pkl used for both runs)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running optimize_model.py and diff_test.py in the provided fuse_bn_into_conv_repro directory to reproduce the mismatch. Then trace the fuse_bn_into_conv pass and compare model.onnx with model.opt.onnx for case_00057_seed20702402. Done means the pass preserves the oracle outputs within the reported comparison.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
performance, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.