apple / apple/coremltools

different output if convert model to mlprogram

Open
#1,617 2 comments 0 reactions 0 assignees View on GitHub
bug PyTorch (traced) triaged
Dominant language
Python
Stars
5.4k
Forks
850
Avg merge
4d 5h
Merged PRs (30d)
10

Description

## 🐞Describing the bug
I try to convert PyTorch model to mlprogram but got different prediction than PyTorch prediction.

## To Reproduce

```python
import torch
import torch.nn as nn
import coremltools as ct
import numpy as np

class test_module(nn.Module):
def __init__(self, F = 961 , device="cpu"):
super(test_module, self).__init__()
self.F = F
self.C = self._build_C(self.F)
self.device = device
self.register_buffer(
"mat",
torch.tensor(self._build_inv_delta_C(self.F, self.C),
dtype=torch.float,
device=self.device)
)

def _build_C(self, F):
im_x, im_y = np.mgrid[-1:1:complex(31), -1:1:complex(31)]
C = np.stack((im_y,im_x), axis=2).reshape(-1,2)
return C

def _build_inv_delta_C(self, F, C):
hat_C = np.zeros((F, F), dtype=float) # F x F
for i in range(0, F):
for j in range(i, F):
r = np.linalg.norm(C[i] - C[j])
hat_C[i, j] = r
hat_C[j, i] = r
np.fill_diagonal(hat_C, 1)
hat_C = (hat_C ** 2) * np.log(hat_C ** 2)
delta_C = np.concatenate( # F+3 x F+3
[
np.concatenate([np.ones((F, 1)), C, hat_C], axis=1), # F x F+3
np.concatenate([np.zeros((1, 3)), np.ones((1, F))], axis=1), # 1 x F+3
np.concatenate([np.zeros((2, 3)), np.transpose(C)], axis=1), # 2 x F+3
],
axis=0
)
mat = np.linalg.inv(delta_C)
return mat # F+3 x F+3

def forward(self, batch_C_prime):
batch_size = batch_C_prime.size(0)
batch_C_prime_with_zeros = torch.cat((batch_C_prime[0], torch.zeros(
batch_size, 3, 2).float().to(self.device)), dim=1) # batch_size x F+3 x 2
batch_T = torch.matmul(self.mat, batch_C_prime_with_zeros) # batch_size x F+3 x 2
return torch.matmul(torch.ones((1024, 964)).float() , torch.clone(batch_T))

m = test_module()
test_input = torch.ones([1,1,961, 2])
traced = torch.jit.trace(m, [test_input])
program = ct.convert(
traced,
convert_to="mlprogram",
# minimum_deployment_target = ct.target.macOS12,
# compute_precision=ct.precision.FLOAT16,
inputs=[
ct.TensorType(name='input', shape=(ct.RangeDim(), *test_input.shape[1:])),
],
)
input_name = program._spec.description.input[0].name
output_name = program._spec.description.output[0].name
program_output = program.predict({input_name: test_input})[output_name]
print(program_output)

mlmodel = ct.convert(
traced,
inputs=[
ct.TensorType(name='input', shape=(ct.RangeDim(), *test_input.shape[1:])),
],
)
input_name = mlmodel._spec.description.input[0].name
output_name = mlmodel._spec.description.output[0].name
mlmodel_output = mlmodel.predict({input_name: test_input})[output_name]
print(mlmodel_output)
```
mlprogram result
```
[[[17.709187 17.709187]
[17.709187 17.709187]
[17.709187 17.709187]
...
[17.709187 17.709187]
[17.709187 17.709187]
[17.709187 17.709187]]]
```
and mlmodel result
```
[[[1.003938 1.003938]
[1.003938 1.003938]
[1.003938 1.003938]
...
[1.003938 1.003938]
[1.003938 1.003938]
[1.003938 1.003938]]]
```

## System environment (please complete the following information):
- coremltools version: 6.0b2
- PyTorch: 1.10.0

Contributor guide

Open the contributing guide

Research direction

Start by running the supplied Python reproducer with PyTorch 1.10.0 and coremltools 6.0b2, comparing ct.convert(..., convert_to="mlprogram") with the default conversion. Investigate the conversion paths for the shown matmul operations and dynamic batch input. Done means the converted outputs match the PyTorch result, with a regression check for this reproducer.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, pytorch
Domain
machine-learning, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.