VectorBlox vnnx_tflite.py Fix: Problem 2 - RESHAPE Operation Issue Resolution

3 minute read

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)