Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 120 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,133 @@

Implementation details are provided in our [technical note](Technical_Details_of_V3DB.pdf).

## Environment Setup

All commands below assume the conda environment `V3DB` (Python 3.11) and a Rust nightly toolchain (`rust-toolchain.toml`).

```bash
conda activate V3DB

# Python dependencies
pip install -r requirements.txt
# or manually:
# pip install maturin numpy tqdm scipy scikit-learn matplotlib duckdb faiss-cpu
# pip install fastapi "uvicorn[standard]" # only for the interactive demo

# MS MARCO embedding generation additionally requires:
# pip install torch transformers
```

Notes:

- `faiss-cpu` is the default. If a GPU build matching your GPU architecture is available you may use `faiss-gpu-cu12` instead — `ivf_pq/util/kmeans.py` auto-detects whether GPU kernels actually run and falls back to CPU.
- Some scripts use `python -m <module>` (e.g. `python -m tests.pipeline`). Running them as `python tests/pipeline.py` will fail with `ModuleNotFoundError` because the project root is not on `sys.path` in that mode.

## Build

Build and install the Python extension:
Build and install the Python extension (requires Rust nightly):

```bash
maturin develop --release
```

This installs the extension as `zk_IVF_PQ.zk_IVF_PQ`, matching the import path `from zk_IVF_PQ.zk_IVF_PQ import ...` used throughout the codebase.

## Interactive Demo (White Theme)

A white-themed, fully local (no external CDN) interactive web demo that compares **Standard IVF-PQ**, **ZK IVF-PQ**, and **Brute-force Ground Truth** side-by-side and can generate set-based + Merkle ZK proofs via the Rust extension.

### Datasets

The demo auto-discovers datasets under `data/`:

| Name | Directory | Content | Size on disk |
|------|-----------|---------|--------------|
| SIFT small | `data/siftsmall/` | 10k × 128 dim | ~5 MB |
| SIFT1M | `data/sift/` | 1M × 128 dim | ~550 MB |
| GIST1M | `data/gist/` | 1M × 960 dim | ~5.4 GB |

If missing, download and extract them from `ftp://ftp.irisa.fr/local/texmex/corpus/`:

```bash
cd data
wget ftp://ftp.irisa.fr/local/texmex/corpus/sift.tar.gz && tar xzf sift.tar.gz
wget ftp://ftp.irisa.fr/local/texmex/corpus/gist.tar.gz && tar xzf gist.tar.gz
wget ftp://ftp.irisa.fr/local/texmex/corpus/siftsmall.tar.gz && tar xzf siftsmall.tar.gz
```

The GIST1M archive is ~2.7 GB compressed. `data/siftsmall` is sufficient for a quick smoke test; SIFT1M and GIST1M are optional.

### Start

```bash
conda activate V3DB
cd /home/huhaoran/V3DB

# foreground (logs to terminal)
python -m demo.server # default 0.0.0.0:8000
python -m demo.server 8080 # custom port

# background (logs to /tmp/demo.log)
nohup python -m demo.server > /tmp/demo.log 2>&1 &
tail -f /tmp/demo.log
```

Then open `http://127.0.0.1:8000` in a browser.

On first use of a dataset the backend builds and caches models under `data/demo_cache/{name}_{std,zk,proof,pca}.npz`:

- Standard IVF-PQ (`ivf_pq/standard.py`)
- ZK integer version (`rescale_database` + `cluster_bound` rebalance + Merkle commitments in `ivf_pq/merkle_zk.py`)
- 2D PCA projection for visualization

Build must run from the **project root** (`/home/huhaoran/V3DB`) so that `python -m demo.server` resolves the `demo` package. Subsequent launches load the cache in seconds and render all three datasets as `ready`.

GIST1M (960 dim, 512 clusters + 8×256 PQ codebooks) takes ~30–40 minutes to build on CPU — the status badge polls `GET /api/status/gist` and the log shows Faiss iteration progress.

### Stop

```bash
pkill -f "demo.server"
# or, if started with nohup:
pkill -9 -f "demo.server"
```

Check whether it is still running:

```bash
curl -s http://127.0.0.1:8000/api/datasets | python3 -m json.tool
# or
ps aux | grep demo.server | grep -v grep
```

### How to use

1. Select a dataset on the left (status badges: `ready` / `building` / `idle`). The first build is triggered automatically.
2. Adjust `query id`, `n_probe` (1–64), `top_k` (5–100), and optionally enable **Generate and verify ZK proof** (set-based + Merkle, backed by the Rust extension; proving takes seconds to tens of seconds).
3. Click **Search** — the right pane shows 6 metric cards (forced to a single row), PCA scatter, latency/recall/cluster-size charts, and a three-column comparison table with hit badges.

API health check:

```bash
curl -s http://127.0.0.1:8000/api/datasets | python3 -m json.tool
curl -s http://127.0.0.1:8000/api/status/gist
curl -s -X POST http://127.0.0.1:8000/api/search \
-H "Content-Type: application/json" \
-d '{"dataset":"siftsmall","query_id":0,"n_probe":8,"top_k":10,"proof":false}' | python3 -m json.tool
```

Demo file layout:

```
demo/
server.py # FastAPI backend (lazy loading, model cache, search + proof API)
static/
index.html # page skeleton
style.css # white theme (no external deps)
app.js # frontend logic, pure Canvas charts (no external deps)
```

## Experiment 1: Retrieval Utility Evaluation

### Classic ANN (SIFT1M / GIST1M)
Expand Down
Empty file added demo/__init__.py
Empty file.
Loading