LoMa-mlx / README.md
mnmly's picture
Add MLX conversions of LoMa B/B128/L/G/R (upstream davnords/LoMa@8fb59c4)
4218d03 verified
|
Raw History Blame Contribute Delete
6.43 kB
---
license: other
license_name: mit-and-apache-2.0
license_link: https://huggingface.co/mnmly/LoMa-mlx/blob/main/LICENSE-MIT
library_name: mlx
pipeline_tag: keypoint-detection
tags:
- mlx
- mlx-swift
- feature-matching
- keypoint-matching
- local-features
- apple-silicon
---
# LoMa — MLX weights (unofficial conversion)
MLX-format (`.safetensors`, NHWC) conversions of the five released
**[LoMa: Local Feature Matching Revisited](https://github.com/davnords/LoMa)** (ECCV 2026)
checkpoints. They are for use with the `mlx-swift-LoMa` Swift package (LoMaKit), which
runs on Apple Silicon.
> **Unofficial.** These files were converted by a third party. They are not produced or endorsed by the
> LoMa authors. All credit for the models goes to the original authors (see [Citation](#citation)).
Each file bundles the whole pipeline: the **DaD** keypoint detector, the **DeDoDe** descriptor
(VGG19-BN, plus DINOv2 ViT-L/14 for the `dedode_g` variants) and the **LoMa matcher**.
| File | Upstream checkpoint | Matcher (embed / heads) | Descriptor | Size |
|---|---|---|---|---|
| `loma_b.safetensors` | `loma_B.pt` | 256 / 4 | DeDoDe-G, 256-d | 758 MB |
| `loma_b128.safetensors` | `loma_B128.pth` | 256 / 4 | DeDoDe-B, 128-d | 127 MB |
| `loma_l.safetensors` | `loma_L.pth` | 512 / 8 | DeDoDe-G, 256-d | 900 MB |
| `loma_g.safetensors` | `loma_G.pth` | 1024 / 16 | DeDoDe-G, 256-d | 1.47 GB |
| `loma_r.safetensors` | `loma_R.pth` (rotation-invariant) | 256 / 4 | DeDoDe-G, 256-d | 758 MB |
Each `loma_<v>.json` holds that variant's configuration, the SHA-256 of the upstream
checkpoint it was converted from, and the SHA-256 of the converted file. The same provenance
is embedded in each safetensors header (`__metadata__`).
## Provenance and modifications
- **Source:** the upstream checkpoints from
`https://github.com/davnords/storage/releases/download/loma/…`, converted against
`davnords/LoMa` at commit `8fb59c458f2a2ef44314f462467b229c27786bf0`.
- **Changes, all structural (no retraining, fine-tuning or quantization):**
- Conv kernels transposed from PyTorch NCHW `(O, I, kH, kW)` to MLX NHWC `(O, kH, kW, I)`.
- Numeric `nn.Sequential` / `nn.ModuleDict` keys renamed (e.g. `ffn.3` → `ffn.fc2`,
`decoder.layers.8` → `decoder.scale8`, VGG `layers.{i}` → `convs.{j}` / `norms.{j}`).
- `num_batches_tracked` buffers dropped. Transformer layers beyond `n_layers = 9` dropped,
as upstream's own loader does.
- Tensor dtypes kept as stored: fp32, and bf16 for DINOv2.
## Verification
The mlx-swift port was checked against the PyTorch reference for all five variants:
- **Exact CPU stream:** every stage agrees to a relative error of 1e-5 or better.
- **GPU float32, full resolution:** match-set IoU of 0.97–1.0.
- **End to end vs the upstream `LoMa.match` (MPS, fp16):** 88–97% of Python's matches
reproduced within 2 px. Most of the remaining gap comes from JPEG decoding (ImageIO vs
libjpeg), not the model.
## Usage (Swift)
```swift
import LoMaKit
let session = try LoMaSession.load(variant: .b, weightsURL: localURL(of: "loma_b.safetensors"))
let result = try session.match(contentsOf: imageA, imageB)
for m in result.matches() { print(m.pointA, m.pointB, m.score) }
```
## Licenses
The files combine components under two permissive licenses:
| Component | Upstream | License |
|---|---|---|
| DaD detector | [Parskatt/dad](https://github.com/Parskatt/dad) | MIT |
| DeDoDe descriptor (VGG19 + refiners) | [Parskatt/DeDoDe](https://github.com/Parskatt/DeDoDe) | MIT |
| DINOv2 ViT-L/14 backbone | [facebookresearch/dinov2](https://github.com/facebookresearch/dinov2) | Apache-2.0 |
| LoMa matcher | [davnords/LoMa](https://github.com/davnords/LoMa) (derived from [LightGlue](https://github.com/cvg/LightGlue)) | Apache-2.0 |
| Everything else in LoMa | [davnords/LoMa](https://github.com/davnords/LoMa) | MIT |
See `LICENSE-MIT` (with the upstream copyright notices) and `LICENSE-APACHE`.
The models were trained by their authors on third-party datasets (e.g. MegaDepth), and the
VGG backbones were initialized from ImageNet-pretrained weights. Refer to the upstream papers
for data details and any dataset terms.
## Citation
If you use these weights, please cite the original works:
```bibtex
@inproceedings{nordstrom2026loma,
title={LoMa: Local Feature Matching Revisited},
author={David Nordström and Johan Edstedt and Georg Bökman and Jonathan Astermark and Anders Heyden and Viktor Larsson and Mårten Wadenbäck and Michael Felsberg and Fredrik Kahl},
booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},
year={2026}
}
@inproceedings{nordstrom2026who,
title={Who Handles Orientation? Investigating Invariance in Feature Matching},
author={David Nordström and Johan Edstedt and Georg Bökman and Fredrik Kahl},
booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR) Workshops},
year={2026}
}
@article{edstedt2025dad,
title={{DaD: Distilled Reinforcement Learning for Diverse Keypoint Detection}},
author={Edstedt, Johan and B{\"o}kman, Georg and Wadenb{\"a}ck, M{\aa}rten and Felsberg, Michael},
journal={arXiv preprint arXiv:2503.07347},
year={2025}
}
@inproceedings{edstedt2024dedode,
title={{DeDoDe: Detect, Don't Describe --- Describe, Don't Detect for Local Feature Matching}},
author={Johan Edstedt and Georg Bökman and Mårten Wadenbäck and Michael Felsberg},
booktitle={2024 International Conference on 3D Vision (3DV)},
year={2024},
organization={IEEE}
}
@misc{oquab2023dinov2,
title={DINOv2: Learning Robust Visual Features without Supervision},
author={Oquab, Maxime and Darcet, Timothée and Moutakanni, Theo and Vo, Huy V. and Szafraniec, Marc and Khalidov, Vasil and Fernandez, Pierre and Haziza, Daniel and Massa, Francisco and El-Nouby, Alaaeldin and Howes, Russell and Huang, Po-Yao and Xu, Hu and Sharma, Vasu and Li, Shang-Wen and Galuba, Wojciech and Rabbat, Mike and Assran, Mido and Ballas, Nicolas and Synnaeve, Gabriel and Misra, Ishan and Jegou, Herve and Mairal, Julien and Labatut, Patrick and Joulin, Armand and Bojanowski, Piotr},
journal={arXiv:2304.07193},
year={2023}
}
@inproceedings{lindenberger2023lightglue,
title={{LightGlue: Local Feature Matching at Light Speed}},
author={Philipp Lindenberger and Paul-Edouard Sarlin and Marc Pollefeys},
booktitle={ICCV},
year={2023}
}
```