Repository navigation
Add ONNX export and an ONNX Runtime example - #5
Merged
Merged
Conversation
This was referenced Oct 28, 2026
Contributor
|
Hey, thanks for the commit, looks nice! The only problem I see is that this creates a twin of the torch implementation, and it might get hard to maintain both in sync. Is there a way how we could make this less invasive? If not, maybe we could setup some tests and a CI for this? |
sarlinpe
force-pushed
the
sarlinpe/onnx-export
branch
2 times, most recently
from
October 28, 2026 23:56
3036394 to
31a459c
Compare
sarlinpe
force-pushed
the
sarlinpe/onnx-export
branch
from
October 29, 2026 00:10
31a459c to
7859529
Compare
Member
Author
|
Added a CI check. Created refactoring PR #11 to reduce code duplication with the torch definition. |
sarlinpe
force-pushed
the
sarlinpe/onnx-export
branch
2 times, most recently
from
October 29, 2026 05:44
0cd1669 to
39b72ca
Compare
- onnx/export.py exports the dense descriptor and the sparse matcher (float32 and float16 transformer) to ONNX. The graphs are traced from the PyTorch implementation itself (FlexGlue.encode_pair, pair_context, keypoint_correspondences, sparse_matches and DINOv3Descriptor.encode), with the thresholds as graph inputs, exact_nn, unchunked heads, blocked q/k/v and ONNX Runtime's fused attention. These are the models of the v0.1 release, used by COLMAP. - onnx/check.py checks exported models (any, e.g. those of the release) against a PyTorch checkpoint on the asset pairs: dense features, matches, match and covisibility scores, and, through a debug graph exported with the options read from the matcher, the predicted points and confidences of all keypoints. - onnx/match_pair.py matches two images with the released models using only numpy, OpenCV and ONNX Runtime. - A GitHub workflow exports the models on CPU and checks them (~4 min). - Document the export in the README.
sarlinpe
force-pushed
the
sarlinpe/onnx-export
branch
from
October 30, 2026 02:26
39b72ca to
383d5b6
Compare
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.
Stacked on #11 (refactor for exporters). This PR adds the ONNX export of FlexGlue that produces the models of the v0.1 release used by COLMAP, an example of inference with ONNX Runtime, and a CI workflow that checks the export against PyTorch.
Contents
onnx/export.pyexports two models:flexglue_descriptor.onnx:image (1, 3, 512, 512)→ densefeatures (1, 256, 64, 64). It runs once per image; the caller squashes the image to 512×512 with a bilinear resize without antialiasing.flexglue_matcher.onnx/flexglue_matcher_fp16.onnx: the sparse mode (match(..., sparse=True)), with float32 or float16 transformer layers.features0/1,kpts0/1(pixels, top-left-corner origin, dynamic count ≥ 1),image_size0/1, and the runtime thresholdsfilter_threshold,max_distance_pxandmin_covisibility.max_distance_px = 0rejects all matches;infdisables the check. This is documented in the README, the export contract andmatch_pair.py.matches0,mscores0andcovisibility_score. All matches are rejected in the graph ifcovisibility_score < min_covisibility.DINOv3Descriptor.encode,FlexGlue.encode_pair, the transformer layers,pair_context,keypoint_correspondencesandsparse_matches.exact_nn, unchunked heads,use_blocked_qkv(), andmodules.attentionreplaced by ONNX Runtime's fusedcom.microsoft::MultiHeadAttention(--no_fused_attentionexports standard operators).onnx/check.pychecks exported models against a PyTorch checkpoint:--weights(default: the release checkpoint),--descriptorand/or--matcherpaths to ONNX models. It can check any model, e.g. those of the release, not only a fresh export.min_covisibility0 and 0.8:check.pyexports from the checkpoint with the same options as the matcher.TOLERANCES)..github/workflows/onnx_export.yml):flexglue/,onnx/orrequirements.txt.export.py), then checks them (check.py), in separate steps.onnx/match_pair.py: a standalone example that matches two images with the released models using only numpy, OpenCV (SIFT keypoints) and ONNX Runtime, without PyTorch.Not exported: early stopping (#7), refinement, the dense and sampled modes, and CUDA graphs.
Validation
CI run on this PR: passed in 6.5 min. Installation takes 0.5 min; the export and check take 5.5 min, including the first download of the weights.
check.pyresults (ONNX Runtime 1.23, A100 / CPU):Same results as the released models: models exported with this code give the same matches and covisibility scores as the v0.1 release models on the asset pairs (2k and 4k keypoints, fp32 and fp16), so the release models are unchanged.
check.pyalso passes on the release models directly (descriptor, fp32 and fp16 matchers on CUDA).Same speed: fp16 on A100, 32.7 vs. 32.6 ms per pair at 2k and 46.5 vs. 46.1 ms at 8k (device I/O).
onnx/match_pair.pygives the same matches and covisibility score asFlexGlue.match(..., sparse=True)on the same SIFT keypoints.Example output on the two asset pairs:
COLMAP integration: colmap/colmap#4908.