Significant Output Discrepancy in CoreML Conversion of PyTorch's Grid Sample- FP16
- Dominant language
- Python
- Stars
- 5.4k
- Forks
- 850
- Avg merge
- 4d 5h
- Merged PRs (30d)
- 10
Description
## 🐞Describing the bug
The CoreML model, when converted from a PyTorch model using grid sampling, shows a large deviation in output values compared to the original PyTorch model.
The output difference is notably high. When using FP16 precision for conversion instead of the default FP32, the relative change in output difference is approximately 131.59, or 13159%. This points towards the issue in the conversion process or compatibility between PyTorch's grid sample implementation and CoreML's .
Here is the screen shot attached for the output of below code:
## Code To Reproduce
- Also, attached feature and grid tensors in the [link](https://github.com/vinayak-sharan/text_file/tree/main), the code will convert ".txt" files to tensors.
```
import torch
import coremltools as ct
import numpy as np
# Define a simple PyTorch model that uses grid sampling
class PytorchGridSample(torch.nn.Module):
def forward(self, input, grid):
return torch.nn.functional.grid_sample(input, grid, align_corners=False)
def convert_to_coreml(model, inputs, is_float16=True):
traced_model = torch.jit.trace(
model, example_inputs=inputs, strict=False)
coreml_model = ct.converters.convert(traced_model,
inputs=[ct.TensorType(shape=inputs[0].shape),
ct.TensorType(shape=inputs[1].shape)],
compute_precision=ct.precision.FLOAT16 if is_float16 else ct.precision.FLOAT32)
return coreml_model
def compare_grid_samples_after_coreml_conversion(pt_model, inputs, is_float16):
"""
Compare the grid sample output before and after conversion to coreML
"""
pt_out = pt_model(*inputs)
coreml_pt_model = convert_to_coreml(pt_model, inputs, is_float16)
input_names_coreml_pt = [i for i in
coreml_pt_model.input_description]
input_data = {name: val.detach().numpy() for name, val in zip(input_names_coreml_pt, inputs)}
coreml_pt_out = torch.as_tensor(list(coreml_pt_model.predict(input_data).values())[0])
diff_pt_coreml = torch.norm(coreml_pt_out - pt_out)
return diff_pt_coreml
if __name__ == "__main__":
feat_file = "feat.txt"
grid_file = "grid.txt"
input_tensor_shape = (1, 64, 288, 288)
grid_shape = (1, 288, 288, 2)
input_tensor = torch.from_numpy(np.loadtxt("feat.txt").reshape(input_tensor_shape)).to(torch.float32)
grid = torch.from_numpy(np.loadtxt("grid.txt").reshape(grid_shape)).to(torch.float32)
inputs = [input_tensor, grid]
pt_model = PytorchGridSample()
diff_pt_coreml_fp16 = compare_grid_samples_after_coreml_conversion(pt_model, [*inputs], is_float16=True)
diff_pt_coreml_fp32 = compare_grid_samples_after_coreml_conversion(pt_model, [*inputs], is_float16=False)
print(
f"Difference between pytorch's grid sample before and after conversion: Note: Pytorch is fp32 and coreML is fp16 : {diff_pt_coreml_fp16}")
print(
f"Difference between pytorch's grid sample before and after conversion: Note: Pytorch is fp32 and coreML is fp32 : {diff_pt_coreml_fp32}")
print(f"Relative change in the difference: {(diff_pt_coreml_fp16 - diff_pt_coreml_fp32) / diff_pt_coreml_fp32}")
```
## System environment (please complete the following information):
- coremltools version: 7.1
- OS: MacOS-14.1
- PyTorch: 2.0.1
## Files required for the above code.
**Note**: _Since loading untrusted .pt files poses a security risk, I am sharing the .txt files instead. The file 'feat.txt' exceeds 75 MB and therefore couldn't be uploaded here. To avoid any suspicion of viruses, I am uploading them to GitHub. The links are provided below. Please download the files and save them in the appropriate directory._ @TobyRoseman
- [grid_tensor](https://github.com/vinayak-sharan/text_file/blob/main/grid.txt)
- [feature_tensor](https://github.com/vinayak-sharan/text_file/blob/main/feat.txt)
Contributor guide
Research direction
Start by running the provided PyTorch and coremltools reproducer with feat.txt and grid.txt, comparing the FP16 and FP32 conversion paths. Trace how grid_sample is represented during conversion and establish whether the discrepancy is conversion-specific or precision-related. Done means the reproduced output mismatch is corrected or clearly bounded, with a regression check for both precision modes.
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
- 35/100