onnx: Optimizer is broken for new PyTorch exports and segfault in onnx.checker
Fist export a model (as I did for this issue) in the latest PyTorch
import torch
import torch.nn as nn
class ToFloat(nn.Module):
def __init__(self):
"""Convert to .float()
"""
super(ToFloat, self).__init__()
def forward(self, x):
return x.float()
@torch.jit.script
def center_slice_helper(x, h_offset, w_offset, h_end, w_end):
return x[:, :, h_offset:h_end, w_offset:w_end]
class CenterCrop(nn.Module):
def __init__(self, crop_size, use_jit=False):
"""Crop from the center of a 4d tensor
Input shape can be dynamic
:param crop_size: the center crop size
:param use_jit: if should use the jit helpter
"""
super(CenterCrop, self).__init__()
self.crop_size = crop_size
self.use_jit = use_jit
self.register_buffer('crop_size_t', torch.tensor(crop_size))
def extra_repr(self):
"""Extra information
"""
return 'crop_size={}'.format(
self.crop_size
)
def forward(self, x):
"""
:type x: torch.Tensor
"""
height, width = x.shape[2], x.shape[3]
if not isinstance(height, torch.Tensor):
height, width = torch.tensor(height).to(x.device), torch.tensor(width).to(x.device)
h_offset = (height - self.crop_size_t) / 2
w_offset = (width - self.crop_size_t) / 2
h_end = h_offset + self.crop_size_t
w_end = w_offset + self.crop_size_t
if self.use_jit:
return center_slice_helper(x, h_offset, w_offset, h_end, w_end)
return x[:, :, h_offset:h_end, w_offset:w_end]
model = nn.Sequential(ToFloat(), CenterCrop(224, use_jit=True))
onnxfile = "/mnt/output/gr/crop.onnx"
targets = ["cropped"]
dynamic_axes = {'data': [2, 3]}
dummy_input = torch.randn(1, 3, 300, 256, device='cpu').byte()
torch.onnx.export(model, dummy_input, onnxfile,
verbose=True, input_names=['data'],
dynamic_axes=dynamic_axes,
output_names=targets,
opset_version=10)
Now try optimzier
import onnx
from onnx import optimizer
onnx_model = onnx.load(onnxfile)
passes = ["extract_constant_to_initializer", "eliminate_unused_initializer"]
optimized_model = optimizer.optimize(onnx_model, passes)
onnx.save(optimized_model, onnxfile)
And you get this cryptic error message:
~/miniconda3/envs/py3/lib/python3.6/site-packages/onnx/optimizer.py in optimize(model, passes, fixed_point)
53 optimized_model_str = C.optimize_fixedpoint(model_str, passes)
54 else:
---> 55 optimized_model_str = C.optimize(model_str, passes)
56
57 return onnx.load_from_string(optimized_model_str)
IndexError: _Map_base::at
And checker segfaults!
onnx.checker.check_model(onnx_model)
Segmentation fault
Related to issue #1385 but with repro
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 5
- Comments: 16 (10 by maintainers)
Commits related to this issue
- 1. add onnx-simplifer. fix bug https://github.com/onnx/onnx/issues/2417 2. optimize_test add onnx operator check — committed to yywbxgl/onnx_helper by deleted user 4 years ago
@dashesy If I run checker on the original exported model (without adding keep_initializers_as_inputs=True) it’s happy. Is it only after you attempt to run the optimizers that the checker is unhappy with the model?
FWIW onnxruntime has working implementations of the optimizations you’re attempting and in the latest version can save an updated model post optimization. Set SessionOptions.optimized_model_filepath before loading the model and it will write the optimized onnx model out to that path. It will check that an initializer is actually const before fusing, and can also search parent graphs for initializers in order to optimize subgraphs in control flow nodes.
It will take a fairly significant overhaul of the IR and optimizer setup in onnx to make the implementations there more correct, so that’s maybe your best short term option.
e.g.
+1. It is because the current code (https://github.com/onnx/onnx/blob/master/onnx/common/ir_pb_converter.cc#L230-L237) only add graph proto’s inputs but not initializers into the map
value_by_name_of.I think it is a very critical bug 😐 It affects all models exported from PyTorch 1.3.
不止是pytorch版本问题,我用keras2onnx 转换模型,然后用onnxsim优化identity,也是这个问题。。。 optimized_model_str = C.optimize(model_str, passes) IndexError: _Map_base::at version:keras 2.3.0 ,onnx1.6.0,tf-gpu 1.14.0 ,keras2onnx source code 446b606
@dashesy There is a gap in how ORT is handling initializers that become redundant during optimizations. https://github.com/microsoft/onnxruntime/pull/2320 should address that.