coremltools icon indicating copy to clipboard operation
coremltools copied to clipboard

RuntimeError: PyTorch convert function for op 'max_pool2d_with_indices' not implemented.

Open kir486680 opened this issue 4 years ago • 1 comments

🐞Describe the bug

  • I am trying to convert my existing pytorch model and I do not directly use max_pool2d_with_indices anywhere. However, I run into the following error RuntimeError: PyTorch convert function for op 'max_pool2d_with_indices' not implemented. Here are some parts of my model.
class RegularBottleNeck(nn.Module):
    def __init__(self,
                 input_ch,
                 output_ch,
                 projection_ratio=4,
                 regularizer_prob=0,
                 dilation=0,
                 assymmetric=False,
                 bias=False):
        super(RegularBottleNeck, self).__init__()
        reduced_depth = input_ch // projection_ratio
        self.ext_branch_1 = nn.Sequential(
            nn.Conv2d(in_channels=input_ch,
                      out_channels=reduced_depth,
                      kernel_size=1,
                      stride=1,
                      padding=0,
                      bias=bias),
            nn.BatchNorm2d(reduced_depth),
            nn.PReLU()
        )
        if dilation:
            self.ext_branch_2 = nn.Sequential(
                nn.Conv2d(in_channels=reduced_depth,
                          out_channels=reduced_depth,
                          kernel_size=3,
                          stride=1,
                          padding=dilation,
                          bias=bias,
                          dilation=dilation),
                nn.BatchNorm2d(reduced_depth),
                nn.PReLU()
            )
        elif assymmetric:
            self.ext_branch_2 = nn.Sequential(
                nn.Conv2d(in_channels=reduced_depth,
                          out_channels=reduced_depth,
                          kernel_size=(5, 1),
                          stride=1,
                          padding=(2, 0),
                          bias=bias),
                nn.Conv2d(in_channels=reduced_depth,
                          out_channels=reduced_depth,
                          kernel_size=(1, 5),
                          stride=1,
                          padding=(0, 2),
                          bias=bias),
                nn.BatchNorm2d(reduced_depth),
                nn.PReLU()
            )
        else: # Regular Bottle Neck
            self.ext_branch_2 = nn.Sequential(
                nn.Conv2d(in_channels=reduced_depth,
                          out_channels=reduced_depth,
                          kernel_size=3,
                          stride=1,
                          padding=1,
                          bias=bias),
                nn.BatchNorm2d(reduced_depth),
                nn.PReLU()
            )
        self.ext_branch_3 = nn.Sequential(
            nn.Conv2d(in_channels=reduced_depth,
                      out_channels=output_ch,
                      kernel_size=1,
                      stride=1,
                      padding=0,
                      bias=bias),
            nn.BatchNorm2d(output_ch),
            nn.PReLU()
        )
        self.regularizer = nn.Dropout2d(p=regularizer_prob)
        self.prelu = nn.PReLU()

class DownSampleBottleNeck(nn.Module):
   def __init__(self,
                 input_ch,
                 output_ch,
                 projection_ratio=4,
                 regularizer_prob=0,
                 bias=False):
        super(DownSampleBottleNeck, self).__init__()
        reduced_depth = input_ch // projection_ratio
        self.ext_branch_1 = nn.Sequential(
            nn.Conv2d(in_channels=input_ch,
                      out_channels=reduced_depth,
                      kernel_size=2,
                      stride=2,
                      padding=0,
                      bias=bias),
            nn.BatchNorm2d(reduced_depth),
            nn.PReLU()
        )
        self.ext_branch_2 = nn.Sequential(
            nn.Conv2d(in_channels=reduced_depth,
                      out_channels=reduced_depth,
                      kernel_size=3,
                      stride=1,
                      padding=1,
                      bias=bias),
            nn.BatchNorm2d(reduced_depth),
            nn.PReLU()
        )
        self.ext_branch_3 = nn.Sequential(
            nn.Conv2d(in_channels=reduced_depth,
                      out_channels=output_ch,
                      kernel_size=1,
                      stride=1,
                      padding=0,
                      bias=bias),
            nn.BatchNorm2d(output_ch),
            nn.PReLU()
        )
        self.max_pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0, return_indices=True)
        self.regularizer = nn.Dropout2d(p=regularizer_prob)
        self.prelu = nn.PReLU()
