-
Notifications
You must be signed in to change notification settings - Fork 657
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
[Urgent] PyTorch GroupNorm and Meshgrid conversion fails for dynamic input #1303
Comments
By any chance, someone can help/share a hint? Thanks! |
Hi, Thanks for filing this issue with the reproducible case. There is definitely a bug in the translation logic of group norm and most likely also an issue in the type inference of the reshape op. We will look into it. Meanwhile, here is a workaround. For the code snippet you have, the following updated logic should work. That is, you can update the conversion script as follows:
The above script will work, if you also update / suppress this error, by replacing this line with
|
Thank you @aseemw! It works smoothly. I found another problem related to dynamic input - Minimum code to reproduce:class DynamicMeshgrid(nn.Module):
def __init__(self):
super(DynamicMeshgrid, self).__init__()
def forward(self, rows, cols):
grid_x, grid_y = torch.meshgrid(rows, cols)
return grid_x, grid_y
def main():
model = DynamicMeshgrid()
xy_poses = [torch.linspace(-1, 1, 8), torch.linspace(-1, 1, 10)]
pytorch_output = model(xy_poses[0], xy_poses[1])
traced_model = torch.jit.trace(model, xy_poses, check_trace=True)
pos_shape_1 = pos_shape_2 = ct.Shape(shape=(ct.RangeDim(1, 16),)) # dynamic size fails
# pos_shape_1 = ct.Shape(shape=(8,)) # fixed size works well
# pos_shape_2 = ct.Shape(shape=(10,))
xy_poses_dynamic = [ct.TensorType(name='x_pos', shape=pos_shape_1), ct.TensorType(name='y_pos', shape=pos_shape_2)]
mlmodel = ct.convert(model=traced_model, inputs=xy_poses_dynamic)
coreml_output = mlmodel.predict({'x_pos': xy_poses[0].numpy(), 'y_pos': xy_poses[1].numpy()}, useCPUOnly=True)
print('Done') Error: TypeError: cannot determine truth value of Relational Trace the bug
Any suggestion would be appreciated, thanks! |
Hmm, the tile op with multiple inputs should work, although the shape of the second input ( example:
|
Thanks for the prompt response! I'm a bit confused here for the example. It seems still takeing one single input for Maybe let me rephrase the question. In In current coremltools implementation, it first gets # for dynamic shape, dim_tuple = (is0, is1)
dim_tuple = tuple(tensor_var.shape[0] for tensor_var in inputs) then expands dimension, get reps and tile for each 1-d vector size = len(inputs)
for i in range(size):
view_shape = [1] * size
view_shape[i] = -1
view_shape = tuple(view_shape) # (-1, 1) and (1, -1)
# expand_dim to (is0, 1) and (1, is1)
view = mb.reshape(
x=inputs[i], shape=view_shape, name=node.name + "_view_" + str(I)
)
# get reps
# For dynamic shape, ds = is0/is1 which breaks below list comprehension
# Tried to replace below if condition to -> if (not isinstance(ds, int) or ds > 0) and ts == 1.
# Then reps become [1, is1] and [is0, 1] but mb.tile breaks as reps are not all integers but contains symbo
reps = [
ds if ds > 0 and ts == 1 else 1 for ts, ds in zip(view.shape, dim_tuple)
]
# tile according to reps
# Ideally for dynamic shape, reps = (1, is1) and (is0, 1) but it doesn't work here for symbolic input
# This is where I have no clue further
expand = mb.tile(x=view, reps=reps, name=node.name + "_expand_" + str(i))
grids.append(expand) To shorten the question, is there any way to do Thanks for the patience! |
Could anyone please share some hints on fixing the above 👆 |
@aseemw Your fix for groupnorm does not work on coremltools==6.2 . I get this error now:
Use this to reproduce
@CanyonWind can you pls check cc - @bhushan23 , |
I'm facing the exact same error with Meshgrid. Any update regarding that?
|
to fix the GroupNorm, I did use the following code on coremltools 7.0b1 by editing
from coremltools.converters.mil.frontend.torch.torch_op_registry import _TORCH_OPS_REGISTRY, register_torch_op
from coremltools.converters.mil import Builder as mb
from coremltools.converters.mil.frontend.torch.ops import _get_inputs, _std
from coremltools.converters.mil.mil.types.symbolic import is_symbolic,any_symbolic
import builtins
del _TORCH_OPS_REGISTRY["group_norm"]
@register_torch_op
def group_norm(context, node):
inputs = _get_inputs(context, node, expected=6)
x = inputs[0]
num_groups = inputs[1].val
weight = inputs[2]
bias = inputs[3]
eps = inputs[4]
n,c = x.shape[0],x.shape[1] # at minimum (N, C) required
input_shape = [*x.shape] # n, c, *
num_groups = builtins.min(num_groups,c)
new_shape = [n, num_groups, c//num_groups]
# Create the new_shape and input_shape to support dynamic sizes.
if not any_symbolic(x.shape[2:]):
new_shape += [*x.shape[2:]] # adds remaining dims
else:
ss = mb.shape(x=x)
for i,v in enumerate(x.shape[2:]):
if is_symbolic(v):
x1 = mb.gather(x=ss, indices=i+2, axis=0)
new_shape.append(x1)
else:
new_shape.append(v)
new_shape = mb.concat(values=new_shape, axis=0)
if any_symbolic(input_shape):
ss = mb.shape(x=x)
for i,v in enumerate(input_shape):
if is_symbolic(v):
x1 = mb.gather(x=ss, indices=i, axis=0)
input_shape[i] = x1
input_shape = mb.concat(values=input_shape, axis=0)
num_extra_axes = len(x.shape[2:])
axes_ = [int(i) for i in range(2, 2 + num_extra_axes + 1)]
weight_shape, bias_shape = [1,c], [1,c]
weight_shape += [1 for _ in range(num_extra_axes)]
bias_shape += [1 for _ in range(num_extra_axes)]
x = mb.reshape(x = x, shape=new_shape)
mean = mb.reduce_mean(x=x, axes=axes_, keep_dims=True)
var = _std(x,axes_,True,False,eps.val)
x = mb.sub(x=x,y=mean)
x = mb.real_div(x=x,y=var)
x = mb.reshape(x=x, shape=input_shape)
if weight is not None:
weight = mb.reshape(x=weight, shape=weight_shape)
x = mb.mul(x=x,y=weight)
if bias is not None:
bias = mb.reshape(x=bias, shape=bias_shape)
x = mb.add(x=x,y=bias)
context.add(x,node.name) I come this idea by looking into how |
@sercand - can you put up a pull request with your fix and a unit test? |
🐞Describe the bug
h
andw
are specified for integers, but dynamic input model'sh
andw
are placeholder.Trace
Please run the code below to see the error.
To Reproduce
Error:
System environment (please complete the following information):
The text was updated successfully, but these errors were encountered: