|
| 1 | +# DEG Sliding Window Benchmark (CleANN Paper Baseline Reproduction) |
| 2 | + |
| 3 | +This example reproduces the **Sliding Window Batched Update** baseline experiment evaluated against the Dynamic Exploration Graph (DEG) in the **CleANN** paper: |
| 4 | +> **"CleANN: Efficient Full Dynamism in Graph-based Approximate Nearest Neighbor Search"** |
| 5 | +> *Ziyu Zhang, Yuanhao Wei, Joshua Engels, Julian Shun (MIT CSAIL)* |
| 6 | +> [arXiv:2507.19802v1](https://arxiv.org/abs/2507.19802v1) |
| 7 | +
|
| 8 | +--- |
| 9 | + |
| 10 | +## Paper Benchmark Mapping |
| 11 | + |
| 12 | +| Benchmark Aspect | CleANN Paper Specification | Reproduction in this Example | |
| 13 | +|---|---|---| |
| 14 | +| **Section** | Section 6.1 (*Setup*), Section 6.2.3 (*Sequential Baseline Comparison*) | Implemented in [`main.py`](./main.py) | |
| 15 | +| **Dataset** | **RedCaps-512** (512D CLIP image-text embeddings with distribution drift) | Downloaded automatically from Zenodo: [`redcaps-512-angular.hdf5`](https://zenodo.org/records/13137120) | |
| 16 | +| **Window Size ($N$)** | $500{,}000$ active vectors | `--window-size 500000` (default) | |
| 17 | +| **Streaming Updates** | 100 rounds of $5{,}000$ inserts & $5{,}000$ deletes (1% of window) | `--rounds 100 --batch-size 5000` | |
| 18 | +| **DEG Deletion Strategy** | Dynamic on-the-fly edge repair upon `remove_entry` | Performed automatically by `deglib.builder.GraphBuilder` | |
| 19 | +| **Query Evaluation** | 800 test queries, $k = 10$, $\varepsilon = 0.03$ | `--num-queries 800 --search-k 10 --search-eps 0.03` | |
| 20 | +| **Execution Mode** | Single-threaded execution (1 thread) | `builder.set_thread_count(1)` & `threads=1` | |
| 21 | +| **Target Figures** | **Figure 20** (Recall 10@10) & **Figure 21** (Single-thread Throughput) | Saved to `sliding_window_benchmark.png` | |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +## How It Works |
| 26 | + |
| 27 | +1. **Initial Index Build:** |
| 28 | + * Loads the first $N = 500{,}000$ vectors from the RedCaps dataset. |
| 29 | + * Populates a mutable `DynamicExplorationGraph` using `OptimizationTarget.StreamingData`. |
| 30 | +2. **100 Sliding Window Update Rounds:** |
| 31 | + * **Insert Batch:** Queues $M = 5{,}000$ new incoming vectors via `builder.add_entry()`. |
| 32 | + * **Delete Batch:** Queues $M = 5{,}000$ oldest active vectors via `builder.remove_entry()`. |
| 33 | + * **Build / Repair:** Calls `builder.build()`. DEG automatically heals and updates local graph connectivity around deleted vertices. |
| 34 | + * **Ground Truth Computation:** Computes exact brute-force Top-10 nearest neighbors for the 800 test queries over the currently active $500{,}000$ vectors. |
| 35 | + * **Query Benchmark:** Executes DEG search with exploration $\varepsilon = 0.03$, measuring Recall@10, single-thread Search QPS/latency, and Update throughput (updates/ms). |
| 36 | +3. **Visual Summary:** |
| 37 | + * Generates a dual-panel plot reproducing Figure 20 (Recall@10 over rounds) and Figure 21 (Throughput). |
| 38 | + |
| 39 | +--- |
| 40 | + |
| 41 | +## Quick Start |
| 42 | + |
| 43 | +### 1. Environment Setup |
| 44 | + |
| 45 | +```bash |
| 46 | +cd examples/sliding_window |
| 47 | +uv sync |
| 48 | +``` |
| 49 | + |
| 50 | +### 2. Run Full Paper Benchmark (500k Vectors, 100 Rounds, RedCaps) |
| 51 | + |
| 52 | +```bash |
| 53 | +uv run main.py --dataset redcaps --window-size 500000 --rounds 100 --search-eps 0.03 --search-k 10 |
| 54 | +``` |
| 55 | +*(On first execution, `redcaps-512-angular.hdf5` will be downloaded automatically from Zenodo to your cache directory).* |
| 56 | + |
| 57 | +### 3. Run a Fast Test Run (Smaller Window / Fewer Rounds) |
| 58 | + |
| 59 | +```bash |
| 60 | +uv run main.py --dataset redcaps --window-size 50000 --rounds 10 |
| 61 | +``` |
| 62 | + |
| 63 | +--- |
| 64 | + |
| 65 | +## CLI Options |
| 66 | + |
| 67 | +| Argument | Type | Default | Description | |
| 68 | +|---|---|---|---| |
| 69 | +| `--dataset` | `str` | `redcaps` | Benchmark dataset (`redcaps`, `sift1m`, `glove`, `deep1m`, or `custom`). | |
| 70 | +| `--window-size` | `int` | `500000` | Number of active vectors maintained in the sliding window ($N$). | |
| 71 | +| `--batch-size` | `int` | `5000` | Number of vectors inserted & deleted per round (CleANN paper: 5,000). | |
| 72 | +| `--rounds` | `int` | `100` | Number of sliding window update rounds (paper: 100). | |
| 73 | +| `--search-eps` | `float` | `0.03` | DEG search exploration $\varepsilon$ (paper: 0.03). | |
| 74 | +| `--search-k` | `int` | `10` | Top-$k$ nearest neighbors to evaluate (paper: 10). | |
| 75 | +| `--num-queries` | `int` | `800` | Number of test queries to evaluate per round. | |
| 76 | +| `--edges-per-vertex` | `int` | `32` | DEG graph out-degree bound ($k$). | |
| 77 | +| `--no-show` | `flag` | `False` | Disable interactive GUI plot display. | |
| 78 | +| `--save-plot` | `str` | `sliding_window_benchmark.png` | Output path for result curves. | |
| 79 | + |
| 80 | +--- |
| 81 | + |
| 82 | +## References |
| 83 | + |
| 84 | +* **CleANN Paper:** Zhang et al., *"CleANN: Efficient Full Dynamism in Graph-based Approximate Nearest Neighbor Search"*, arXiv:2507.19802v1, 2025. |
| 85 | +* **RedCaps Dataset on Zenodo:** [https://zenodo.org/records/13137120](https://zenodo.org/records/13137120) |
| 86 | +* **CleANN Code Repository:** [https://github.com/SylviaZiyuZhang/CleANN](https://github.com/SylviaZiyuZhang/CleANN) |
0 commit comments