dotnet / dotnet/machinelearning

Update ONNX export to ONNX 1.22 opsets

Open
#7,683 2 comments 0 reactions 0 assignees View on GitHub
area-ONNX
Dominant language
C#
Stars
9.4k
Forks
2k
Avg merge
2d 20h
Merged PRs (30d)
11

Description

Update ML.NET's ONNX exporter to target the latest released ONNX specification:

- ONNX version: 1.22
- Core `ai.onnx` opset: 27
- `ai.onnx.ml` opset: 5
- ONNX Runtime: 1.29

ML.NET currently targets core opset 12 and `ai.onnx.ml` opset 2. Maintaining these old targets limits future exporter development and leaves several emitted graphs using obsolete operator schemas.

## Motivation

The latest released opsets should be ML.NET's primary export target. Compatibility with older runtimes should not prevent the exporter from tracking the maintained ONNX specification.

Moving to the current opsets will:

- Allow new exporters to use modern ONNX operators and data types.
- Enable standard bitwise and string operators where suitable.
- Enable the newer `TreeEnsemble` representation.
- Allow tree thresholds and weights to retain double precision through tensor attributes.
- Align exported models with a currently maintained ONNX Runtime release.
- Remove accumulated schema and domain-import debt.

This intentionally raises the runtime requirement for newly exported models. Existing ONNX files and ML.NET's ability to consume older models are unaffected.

## Required changes

### Update versions and dependencies

- Change the default core opset from 12 to 27.
- Change the `ai.onnx.ml` opset from 2 to 5.
- Upgrade `Microsoft.ML.OnnxRuntime` to 1.29.
- Refresh the generated ONNX protobuf bindings from ONNX 1.22.
- Update the emitted IR version as required by the features used.
- Update public documentation and validation of supported target versions.

### Emit current core operator schemas

Update operators whose signatures changed after opset 12:

- Emit `axes` as an `int64` tensor input for `Squeeze`, `Unsqueeze`, and `ReduceSum`.
- Emit `axes` as an input for the remaining `Reduce*` operators changed in opset 18.
- Emit `Clip` bounds as inputs rather than attributes.
- Review every emitted core operator against its opset-27 schema.
- Preserve ML.NET inference behaviour and output shapes.

There are currently more than twenty `axes` attributes across the exporter which require review.

### Migrate tree exports

`TreeEnsembleRegressor` and `TreeEnsembleClassifier` are deprecated in `ai.onnx.ml` opset 5 and are rejected by the official ONNX checker.

- Replace the existing tree representation with `TreeEnsemble`.
- Reconstruct classification labels and scores where necessary.
- Use tensor-valued splits and weights to avoid unnecessary float conversion.
- Preserve missing-value routing and post-transform behaviour.
- Cover FastTree, FastForest, LightGBM, ranking, regression, and classification exports.

### Correct operator-domain imports

ML.NET emits operators from the `com.microsoft` domain for tokenisation, hashing, and some trainer graphs, but currently writes only the core and `ai.onnx.ml` imports.

- Track every operator domain used by a graph.
- Emit a corresponding `opset_import` entry for each domain.
- Add `com.microsoft` version 1 when required.
- Avoid importing unused domains where practical.

## Compatibility

Newly exported models will require a runtime supporting core opset 27 and `ai.onnx.ml` opset 5. ONNX Runtime 1.29 is the corresponding current release.

Support for producing older opsets may remain available where it is correct and maintainable, but it must not constrain or delay the current default exporter.

## Acceptance criteria

- [ ] Default exports declare core opset 27 and `ai.onnx.ml` opset 5.
- [ ] Exported models use valid schemas for those opsets.
- [ ] Every exported model passes the ONNX 1.22 checker with full checking enabled.
- [ ] Every exported model loads and executes with ONNX Runtime 1.29.
- [ ] ONNX results retain parity with the corresponding ML.NET pipeline.
- [ ] Tree-based models use the non-deprecated `TreeEnsemble` operator.
- [ ] Every custom operator domain has an `opset_import` entry.
- [ ] Existing export baselines and documentation are updated.
- [ ] Loading and executing existing older ONNX models remains supported.

## Non-goals

- Targeting unreleased core opset 28.
- Automatically rewriting ONNX files previously exported by ML.NET.
- Implementing every operator introduced between opsets 12 and 27.

## References

- [ONNX 1.22 release](https://github.com/onnx/onnx/releases/tag/v1.22.0)
- [ONNX versioning](https://github.com/onnx/onnx/blob/main/docs/Versioning.md)
- [Core operator changelog](https://github.com/onnx/onnx/blob/main/docs/Changelog.md)
- [`ai.onnx.ml` operator changelog](https://github.com/onnx/onnx/blob/main/docs/Changelog-ml.md)
- [ONNX Runtime 1.29](https://github.com/microsoft/onnxruntime/releases/tag/v1.29.0)

Contributor guide

Open the contributing guide

Research direction

Start by locating ML.NET's ONNX exporter, generated protobuf bindings, export baselines, and validation and documentation areas referenced in the issue; no specific files or tests are named. Review emitted schemas, tree exports, and custom-domain imports against ONNX 1.22, then use the stated acceptance criteria to verify checker validity, ONNX Runtime 1.29 execution, parity, and older-model loading.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, machine-learning
Domain
machine-learning
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.