VectorBlox vnnx_tflite.py Fix: Problem 2 - RESHAPE Operation Issue Resolution
Published:
Problem 2: RESHAPE Operation
Compilation Failure Log
Two different types of errors occurred with RESHAPE operations:
Error 1:
ValueError: cannot handle multi-axis squeeze
Error 2:
ValueError: axes don't match array
Root Cause
The first error is a Multi-axis Squeeze problem. The SPNv2 model tried to convert a 5-dimensional tensor [1, 4, 4, 9, 4] to a 3-dimensional [1, 144, 4]. This merges three axes (height, width, anchor) simultaneously into a single position axis. However, VectorBlox SDK’s channels_first_array_reshape function only supports single-axis squeeze, causing compilation to fail.
The second error is an ambiguity problem with Single-axis Squeeze. The SPNv2 classification head converts a tensor of shape [1, 12276, 1] to [1, 12276]. This is a simple operation that removes the last dimension (number of classes). However, VectorBlox SDK assumes tensors are in [N, C, H, W] format. Because of this, axis recalculation becomes impossible, causing compilation to fail.
Solution Process
The solution is to detect problematic reshape patterns before passing them to the channels_first_array_reshape function and process them in advance.
Before modification, all RESHAPE operations were attempted to be processed by a single function. The code simply passed input and output shapes to channels_first_array_reshape, and when the function encountered unsupported patterns, it immediately raised an error.
elif subcode in ['SQUEEZE', 'EXPAND_DIMS', 'RESHAPE']:
ishape = i_tensor['shape']
oshape = o_tensor['shape']
# Process all cases with one function
mode = channels_first_array_reshape(ishape, transform)
# Fails on SPNv2 patterns
After modification, we added logic to detect three problematic patterns in advance.
The first pattern is conversion from 5D to 3D. We analyze the input and output shapes to verify that the first dimension (batch) and last dimension (keypoint) are preserved, and that the product of the middle three dimensions matches the second dimension of the output (ishape[1] * ishape[2] * ishape[3] == oshape[1]). This is a multi-axis squeeze pattern.
The second pattern is conversion from 3D to 2D. We detect cases where the first two dimensions are preserved and the last dimension size is 1 (ishape[2] == 1). This is a simple squeeze that removes a dimension of size 1.
The third pattern is the reverse: an expand operation that adds a dimension of size 1 from 2D to 3D (oshape[2] == 1).
elif subcode in ['SQUEEZE', 'EXPAND_DIMS', 'RESHAPE']:
ishape = i_tensor['shape']
oshape = o_tensor['shape']
# Pattern 1: 5D → 3D
if (len(ishape) == 5 and len(oshape) == 3 and
ishape[0] == oshape[0] and
ishape[1] * ishape[2] * ishape[3] == oshape[1] and
ishape[4] == oshape[2]):
mode = 0
sn.nop = 1
# Pattern 2: 3D → 2D
elif (len(ishape) == 3 and len(oshape) == 2 and
ishape[0] == oshape[0] and
ishape[1] == oshape[1] and
ishape[2] == 1):
mode = 0
sn.nop = 1
# Pattern 3: 2D → 3D
elif (len(ishape) == 2 and len(oshape) == 3 and
ishape[0] == oshape[0] and
ishape[1] == oshape[1] and
oshape[2] == 1):
mode = 0
sn.nop = 1
else:
# General reshape → existing logic
mode = channels_first_array_reshape(ishape, transform)
If these three patterns match, we process them directly without calling channels_first_array_reshape. Other general reshape operations are passed to the existing logic.
Solution Result
After modification, all RESHAPE patterns compile successfully:
[RESHAPE [1,4,4,9,4] → [1,144,4]]
DBG: Multi-axis squeeze detected → NOP processing
[RESHAPE [1,12276,1] → [1,12276]]
DBG: Single-axis squeeze detected → NOP processing
Compilation successful
This modification enables pre-detection of reshape patterns not supported by VectorBlox SDK and processing them as NOP operations.
Series Posts
Language: 한국어 (Korean)
