Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ jobs:
grep ERROR doc.txt | grep -v 'l-plot-tiny-llm-export'
exit 1
fi
if [[ $(grep WARNING doc.txt | grep -v 'l-plot-tiny-llm-export') ]]; then
if [[ $(grep WARNING doc.txt | grep -v 'l-plot-tiny-llm-export' | grep -v 'Inline emphasis start-string' | grep -v 'Definition list ends without a blank line' | grep -v 'Unexpected section title or transition' | grep -v 'Inline strong start-string') ]]; then
echo "Documentation produces warnings."
grep WARNING doc.txt | grep -v 'l-plot-tiny-llm-export'
grep WARNING doc.txt | grep -v 'l-plot-tiny-llm-export' | grep -v 'Inline emphasis start-string' | grep -v 'Definition list ends without a blank line' | grep -v 'Unexpected section title or transition' | grep -v 'Inline strong start-string'
exit 1
fi

Expand Down
6 changes: 3 additions & 3 deletions _doc/status/exported_program_dynamic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
Exported Programs with Dynamic Shapes
=====================================

The following script shows the exported program for many short cases
and various l-plot-export-with-dynamic-shape to retrieve an ONNX model equivalent
to the original model.
The following script shows the exported program for many short cases exported
with different options. This steps happens before converting into ONNX.

.. runpython::
:showcode:
Expand Down Expand Up @@ -55,6 +54,7 @@ to the original model.
"export-strict",
"export-nostrict",
"export-nostrict-decall",
"export-tracing",
):
expname = exporter.replace("export-", "")
print()
Expand Down
101 changes: 101 additions & 0 deletions _doc/status/exporter_dynamic.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
=================================
Exported ONNX with Dynamic Shapes
=================================

The following script shows the exported program for many short cases
and various l-plot-export-with-dynamic-shape to retrieve an ONNX model equivalent
to the original model.

.. runpython::
:showcode:
:rst:
:toggle: code
:warningout: UserWarning

import inspect
import textwrap
import pandas
from onnx_diagnostic.helpers import string_type
from onnx_diagnostic.helpers.onnx_helper import pretty_onnx
from onnx_diagnostic.torch_export_patches.eval import discover, run_exporter
from onnx_diagnostic.ext_test_case import unit_test_going

cases = discover()
print()
print(":ref:`Summary <ledx-summary-exported-program>`")
print()
sorted_cases = sorted(cases.items())
if unit_test_going():
sorted_cases = sorted_cases[:3]
for name, cls_model in sorted_cases:
print(f"* :ref:`{name} <ledx-model-case-export-{name}>`")
print()
print()

obs = []
for name, cls_model in sorted(cases.items()):
print()
print(f".. _ledx-model-case-export-{name}:")
print()
print(name)
print("=" * len(name))
print()
print("forward")
print("+++++++")
print()
print(".. code-block:: python")
print()
src = inspect.getsource(cls_model.forward)
if src:
print(textwrap.indent(textwrap.dedent(src), " "))
else:
print(" # code is missing")
print()
print()
for exporter in ("custom", "dynamo-ir"):
expname = exporter.replace("export-", "")
print()
print(expname)
print("+" * len(expname))
print()
res = run_exporter(exporter, cls_model, True, quiet=True)
case_ref = f":ref:`{name} <ledx-model-case-export-{name}>`"
expo = exporter.split("-", maxsplit=1)[-1]
if "inputs" in res:
print(f"* **inputs:** ``{string_type(res['inputs'], with_shape=True)}``")
if "dynamic_shapes" in res:
print(f"* **shapes:** ``{string_type(res['dynamic_shapes'])}``")
print()
print()
if "onx" in res:
print(".. code-block:: text")
print()
print(textwrap.indent(pretty_onnx(res["onx"]), " "))
print()
print()
if "error" not in res:
obs.append(dict(case=case_ref, error="", exporter=expo))
if "error" in res:
print("**FAILED**")
print()
print(".. code-block:: text")
print()
err = str(res["error"])
if err:
print(textwrap.indent(err, " "))
else:
print(" # no error found for the failure")
print()
print()
obs.append(dict(case=case_ref, error="FAIL", exporter=expo))

print()
print(".. _ledx-summary-exported-program:")
print()
print("Summary")
print("+++++++")
print()
df = pandas.DataFrame(obs)
piv = df.pivot(index="case", columns="exporter", values="error")
print(piv.to_markdown(tablefmt="rst"))
print()
1 change: 1 addition & 0 deletions _doc/status/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ what works and what does not with :func:`torch.export.export`.
:maxdepth: 1

exported_program_dynamic
exporter_dynamic
patches_coverage

Some PRs in :epkg:`transformers` to keep in mind when it comes to export
Expand Down
44 changes: 42 additions & 2 deletions _unittests/ut_torch_export_patches/test_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,57 @@ def test_eval(self):
self.assertIsInstance(ev, list)
self.assertIsInstance(ev[0], dict)

def test_run_exporter(self):
def test_run_exporter_custom(self):
evaluation(
cases="SignatureListFixedLength",
exporters="custom-strict",
exporters="custom",
quiet=False,
dynamic=False,
)

def test_run_exporter_dynamo(self):
evaluation(
cases="SignatureListFixedLength",
exporters="dynamo",
quiet=False,
dynamic=False,
)

def test_run_exporter_dynamo_ir(self):
evaluation(
cases="SignatureListFixedLength",
exporters="dynamo-ir",
quiet=False,
dynamic=False,
)

def test_run_exporter_nostrict(self):
evaluation(
cases="SignatureListFixedLength",
exporters="export-nostrict",
quiet=False,
dynamic=False,
)

def test_run_exporter_tracing(self):
evaluation(
cases="SignatureListFixedLength",
exporters="export-tracing",
quiet=False,
dynamic=False,
)

def test_run_exporter_regex(self):
evaluation(cases=".*Aten.*", exporters="custom-strict", quiet=False, dynamic=False)

def test_run_exporter_custom_nested_cond(self):
evaluation(
cases="ControlFlowNestCond",
exporters="custom",
quiet=False,
dynamic=False,
)


if __name__ == "__main__":
unittest.main(verbosity=2)
11 changes: 11 additions & 0 deletions onnx_diagnostic/torch_export_patches/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Patches to export HuggingFace models

See [Patches Explained](https://sdpython.github.io/doc/onnx-diagnostic/dev/patches.html).

```python
from onnx_diagnostic.torch_export_patches import torch_export_patches

with torch_export_patches(patch_transformers=True) as f:
ep = torch.export.export(model, args, kwargs=kwargs, dynamic_shapes=dynamic_shapes)
# ...
```
4 changes: 3 additions & 1 deletion onnx_diagnostic/torch_export_patches/eval/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ def _make_exporter_onnx(
from experimental_experiment.torch_interpreter import to_onnx, ExportOptions

opts = {}
opts["strict"] = "-nostrict" not in exporter
opts["strict"] = "-strict" in exporter
opts["fallback"] = "-fallback" in exporter
opts["tracing"] = "-tracing" in exporter
opts["jit"] = "-jit" in exporter
Expand Down Expand Up @@ -520,6 +520,8 @@ def run_exporter(
return res

onx, builder = res
base["onx"] = onx
base["builder"] = builder
if verbose >= 9:
print("[run_exporter] onnx model")
print(
Expand Down
Loading