Introspection#7
Merged
Merged
Conversation
Introduce a TorchModule Export extension that uses ICSharpCode.Decompiler to decompile a module's forward method (stubbed export implementation) and add the decompiler package reference. Add a DeepExportSample to examples (and register it) that demonstrates exporting an LSTM model to ONNX with opset 22. Adjust LSTM example: add using Onnxify.TorchSharp, move embedding/hidden/layers variable declarations, and reduce training sample count for faster runs. Bump project package versions from 0.1.0.0 to 0.1.1 across multiple projects.
Implement deep export of a TorchModule by decompiling its forward method and translating the method body into ONNX graph operations. TorchModuleExportExtensions now validates inputs, creates graph inputs/outputs, decompiles the forward method, and walks the AST to handle variable declarations, deconstruction, member access, invocations (including module.forward calls and torch.sum), tuple elements, and assignments. It resolves nested module instances via reflection and invokes the appropriate Export overload for submodules. Also adds a test (DeepExport_ForLstmStyleForward_EmitsGraphFromForwardAst) and a DeepExportTestModule to verify LSTM/Embedding/Linear patterns produce expected ONNX nodes and an identity output mapping.
Split the deep export logic in Program.RunAsync into two local functions (A and B) and call them from RunAsync. Function A contains the existing LSTMLIDModel export, while function B adds a new export for MiniGpt2LikeModel, saving gpt-deep-export.onnx. Also apply minor formatting changes in MiniGpt2LikeModel (reflow causalMask initialization and a small using/whitespace tweak). Preserves OnnxModelCreationOptions (Opset = 22) for both exports.
Add a unit test and comprehensive exporter logic to deep-export MiniGPT-like transformer blocks. - Add DeepExportMiniGptModule and related transformer/attention helpers to tests and a DeepExport_ForMiniGptStyleForward test. - Replace direct decompiler usage with DecompileForward and add a fallback to recursively decompile user-defined TorchModule children when no concrete TorchModuleExtensions exporter exists. - Interpret decompiled forward bodies as data-flow programs: handle UsingStatement, validation invocations, invocation statements, tuple deconstruction, and resolve private member values referenced by the decompiler. - Support tensor instance methods (view/reshape/permute/transpose/contiguous/unsqueeze/slice) and indexers (including shape reads) by lowering them to ONNX ops (Reshape/Transpose/Gather/Slice/Unsqueeze/etc.). - Special-case materialization of position ids and causal mask initializers as deterministic tensors/initializers instead of lowering full runtime construction (torch.full/triu/slice/expand). - Implement export for torch.matmul and torch.softmax and tie LM head to token embedding weights by adding a transposed initializer for MatMul. - Add helpers for inline-array temporaries emitted by the decompiler, shape/permutation resolution, axis normalization, scalar initializers, and 2D transposition of weight buffers. These changes enable exporting recursive transformer graphs from user modules by decompiling and lowering common tensor operations into ONNX graph constructs.
Widen ONNX export coverage and robustness for TorchSharp modules. Key changes: add handling for runtime tensor methods and initializers (AddTensorInitializer, ExportRuntimeTensorMethod), implement torch factory exports (arange, full, triu) and tensor ops (unsqueeze, slice, expand), better slice end resolution, and support for negative axes. Change many export APIs to use ExportValue for richer semantics and handle null/throw/null-coalescing expressions, symbolic tensor members, inline-array spans, and local method decompilation/invocation (TryExportLocalMethodInvocation / ExportMethodBody). Update export logic for member access, transpose heuristics, and tensor value extraction. Tests updated to assert initializer shapes/values. Examples updated to call model.eval() and export additional models (AlexNet, MobileNet) from the deep export sample.
Create a new Onnxify.Examples.Models project and move model source files into it (renamed paths). The new csproj targets net10.0, enables implicit usings and nullable, references Onnxify.TorchSharp and Onnxify projects, and adds package references for TorchSharp and TorchVision (0.106.0). Update Onnxify.Examples to reference the new project and add the project to the solution file.
Add multi-targeting for Onnxify.Examples.Models (net8.0;net10.0) and include it in Onnxify.Tests project references. Substantially extend TorchModuleExportExtensions: improve decompiler-driven export by handling more C# constructs (variable declarations, using, returns, assignments, unary operators, indexers, parenthesized/cast expressions, primitive literals, inline array builders), fold numeric constants, resolve shape dimension references, treat tensor-scalar arithmetic, treat runtime constant tensors as initializers, broaden reflection flags, and add multiple helper utilities (TryGetIntegral/TryGetFloating, TryFoldNumericBinary, InlineArrayBuilder, ShapeDimensionReference, SymbolicTensorMember). Replace view/reshape handling to use ExportReshape and export tensor ops (permute, slice, matmul, softmax, arange, full, triu, etc.) more robustly. Update module export dispatching and inline local helper decompilation, and add extensive explanatory comments. In TorchModuleExtensions, change Linear export to produce a MatMul (with weight transposed into an initializer) plus optional Add for bias, add Transpose2D helper, and validate weight rank. These changes increase coverage and correctness of exporting TorchSharp modules to ONNX.
Introduce comprehensive deep-export test coverage by adding TorchModuleDeepExportTests.cs (detailed unit tests for many deep-export scenarios: LSTM, MiniGPT/transformer block, helper projection, arange/triu masks, symbolic slices, validation guards, arithmetic folding, unsupported statements) and TorchModuleDeepExportSmokeTests.cs (smoke tests that export example TorchSharp models to ONNX and validate outputs against TorchSharp). Refactor TorchModuleExtensionsTests.cs by removing the moved deep-export test implementations to avoid duplication. Tests use Opset 22 and include temporary ONNX model serialization and runtime validation where applicable.
Add 0.1.1 release-note headers to multiple NuGet package docs to align package versions across the Onnxify 0.1.1 family. Updated files: Onnxify.CLI, Onnxify.ML, Onnxify.ML.TorchSharp, Onnxify.ModelGenerator, Onnxify.ProjectGenerator, Onnxify.Safetensors, Onnxify.TorchSharp, and Onnxify.md. The TorchSharp notes include detailed 0.1.1 changes (deep export for single-input modules, recursive child-module export, lowering for common forward patterns, nn.Linear export change to MatMul+Add, and added test coverage).
Introduce a TorchSharp port of the Real-ESRGAN RRDB generator (RealEsrganRrdbNet) with export-to-ONNX support. The new implementation includes nested RRDB and residual dense block types, validation, factory constructors for common variants, and helpers for nearest upsampling and scaling in the exported graph. Add unit tests (RealEsrganRrdbNetTests) to verify forward upscaling behavior, ONNX export correctness vs. TorchSharp output, and factory/constructor behavior. Also update the example Program to include a deep export sample that writes an ONNX model (realesrgan-deep-export.onnx).
Rename experimental deep-export API from Export to ExportOnnxModel and update all callsites (examples/tests). Implement deep-export enhancements: static conditional expression evaluation, boolean folding, torch.cat and functional.interpolate handling, sequential module fallback, and numerous helper resolvers (array/graph-edge/double-array/empty-array detection and interpolation mode resolution). Add tests covering small RealESRGAN export and conditional-branch exports, plus helper test modules. Update RealEsrgan example (add Roi placeholder) and release notes to reflect the API rename.
Document the experimental ExportOnnxModel deep-export API in Onnxify.TorchSharp.md (usage, capabilities, limitations and examples). Update tests: RealEsrganRrdbNetTests now computes expected TorchSharp output and asserts shape/values with tolerance; TorchModuleDeepExportSmokeTests adds a new smoke test for a documented transformer-style example and supporting test-only modules (DocumentedTransformerSyntaxModule and DocumentedAttentionBlock), plus a using import for torch.nn. These changes validate and demonstrate the new deep-export path.
There was a problem hiding this comment.
Pull request overview
Adds an experimental “deep export” path for TorchSharp models by decompiling forward(Tensor) and lowering supported syntax/ops into an ONNX graph, along with new example models and tests to validate the exporter.
Changes:
- Introduced
TorchModule.ExportOnnxModel(...)deep-export implementation (ICSharpCode.Decompiler-based) with recursive export fallback for user-defined child modules. - Updated
nn.Linearlowering toMatMul+ optionalAdd(instead ofGemm) to preserve leading batch dimensions for higher-rank inputs. - Added new example model project (
Onnxify.Examples.Models), deep-export sample, and extensive unit + smoke tests; bumped package versions to0.1.1.
Reviewed changes
Copilot reviewed 31 out of 35 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Onnxify/Onnxify.csproj | Bumps package version to 0.1.1. |
| src/Onnxify.TorchSharp/TorchModuleExtensions.cs | Changes Linear export to MatMul (+ optional Add) and adds 2D transpose helper. |
| src/Onnxify.TorchSharp/TorchModuleExportExtensions.cs | Adds experimental deep-export implementation that decompiles forward and synthesizes an ONNX graph. |
| src/Onnxify.TorchSharp/Onnxify.TorchSharp.csproj | Bumps version and adds ICSharpCode.Decompiler dependency. |
| src/Onnxify.Tests/TorchModuleDeepExportTests.cs | Adds unit tests covering deep-export AST patterns and supported ops. |
| src/Onnxify.Tests/TorchModuleDeepExportSmokeTests.cs | Adds ONNX Runtime smoke tests comparing deep-export outputs to TorchSharp outputs. |
| src/Onnxify.Tests/RealEsrganRrdbNetTests.cs | Adds runnable Real-ESRGAN RRDBNet tests incl. deep-export coverage. |
| src/Onnxify.Tests/Onnxify.Tests.csproj | References Onnxify.Examples.Models for test models. |
| src/Onnxify.slnx | Adds Onnxify.Examples.Models to solution structure. |
| src/Onnxify.Safetensors/Onnxify.Safetensors.csproj | Bumps package version to 0.1.1. |
| src/Onnxify.ProjectGenerator/Onnxify.ProjectGenerator.csproj | Bumps package version to 0.1.1. |
| src/Onnxify.ModelGenerator/Onnxify.ModelGenerator.csproj | Bumps package version to 0.1.1. |
| src/Onnxify.ML/Onnxify.ML.csproj | Bumps package version to 0.1.1. |
| src/Onnxify.ML.TorchSharp/Onnxify.ML.TorchSharp.csproj | Bumps package version to 0.1.1. |
| src/Onnxify.Examples/Program.cs | Adds a deep-export example sample and reduces LSTM sample training set size. |
| src/Onnxify.Examples/Onnxify.Examples.csproj | References Onnxify.Examples.Models. |
| src/Onnxify.Examples/Models/LanguageLstmTrainingPipeline.cs | Adds a new using (currently unused). |
| src/Onnxify.Examples.Models/TorchSharpExportShowcase.cs | Adds a showcase CNN-like model plus a manual Export() method. |
| src/Onnxify.Examples.Models/TinyYoloLikeDetector.cs | Adds a tiny YOLO-like detector model plus a manual Export() method. |
| src/Onnxify.Examples.Models/RealEsrganRrdbNet.cs | Adds Real-ESRGAN RRDBNet TorchSharp model plus a manual Export() method. |
| src/Onnxify.Examples.Models/Onnxify.Examples.Models.csproj | Introduces a dedicated project for reusable example models. |
| src/Onnxify.Examples.Models/MobileNetV1LikeClassifier.cs | Adds a MobileNetV1-like classifier plus a manual Export() method. |
| src/Onnxify.Examples.Models/MiniGpt2LikeModel.cs | Minor formatting adjustments. |
| src/Onnxify.Examples.Models/LSTMLIDModel.cs | Switches to using Linear.Export(...) instead of a custom projection helper. |
| src/Onnxify.Examples.Models/AlexNet.cs | Adds an AlexNet model plus a manual Export() method. |
| src/Onnxify.CLI/Onnxify.CLI.csproj | Bumps package version to 0.1.1. |
| .docs/nuget/release-notes/Onnxify.TorchSharp.md | Adds 0.1.1 release notes highlighting deep export and Linear lowering change. |
| .docs/nuget/release-notes/Onnxify.Safetensors.md | Adds 0.1.1 release notes (version alignment). |
| .docs/nuget/release-notes/Onnxify.ProjectGenerator.md | Adds 0.1.1 release notes (version alignment). |
| .docs/nuget/release-notes/Onnxify.ModelGenerator.md | Adds 0.1.1 release notes (version alignment). |
| .docs/nuget/release-notes/Onnxify.ML.TorchSharp.md | Adds 0.1.1 release notes (version alignment). |
| .docs/nuget/release-notes/Onnxify.ML.md | Adds 0.1.1 release notes (version alignment). |
| .docs/nuget/release-notes/Onnxify.md | Adds 0.1.1 release notes (version alignment). |
| .docs/nuget/release-notes/Onnxify.CLI.md | Adds 0.1.1 release notes (version alignment). |
| .docs/nuget/Onnxify.TorchSharp.md | Documents the experimental deep-export API and supported patterns. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+1503
to
+1505
| var shape = tensor.GetShape(); | ||
| var detached = tensor.detach().cpu(); | ||
| // Runtime tensor constants are materialized as initializers: |
Comment on lines
+2145
to
+2152
| private static float[] Transpose2D( | ||
| float[] input, | ||
| int rows, | ||
| int columns | ||
| ) | ||
| { | ||
| var output = new float[input.Length]; | ||
| for (var row = 0; row < rows; row++) |
| using TorchSharp; | ||
| using Onnxify.TorchSharp; | ||
| using static TorchSharp.torch; | ||
| using static TorchSharp.torch.nn; |
Comment on lines
+513
to
+523
| public override string Name => "deep-export"; | ||
|
|
||
| public override string Description => "Deep export of LSTM model"; | ||
|
|
||
| public override async Task RunAsync() | ||
| { | ||
| A(); | ||
| B(); | ||
| C(); | ||
| D(); | ||
| E(); |
Comment on lines
+549
to
+556
| var model = new LSTMLIDModel( | ||
| charToIdx, | ||
| langToIdx, | ||
| langToIdx.Count, | ||
| embeddingDim, | ||
| hiddenDim, | ||
| layers | ||
| ); |
Stop exporting after a returned value and support statically-resolvable if-else branches during deep export. ForwardExportContext now tracks return value/flag and ReturnStatement sets it; export loops break when a return is seen and final return chooses the recorded return value. Added ExportIfElseStatement which evaluates conditions at export time (throws if not statically resolvable). Updated tests to expect dynamic-if rejection and replaced the test module accordingly. Also updated example programs to dispose Torch modules via using var.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.