coremltools icon indicating copy to clipboard operation
coremltools copied to clipboard

ValueError: Ops['identity_0', 'identity_0', 'identity_0', 'identity_0'] not found in block block0

Open JRGit4UE opened this issue 3 years ago • 4 comments

In my Pytorch 1.9.1 test model on Python 3.8 with CoreMLTools 5.2.0 I try to convert a simple traced model that returns a tuple of tensors, but run into a ValueError of missing ops. Can someone please give me a hint, what's missing?

import torch
from torch import nn, Tensor
from typing import Optional, List, Any, Tuple
import coremltools as ct

class MyTupleModule9(nn.Module):
    def __init__(self):
        super().__init__()
    def forward(self, x)->Tuple[Tensor, Tensor, Tensor, Tensor, Tensor]:
        d: Tensor = torch.zeros(2, dtype=torch.float32)
        result: Tuple[Tensor, Tensor, Tensor, Tensor, Tensor] = (d,d,d,d,d)
        return result

if __name__ == '__main__':
    t1 = MyTupleModule9()
    x = torch.rand(2,2,1,1)
    t = torch.jit.trace(t1, example_inputs=x)
    result = t(x)
    model = ct.convert(t,  inputs=[ct.TensorType(shape=x.shape)], convert_to='mlprogram')
    # ValueError: Ops['identity_0', 'identity_0', 'identity_0', 'identity_0']  not found in block  block0
    sys.exit(0)

JRGit4UE avatar Apr 11 '22 09:04 JRGit4UE

Thanks for the minimal example. I can reproduce this issue. This looks an issue with an optimization pass to reduce the number of transpose operations.

TobyRoseman avatar Apr 13 '22 02:04 TobyRoseman

Here is an even simpler reproduction code:

import torch
from torch import nn, Tensor
import coremltools as ct

class Net(nn.Module):
    def forward(self, x):
        d = torch.zeros(2, dtype=torch.float32)
        return (d, d)

t1 = Net()
x = torch.rand(2,2,1,1)
t = torch.jit.trace(t1, example_inputs=x)
model = ct.convert(t, inputs=[ct.TensorType(shape=x.shape)], convert_to='mlprogram')

Here is the stacktrace:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~/Documents/coremltools/test.py in <module>
     11 x = torch.rand(2,2,1,1)
     12 t = torch.jit.trace(t1, example_inputs=x)
---> 13 model = ct.convert(t, inputs=[ct.TensorType(shape=x.shape)], convert_to='mlprogram')

~/Documents/coremltools/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, useCPUOnly, package_dir, debug)
    361         compute_units=compute_units,
    362         package_dir=package_dir,
--> 363         debug=debug,
    364     )
    365 

~/Documents/coremltools/coremltools/converters/mil/converter.py in mil_convert(model, convert_from, convert_to, compute_units, **kwargs)
    181         See `coremltools.converters.convert`
    182     """
--> 183     return _mil_convert(model, convert_from, convert_to, ConverterRegistry, MLModel, compute_units, **kwargs)
    184 
    185 

~/Documents/coremltools/coremltools/converters/mil/converter.py in _mil_convert(model, convert_from, convert_to, registry, modelClass, compute_units, **kwargs)
    213                             convert_to,
    214                             registry,
--> 215                             **kwargs
    216                          )
    217 

~/Documents/coremltools/coremltools/converters/mil/converter.py in mil_convert_to_proto(model, convert_from, convert_to, converter_registry, **kwargs)
    279         passes = [p for p in kwargs.get("transforms", list()) if not isinstance(p, AbstractQuantizationPass)]
    280 
--> 281     apply_common_pass_pipeline(prog, passes)
    282 
    283     if convert_to == 'milinternal':

~/Documents/coremltools/coremltools/converters/mil/mil/passes/apply_common_pass_pipeline.py in apply_common_pass_pipeline(prog, passes)
     77     ]
     78 
---> 79     _apply(common_passes, name="Common")
     80 
     81     for p in passes:

~/Documents/coremltools/coremltools/converters/mil/mil/passes/apply_common_pass_pipeline.py in _apply(passes, name)
     28             _logging.info('Performing pass: "{}"'.format(p))
     29             graph_pass = PASS_REGISTRY[p] if not isinstance(p, AbstractQuantizationPass) else p
---> 30             graph_pass(prog)
     31             if isinstance(p, AbstractQuantizationPass) or not isinstance(PASS_REGISTRY[p], PassContainer):
     32                 prog.validate()

~/Documents/coremltools/coremltools/converters/mil/mil/passes/graph_pass.py in __call__(self, prog)
      7 
      8         def __call__(self, prog):
----> 9                 self.apply(prog)
     10 
     11         def __str__(self):

~/Documents/coremltools/coremltools/converters/mil/mil/passes/reduce_transposes.py in apply(self, prog)
   1253     def apply(self, prog):
   1254         for f in prog.functions.values():
-> 1255             _reduce_transposes_block(f)

~/Documents/coremltools/coremltools/converters/mil/mil/passes/reduce_transposes.py in _reduce_transposes_block(block)
   1245     opt_transposes = TransposeOptimization(block)
   1246     opt_transposes.block_traversal()
-> 1247     opt_transposes.apply_transform()
   1248 
   1249 

~/Documents/coremltools/coremltools/converters/mil/mil/passes/reduce_transposes.py in apply_transform(self)
   1212             self._remove_transpose_ops(transpose_op)
   1213         self.block.set_outputs([sink_op.x for sink_op in self.output_sink_ops])
-> 1214         self.block.remove_ops(list(self.output_sink_ops))
   1215 
   1216         if DEBUG:

~/Documents/coremltools/coremltools/converters/mil/mil/block.py in remove_ops(self, existing_ops)
    673                     not_found.append(op.name)
    674             raise ValueError(
--> 675                 "Ops {} not found in block {}".format(not_found, self.name)
    676             )
    677 

ValueError: Ops ['identity_0'] not found in block block0

However the following network works fines:

class Net(nn.Module):
    def forward(self, x):
        d1 = torch.zeros(2, dtype=torch.float32)
        d2 = torch.zeros(2, dtype=torch.float32)
        return (d1, d2)

TobyRoseman avatar May 14 '22 00:05 TobyRoseman

Any guidance on what to do here? Running into the same problem

MatthewWaller avatar Sep 19 '22 21:09 MatthewWaller

As a temporary workaround, you could disable the problematic reduce_transposes optimization/pass. Delete or comment out, this line and this line.

TobyRoseman avatar Sep 20 '22 16:09 TobyRoseman

A fix for this bug was included in our 6.1 release. With coremltools 6.1 the model now converts without error.

TobyRoseman avatar Nov 16 '22 17:11 TobyRoseman