Onnxify 0.3.3
dotnet add package Onnxify --version 0.3.3
NuGet\Install-Package Onnxify -Version 0.3.3
<PackageReference Include="Onnxify" Version="0.3.3" />
<PackageVersion Include="Onnxify" Version="0.3.3" />
<PackageReference Include="Onnxify" />
paket add Onnxify --version 0.3.3
#r "nuget: Onnxify, 0.3.3"
#:package Onnxify@0.3.3
#addin nuget:?package=Onnxify&version=0.3.3
#tool nuget:?package=Onnxify&version=0.3.3
Onnxify
Onnxify is for programmatic ONNX model work in .NET: open an existing .onnx, inspect the graph, modify it, save it back, or build a model from scratch in C#.
Install
dotnet add package Onnxify
ONNX Version Baseline
New models created with OnnxModel.Create() use standard ONNX opset 25 and IR version 11 by default. These are the package's baseline ONNX versions: opset 25 comes from the bundled standard-domain operator schemas, and IR version 11 is the repository's current compatibility target for generated models.
Set OnnxModelCreationOptions.Opset and IrVersion explicitly when you need to target an older runtime or a deployment profile with stricter ONNX support.
Why This Package Exists
ONNX is often used as a model interchange format, but in .NET there is usually an awkward gap between two extremes:
- an inference runtime can execute a model, but usually does very little to help you rewrite it;
- the protobuf layer lets you do almost anything, but it is too low-level for day-to-day engineering work.
Onnxify is meant to fill exactly that space. The package exists for cases where an ONNX model is not just an artifact you "run and forget", but something you need to read, understand, version, patch, and generate programmatically.
In practice, it helps with scenarios like these:
- open an existing ONNX model and quickly understand its inputs, outputs, initializers, and nodes;
- patch a graph in C# without dropping down into raw protobuf manipulation;
- generate ONNX as the output of your own tool, exporter, converter, or build pipeline;
- keep graph structure, value types, shapes, and opset versions in normal .NET code instead of manual protobuf plumbing.
In short, Onnxify is for teams that need control, transparency, and editability around ONNX in .NET.
What The Package Provides
OnnxModel.FromFile(...),FromFileAsync(...),FromStream(...),FromStreamAsync(...),Save(...), andSaveAsync(...)for reading and writing.onnxmodels from files or streams.OnnxModel.Create(...)for creating a new model from scratch. By default it writes standard ONNX opset 25 and IR version 11.OnnxGraphfor working with inputs, outputs, intermediate values, initializers, loose edges, and nodes.- Typed value and tensor descriptions through
OnnxValue,OnnxTensor<T>, andOnnxTensorType. - Explicit operator construction through
AddNode(...)and typed operator wrappers when they are available. - Direct graph editing through
AddInput(OnnxValue),AddOutput(OnnxValue),RemoveInput(...),RemoveOutput(...),RemoveNode(...),ReplaceNode(...),RemoveValue(...),ReplaceValue(...),RemoveTensor(...), andRemoveEdge(...). ValidateCompatibility(...)for structural compatibility checks.
Quick Start
- If you want the first copy-paste example to run as-is, start with
Build A Small ONNX Model Manually. - If you already have a
.onnxfile and want to inspect it, useOpen A Model And Inspect The Graph.
Example: Open A Model And Inspect The Graph
This snippet assumes you already have an ONNX file on disk. Replace "model.onnx" with the path to a real model in your project or local workspace.
using System.Linq;
using Onnxify;
var model = OnnxModel.FromFile("model.onnx");
Console.WriteLine($"Producer: {model.ProducerName}");
Console.WriteLine($"IR version: {model.IrVersion}");
Console.WriteLine($"Opsets: {string.Join(", ", model.OpsetImport.Select(x => $"{x.Domain}:{x.Version}"))}");
Console.WriteLine($"Inputs: {model.Graph.Inputs.Count}");
Console.WriteLine($"Outputs: {model.Graph.Outputs.Count}");
Console.WriteLine($"Nodes: {model.Graph.Nodes.Count}");
foreach (var input in model.Graph.Inputs)
{
Console.WriteLine($"Input: {input.Name} -> {input}");
}
var weights = model.Graph.Initializers
.OfType<OnnxTensor<float>>()
.FirstOrDefault(x => x.Name == "weights");
if (weights is not null)
{
Console.WriteLine($"Weights shape: [{string.Join(", ", weights.Shape)}]");
Console.WriteLine($"Preview: {weights}");
}
This is useful when a model comes from somewhere else and the first step is understanding it before changing anything.
Use await OnnxModel.FromFileAsync("model.onnx") when model I/O should not block the caller, or OnnxModel.FromStream(stream) when the model already lives in memory, a network response, or another stream source.
Example: Build A Small ONNX Model Manually
using Onnxify;
var model = OnnxModel.Create(new OnnxModelCreationOptions
{
ProducerName = "demo",
Opset = 25,
IrVersion = 11,
});
var graph = model.Graph;
graph.Name = "bias_add";
var input = graph.AddInput(
name: "input",
type: OnnxTensorType.Create<float>(["batch", 4])
);
var bias = graph.AddTensor(
name: "bias",
shape: [4],
value: [0.1f, 0.2f, 0.3f, 0.4f]
);
var hidden = graph.Add(
name: "add_bias",
options: new AddInputOptions
{
A = input,
B = bias,
}
);
var outputEdge = graph.AddEdge("output");
graph.Identity(
name: "publish_output",
options: new IdentityInputOutputOptions
{
Input = hidden,
Output = outputEdge,
}
);
graph.AddOutput(
name: "output",
type: OnnxTensorType.Create<float>(["batch", 4])
);
model.AddMetadataProps("author", "onnxify-demo");
model.Save("bias_add.onnx", overwrite: true);
This approach is useful when the ONNX model is generated by your own code instead of being exported from an external framework. It is also the best first smoke test if you want to verify that the package is installed and working in a new project.
Use await model.SaveAsync("bias_add.onnx", overwrite: true) when saving from an async workflow, or model.Save(stream) / await model.SaveAsync(stream) when you need to write to an existing stream.
Example: Edit An Existing Graph
using Onnxify;
var model = OnnxModel.FromFile("classifier.onnx");
var graph = model.Graph;
var logits = graph.GetValue("logits")
?? throw new InvalidOperationException("Expected logits.");
var probabilities = graph.Softmax(
name: graph.NextName("probabilities"),
options: new SoftmaxInputOptions
{
Input = logits,
Axis = 1,
}
);
var output = graph.AddValue(
"probabilities",
OnnxTensorType.Create<float>(["batch", "classes"])
);
graph.Identity(
name: graph.NextName("probabilities_out"),
options: new IdentityInputOutputOptions
{
Input = probabilities,
Output = output,
}
);
graph.AddOutput(output);
model.Save("classifier_patched.onnx", overwrite: true);
For targeted rewrites, use ReplaceNode(...) or ReplaceValue(...). For deletion, RemoveNode(...), RemoveValue(...), RemoveTensor(...), and RemoveEdge(...) clear matching node input/output references and prune unused loose edges so edited graphs do not retain dangling graph pieces.
Recommendations
- Use
OnnxModel.FromFile(...)when you are adapting an existing ONNX model and want to make targeted changes without working directly with protobuf APIs. - Use
OnnxModel.Create(...)when the ONNX graph is the end product of your own generator, exporter, or toolchain. - The default creation profile is standard ONNX opset 25 and IR version 11. Set
OpsetorIrVersionexplicitly, and useSetOpsetImport(...)when needed, if you are working beyond the defaultai.onnxdomain or targeting a specific runtime. - Run
ValidateCompatibility(...)before publishing or handing models off to other systems, especially when graphs are generated or modified automatically. - If the source model uses external tensor data, configure
DataLocationandDataReader. The currentOnnxifyserialization flow writes tensors back as embedded data by default. - Use the base
Onnxifypackage when your main need is direct control over the ONNX graph itself. If the task is more specialized, look at the neighboring packages: Onnxify.TorchSharpfor exporting TorchSharp models into a controllable ONNX graph.Onnxify.ModelGeneratorfor generating typed wrappers from an existing.onnx.Microsoft.ML.OnnxRuntimeif you only need inference and not model editing.
Repository
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Google.Protobuf (>= 3.34.0)
- System.Collections.Immutable (>= 9.0.0)
- System.Text.Json (>= 10.0.0)
-
net10.0
- Google.Protobuf (>= 3.34.0)
-
net8.0
- Google.Protobuf (>= 3.34.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Onnxify:
| Package | Downloads |
|---|---|
|
Onnxify.TorchSharp
TorchSharp-to-ONNX export layer for translating TorchSharp modules and model structure into explicit Onnxify graph operations. |
|
|
Onnxify.ProjectGenerator
Code generation library that turns an existing ONNX model into a C# project or program that reconstructs the model through the Onnxify API. |
GitHub repositories
This package is not used by any popular GitHub repositories.
## 0.3.3
- Added `OnnxDimensionNone` and ONNX shape parsing support for dimensions whose protobuf value case is `None`.
- Preserved empty optional node input and output slots when loading, editing, and saving ONNX graphs, fixing operators such as `Resize` that rely on positional optional inputs.
- Improved graph string output and project-generation rendering for unknown `None` dimensions by displaying them as `[none]`.
- Added regression coverage with `yolo26s.onnx` for loading `OnnxModel`, saving it back to ONNX, and rendering `OnnxGraph.ToString()`.
## 0.3.2
- Fixed ONNX graph loading for models whose `graph.value_info` repeats a graph input or output name, preserving the first loaded value metadata while marking the value as an input or output.
- Added regression coverage for loading a MobileNetV2 ONNX model whose `logits` output is also present in `value_info`.
- Added a `netstandard2.0` target for core graph/model APIs so analyzer packages can share the same `OnnxModel` and `OnnxGraph` implementation.
- Added `NodeTypeResolutionStrategy.PreserveUntyped` for callers that need to inspect loaded graphs without projecting nodes into generated typed wrappers.
- Aligned the package version with the 0.3.2 Onnxify package family release.
## 0.3.0
- Aligned the package version with the 0.3.0 Onnxify package family release.
- Kept core ONNX model APIs aligned with the expanded TorchModule generation and package documentation updates in the 0.3.0 family.
- Added `OnnxGraph.SortTopologically()` to deterministically reorder graph nodes, initializers, loose edges, and value-info entries for structurally comparable ONNX graphs.
## 0.2.0
- Raised the default `OnnxModel.Create()` profile to standard ONNX opset 25 and IR version 11.
- Added graph editing APIs for marking existing `OnnxValue` instances as inputs or outputs, replacing and removing nodes and values, and removing tensors or loose edges.
- Removal helpers now clear matching node input/output references and prune unused loose edges to avoid dangling graph pieces after edits.
## 0.1.2
- Added async ONNX model file I/O with `OnnxModel.FromFileAsync(...)` and `SaveAsync(...)`.
- Added stream-based ONNX model I/O with `OnnxModel.FromStream(...)`, `FromStreamAsync(...)`, `Save(Stream)`, and `SaveAsync(Stream, ...)`.
- Aligned the package version with the 0.1.2 Onnxify package family release.
## 0.1.1
- Aligned the package version with the 0.1.1 Onnxify package family release.
## 0.0.0.1
- Initial release