class UpSampleBottleNeck(nn.Module):
    def __init__(self,
                 input_ch,
                 output_ch,
                 projection_ratio=4,
                 regularizer_prob=0,
                 bias=False):
        super(UpSampleBottleNeck, self).__init__()
        reduced_depth = input_ch // projection_ratio
        self.main_branch = nn.Sequential(
            nn.Conv2d(in_channels=input_ch,
                      out_channels=output_ch,
                      kernel_size=3,
                      stride=1,
                      padding=1,
                      bias=bias),
            nn.BatchNorm2d(output_ch)
        )
        self.ext_branch_1 = nn.Sequential(
            nn.Conv2d(in_channels=input_ch,
                      out_channels=reduced_depth,
                      kernel_size=1,
                      stride=1,
                      padding=0,
                      bias=bias),
            nn.BatchNorm2d(reduced_depth),
            nn.PReLU()
        )
        self.ext_branch_2 = nn.Sequential(
            nn.ConvTranspose2d(in_channels=reduced_depth,
                      out_channels=reduced_depth,
                      kernel_size=3,
                      stride=2,
                      padding=1,
                      output_padding=1,
                      bias=bias),
            nn.BatchNorm2d(reduced_depth),
            nn.PReLU()
        )
        self.ext_branch_3 = nn.Sequential(
            nn.Conv2d(in_channels=reduced_depth,
                      out_channels=output_ch,
                      kernel_size=1,
                      stride=1,
                      padding=0,
                      bias=bias),
            nn.BatchNorm2d(output_ch),
            nn.PReLU()
        )
        self.max_unpool = nn.MaxUnpool2d(kernel_size=2, stride=2, padding=0)
        self.regularizer = nn.Dropout2d(p=regularizer_prob)
        self.prelu = nn.PReLU()

System environment

  • coremltools version 4:
  • python version 3.8.0:
  • pytorch 1.6.0

kir486680 avatar Feb 05 '21 09:02 kir486680

Need this too. A lot of recent models use this operator. I tried to rewrite the computing of the indices directly on the model, but I didn't succeed. I've also posted a question on stack overflow on this specific issue

pboudoin avatar May 12 '22 22:05 pboudoin

@kir486680 - which of the three models you shared is generating this error? How are you calling coremltools.convert?

TobyRoseman avatar Oct 25 '22 18:10 TobyRoseman

Since we have not heard back here, I'm going to close this issue. If we ever get the requested information, I'll reopen.

TobyRoseman avatar Feb 15 '23 00:02 TobyRoseman

I also face this issue, so I am adding comments here.

RuntimeError: PyTorch convert function for op 'max_pool2d_with_indices' not implemented.

How to reproduce:

  1. Download Resnet ONNX model
  2. Convert to PyTorch using onnx2pytorch.
import onnx
onnx_model = onnx.load(model_name)
from onnx2pytorch import ConvertModel
pytorch_model = ConvertModel(onnx_model)
import torch
torch.save(pytorch_model, 'resnet152-7.pt')
  1. Convert to TorchScript using Model Tracing
pytorch_model = torch.load('resnet152-7.pt')

# Example input, needed by jit tracer.
example = torch.rand(1, 3, 224, 224)

# # Generate TorchScript by tracing.
pytorch_model.eval()
traced = torch.jit.trace(pytorch_model, example)
  1. Convert to Core ML.
import coremltools as ct
model = ct.convert(traced, inputs=[ct.TensorType(shape=example.shape)])

TimYao18 avatar Sep 22 '23 05:09 TimYao18

@TimYao18 - can you give us a minimal example (standalone code we can just copy and paste)?

TobyRoseman avatar Sep 25 '23 18:09 TobyRoseman

import onnx
from onnx2pytorch import ConvertModel
import torch

model_name = 'resnet152-v1-7.onnx'
onnx_model = onnx.load(model_name)

pytorch_model = ConvertModel(onnx_model)

# Example input, needed by jit tracer.
example = torch.rand(1, 3, 224, 224)

# # Generate TorchScript by tracing.
pytorch_model.eval()
traced = torch.jit.trace(pytorch_model, example)

import coremltools as ct
model = ct.convert(traced, inputs=[ct.TensorType(shape=example.shape)])

TimYao18 avatar Sep 26 '23 05:09 TimYao18

This isn't standalone or minimal. It uses two external packages and a full sized model.

Ideally, we'd have something that could be used as a unit test.

TobyRoseman avatar Sep 26 '23 16:09 TobyRoseman