-
Notifications
You must be signed in to change notification settings - Fork 21
Fix UnsqueezeParser for ONNX Opset 13+ #119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix UnsqueezeParser for ONNX Opset 13+ #119
Conversation
- axes attribute was change to input starting from ONNX opset 13
📝 WalkthroughSummary by CodeRabbit
WalkthroughUnsqueeze parser updated to support axes provided either as a node attribute (opset v11 behavior) or as a second input tensor (opset v13+). parseNodeCtxt input-to-context mapping adjusted; axes are extracted from the appropriate source and axes buffer is marked non-deployable when axes come from an input. CHANGELOG updated accordingly. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant ONNX as ONNX Node
participant Parser as UnsqueezeParser
participant Ctxt as parseNodeCtxt
participant Op as OperatorRepresentation
Note over Parser, Op: Unsqueeze axes handling differs by opset
Parser->>ONNX: Inspect node.attrs and node.inputs
alt Opset v11 (axes as attribute)
ONNX-->>Parser: attrs contain `axes`
Parser->>Ctxt: Map single input -> data_in/data_out
Parser->>Op: Set axes = node.attrs['axes'] (list of ints)
else Opset v13+ (axes as input)
ONNX-->>Parser: inputs[0]=data, inputs[1]=axesTensor
Parser->>Ctxt: Map inputs[0] -> data_in/data_out, inputs[1] -> axes_buf
Parser->>Op: Read axes list from axes_buf tensor
Note right of Ctxt: axes_buf._live = False<br/>axes_buf._deploy = False
end
Parser-->>Op: Emit operatorRepresentation with axes populated
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Deeploy/Targets/Generic/Parsers.py (1)
962-973
: Bug: opset13 path stores axes as a tensor name, not values. Extract constant axes and don’t expose it as a runtime input.Templates likely expect numeric axes (as in opset 11). Keep representation consistent and mark the axes constant as not deployed.
- if len(node.inputs) == 1: - inputs = ['data_in'] - else: - inputs = ['data_in','axes'] - outputs = ['data_out'] - - for idx, inputNode in enumerate(node.inputs): - self.operatorRepresentation[inputs[idx]] = ctxt.lookup(inputNode.name).name - for idx, outputNode in enumerate(node.outputs): - self.operatorRepresentation[outputs[idx]] = ctxt.lookup(outputNode.name).name + outputs = ['data_out'] + if len(node.inputs) == 1: + inputs = ['data_in'] + for idx, inputNode in enumerate(node.inputs): + self.operatorRepresentation[inputs[idx]] = ctxt.lookup(inputNode.name).name + for idx, outputNode in enumerate(node.outputs): + self.operatorRepresentation[outputs[idx]] = ctxt.lookup(outputNode.name).name + else: + # data + data_in = ctxt.lookup(node.inputs[0].name) + data_out = ctxt.lookup(node.outputs[0].name) + self.operatorRepresentation['data_in'] = data_in.name + self.operatorRepresentation['data_out'] = data_out.name + # axes must be a constant; extract values + axes_buf = ctxt.lookup(node.inputs[1].name) + assert hasattr(axes_buf, 'values'), "Unsqueeze: expected constant 'axes' input for opset 13+" + axes_vals = np.array(axes_buf.values).astype(int).flatten().tolist() + self.operatorRepresentation['axes'] = axes_vals + # Do not deploy the axes tensor + axes_buf._live = False + axes_buf._deploy = False
🧹 Nitpick comments (1)
Deeploy/Targets/Generic/Parsers.py (1)
943-954
: Normalize axes handling and fix ONNX doc reference.
- Use Unsqueeze doc link.
- For opset 11, store axes as a list of ints.
- For opset 13+, don’t set axes here; defer extraction to parseNodeCtxt.
- # ONNX v11: 'axes' is a node attribute + # ONNX v11: 'axes' is a node attribute if 'axes' in node.attrs: ret = all(['axes' in node.attrs, len(node.inputs) == 1, len(node.outputs) == 1]) - # ONNX v13+: 'axes' becomes an input together with the data (source: https://onnx.ai/onnx/operators/onnx__Squeeze.html) + # ONNX v13+: 'axes' becomes an input with the data + # Source: https://onnx.ai/onnx/operators/onnx__Unsqueeze.html else: ret = all([len(node.inputs) == 2, len(node.outputs) == 1]) - if ret and 'axes' in node.attrs: - self.operatorRepresentation['axes'] = node.attrs['axes'] - elif ret: - self.operatorRepresentation['axes'] = node.inputs[1] + if ret and 'axes' in node.attrs: + axes_attr = node.attrs['axes'] + self.operatorRepresentation['axes'] = [int(axes_attr)] if isinstance(axes_attr, int) \ + else [int(a) for a in axes_attr] + # For opset 13+, axes will be extracted from the second input in parseNodeCtxt
… CCT_2_32_32_128_Opset20 test case using ONNX Opset version 20
…on ONNX Opset version and number of inputs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…higher as list of PRs
Looks good to me. To ensure compatibility with the new parser when using ONNX opset > 13, the implementation should follow the logic outlined here: Deeploy/Deeploy/OperatorDescriptor.py Lines 443 to 455 in 610e530
but |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am okay with the changes and open to merge it. However, I strongly suggest adding the new test to the CI to prevent future fallbacks.
…platforms testing Squeeze and Unsqueeze new format for recent ONNX Opsets
PR to align the recent ONNX Opset standard for
Squeeze
/Unsqueeze
Ops.Starting from version 13, 'axes' is not anymore a node attribute but rather an input together with the data.
Complete changelog from ONNX documentation: https://onnx.ai/onnx/operators/text_diff_Squeeze_11_13.html and https://onnx.ai/onnx/operators/text_diff_Unsqueeze_11_13.html
Changes should be non-breaking since the old flow is still called when there is only 1 single input.
There is already a test for
Squeeze
Op in FP but it is failing under both old and new ONNX Opsets.To test if it works with recent Opsets of ONNX, I added
CCT/CCT_2_32_32_128_Opset20
test case with input, output, and network files exported from PyTorch using ONNX Opset version 20.Added
Changed
axes
in node attributes and use the old workflow otherwise check for exactly 2 inputs (data and axes).Fixed
Squeeze
Op.PR Merge Checklist
devel
commit and pointing todevel
.CHANGELOG.md
file has been updated.