|
1 | | -# OMEGA: One-Model Efficient Generalized Approximate Nearest Neighbor Search |
| 1 | +# OMEGA |
2 | 2 |
|
3 | | -OMEGA is an adaptive approximate nearest neighbor (ANN) search system that dynamically adjusts search effort per query with minimal preprocessing cost. It achieves significant speedups by using machine learning to predict when sufficient search has been performed to find top-K results with high confidence. |
| 3 | +Adaptive ANN search that learns when to stop searching. Train once on K=1, works for any K. |
4 | 4 |
|
5 | | ---- |
| 5 | +Built on HNSW + LightGBM. Adapts search effort per query instead of using fixed parameters for everything. |
6 | 6 |
|
7 | | -## What is OMEGA? |
| 7 | +## Installation |
8 | 8 |
|
9 | | -OMEGA is a K-generalizable learned vector search system built on top of the HNSW (Hierarchical Navigable Small World) algorithm. The key innovation is that **a single model trained on K=1** can generalize to any K value through iterative refinement and trajectory-based features. |
10 | | - |
11 | | -It combines: |
12 | | - |
13 | | -- **Python Frontend**: Built on the [big-ann-benchmarks](./README_Big_ANN_Benchmarks.md) framework for evaluation and orchestration |
14 | | -- **C++ Backend**: Modified [hnswlib](./hnswlib/) with adaptive search capabilities |
15 | | -- **Machine Learning**: LightGBM models to predict optimal stopping points during search |
16 | | - |
17 | | -The system learns from query patterns to adaptively determine when to stop searching, eliminating the need for manual parameter tuning while maintaining high recall. |
18 | | - |
19 | | ---- |
20 | | - |
21 | | -## What Problem Does It Solve? |
22 | | - |
23 | | -Traditional ANN search algorithms and learned search systems face two key challenges: |
24 | | - |
25 | | -### 1. Fixed Parameters Problem |
26 | | -Traditional algorithms use **fixed parameters** (like `ef` in HNSW) for all queries: |
27 | | -- **Easy queries** are over-searched, wasting computation |
28 | | -- **Hard queries** are under-searched, potentially missing relevant results |
29 | | -- **Manual tuning** is required for each dataset and recall target |
30 | | - |
31 | | -### 2. Multi-K Preprocessing Cost Problem |
32 | | -Existing learned search systems (like DARTH, LAET) require: |
33 | | -- **Training separate models for each K value** (K=1, K=10, K=100, etc.) |
34 | | -- **Expensive preprocessing** that can exceed 22% of serving cost in production |
35 | | -- **Poor generalization** across different K values |
36 | | - |
37 | | -OMEGA solves both problems by: |
38 | | -- **Adapting search effort per query** based on learned patterns |
39 | | -- **Using ONE model trained on K=1** that generalizes to all K values |
40 | | -- **Minimal preprocessing cost** (only train once for K=1) |
41 | | -- **Iterative refinement** that reduces top-K to K sequential top-1 problems |
42 | | - |
43 | | ---- |
44 | | - |
45 | | -## How Does It Work? |
46 | | - |
47 | | -OMEGA uses a **K-generalizable learning approach** with three key innovations: |
48 | | - |
49 | | -### 1. Trajectory-Based Features |
50 | | -Instead of query-specific features, OMEGA uses **distance variation patterns** during graph traversal: |
51 | | -- Distance to current candidate |
52 | | -- Distance changes over search trajectory |
53 | | -- Statistical properties of the candidate pool |
54 | | -- These features naturally generalize across K values through **masking** |
55 | | - |
56 | | -### 2. Iterative Refinement via Masking |
57 | | -OMEGA reduces top-K search to **K sequential top-1 problems**: |
58 | | -- Train a single binary classifier for K=1: "Has top-1 been found?" |
59 | | -- For K>1: Mask already-found results and repeat K times |
60 | | -- Each iteration uses the same K=1 model |
61 | | -- No need to train separate models for different K values |
62 | | - |
63 | | -### 3. Statistical Forecasting |
64 | | -To reduce model invocation overhead: |
65 | | -- Pre-profile probability tables during training |
66 | | -- Map recall targets to prediction intervals |
67 | | -- Use lookup tables for fast inference |
68 | | -- Only invoke model at strategic checkpoints |
69 | | - |
70 | | -### Training Phase |
71 | | - |
72 | | -1. **Collect Statistics**: Run sample queries (typically 4,000) with K=1 and collect: |
73 | | - - Distance to entry point |
74 | | - - Distances to nearest neighbors found so far |
75 | | - - Number of graph hops and distance comparisons |
76 | | - - Traversal window statistics |
77 | | - |
78 | | -2. **Train Model**: Use LightGBM to train a binary classifier: |
79 | | - - Input: 12 trajectory-based features |
80 | | - - Output: Probability that top-1 result has been found |
81 | | - - Model is trained only for K=1 |
82 | | - |
83 | | -3. **Generate Lookup Tables**: |
84 | | - - **Threshold table**: Maps model confidence scores to recall levels |
85 | | - - **Interval table**: Maps recall targets to prediction intervals |
86 | | - |
87 | | -### Inference Phase |
88 | | - |
89 | | -1. **Start Search**: Begin traversing the HNSW graph |
90 | | -2. **For each rank k from 1 to K**: |
91 | | - - Collect trajectory features |
92 | | - - Use K=1 model to predict if top-1 is found |
93 | | - - Stop when predicted recall target is reached |
94 | | - - Mask the found result |
95 | | - - Continue for next rank |
96 | | -3. **Return top-K results** |
97 | | - |
98 | | ---- |
99 | | - |
100 | | -## Prerequisites and Setup |
101 | | - |
102 | | -### System Requirements |
103 | | - |
104 | | -- **Operating System**: Linux |
105 | | -- **Conda**: Miniconda or Anaconda |
106 | | -- **C/C++ Compiler**: GCC/G++ with C++17 support |
107 | | -- **Sufficient disk space** for datasets |
108 | | - |
109 | | -### Installation |
110 | | - |
111 | | -#### 1) Create and Activate the Conda Environment |
112 | | - |
113 | | -Create the environment from `environment.yml`: |
| 9 | +**Requirements**: Linux, Conda, GCC with C++17 |
114 | 10 |
|
115 | 11 | ```bash |
| 12 | +# Setup environment |
116 | 13 | conda env create -f environment.yml |
117 | 14 | conda activate OMEGA |
118 | | -``` |
119 | | - |
120 | | -#### 2) Build Dependencies (HNSWLIB + OMEGA) |
121 | | - |
122 | | -Build required libraries and bindings: |
123 | 15 |
|
124 | | -```bash |
| 16 | +# Build |
125 | 17 | bash ./scripts/build_hnswlib.sh |
126 | | -``` |
127 | | - |
128 | | -#### 3) Download and Prepare Datasets |
129 | | - |
130 | | -Download and preprocess a dataset: |
131 | 18 |
|
132 | | -```bash |
| 19 | +# Download dataset |
133 | 20 | python create_dataset.py --dataset deep-100M |
134 | 21 | ``` |
135 | 22 |
|
136 | | -Replace `deep-100M` with other supported dataset names (e.g., `bigann-100M`, `gist-1M`). |
137 | | - |
138 | | ---- |
139 | | - |
140 | | -## How to Run OMEGA |
141 | | - |
142 | | -### Runbooks |
143 | | - |
144 | | -Pre-generated runbooks are located at `neurips23/runbooks/`. You can also generate runbooks manually: |
145 | | - |
146 | | -```bash |
147 | | -python bench_runbook_gen2.py |
148 | | -``` |
149 | | - |
150 | | -### End-to-End Evaluation |
151 | | - |
152 | | -Run the complete end-to-end evaluation: |
| 23 | +## Running Experiments |
153 | 24 |
|
154 | 25 | ```bash |
| 26 | +# Run full evaluation (OMEGA vs LAET/DARTH/Fixed-ef baselines) |
155 | 27 | bash ./scripts/eval_end2end.sh |
156 | | -``` |
157 | | - |
158 | | -This script evaluates **LAET**, **DARTH**, **OMEGA**, and **Fixed efSearch** baseline on the configured dataset/runbook(s), and produces metrics such as latency and recall. |
159 | | - |
160 | | -After `./scripts/eval_end2end.sh` finishes, you will see a per-dataset JSON result under `./plot/eval_end2end_results/` (e.g., `./plot/eval_end2end_results/deep-100M.json`). This file contains all metrics for all tested configurations/modes. |
161 | | - |
162 | | -### Understanding the Results |
163 | | - |
164 | | -#### What metrics are in the result JSON? |
165 | | - |
166 | | -The top-level JSON typically includes `microbench_results` and `end2end_results`. Each entry in `end2end_results` corresponds to one evaluated configuration and includes: |
167 | | - |
168 | | -- **recall**: Overall recall achieved under this configuration |
169 | | -- **recall_target**: The target recall (if applicable) for this run |
170 | | -- **recall_cdf**: The CDF of per-query recall (useful to see tail behavior / worst-case recall) |
171 | | -- **recall_groupby_count**: Recall broken down by count buckets |
172 | | -- **mean_latency**: Mean end-to-end query latency (typically in microseconds) |
173 | | -- **latency_cdf**: Latency CDF (for tail latency analysis) |
174 | | -- **latency_groupby_count**: Latency broken down by count buckets |
175 | | -- **mean_cmps**: Average number of comparisons per query |
176 | | -- **thpt**: Throughput (queries/second) for the run |
177 | | -- **prediction_times**: Time spent on model prediction |
178 | | -- **prediction_overhead**: Overhead attributed to prediction (if enabled) |
179 | | -- **run_latency / generate_latency / train_latency / total_preparation_latency**: A breakdown of preparation/training-related overheads |
180 | 28 |
|
181 | | -It also records run context fields such as `threads`, `num_queries`, `mode`, `train_counts`, `train_queries`, and `traversal_window_size`. |
182 | | - |
183 | | -### Plotting Results |
184 | | - |
185 | | -If you run the default `./scripts/eval_end2end.sh` to completion and then run: |
186 | | - |
187 | | -```bash |
| 29 | +# Plot results |
188 | 30 | python ./plot/eval_end2end.py |
189 | 31 | ``` |
190 | 32 |
|
191 | | -you will obtain visualizations showing a comparison of recall and search latency with different preprocessing time budgets. |
192 | | - |
193 | | ---- |
194 | | - |
195 | | -## Comparing with Baselines |
196 | | - |
197 | | -OMEGA is compared against: |
198 | | -- **Normal mode**: Fixed ef parameter (baseline) |
199 | | -- **LAET**: Learning-Augmented Early Termination |
200 | | -- **DARTH**: Dynamic Adaptive Recall Threshold Heuristic |
201 | | -- **Optimal**: Oracle with perfect knowledge (upper bound) |
202 | | - |
203 | | ---- |
204 | | - |
205 | | -## References and Credits |
206 | | - |
207 | | -### Related Work |
208 | | - |
209 | | -We have ported the following learned ANN search systems and compared OMEGA against them: |
210 | | - |
211 | | -- **LAET (Learned Adaptive Early Termination)** |
212 | | - Conglong Li, Minjia Zhang, David G. Andersen, Yuxiong He. |
213 | | - *"Improving Approximate Nearest Neighbor Search through Learned Adaptive Early Termination"* |
214 | | - SIGMOD Conference 2020, pages 2539-2554. |
215 | | - DOI: [10.1145/3318464.3380600](https://doi.org/10.1145/3318464.3380600) |
216 | | - |
217 | | -- **DARTH (Declarative Recall Through Early Termination)** |
218 | | - Manos Chatzakis, Yannis Papakonstantinou, Themis Palpanas. |
219 | | - *"DARTH: Declarative Recall Through Early Termination for Approximate Nearest Neighbor Search"* |
220 | | - Proceedings of the ACM on Management of Data (PACMMOD), 3(4), Article 242, 2025. |
221 | | - DOI: [10.1145/3749160](https://doi.org/10.1145/3749160) |
222 | | - |
223 | | -### Original Projects |
224 | | - |
225 | | -This project builds upon: |
226 | | - |
227 | | -- **Big ANN Benchmarks**: See [README_Big_ANN_Benchmarks.md](./README_Big_ANN_Benchmarks.md) for the original benchmark framework |
228 | | - - Original project: [ann-benchmarks](https://github.com/erikbern/ann-benchmarks) by Erik Bernhardsson |
229 | | - - NeurIPS competitions: [big-ann-benchmarks.com](http://big-ann-benchmarks.com/) |
230 | | - |
231 | | -- **hnswlib**: Fast approximate nearest neighbor search library |
232 | | - - GitHub: [nmslib/hnswlib](https://github.com/nmslib/hnswlib) |
| 33 | +Results are saved to `./plot/eval_end2end_results/` as JSON files with recall, latency, and throughput metrics. |
233 | 34 |
|
234 | | -- **LightGBM**: Gradient boosting framework |
235 | | - - GitHub: [microsoft/LightGBM](https://github.com/microsoft/LightGBM) |
| 35 | +## References |
236 | 36 |
|
237 | | -### License |
| 37 | +Built on [big-ann-benchmarks](./README_Big_ANN_Benchmarks.md), [hnswlib](https://github.com/nmslib/hnswlib), and [LightGBM](https://github.com/microsoft/LightGBM). |
238 | 38 |
|
239 | | -This project respects the licenses of all incorporated components. See individual project directories for specific license information. |
| 39 | +Baselines implemented: [LAET](https://doi.org/10.1145/3318464.3380600) (SIGMOD'20), [DARTH](https://doi.org/10.1145/3749160) (PACMMOD'25). |
0 commit comments