Skip to content

Commit 6ada7fc

Browse files
YifanShenSZyifan_shen3
andauthored
update doc to reflect new torch.export features in coremltools 8.1, and torch.export openelm issue has been fixed in torch 2.5 (#2402)
Co-authored-by: yifan_shen3 <[email protected]>
1 parent c0446dd commit 6ada7fc

29 files changed

+107
-328
lines changed

docs-guides/_sources/source/convert-a-torchvision-model-from-pytorch.md

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,9 @@ mlmodel_from_trace = ct.convert(
135135
classifier_config = ct.ClassifierConfig(class_labels),
136136
compute_units=ct.ComputeUnit.CPU_ONLY,
137137
)
138-
```
139-
140-
Torch.export path does not support image input yet (as of Core ML Tools 8.0), so it still uses tensor input
141-
```python
142-
# Using image_input in the inputs parameter:
143-
# Convert to Core ML using the Unified Conversion API.
144138
mlmodel_from_export = ct.convert(
145139
exported_program,
140+
inputs=[image_input],
146141
classifier_config = ct.ClassifierConfig(class_labels),
147142
compute_units=ct.ComputeUnit.CPU_ONLY,
148143
)
@@ -152,7 +147,7 @@ Save the ML program using the `.mlpackage` extension. It may also be helpful to
152147

153148
```python
154149
# Save the converted model.
155-
mlmodel_from_trace.save("mobilenet.mlpackage")
150+
mlmodel_from_export.save("mobilenet.mlpackage")
156151
# Print a confirmation message.
157152
print("model converted and saved")
158153
```
@@ -254,7 +249,7 @@ To get the fields and types used in the model, get the protobuf spec with [get_s
254249

255250
```python
256251
# Get the protobuf spec of the model.
257-
spec = mlmodel_from_trace.get_spec()
252+
spec = mlmodel_from_export.get_spec()
258253
for out in spec.description.output:
259254
if out.type.WhichOneof("Type") == "dictionaryType":
260255
coreml_dict_name = out.name
@@ -266,60 +261,41 @@ You can now make a prediction with the converted model, using the test image. To
266261

267262
```python
268263
# Make a prediction with the Core ML version of the model.
269-
coreml_out_dict = mlmodel_from_trace.predict({"x": img})
270-
print("coreml predictions: ")
271-
print("top class label: ", coreml_out_dict["classLabel"])
272-
273-
coreml_prob_dict = coreml_out_dict[coreml_dict_name]
274-
275-
values_vector = np.array(list(coreml_prob_dict.values()))
276-
keys_vector = list(coreml_prob_dict.keys())
277-
top_3_indices_coreml = np.argsort(-values_vector)[:3]
278-
for i in range(3):
279-
idx = top_3_indices_coreml[i]
280-
score_value = values_vector[idx]
281-
class_id = keys_vector[idx]
282-
print("class name: {}, raw score value: {}".format(class_id, score_value))
264+
def predict_with_coreml(mlmodel):
265+
coreml_out_dict = mlmodel.predict({"x": img})
266+
print("top class label: ", coreml_out_dict["classLabel"])
267+
268+
coreml_prob_dict = coreml_out_dict[coreml_dict_name]
269+
270+
values_vector = np.array(list(coreml_prob_dict.values()))
271+
keys_vector = list(coreml_prob_dict.keys())
272+
top_3_indices_coreml = np.argsort(-values_vector)[:3]
273+
for i in range(3):
274+
idx = top_3_indices_coreml[i]
275+
score_value = values_vector[idx]
276+
class_id = keys_vector[idx]
277+
print("class name: {}, raw score value: {}".format(class_id, score_value))
278+
279+
print("coreml (converted from torch.jit.trace) predictions: ")
280+
predict_with_coreml(mlmodel_from_trace)
281+
282+
print("coreml (converted from torch.export) predictions: ")
283+
predict_with_coreml(mlmodel_from_export)
283284
```
284285

285286
When you run this example, the output should be something like the following, using the image of a daisy as the input:
286287

287288
```text Output
288-
coreml predictions:
289+
coreml (converted from torch.jit.trace) predictions:
289290
top class label: daisy
290291
class name: daisy, raw score value: 15.8046875
291292
class name: vase, raw score value: 8.4921875
292293
class name: ant, raw score value: 8.2109375
293-
```
294-
295-
The model converted from torch.export will need to use the image tensor same to torch
296-
297-
```python
298-
# Make a prediction with the Core ML version of the model.
299-
coreml_out_dict = mlmodel_from_export.predict({"x": img_torch.detach().numpy()})
300-
print("coreml predictions: ")
301-
print("top class label: ", coreml_out_dict["classLabel"])
302-
303-
coreml_prob_dict = coreml_out_dict[coreml_dict_name]
304-
305-
values_vector = np.array(list(coreml_prob_dict.values()))
306-
keys_vector = list(coreml_prob_dict.keys())
307-
top_3_indices_coreml = np.argsort(-values_vector)[:3]
308-
for i in range(3):
309-
idx = top_3_indices_coreml[i]
310-
score_value = values_vector[idx]
311-
class_id = keys_vector[idx]
312-
print("class name: {}, raw score value: {}".format(class_id, score_value))
313-
```
314-
315-
When you run this example, the output should be something like the following, using the image of a daisy as the input:
316-
317-
```text Output
318-
coreml predictions:
294+
coreml (converted from torch.export) predictions:
319295
top class label: daisy
320-
class name: daisy, raw score value: 15.7890625
321-
class name: vase, raw score value: 8.546875
322-
class name: ant, raw score value: 8.34375
296+
class name: daisy, raw score value: 15.8046875
297+
class name: vase, raw score value: 8.4921875
298+
class name: ant, raw score value: 8.2109375
323299
```
324300

325301
As you can see from the results, the converted model performs very closely to the original model — the raw score values are very similar.

docs-guides/_sources/source/convert-openelm.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ pip install coremltools
2323

2424
At the time of creating this example, the author environment is
2525
```text Output
26-
torch 2.4.1
27-
transformers 4.45.1
28-
coremltools 8.0
26+
torch 2.5.1
27+
transformers 4.46.3
28+
coremltools 8.1
2929
```
3030

3131
## Import Libraries and Set Up the Model
@@ -66,9 +66,6 @@ exported_program = torch.export.export(
6666
torch_model,
6767
(example_input_ids,),
6868
dynamic_shapes=dynamic_shapes,
69-
# Because of https://github.com/pytorch/pytorch/issues/133252
70-
# we need to use strict=False until torch 2.5
71-
strict=False,
7269
)
7370
```
7471

docs-guides/_sources/source/convert-pytorch-workflow.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The conversion from a graph captured via `torch.jit.trace` has been supported fo
2020

2121
The conversion from `torch.export` graph has been newly added to Core ML Tools 8.0.
2222
It is currently in beta state, in line with the export API status in PyTorch.
23-
As of Core ML Tools 8.0, representative models such as MobileBert, ResNet, ViT, [MobileNet](convert-a-torchvision-model-from-pytorch), [DeepLab](convert-a-pytorch-segmentation-model), [OpenELM](convert-openelm) can be converted, and the total PyTorch op translation test coverage is roughly ~60%. You can start trying the torch.export path on your models that are working with torch.jit.trace already, so as to gradually move them to the export path as PyTorch also [moves](https://github.com/pytorch/pytorch/issues/103841#issuecomment-1605017153) its support and development to that path over a period of time. In case you hit issues (e.g. models converted via export path are slower than the ones converted from jit.trace path), please report them on Github.
23+
As of Core ML Tools 8.0, representative models such as MobileBert, ResNet, ViT, [MobileNet](convert-a-torchvision-model-from-pytorch), [DeepLab](convert-a-pytorch-segmentation-model), [OpenELM](convert-openelm) can be converted, and the total PyTorch op translation test coverage is roughly ~70%. You can start trying the torch.export path on your models that are working with torch.jit.trace already, so as to gradually move them to the export path as PyTorch also [moves](https://github.com/pytorch/pytorch/issues/103841#issuecomment-1605017153) its support and development to that path over a period of time. In case you hit issues (e.g. models converted via export path are slower than the ones converted from jit.trace path), please report them on Github.
2424

2525
Now let us take a closer look at how to convert from PyTorch to Core ML through an example.
2626

docs-guides/_sources/source/flexible-inputs.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ Core ML preallocates the memory for the default shape, so the first prediction w
9595
For a multi-input model, only one of the inputs can be marked with `EnumeratedShapes`; the rest must have fixed single shapes. If you require multiple inputs to be flexible, set the range for each dimension.
9696
```
9797

98+
```{admonition} Torch.Export Dynamism
99+
100+
If the source PyTorch model is exported by [`torch.export.export`](https://pytorch.org/docs/stable/export.html#torch.export.export), then user will need to [express dynamism in torch.export](https://pytorch.org/docs/stable/export.html#expressing-dynamism), and only the torch.export dynamic dimensions are allowed to have more-than-1 possible sizes, see [Model Exporting](model-exporting).
101+
```
102+
98103
```{eval-rst}
99104
.. index::
100105
single: RangeDim

docs-guides/_sources/source/installing-coremltools.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This page describes how to install the [`coremltools`](https://github.com/apple/
44

55
```{admonition} Supported Python and MacOS Versions
66
7-
The current version of coremltools ([version 7.1](https://github.com/apple/coremltools)) includes wheels for Python 3.7, 3.8, 3.9, 3.10, and 3.11. The last stable release of coremltools to support Python 2 is version 4.0.
7+
The current version of coremltools ([version 8.0](https://github.com/apple/coremltools)) includes wheels for Python 3.7, 3.8, 3.9, 3.10, 3.11, and 3.12. The last stable release of coremltools to support Python 2 is version 4.0.
88
99
The supported MacOS versions are as follows:
1010

docs-guides/_sources/source/model-exporting.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The recommended way to generate ExportedProgram for your model is to use PyTorch
1313
1414
The conversion from `torch.export` graph has been newly added to Core ML Tools 8.0.
1515
It is currently in beta state, in line with the export API status in PyTorch.
16-
As of Core ML Tools 8.0, representative models such as MobileBert, ResNet, ViT, [MobileNet](convert-a-torchvision-model-from-pytorch), [DeepLab](convert-a-pytorch-segmentation-model), [OpenELM](convert-openelm) can be converted, and the total PyTorch op translation test coverage is roughly ~60%. You can start trying the torch.export path on your models that are working with torch.jit.trace already, so as to gradually move them to the export path as PyTorch also [moves](https://github.com/pytorch/pytorch/issues/103841#issuecomment-1605017153) its support and development to that path over a period of time. In case you hit issues (e.g. models converted via export path are slower than the ones converted from jit.trace path), please report them on Github.
16+
As of Core ML Tools 8.0, representative models such as MobileBert, ResNet, ViT, [MobileNet](convert-a-torchvision-model-from-pytorch), [DeepLab](convert-a-pytorch-segmentation-model), [OpenELM](convert-openelm) can be converted, and the total PyTorch op translation test coverage is roughly ~70%. You can start trying the torch.export path on your models that are working with torch.jit.trace already, so as to gradually move them to the export path as PyTorch also [moves](https://github.com/pytorch/pytorch/issues/103841#issuecomment-1605017153) its support and development to that path over a period of time. In case you hit issues (e.g. models converted via export path are slower than the ones converted from jit.trace path), please report them on Github.
1717
1818
Also, torch.export has limitations, see [here](https://pytorch.org/docs/stable/export.html#limitations-of-torch-export)
1919
```
@@ -110,11 +110,11 @@ The following example builds a simple model from scratch and exports it to gener
110110
```
111111

112112
## Difference from Tracing
113-
For tracing, `ct.convert` requires the `inputs` arg from user. This is no longer the case for exporting, since the ExportedProgram object carries all name and shape and dtype info.
114-
115-
Subsequently, for exporting, dynamic shape is no longer specified through the `inputs` arg of `ct.convert`. Instead, user will need to [express dynamism in torch.export](https://pytorch.org/docs/stable/export.html#expressing-dynamism), which will then be automatically converted to Core ML [`RangeDim`](https://apple.github.io/coremltools/source/coremltools.converters.mil.input_types.html#rangedim).
116-
117-
As of Core ML Tools 8.0, there are several features that the torch.export conversion path is yet to support, compared to the mature torch.jit.trace path. Such as:
118-
* [EnumeratedShapes](https://apple.github.io/coremltools/source/coremltools.converters.mil.input_types.html#enumeratedshapes)
119-
* [ImageType](https://apple.github.io/coremltools/source/coremltools.converters.mil.input_types.html#coremltools.converters.mil.input_types.ImageType)
120-
* Setting custom names and dtypes for model inputs and outputs
113+
For tracing, [`ct.convert`](https://apple.github.io/coremltools/source/coremltools.converters.convert.html#coremltools.converters._converters_entry.convert) requires the `inputs` arg from user. This is no longer required for exporting, since the ExportedProgram object carries all name and shape and dtype info, so [`TensorType`](https://apple.github.io/coremltools/source/coremltools.converters.mil.input_types.html#tensortype), [`RangeDim`](https://apple.github.io/coremltools/source/coremltools.converters.mil.input_types.html#rangedim), and [`StateType`](https://apple.github.io/coremltools/source/coremltools.converters.mil.input_types.html#statetype) will be automatically created based on ExportedProgram info if `inputs` is abscent. There are 3 cases where `inputs` is still necessary
114+
1. [`ImageType`](https://apple.github.io/coremltools/source/coremltools.converters.mil.input_types.html#coremltools.converters.mil.input_types.ImageType)
115+
2. [`EnumeratedShapes`](https://apple.github.io/coremltools/source/coremltools.converters.mil.input_types.html#enumeratedshapes)
116+
3. Customize name / dtype
117+
118+
Another difference between tracing and exporting is how to create dynamic shapes. Torch.jit.trace simply traces the executed torch ops and does not have the concept of dynamism, so dynamic shapes are specified and propagated in `ct.convert`. Torch.export, however, [rigorously expresses dynamism](https://pytorch.org/docs/stable/export.html#expressing-dynamism), so dynamic shapes are first specified and propagated in torch.export, then when calling `ct.convert`
119+
* If `RangeDim` is desired, then nothing more is needed, since it will be automatically converted from [`torch.export.Dim`](https://pytorch.org/docs/stable/export.html#torch.export.dynamic_shapes.Dim)
120+
* Else if `EnumeratedShapes` are desired, then user will need to specify shape enumeration in `inputs` arg, and only the torch.export dynamic dimensions are allowed to have more-than-1 possible sizes

docs-guides/_static/styles/bootstrap.css

Lines changed: 0 additions & 6 deletions
This file was deleted.

docs-guides/_static/styles/bootstrap.css.map

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)