Skip to content

Commit 1642132

Browse files
authored
doc (#78)
* doc * improve documentation * fix doc * fix a few things * update CI * onnx
1 parent 3c81a44 commit 1642132

File tree

14 files changed

+159
-27
lines changed

14 files changed

+159
-27
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ jobs:
6464
- name: Install requirements dev
6565
run: python -m pip install -r requirements-dev.txt
6666

67+
- name: Uninstall onnx and install onnx-weekly
68+
run: |
69+
python -m pip uninstall -y onnx
70+
python -m pip install onnx-weekly
71+
6772
- name: Cache pip
6873
uses: actions/cache@v4
6974
with:

.github/workflows/documentation.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ jobs:
4141
- name: Install requirements dev
4242
run: python -m pip install -r requirements-dev.txt
4343

44+
- name: Uninstall onnx and install onnx-weekly
45+
run: |
46+
python -m pip uninstall -y onnx
47+
python -m pip install onnx-weekly
48+
4449
- name: Cache pip
4550
uses: actions/cache@v4
4651
with:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dump_models/*
3737
dump_bash_bench/*
3838
dump_llama/*
3939
dump_test*
40+
dump_validate*
4041
dump_sdpa_*
4142
temp_dump_models/*
4243
dump_dort_bench/*

README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ or
5656
Enlightening Examples
5757
+++++++++++++++++++++
5858

59+
**Where to start to export a model**
60+
61+
* `Export microsoft/phi-2
62+
<https://sdpython.github.io/doc/onnx-diagnostic/dev/auto_examples/plot_export_tiny_phi2.html>`_
63+
5964
**Torch Export**
6065

6166
* `Use DYNAMIC or AUTO when exporting if dynamic shapes has constraints

_doc/examples/plot_export_tiny_llm.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"""
22
.. _l-plot-tiny-llm-export:
33
4-
Steel method forward to guess the dynamic shapes (with Tiny-LLM)
5-
================================================================
4+
Steel method forward to guess inputs and dynamic shapes (with Tiny-LLM)
5+
=======================================================================
66
77
Inputs are always dynamic with LLMs that is why dynamic shapes
8-
needs to be specified when a LLM is exported with:func:`torch.export.export`.
8+
needs to be specified when a LLM is exported with :func:`torch.export.export`.
99
Most of the examples on :epkg:`HuggingFace` use method
1010
:meth:`transformers.GenerationMixin.generate` but we only want to
1111
export the model and its method ``forward``.

_doc/examples/plot_export_tiny_phi2.py

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
"""
22
.. _l-plot-export_tiny_phi2:
33
4-
Untrained microsoft/phi-2
5-
=========================
4+
======================
5+
Export microsoft/phi-2
6+
======================
67
7-
:epkg:`microsoft/phi-2` is not a big models but still quite big
8-
when it comes to write unittest. Function
8+
This function exports an smaller untrained model with the same architecture.
9+
It is faster than the pretrained model.
10+
When this works, the untrained model can be replaced by the trained one.
11+
12+
:epkg:`microsoft/phi-2` is not a big model but still quite big
13+
when it comes to write unittests. Function
914
:func:`onnx_diagnostic.torch_models.hghub.get_untrained_model_with_inputs`
1015
can be used to create a reduced untrained version of a model coming from
1116
:epkg:`HuggingFace`. It downloads the configuration from the website
@@ -14,7 +19,7 @@
1419
the export or to compare performance. The relevance does not matter.
1520
1621
Create the dummy model
17-
++++++++++++++++++++++
22+
======================
1823
"""
1924

2025
import copy
@@ -45,9 +50,11 @@
4550
data["n_weights"],
4651
)
4752

48-
print(f"model {size / 2**20:1.3f} Mb with {n_weights // 1000} mille parameters.")
53+
print(f"model {size / 2**20:1.1f} Mb with {n_weights // 1000} thousands of parameters.")
4954
# %%
5055
# The original model has 2.7 billion parameters. It was divided by more than 10.
56+
# However, it can still be used with
57+
# ``get_untrained_model_with_inputs("microsoft/phi-2", same_as_pretrained=True)``.
5158
# Let's see the configuration.
5259
print(config)
5360

@@ -72,13 +79,18 @@
7279

7380

7481
# %%
75-
# Export
76-
# ++++++
82+
# Export to fx.Graph
83+
# ==================
84+
#
85+
# :func:`torch.export.export` is the first step before converting
86+
# a model into ONNX. The inputs are duplicated (with ``copy.deepcopy``)
87+
# because the model may modify them inline (a cache for example).
88+
# Shapes may not match on the second call with the modified inputs.
7789

7890

79-
with torch_export_patches(patch_transformers=True) as modificator:
91+
with torch_export_patches(patch_transformers=True):
8092

81-
# Unnecessary steps but useful in case of an error
93+
# Two unnecessary steps but useful in case of an error
8294
# We check the cache is registered.
8395
assert is_cache_dynamic_registered()
8496

@@ -88,24 +100,26 @@
88100
d["abs"] < 1e-5
89101
), f"The model with patches produces different outputs: {string_diff(d)}"
90102

91-
# Then we export.
103+
# Then we export: the only import line in this section.
92104
ep = torch.export.export(
93105
untrained_model,
94106
(),
95-
kwargs=modificator(copy.deepcopy(inputs)),
107+
kwargs=copy.deepcopy(inputs),
96108
dynamic_shapes=use_dyn_not_str(dynamic_shapes),
97109
strict=False, # mandatory for torch==2.6
98110
)
99111

100112
# We check the exported program produces the same results as well.
113+
# This step is again unnecessary.
101114
d = max_diff(expected, ep.module()(**copy.deepcopy(inputs)))
102115
assert d["abs"] < 1e-5, f"The exported model different outputs: {string_diff(d)}"
103116

104117
# %%
105118
# Export to ONNX
106-
# ++++++++++++++
119+
# ==============
107120
#
108-
# The export works. We can export to ONNX now.
121+
# The export works. We can export to ONNX now
122+
# :func:`torch.onnx.export`.
109123
# Patches are still needed because the export
110124
# applies :meth:`torch.export.ExportedProgram.run_decompositions`
111125
# may export local pieces of the model again.
@@ -157,4 +171,52 @@
157171
# It looks good.
158172

159173
# %%
160-
doc.plot_legend("untrained smaller\nmicrosoft/phi-2", "torch.onnx.export", "orange")
174+
doc.plot_legend("export\nuntrained smaller\nmicrosoft/phi-2", "torch.onnx.export", "orange")
175+
176+
# %%
177+
# Possible Issues
178+
# ===============
179+
#
180+
# Unknown task
181+
# ++++++++++++
182+
#
183+
# Function :func:`onnx_diagnostic.torch_models.hghub.get_untrained_model_with_inputs`
184+
# is unabl to guess a task associated to the model.
185+
# A different set of dummy inputs is defined for every task.
186+
# The user needs to explicitly give that information to the function.
187+
# Tasks are the same as the one defined by
188+
# `HuggingFace/models <https://huggingface.co/models>`_.
189+
#
190+
# Inputs are incorrect
191+
# ++++++++++++++++++++
192+
#
193+
# Example :ref:`l-plot-tiny-llm-export` explains
194+
# how to retrieve that information. If you cannot guess the dynamic
195+
# shapes - a cache can be tricky sometimes, follow example
196+
# :ref:`l-plot-export-with-args-kwargs`.
197+
#
198+
# DynamicCache or any other cache cannot be exported
199+
# ++++++++++++++++++++++++++++++++++++++++++++++++++
200+
#
201+
# That's the role of :func:`onnx_diagnostic.torch_export_patches.torch_export_patches`.
202+
# It registers the necessary information into pytorch to make the export
203+
# work with these. Its need should slowly disappear until :epkg:`transformers`
204+
# includes the serialization functions.
205+
#
206+
# Control Flow
207+
# ++++++++++++
208+
#
209+
# Every mixture of models goes through a control flow (a test).
210+
# It also happens when a cache is truncated. The code of the model
211+
# needs to be changed. See example :ref:`l-plot-export-cond`.
212+
# Loops are not supported yet.
213+
#
214+
# Issue with dynamic shapes
215+
# +++++++++++++++++++++++++
216+
#
217+
# Example :ref:`l-plot-dynamic-shapes-python-int` gives one reason
218+
# this process may fail but that's not the only one.
219+
# Example :ref:`l-plot-export-locale-issue` gives an way to locate
220+
# the cause but that does not cover all the possible causes.
221+
# Raising an issue on github would be the recommended option
222+
# until it is fixed.

_doc/index.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ or
6565
Enlightening Examples
6666
+++++++++++++++++++++
6767

68+
**Where to start to export a model**
69+
70+
* :ref:`l-plot-export_tiny_phi2`
71+
6872
**Torch Export**
6973

7074
* :ref:`l-plot-export-cond`

_doc/recipes/plot_dynamic_shapes_python_int.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""
2+
.. _l-plot-dynamic-shapes-python-int:
3+
24
Do not use python int with dynamic shapes
35
=========================================
46

_unittests/ut_reference/test_reference_back.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
class ExtendedReferenceEvaluatorBackendRep(onnx.backend.base.BackendRep):
1717
def __init__(self, session):
18+
super().__init__()
1819
self._session = session
1920

2021
def run(self, inputs, **kwargs):

onnx_diagnostic/tasks/image_classification.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77

88
def reduce_model_config(config: Any) -> Dict[str, Any]:
99
"""Reduces a model size."""
10+
if (
11+
hasattr(config, "model_type")
12+
and config.model_type == "timm_wrapper"
13+
and not hasattr(config, "num_hidden_layers")
14+
):
15+
# We cannot reduce.
16+
return {}
1017
check_hasattr(config, ("num_hidden_layers", "hidden_sizes"))
1118
kwargs = dict(
1219
num_hidden_layers=(
@@ -82,6 +89,20 @@ def random_input_kwargs(config: Any) -> Tuple[Dict[str, Any], Callable]:
8289
If the configuration is None, the function selects typical dimensions.
8390
"""
8491
if config is not None:
92+
if (
93+
hasattr(config, "model_type")
94+
and config.model_type == "timm_wrapper"
95+
and not hasattr(config, "num_hidden_layers")
96+
):
97+
input_size = config.pretrained_cfg["input_size"]
98+
kwargs = dict(
99+
batch_size=2,
100+
input_width=input_size[-2],
101+
input_height=input_size[-1],
102+
input_channels=input_size[-3],
103+
)
104+
return kwargs, get_inputs
105+
85106
check_hasattr(config, ("image_size", "architectures"), "num_channels")
86107
if config is not None:
87108
if hasattr(config, "image_size"):

0 commit comments

Comments
 (0)