Repository navigation
ONNX export: optional early stopping of non-covisible pairs - #7
Merged
Merged
Conversation
sarlinpe
force-pushed
the
sarlinpe/onnx-early-stop
branch
from
October 28, 2026 23:56
9cdf8d7 to
ec7c2ce
Compare
sarlinpe
force-pushed
the
sarlinpe/onnx-early-stop
branch
from
October 29, 2026 00:10
ec7c2ce to
f4b3f10
Compare
sarlinpe
force-pushed
the
sarlinpe/onnx-early-stop
branch
from
October 29, 2026 00:49
f4b3f10 to
efc3b55
Compare
sarlinpe
force-pushed
the
sarlinpe/onnx-early-stop
branch
from
October 29, 2026 05:44
efc3b55 to
a09441e
Compare
Phil26AT
approved these changes
Oct 29, 2026
Phil26AT
left a comment
Contributor
There was a problem hiding this comment.
LGTM, cool implementation! One thing I would like to add is that we never stop after layer 1 - the model is too uncertain there (see Fig. 5 in paper). This will likely reduce the number of incorrectly rejected pairs, and might allow higher decay values. Feel free to add here, or we open a PR later.
sarlinpe
force-pushed
the
sarlinpe/onnx-early-stop
branch
from
October 29, 2026 23:27
a09441e to
9284c03
Compare
sarlinpe
force-pushed
the
sarlinpe/onnx-early-stop
branch
from
October 30, 2026 02:21
9284c03 to
791be87
Compare
--early_stop_layers (e.g. 2,4,6,8) exports a matcher that, after each listed layer k, rejects the pair without running the remaining layers and the readout if its covisibility score is below min_covisibility * (1 - early_stop_decay) ** (9 - k), as FlexGlue.match(..., early_stop_decay=...). The checks are ONNX If nodes built from per-layer covisibility-score outputs of the traced graph (torch.cond is not practical: tracing nested conditionals does not finish). early_stop_decay is a new graph input; 1 never stops early, which gives the same results as the regular matcher. The example passes it when the model has it, the README documents it, and the CI also checks the early-stopping matcher.
sarlinpe
force-pushed
the
sarlinpe/onnx-early-stop
branch
from
October 30, 2026 02:26
791be87 to
19b299b
Compare
Member
Author
We only attempt early-stopping at layers 2,4,6,8 (see argument |
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 #6 (fused GELU) and #5. This PR adds optional early stopping of non-covisible pairs to the ONNX matcher, as
FlexGlue.match(..., early_stop_decay=...)does in PyTorch.What
python onnx/export.py --early_stop_layers 2,4,6,8exportsflexglue_matcher_early_stop{,_fp16}.onnx.k, the pair is rejected without running the remaining transformer layers and the readout if its covisibility score is belowmin_covisibility * (1 - early_stop_decay) ** (9 - k).matches0 = -1,mscores0 = 0, andcovisibility_scoreis the score after layerk.early_stop_decayis a new scalar input.early_stop_decay = 1(ormin_covisibility = 0) never stops early, and then gives the same results as the regular matcher.onnx/match_pair.pygets--early_stop(selects the early-stop models) and--early_stop_decay, and passesearly_stop_decayto models that have it. The README documents the feature.How
torch.conddoesn't work here. In torch 2.6 it needs dynamo to trace the branches, which fails onTensor.unflattenand on the custom ops' autograd. With these fixed, tracing 8 nested conditionals ran for more than 15 minutes without finishing.Ifnodes are built on the exported ONNX graph (add_early_stopping):LayerScoresMatcherONNX).Ifwhose then-branch outputs the rejection.Does the
Ifactually skip the computation? Yes.fp16, N = 2048, A100, ONNX Runtime 1.23. Wall time per pair, device I/O:
min_covisibility0.8, decay 0.5How much do we gain? It depends on the share of non-covisible pairs.
Per-layer covisibility scores of all exhaustive pairs, checks after layers 2/4/6/8,
early_stop_decay=0.5:min_covisibilitymin_covisibility0.5) and −7.3% (0.8).Parity
onnx/check.pyasserts the early-stop branch:early_stop_decay=1, which never stops.--early_stop_layers 1,...,8), it also comparesmatches0, the scores andcovisibility_scorewithFlexGlue.match(..., early_stop_decay=d)for d ∈ {0, 0.2, 0.5}. On the asset pairs, the stops happen after different layers.The models are
flexglue_matcher_early_stop.onnxandflexglue_matcher_early_stop_fp16.onnx(sha256c86714cd…/01286e69…), to be uploaded to the v0.1 release for COLMAP.