Realcat commited on
Commit
ac5bcb0
·
verified ·
1 Parent(s): 88774af

Update benchmark with full 6-model comparison

Browse files
Files changed (1) hide show
  1. megaloc/README.md +87 -46
megaloc/README.md CHANGED
@@ -1,80 +1,121 @@
1
- # MegaLoc Quantized Models
 
2
 
3
- Quantized ONNX and CoreML models for [MegaLoc](https://arxiv.org/abs/2502.17237) SOTA visual place recognition.
4
 
5
- ## Directory
 
6
 
 
 
 
 
 
7
  ```
8
- megaloc/
9
- ├── onnx/ # ONNX models (cross-platform)
10
- │ ├── megaloc.onnx # FP32 (873 MB, batch=1)
11
- │ ├── megaloc_fp16.onnx # FP16 (437 MB, dynamic batch)
12
- │ └── megaloc_int8.onnx # INT8 (223 MB, batch=1)
13
- └── coreml/ # CoreML models (macOS / Apple Silicon, all multi-batch)
14
- ├── megaloc_coreml_fp32.mlpackage # FP32 (873 MB)
15
- ├── megaloc_coreml_fp16.mlpackage # FP16 (437 MB)
16
- └── megaloc_coreml_int8.mlpackage # INT8 (219 MB)
17
  ```
18
 
19
- ## Benchmark (MacBook Pro M-series, 518×518 input)
20
 
21
- ### ONNX (CPU)
 
22
 
23
- | Model | Size | CosSim | B=1 | B=2 | B=4 | B=8 |
24
- |-------|------|--------|-----|-----|-----|-----|
25
- | FP32 | 873 MB | 1.000000 | 399ms / 2.5fps | 872ms / 2.3fps | 1514ms / 2.6fps | 2699ms / 3.0fps |
26
- | FP16 | 437 MB | 0.999989 | 400ms / 2.5fps | 850ms / 2.4fps | 1602ms / 2.5fps | 2876ms / 2.8fps |
27
- | INT8 | 223 MB | 0.996453 | 475ms / 2.1fps | — | — | — |
28
 
29
- FP16 is near-lossless at all batch sizes. INT8 preserves Recall@1 = 100% in retrieval tasks.
30
 
31
- ### CoreML (Apple Silicon GPU, multi-batch)
32
 
33
- | Model | Size | CosSim | B=1 latency | Notes |
34
- |-------|------|--------|-------------|-------|
35
- | FP32 | 873 MB | 1.000000 | ~74ms / 13fps | RangeDim(1,16) dynamic batch |
36
- | FP16 | 437 MB | TBD | TBD | RangeDim(1,16) dynamic batch |
37
- | INT8 | 219 MB | TBD | TBD | RangeDim(1,16) dynamic batch |
38
 
39
- CoreML is ~5× faster than ONNX Runtime (GPU vs CPU). All CoreML models support dynamic batch via `RangeDim(1, 16)`.
40
 
41
- ## Usage
42
 
43
- ### ONNX
 
 
 
 
 
44
 
45
- ```python
46
- import onnxruntime as ort, numpy as np
47
- from PIL import Image
48
 
49
- sess = ort.InferenceSession('megaloc_fp16.onnx', providers=['CPUExecutionProvider'])
 
 
 
 
 
 
 
50
 
51
- img = Image.open('image.jpg').convert('RGB').resize((518, 518), Image.LANCZOS)
52
- data = np.expand_dims(np.array(img).astype(np.float32).transpose(2,0,1)/255.0, 0)
53
 
54
- descriptor = sess.run(None, {'images': data})[0] # [B, 8448]
55
- ```
56
 
57
- ### CoreML (macOS only)
 
 
 
 
58
 
59
- ```python
60
- import coremltools as ct, numpy as np
61
- from PIL import Image
 
 
 
 
 
 
62
 
63
- model = ct.models.MLModel('megaloc_coreml_fp16.mlpackage')
64
 
65
- img = Image.open('image.jpg').convert('RGB').resize((518, 518), Image.LANCZOS)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  data = np.expand_dims(np.array(img).astype(np.float32).transpose(2,0,1)/255.0, 0)
 
 
 
67
 
68
- descriptor = list(model.predict({'images': data}).values())[0] # [B, 8448]
 
 
 
 
 
69
  ```
70
 
71
- ## Reference
 
 
72
 
 
73
  ```bibtex
74
  @inproceedings{Berton_2025_MegaLoc,
75
  author = {Berton, Gabriele and Masone, Carlo},
76
  title = {MegaLoc: One Retrieval to Place Them All},
77
- booktitle = {CVPR Workshops},
 
78
  year = {2025},
 
79
  }
80
  ```
 
 
1
+ # MegaLoc
2
+ An image retrieval model for any localization task, which achieves SOTA on most VPR datasets, including indoor and outdoor ones.
3
 
4
+ [Gradio Demo](https://gmberton.github.io/demos-url/megaloc/) - [ArXiv](https://arxiv.org/abs/2502.17237) - [Paper on ArXiv](https://arxiv.org/pdf/2502.17237) - [Paper on HF](https://huggingface.co/papers/2502.17237) - [Model on HF](https://huggingface.co/gberton/MegaLoc).
5
 
6
+ ### Demo
7
+ Try the demo on your own images to see how good MegaLoc is! The demo uses a database of ~5M street-view images from San Francisco, and when you upload one it will find the most similar one from the same place.
8
 
9
+ <img width="746" height="576" alt="image" src="https://github.com/user-attachments/assets/4e7a3eec-dfee-4aae-83cc-f5146a1b421d" />
10
+
11
+
12
+ ### Using the model
13
+ You can use the model with torch.hub, as simple as this
14
  ```
15
+ import torch
16
+ model = torch.hub.load("gmberton/MegaLoc", "get_trained_model")
 
 
 
 
 
 
 
17
  ```
18
 
19
+ For more complex uses, like computing results on VPR datasets, visualizing predictions and so on, you can use our [VPR-methods-evaluation](https://github.com/gmberton/VPR-methods-evaluation), which lets you do all this for MegaLoc and multiple other VPR methods on labelled or unlabelled datasets.
20
 
21
+ ### Qualitative examples
22
+ Here are some examples of top-1 retrieved images from the SF-XL test set, which has 2.8M images as database.
23
 
24
+ ![teaser](https://github.com/user-attachments/assets/a90b8d4c-ab53-4151-aacc-93493d583713)
 
 
 
 
25
 
 
26
 
 
27
 
28
+ ---
 
 
 
 
29
 
30
+ ## Available Models
31
 
32
+ Pre-quantized models on HuggingFace: [Realcat/image_retrieval_checkpoints](https://huggingface.co/Realcat/image_retrieval_checkpoints)
33
 
34
+ ```bash
35
+ # ONNX
36
+ huggingface-cli download Realcat/image_retrieval_checkpoints --include "megaloc/onnx/*" --local-dir .
37
+ # CoreML
38
+ huggingface-cli download Realcat/image_retrieval_checkpoints --include "megaloc/coreml/*" --local-dir .
39
+ ```
40
 
41
+ ### Benchmark (MacBook Pro M-series, 518×518, B=1 vs PyTorch FP32)
 
 
42
 
43
+ | Model | Size | CosSim | SNR | Latency | FPS | Multi-Batch |
44
+ |-------|------|--------|-----|---------|-----|-------------|
45
+ | **PyTorch FP32** | (mem) | 1.000000 | ∞ | 367 ms | 2.7 | — |
46
+ | ONNX FP32 | 873 MB | 1.000000 | 80.5 dB | 367 ms | 2.7 | **Y** |
47
+ | ONNX FP16 | 437 MB | 0.999989 | 46.4 dB | 345 ms | 2.9 | **Y** |
48
+ | ONNX INT8 | 223 MB | 0.996625 | 21.7 dB | 395 ms | 2.5 | **Y** |
49
+ | CoreML FP32 | 873 MB | 1.000000 | 80.5 dB | **74 ms** | **13.6** | N |
50
+ | CoreML INT8 | 219 MB | 0.998699 | 25.8 dB | **74 ms** | **13.5** | N |
51
 
52
+ > CoreML FP16 excluded due to poor accuracy (cos=0.944, SNR=9.5dB). CoreML's FP16 path uses half-precision for all intermediate activations, causing error accumulation in this deep ViT.
 
53
 
54
+ ### ONNX Multi-Batch Throughput
 
55
 
56
+ | Model | B=1 | B=2 | B=4 | B=8 |
57
+ |-------|-----|-----|-----|-----|
58
+ | ONNX FP32 | 2.7 img/s | 2.3 img/s | 2.7 img/s | 2.9 img/s |
59
+ | ONNX FP16 | 2.9 img/s | 2.6 img/s | 2.7 img/s | 2.9 img/s |
60
+ | ONNX INT8 | 2.5 img/s | 2.1 img/s | 2.3 img/s | 2.5 img/s |
61
 
62
+ ### Recommendations
63
+
64
+ - **Best accuracy/size**: CoreML INT8 — 219 MB, 74ms, cos=0.9987, 13.5 FPS (macOS only)
65
+ - **Cross-platform**: ONNX FP16 — 437 MB, 345ms, cos=0.99999, multi-batch
66
+ - **Maximum compression**: ONNX INT8 — 223 MB, all platforms, multi-batch
67
+
68
+ ### On sub-8-bit quantization
69
+
70
+ 4-bit/1-bit quantization fails catastrophically (cos_sim ≈ 0). DINOv2 ViT has 12 blocks + aggregator (~200 weight tensors). Error from only 16 levels accumulates across 48+ MatMul layers. ViT architectures below 8-bit require **quantization-aware training**.
71
 
72
+ ### Usage
73
 
74
+ ```bash
75
+ uv sync
76
+
77
+ # ONNX (cross-platform, multi-batch)
78
+ python3 -c "
79
+ import onnxruntime as ort, numpy as np
80
+ from PIL import Image
81
+ sess = ort.InferenceSession('megaloc_fp16.onnx', providers=['CPUExecutionProvider'])
82
+ img = Image.open('img.jpg').convert('RGB').resize((518,518), Image.LANCZOS)
83
+ data = np.expand_dims(np.array(img).astype(np.float32).transpose(2,0,1)/255.0, 0)
84
+ desc = sess.run(None, {'images': data})[0] # [B, 8448]
85
+ "
86
+
87
+ # CoreML (macOS, 5x faster)
88
+ python3 -c "
89
+ import coremltools as ct, numpy as np
90
+ from PIL import Image
91
+ model = ct.models.MLModel('megaloc_coreml_int8.mlpackage')
92
+ img = Image.open('img.jpg').convert('RGB').resize((518,518), Image.LANCZOS)
93
  data = np.expand_dims(np.array(img).astype(np.float32).transpose(2,0,1)/255.0, 0)
94
+ desc = list(model.predict({'images': data}).values())[0]
95
+ "
96
+ ```
97
 
98
+ ### Reproduce
99
+
100
+ ```bash
101
+ uv run python export_onnx_batch.py # ONNX multi-batch
102
+ uv run python quantize_megaloc.py --method 8bit --input megaloc_fp32.onnx # ONNX INT8
103
+ uv run python convert_coreml.py # CoreML FP32/FP16/INT8
104
  ```
105
 
106
+ ---
107
+
108
+ ## Acknowledgements / Cite / BibTex
109
 
110
+ If you use this repository please cite the following
111
  ```bibtex
112
  @inproceedings{Berton_2025_MegaLoc,
113
  author = {Berton, Gabriele and Masone, Carlo},
114
  title = {MegaLoc: One Retrieval to Place Them All},
115
+ booktitle = {IEEE/CVF Conference on Computer Vision and Pattern Recognition Workshops},
116
+ month = {June},
117
  year = {2025},
118
+ pages = {2886--2892}
119
  }
120
  ```
121
+