apple / coremltools

Core ML tools contain supporting tools for Core ML model conversion, editing, and validation.
https://coremltools.readme.io
BSD 3-Clause "New" or "Revised" License
4.38k stars 631 forks source link

PyTorch to CoreML conversion fails with tools 4.0b1 at BatchNorm2d with track_running_stats=False, ValueError: Input mean is required for op batch_norm. #784

Open leovinus2001 opened 4 years ago

leovinus2001 commented 4 years ago

Title:

PyTorch to CoreML conversion fails with tools 4.0b1 at BatchNorm2d with track_running_stats=False, ValueError: Input mean is required for op batch_norm.

Relevance:

This might seem like an edge case but we have several models where this is relevant. Hence the report.

Documentation at

https://pytorch.org/docs/master/generated/torch.nn.BatchNorm2d.html#batchnorm2d

If track_running_stats is set to False, this layer then does not keep running estimates, and batch statistics are instead used during evaluation time as well.

In detail, affine=True, track_running_stats=True OK affine=False, track_running_stats=True OK affine=True, track_running_stats=False FAILS affine=False, track_running_stats=False FAILS

Reproducible

yes, see testcase attached

testBN.txt

Setup

Torch version : 1.5.1 CoreML tools version : 4.0b1 Python 3.7.6 macOS Catalina latest

Log:

Converting Frontend ==> MIL Ops: 91%|██ | 10/11 [00:00<00:00, 4716.94 ops/s] Traceback (most recent call last): File "testBN.py", line 29, in mlmodel = ct.convert( traced_model, inputs= [ ct.TensorType(name="input1", shape=dummy_input.shape) ] ) File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/_converters_entry.py", line 299, in convert kwargs File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/converter.py", line 120, in _convert prog = frontend_converter(model, kwargs) File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/converter.py", line 62, in call return load(*args, kwargs) File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/frontend/torch/load.py", line 86, in load raise e File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/frontend/torch/load.py", line 76, in load prog = converter.convert() File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/frontend/torch/converter.py", line 302, in convert convert_nodes(self.context, self.graph) File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/frontend/torch/ops.py", line 56, in convert_nodes _add_op(context, node) File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/frontend/torch/ops.py", line 734, in batch_norm name=node.name, File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/mil/ops/registry.py", line 62, in add_op return cls._add_op(op_cls, kwargs) File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/mil/builder.py", line 186, in _add_op op_cls.input_spec, kwargs["name"], op_cls, before_op, kwargs File "~/Library/Python/3.7/lib/python/site-packages/coremltools/converters/mil/mil/builder.py", line 117, in _create_input_vars "Input {} is required for op {}.".format(in_name, op_cls.name) ValueError: Input mean is required for op batch_norm.

TobyRoseman commented 2 years ago

This is still an issue with coremltools 5.0. Although the stacktrace is different.

Current stacktrace:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-1-41e7842de3ca> in <module>
     27     output = model(dummy_input)
     28     traced_model   = torch.jit.trace (model, dummy_input)
---> 29     mlmodel = ct.convert( traced_model, inputs= [ ct.TensorType(name="input1", shape=dummy_input.shape) ] )
     30 

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/_converters_entry.py in convert(model, source, inputs, outputs, classifier_config, minimum_deployment_target, convert_to, compute_precision, skip_model_load, compute_units, **kwargs)
    304         raise ValueError("Invalid value of the argument 'compute_precision'")
    305 
--> 306     mlmodel = mil_convert(
    307         model,
    308         convert_from=exact_source,

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/converter.py in mil_convert(model, convert_from, convert_to, compute_units, **kwargs)
    173         See `coremltools.converters.convert`
    174     """
--> 175     return _mil_convert(model, convert_from, convert_to, ConverterRegistry, MLModel, compute_units, **kwargs)
    176 
    177 

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/converter.py in _mil_convert(model, convert_from, convert_to, registry, modelClass, compute_units, **kwargs)
    200         _os.chmod(weights_dir, _stat.S_IRWXU | _stat.S_IRWXG | _stat.S_IRWXO)
    201 
--> 202     proto, mil_program = mil_convert_to_proto(
    203                             model,
    204                             convert_from,

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/converter.py in mil_convert_to_proto(model, convert_from, convert_to, converter_registry, **kwargs)
    291     frontend_converter = frontend_converter_type()
    292 
--> 293     prog = frontend_converter(model, **kwargs)
    294 
    295     if convert_to.lower() != "neuralnetwork":

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/converter.py in __call__(self, *args, **kwargs)
    101         from .frontend.torch import load
    102 
--> 103         return load(*args, **kwargs)
    104 
    105 

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/frontend/torch/load.py in load(model_spec, debug, **kwargs)
     80         raise e
     81     except Exception as e:
---> 82         raise e
     83 
     84     return prog

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/frontend/torch/load.py in load(model_spec, debug, **kwargs)
     70 
     71     try:
---> 72         prog = converter.convert()
     73     except RuntimeError as e:
     74         if debug and "convert function" in str(e):

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/frontend/torch/converter.py in convert(self)
    228 
    229             # Add the rest of the operations
--> 230             convert_nodes(self.context, self.graph)
    231 
    232             graph_outputs = [self.context[name] for name in self.graph.outputs]

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/frontend/torch/ops.py in convert_nodes(context, graph)
     68             )
     69         else:
---> 70             _add_op(context, node)
     71 
     72         # We've generated all the outputs the graph needs, terminate conversion.

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/frontend/torch/ops.py in batch_norm(context, node)
   1328 
   1329     if training or running_mean.val is None or running_var.val is None or weight is None or bias is None:
-> 1330         _add_batch_norm_dynamic()
   1331     elif is_batch_norm_1d:
   1332         _add_batch_norm_1d()

~/opt/miniconda3/envs/test/lib/python3.8/site-packages/coremltools/converters/mil/frontend/torch/ops.py in _add_batch_norm_dynamic()
   1198         x = _input
   1199         shape = [1] * x.rank
-> 1200         shape[1] = -1 if any_symbolic(running_mean.shape) else running_mean.shape[0]
   1201 
   1202         if training:

AttributeError: 'NoneType' object has no attribute 'shape'