Skip to content

Conversation

MatteoFasulo
Copy link
Contributor

@MatteoFasulo MatteoFasulo commented Sep 25, 2025

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

  • Added support for ONNX Opset 13 and higher.

Changed

  • UnsqueezeParser in Generic NodeParser
    • Check for the presence of axes in node attributes and use the old workflow otherwise check for exactly 2 inputs (data and axes).
    • Node context was changes accordingly; 1 single input follows the old workflow, 2 inputs uses the new 2 input Op. format.

Fixed

  • Breaking compilation with ONNX Opset 13 and higher when using Squeeze Op.

PR Merge Checklist

  1. The PR is rebased on the latest devel commit and pointing to devel.
  2. Your PR reviewed and approved.
  3. All checks are passing.
  4. The CHANGELOG.md file has been updated.
  5. If the docker was modified, change back its link after review.

- axes attribute was change to input starting from ONNX opset 13
@MatteoFasulo MatteoFasulo changed the title [DRAFT] Fix UnsqueezeParser for ONNX Opset 13+ [Draft] Fix UnsqueezeParser for ONNX Opset 13+ Sep 25, 2025
@MatteoFasulo MatteoFasulo changed the title [Draft] Fix UnsqueezeParser for ONNX Opset 13+ Fix UnsqueezeParser for ONNX Opset 13+ Sep 25, 2025
@MatteoFasulo MatteoFasulo marked this pull request as ready for review September 25, 2025 15:58
Copy link
Contributor

coderabbitai bot commented Sep 25, 2025

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Resolved Unsqueeze handling for ONNX opset 13+ by supporting axes provided as an input tensor, improving compatibility while retaining behavior for older opsets.
  • Documentation

    • Updated changelog to reflect the Unsqueeze fix.
  • Tests

    • Expanded CI with a new opset 20 model test to increase coverage.

Walkthrough

Unsqueeze 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

Cohort / File(s) Summary of Changes
ONNX parser opset handling
Deeploy/Targets/Generic/Parsers.py
Updated UnsqueezeParser to handle axes from node.attrs['axes'] (opset v11) or from the second input tensor node.inputs[1] (opset v13+). parseNodeCtxt now maps inputs differently for single vs two-input forms, extracts axes as a Python list of ints from the appropriate source, and when axes are supplied as an input marks the axes buffer with _live = False and _deploy = False. Added explanatory comments about ONNX opset behavior.
CI test matrix
.github/workflows/ci-platform-generic.yml
.github/workflows/ci-platform-siracusa.yml
Added new test name CCT/CCT_2_32_32_128_Opset20 to the test-names lists in both workflows to expand CI coverage.
Changelog
CHANGELOG.md
Recorded the Unsqueeze fix for ONNX opset 13+ (axes handled as input rather than attribute) in Unreleased and Fixed sections.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly describes the main change by specifying that the UnsqueezeParser is being fixed for ONNX Opset 13 and above, using concise and specific language without any unnecessary details.
Description Check ✅ Passed The description is directly related to the changeset, providing context on the ONNX Opset update, detailing modifications to the UnsqueezeParser logic, associated test additions, and changelog updates, so it correctly describes the pull request’s content.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e0fed5 and 4d9bd36.

📒 Files selected for processing (2)
  • .github/workflows/ci-platform-generic.yml (1 hunks)
  • .github/workflows/ci-platform-siracusa.yml (1 hunks)

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2fa3c31 and cc439a7.

📒 Files selected for processing (2)
  • CHANGELOG.md (1 hunks)
  • Deeploy/Targets/Generic/Parsers.py (2 hunks)

… CCT_2_32_32_128_Opset20 test case using ONNX Opset version 20
@Xeratec Xeratec added the Bug Something isn't working label Sep 29, 2025
@Xeratec Xeratec added this to Deeploy Sep 29, 2025
@Xeratec Xeratec added this to the Release 0.2.1 milestone Sep 29, 2025
@Xeratec Xeratec moved this to Need Reviewer in Deeploy Sep 29, 2025
Copy link
Member

@Xeratec Xeratec left a comment

Choose a reason for hiding this comment

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

The changes will hopefully become obsolete after we merge #118 from @lukamac, but that may take some time. Hence, I’m fine with merging this once the open comments are addressed. In any case, as noted in #95, we should eventually freeze the supported opset version.

@Xeratec Xeratec moved this from Need Reviewer to In review in Deeploy Sep 29, 2025
@MatteoFasulo
Copy link
Contributor Author

The changes will hopefully become obsolete after we merge #118 from @lukamac, but that may take some time. Hence, I’m fine with merging this once the open comments are addressed. In any case, as noted in #95, we should eventually freeze the supported opset version.

Looks good to me. To ensure compatibility with the new parser when using ONNX opset > 13, the implementation should follow the logic outlined here:

# Opset <= 11
unsqueezeDesc = OperatorDescriptor(
inputDescriptor = IoDesc("data_in"),
outputDescriptor = IoDesc("data_out"),
attrDescriptors = [AttrDesc("axes", IntTupleUnpack)],
)
# Opset <= 11
squeezeDesc = OperatorDescriptor(
inputDescriptor = IoDesc("data_in"),
outputDescriptor = IoDesc("data_out"),
attrDescriptors = [AttrDesc("axes", IntTupleUnpack)],
)

but axes should be treated as an input rather than an attribute.

Copy link
Member

@Xeratec Xeratec left a 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
@Xeratec Xeratec merged commit 15c4a23 into pulp-platform:devel Oct 14, 2025
134 checks passed
@github-project-automation github-project-automation bot moved this from In review to Done in Deeploy Oct 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants