Skip to content

[Fix][Relax][ONNX] Fix Upsample and Resize-10 import - #20415

Open
LiRunGuo wants to merge 1 commit into
apache:mainfrom
LiRunGuo:fix/onnx-legacy-upsample-resize10
Open

LiRunGuo wants to merge 1 commit into
apache:mainfrom
LiRunGuo:fix/onnx-legacy-upsample-resize10

Conversation

@LiRunGuo

Copy link
Copy Markdown
Contributor

The ONNX importer's handling of the legacy upsampling ops was broken in ways that affect most real models that use them. Upsample only exists in opsets 7 to 9 and Resize-10 is its direct successor, so these are exactly the ops found in older exported models such as YOLOv3-era detectors.

For Upsample-9, scales became an input, but the converter still read the removed attribute, so every opset 9 model failed with TypeError: object of type 'NoneType' has no len(). For Upsample-7/8 the model imported, but nearest mode was lowered with resize2d's default round rounding. Upsample maps each output index to floor(x_out / scale), so the imported model silently produced wrong values even for plain 2x upsampling (max abs diff around 4.8 against onnxruntime on random input). Every input dimension was also forced through int(), so a dynamic batch or spatial extent failed with int(Var), and non-4-D inputs were rejected by bare asserts.

Resize-10 has the signature (X, scales) and the same semantics as Upsample-9, but because only _impl_v18 existed it was dispatched to the Resize-18 converter, which interpreted scales as roi and failed for every Resize-10 model.

This PR lowers Upsample-7, Upsample-9 and Resize-10 through one helper that follows the legacy semantics as implemented by onnxruntime. Output extents are floor(input * scale), coordinates are asymmetric, and nearest mode rounds the source index down when upsampling and up when downsampling (Resize-10 accepts scales below one). Symbolic extents with integer scales are kept as exact products such as 2 * H, so they still unify with other shapes, for example a skip connection concatenated after the upsample. 3-D and 5-D inputs go through resize1d and resize3d. Scaling the batch or channel dimension, or mixing upsampling and downsampling axes in nearest mode, raises OpAttributeUnImplemented instead of an assertion. Resize-11 through Resize-17 are explicitly mapped to the existing converter so their behaviour does not change.

The new tests compare against onnxruntime for all three op versions across nearest and linear modes, 3-D/4-D/5-D inputs, a non-integer scale, Resize-10 downsampling, and symbolic batch and spatial dimensions. 26 of the 28 fail without this change; the other two guard behaviour that was already correct.

Two related cases are not covered here. Linear mode with a non-integer scale where input * scale is not an integer still differs from onnxruntime, because TOPI derives the coordinate ratio from the output size rather than the given scale; that is the problem addressed for Resize by #19698. Linear mode with a symbolic extent and an integer scale hits a separate crash in the interval-set analysis, fixed in #20414.

The Upsample converter only handled the opset 7/8 form and was wrong or
unusable in several ways:

- Since opset 9 `scales` is an input, but the converter still read the
  attribute, so every Upsample-9 model failed with `len(None)`.
- Nearest mode used resize2d's default `round` rounding, while Upsample
  maps source indices with floor, so the output values were wrong even
  for plain 2x upsampling.
- Every input dimension was converted with `int()`, so models with a
  dynamic batch or spatial extent failed with `int(Var)`.
- Only 4-D inputs were accepted, via bare asserts.

Resize-10 takes `(X, scales)` like Upsample-9, but it was dispatched to
the Resize-18 converter, which read `scales` as `roi` and failed for all
Resize-10 models.

Lower both through a shared helper that follows the legacy semantics:
output extents are floor(input * scale), coordinates are asymmetric, and
nearest rounds the source index down when upsampling and up when
downsampling (Resize-10 allows scales below one). Symbolic extents with
integer scales stay exact integer products so they unify with other
shapes, and 3-D/5-D inputs are handled with resize1d/resize3d.
Unsupported configurations (batch or channel scaling, or nearest mode
mixing up- and downsampling axes) raise OpAttributeUnImplemented.
Resize-11 to 17 keep using the existing converter.
@LiRunGuo

Copy link
Copy Markdown
Contributor Author

Hi @tlopex, could you help review this when you have time? It fixes the legacy Upsample (opset 7/9) and Resize-10 import paths, which were failing or giving wrong nearest-mode results. Thanks!

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.

1 participant