|
1 | 1 | """ |
2 | 2 | .. _l-plot-export_tiny_phi2: |
3 | 3 |
|
4 | | -Untrained microsoft/phi-2 |
5 | | -========================= |
| 4 | +====================== |
| 5 | +Export microsoft/phi-2 |
| 6 | +====================== |
6 | 7 |
|
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 |
9 | 14 | :func:`onnx_diagnostic.torch_models.hghub.get_untrained_model_with_inputs` |
10 | 15 | can be used to create a reduced untrained version of a model coming from |
11 | 16 | :epkg:`HuggingFace`. It downloads the configuration from the website |
|
14 | 19 | the export or to compare performance. The relevance does not matter. |
15 | 20 |
|
16 | 21 | Create the dummy model |
17 | | -++++++++++++++++++++++ |
| 22 | +====================== |
18 | 23 | """ |
19 | 24 |
|
20 | 25 | import copy |
|
45 | 50 | data["n_weights"], |
46 | 51 | ) |
47 | 52 |
|
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.") |
49 | 54 | # %% |
50 | 55 | # 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)``. |
51 | 58 | # Let's see the configuration. |
52 | 59 | print(config) |
53 | 60 |
|
|
72 | 79 |
|
73 | 80 |
|
74 | 81 | # %% |
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. |
77 | 89 |
|
78 | 90 |
|
79 | | -with torch_export_patches(patch_transformers=True) as modificator: |
| 91 | +with torch_export_patches(patch_transformers=True): |
80 | 92 |
|
81 | | - # Unnecessary steps but useful in case of an error |
| 93 | + # Two unnecessary steps but useful in case of an error |
82 | 94 | # We check the cache is registered. |
83 | 95 | assert is_cache_dynamic_registered() |
84 | 96 |
|
|
88 | 100 | d["abs"] < 1e-5 |
89 | 101 | ), f"The model with patches produces different outputs: {string_diff(d)}" |
90 | 102 |
|
91 | | - # Then we export. |
| 103 | + # Then we export: the only import line in this section. |
92 | 104 | ep = torch.export.export( |
93 | 105 | untrained_model, |
94 | 106 | (), |
95 | | - kwargs=modificator(copy.deepcopy(inputs)), |
| 107 | + kwargs=copy.deepcopy(inputs), |
96 | 108 | dynamic_shapes=use_dyn_not_str(dynamic_shapes), |
97 | 109 | strict=False, # mandatory for torch==2.6 |
98 | 110 | ) |
99 | 111 |
|
100 | 112 | # We check the exported program produces the same results as well. |
| 113 | + # This step is again unnecessary. |
101 | 114 | d = max_diff(expected, ep.module()(**copy.deepcopy(inputs))) |
102 | 115 | assert d["abs"] < 1e-5, f"The exported model different outputs: {string_diff(d)}" |
103 | 116 |
|
104 | 117 | # %% |
105 | 118 | # Export to ONNX |
106 | | -# ++++++++++++++ |
| 119 | +# ============== |
107 | 120 | # |
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`. |
109 | 123 | # Patches are still needed because the export |
110 | 124 | # applies :meth:`torch.export.ExportedProgram.run_decompositions` |
111 | 125 | # may export local pieces of the model again. |
|
157 | 171 | # It looks good. |
158 | 172 |
|
159 | 173 | # %% |
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. |
0 commit comments