Can't convert Pytorch to ONNX
Asked Answered
W

5

7

Trying to convert this pytorch model with ONNX gives me this error. I've searched github and this error came up before in version 1.1.0 but was apparently rectified. Now I'm on torch 1.4.0. (python 3.6.9) and I see this error.

File "/usr/local/lib/python3.6/dist-packages/torch/onnx/init.py", line 148, in export
strip_doc_string, dynamic_axes, keep_initializers_as_inputs)
File "/usr/local/lib/python3.6/dist-packages/torch/onnx/utils.py", line 66, in export
dynamic_axes=dynamic_axes, keep_initializers_as_inputs=keep_initializers_as_inputs)
File "/usr/local/lib/python3.6/dist-packages/torch/onnx/utils.py", line 416, in _export
fixed_batch_size=fixed_batch_size)
File "/usr/local/lib/python3.6/dist-packages/torch/onnx/utils.py", line 296, in _model_to_graph
fixed_batch_size=fixed_batch_size, params_dict=params_dict)
File "/usr/local/lib/python3.6/dist-packages/torch/onnx/utils.py", line 135, in _optimize_graph
graph = torch._C._jit_pass_onnx(graph, operator_export_type)
File "/usr/local/lib/python3.6/dist-packages/torch/onnx/init.py", line 179, in _run_symbolic_function
return utils._run_symbolic_function(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/torch/onnx/utils.py", line 657, in _run_symbolic_function
return op_fn(g, *inputs, **attrs)
File "/usr/local/lib/python3.6/dist-packages/torch/onnx/symbolic_helper.py", line 128, in wrapper
args = [_parse_arg(arg, arg_desc) for arg, arg_desc in zip(args, arg_descriptors)]
File "/usr/local/lib/python3.6/dist-packages/torch/onnx/symbolic_helper.py", line 128, in
args = [_parse_arg(arg, arg_desc) for arg, arg_desc in zip(args, arg_descriptors)]
File "/usr/local/lib/python3.6/dist-packages/torch/onnx/symbolic_helper.py", line 81, in _parse_arg
"', since it's not constant, please try to make "
RuntimeError: Failed to export an ONNX attribute 'onnx::Gather', since it's not constant, please try to make things (e.g., kernel size) static if possible

How to fix it? I've also tried latest nightly build, same error comes up.

My code:

from model import BiSeNet
import torch.onnx
import torch

net = BiSeNet(19)
net.cuda()
net.load_state_dict(torch.load('/content/drive/My Drive/Collab/fp/res/cp/79999_iter.pth'))
net.eval()

dummy = torch.rand(1,3,512,512).cuda()
torch.onnx.export(net, dummy, "Model.onnx", input_names=["image"], output_names=["output"])

I added print (v.node ()) to symbolic_helper.py just before the runtime error is raised to see what's causing the error.

This is the output: %595 : Long() = onnx::Gather[axis=0](%592, %594) # /content/drive/My Drive/Collab/fp/model.py:111:0

And that line in 111 in model.py is: avg = F.avg_pool2d(feat32, feat32.size()[2:])

This source suggests that tensor.size method in pytorch cannot be recognized by onnx and needs to be modified into a constant.

Wingard answered 14/3, 2020 at 12:17 Comment(0)
I
9

I used to have a similar error when exporting using

torch.onnx.export(model, x, ONNX_FILE_PATH)

and I fixed it by specifying the opset_version like so:

torch.onnx.export(model, x, ONNX_FILE_PATH, opset_version = 11)

Iand answered 31/12, 2020 at 17:40 Comment(3)
Any justification or simply trial and error?Curvet
@bob if I remember correctly, it was one of the suggestions on the Github issues. Maybe this one: github.com/pytorch/pytorch/issues/36997#issuecomment-636321420Iand
My case is different, but thank you anywayCurvet
S
3

For those hitting this question from a Google search and who are getting a Unable to cast from non-held to held instance (T& to Holder) (compile in debug mode for type information), try adding operator_export_type=torch.onnx.OperatorExportTypes.ONNX_ATEN_FALLBACK (as mentioned here) like this:

torch.onnx.export(model, input, "output-name.onnx", export_params=True, opset_version=12, operator_export_type=torch.onnx.OperatorExportTypes.ONNX_ATEN_FALLBACK)

That fixed the "held instance" problem in my case.

Switzerland answered 14/11, 2021 at 9:38 Comment(0)
D
1

Change instances of

x = F.avg_pool2d(x, x.shape[2:])

to

x_shape = [int(s) for s in x.shape[2:]]
x = F.avg_pool2d(x, x_shape)

such that the input shape to avg_pool2d is constant [k,k], not torch.Size([k, k]) as mentioned here.

Danny answered 28/9, 2020 at 7:44 Comment(0)
M
0

You can:

print(feat32.size()[2:])

and replace:

F.avg_pool2d(feat32, feat32.size()[2:]) 

with:

F.avg_pool2d(feat32, your_print_contant_result)
Midi answered 21/5, 2020 at 17:56 Comment(0)
A
0

I have struggled with same issue.

F.adaptive_avg_pool2d is not supported in my case. you have to try other operations.

I hope this helps.

Thanks

Auerbach answered 3/6, 2020 at 8:53 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.