From b7f7aad2c719da3c2222657814d3d1207cf865fd Mon Sep 17 00:00:00 2001 From: Devasena Inupakutika Date: Fri, 3 Jul 2026 21:14:18 -0500 Subject: [PATCH 1/2] fix(#590): use snake_case DiskANN build params so max_degree/search_list_size are applied + README updates based on mlpstorage cli changes (pulled from PR #588) --- mlpstorage_py/cli/vectordb_args.py | 4 +- vdb_benchmark/README.md | 601 +++++++++--------- .../benchmark/backends/milvus/README.md | 9 +- .../benchmark/backends/milvus/__init__.py | 4 +- .../benchmark/backends/milvus/backend.py | 9 +- .../benchmark/configs/1m_diskann.yaml | 4 +- vdb_benchmark/vdbbench/load_vdb.py | 11 +- vdb_benchmark/vdbbench/mpi_wrapper.py | 6 +- 8 files changed, 340 insertions(+), 308 deletions(-) diff --git a/mlpstorage_py/cli/vectordb_args.py b/mlpstorage_py/cli/vectordb_args.py index 165a58b3..77536c0b 100644 --- a/mlpstorage_py/cli/vectordb_args.py +++ b/mlpstorage_py/cli/vectordb_args.py @@ -509,13 +509,13 @@ def _add_vectordb_open_args(parser, command): '--max-degree', type=int, default=16, - help="DiskANN MaxDegree parameter.", + help="DiskANN max_degree build parameter.", ) parser.add_argument( '--search-list-size', type=int, default=200, - help="DiskANN SearchListSize parameter.", + help="DiskANN search_list_size build parameter.", ) # HNSW parameters. parser.add_argument( diff --git a/vdb_benchmark/README.md b/vdb_benchmark/README.md index 9768ac5a..9ea7892c 100644 --- a/vdb_benchmark/README.md +++ b/vdb_benchmark/README.md @@ -1,18 +1,17 @@ # Vector Database Benchmark Tool -Benchmarks and compares vector database performance for MLPerf Storage. Currently -supports Milvus with DiskANN, HNSW, AISAQ, FLAT, and IVF-style indexes. +Benchmarks and compares vector database performance for MLPerf Storage. Currently supports Milvus with DiskANN, HNSW, AISAQ, FLAT, and IVF-style indexes. The benchmark can be run in two ways: 1. Directly with the scripts in `vdb_benchmark/vdbbench/` -2. Through the MLPerf Storage CLI with `./mlpstorage vectordb` +2. Through the MLPerf Storage CLI with `./mlpstorage vectordb` The `mlpstorage` path is recommended for standard benchmark workflows. > The modular backend-agnostic runner is currently a standalone preview. > It is invoked with `python -m vdbbench.benchmark`. -> The existing `./mlpstorage vectordb` command continues to use the Milvus-oriented scripts until the modular runner is integrated. +> The existing `./mlpstorage vectordb` command continues to use the Milvus-oriented scripts until the modular runner is integrated. --- @@ -81,8 +80,8 @@ The `mlpstorage` path is recommended for standard benchmark workflows. | `pyyaml` | ≥ 6.0 | YAML config support | | `tabulate` | ≥ 0.9.0 | Collection info table display | -The `datasize` command does not require Milvus or `pymilvus`. Load and run -commands require a running Milvus server. +The `datasize` command does not require Milvus or `pymilvus`. +Load and run commands require a running Milvus server. ### Clone the Repository @@ -95,9 +94,7 @@ cd storage ## 2. Deploy Milvus -A running Milvus instance is required for all load (`datagen`) and benchmark -(`run`) commands. This section applies to both the mlpstorage CLI and direct -script paths. +A running Milvus instance is required for all load (`datagen`) and benchmark (`run`) commands. This section applies to both the mlpstorage CLI and direct script paths. Standalone Milvus stacks are available in the `vdb_benchmark/stacks` directory: @@ -114,8 +111,7 @@ vdb_benchmark/stacks/ └── docker-compose-s3.yml ``` -For each specific instance, copy the `.env.example` file to `.env` and update -the values as needed. +For each specific instance, copy the `.env.example` file to `.env` and update the values as needed. ### Option A: Local Storage with MinIO @@ -124,9 +120,7 @@ cp vdb_benchmark/stacks/milvus/standalone/minio/.env.example \ vdb_benchmark/stacks/milvus/standalone/minio/.env ``` -The compose file uses `/mnt/vdb` as the root directory for Docker volumes. Set -`DOCKER_VOLUME_DIRECTORY` in the `.env` file or edit the compose file to point to -your target storage location. +The compose file uses `/mnt/vdb` as the root directory for Docker volumes. Set `DOCKER_VOLUME_DIRECTORY` in the `.env` file or edit the compose file to point to your target storage location. The stack creates three containers: @@ -173,8 +167,7 @@ docker-compose -f vdb_benchmark/stacks/milvus/standalone/s3/docker-compose-s3.ym docker ps -a ``` -All three containers (`milvus-etcd`, `milvus-minio`, `milvus-standalone`) should -show healthy/running. +All three containers (`milvus-etcd`, `milvus-minio`, `milvus-standalone`) should show healthy/running. The default Milvus endpoint is: @@ -184,10 +177,9 @@ The default Milvus endpoint is: --- -## 3. Quick Start +## 3. Quick Start — First Benchmark in 10 Minutes -This section gets you from zero to a working benchmark result on a standalone-system. -Assumes Milvus is set up as per section #2 instructions. +This section gets you from zero to a working benchmark result on a standalone-system. Assumes Milvus is set up as per section #2 instructions. ### Step 1 — Install @@ -200,7 +192,7 @@ uv pip install -e ./vdb_benchmark Verify: ```bash -./mlpstorage vectordb --help +./mlpstorage open vectordb --help ``` ### Step 2 — Start Milvus @@ -218,15 +210,22 @@ Wait for healthy status: docker ps -a ``` -All three containers (`milvus-etcd`, `milvus-minio`, `milvus-standalone`) should -show healthy/running. The default endpoint is `127.0.0.1:19530`. +All three containers (`milvus-etcd`, `milvus-minio`, `milvus-standalone`) should show healthy/running. -### Step 3 — Load 50K vectors (smoke test) +The default endpoint is `127.0.0.1:19530`. + +### Step 3 — Initialize the results directory + +```bash +./mlpstorage init MLCommons /tmp/vdb_results +``` + +### Step 4 — Load 50K vectors (smoke test) ```bash -./mlpstorage vectordb datagen \ - --file \ - --open \ +./mlpstorage open vectordb datagen file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ @@ -235,27 +234,29 @@ show healthy/running. The default endpoint is `127.0.0.1:19530`. --dimension 1536 \ --num-shards 1 \ --force \ + --systemname vdb_smoke_system \ --results-dir /tmp/vdb_results ``` -### Step 4 — Run a 30-second benchmark +### Step 5 — Run a 30-second benchmark ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ --collection mlps_smoke \ - --mode timed \ + --benchmark-mode timed \ --runtime 30 \ --num-query-processes 2 \ --batch-size 10 \ + --systemname vdb_smoke_system \ --results-dir /tmp/vdb_results ``` -### Step 5 — Check results +### Step 6 — Check results ```bash python - <<'PY' @@ -263,10 +264,11 @@ import json from pathlib import Path stats_files = sorted( - Path("/tmp/vdb_results").glob("**/vectordb/simple/statistics.json") + Path("/tmp/vdb_results").glob( + "**/vector_database/milvus/DISKANN/run/**/statistics.json" + ) ) assert stats_files, "No statistics.json found" - stats = json.loads(stats_files[-1].read_text()) print(f"Throughput: {stats['throughput_qps']:.1f} QPS") print(f"P95 latency: {stats['p95_latency_ms']:.2f} ms") @@ -274,15 +276,15 @@ print(f"Total queries: {stats['total_queries']}") PY ``` -If you see QPS and latency numbers, your setup is working. Continue to -[Section 4](#4-recommended-path-mlpstorage-cli) for full documentation. +If you see QPS and latency numbers, your setup is working. + +Continue to [Section 4](#4-recommended-path-mlpstorage-cli) for full documentation. --- ## 4. Recommended Path: mlpstorage CLI -This section covers the complete workflow using the `mlpstorage` CLI. This is the -recommended approach for standard benchmark workflows. +This section covers the complete workflow using the `mlpstorage` CLI. This is the recommended approach for standard benchmark workflows. ### 4.1 Installation @@ -301,10 +303,18 @@ uv pip install -e ./vdb_benchmark This makes the following commands available: ```bash -./mlpstorage vectordb --help -./mlpstorage vectordb datasize --help -./mlpstorage vectordb datagen --help -./mlpstorage vectordb run --help +./mlpstorage open vectordb --help +./mlpstorage open vectordb datasize --help +./mlpstorage open vectordb datagen --help +./mlpstorage open vectordb run --help +./mlpstorage closed vectordb run --help +./mlpstorage whatif vectordb run --help +``` + +Before running commands that write benchmark output, initialize the results directory once: + +```bash +./mlpstorage init MLCommons /tmp/vdb_results ``` The distributed VectorDB launcher additionally provides: @@ -327,16 +337,14 @@ uv run vdb-aggregate --help ### 4.2 Estimate Storage (datasize) -This step is optional. It is pure math and does not require a running Milvus -instance. +This step is optional. It is pure math and does not require a running Milvus instance. ```bash -./mlpstorage vectordb datasize \ - --file \ - --open \ +./mlpstorage open vectordb datasize \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --dimension 1536 \ --num-vectors 10000000 \ - --index-type DISKANN \ --num-shards 10 ``` @@ -357,37 +365,39 @@ Estimated total: 798.72 GB #### Load using the default config (1M vectors) ```bash -./mlpstorage vectordb datagen \ - --file \ - --open \ +./mlpstorage open vectordb datagen file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ --force \ + --systemname vdb_system \ --results-dir /tmp/vdb_results ``` #### Load using the 10M config ```bash -./mlpstorage vectordb datagen \ - --file \ - --open \ +./mlpstorage open vectordb datagen file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config 10m \ --collection mlps_10m_1536dim_uniform_diskann \ --force \ + --systemname vdb_system \ --results-dir /tmp/vdb_results ``` #### Override vector count for quick testing ```bash -./mlpstorage vectordb datagen \ - --file \ - --open \ +./mlpstorage open vectordb datagen file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ @@ -396,27 +406,23 @@ Estimated total: 798.72 GB --dimension 1536 \ --num-shards 1 \ --force \ + --systemname vdb_system \ --results-dir /tmp/vdb_results ``` #### Notes -- The `--config` argument refers to YAML files in `configs/vectordbbench/` - without the `.yaml` extension. +- The `--config` argument refers to YAML files in `configs/vectordbbench/` without the `.yaml` extension. - The `--force` flag drops and recreates the collection if it already exists. -- See [Dimension Consistency](#dimension-consistency) for important rules about - keeping dimensions aligned between load and run. +- See [Dimension Consistency](#dimension-consistency) for important rules about keeping dimensions aligned between load and run. --- ### 4.4 Compact -The load script performs compaction automatically when enabled in the config or -when `--compact` is passed. +The load script performs compaction automatically when enabled in the config or when `--compact` is passed. Compaction runs as part of the `datagen` workflow. No separate command is needed unless the load command exits early. -Compaction runs as part of the `datagen` workflow. No separate command is needed -unless the load command exits early. See -[Section 5.3](#53-compact) for manual compaction if needed. +See [Section 5.3](#53-compact) for manual compaction if needed. --- @@ -424,44 +430,46 @@ unless the load command exits early. See #### Simple benchmark modes -| `mlpstorage` mode | Script | Purpose | -|-------------------|--------|---------| +| `--benchmark-mode` value | Script | Purpose | +|--------------------------|--------|---------| | `timed` | `vdbbench` | Run for a fixed duration | | `query_count` | `vdbbench` | Run exactly N total queries | ##### Timed mode ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ - --mode timed \ + --benchmark-mode timed \ --runtime 120 \ --num-query-processes 4 \ --batch-size 10 \ --report-count 100 \ + --systemname vdb_system \ --results-dir /tmp/vdb_results ``` ##### Query-count mode ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ - --mode query_count \ + --benchmark-mode query_count \ --queries 10000 \ --num-query-processes 4 \ --batch-size 10 \ --report-count 100 \ + --systemname vdb_system \ --results-dir /tmp/vdb_results ``` @@ -475,19 +483,20 @@ Use enhanced mode for: * richer disk and memory reporting * comparing index/search configurations -Enhanced mode is selected with `--mode sweep`: +Enhanced mode is selected with `--benchmark-mode sweep`: ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ - --mode sweep \ + --benchmark-mode sweep \ --queries 10000 \ --num-query-processes 4 \ + --systemname vdb_system \ --results-dir /tmp/vdb_results ``` @@ -503,8 +512,7 @@ Enhanced mode is selected with `--mode sweep`: ## 5. Alternative Path: Direct Scripts -This section covers the complete workflow using the Python scripts directly, -without the `mlpstorage` CLI wrapper. +This section covers the complete workflow using the Python scripts directly, without the `mlpstorage` CLI wrapper. ### 5.1 Installation @@ -530,16 +538,13 @@ uv run vdbbench --help uv run enhanced-bench --help ``` -**Note:** You still need a running Milvus instance. Follow the Docker setup -in [Section 2](#2-deploy-milvus). +**Note:** You still need a running Milvus instance. Follow the Docker setup in [Section 2](#2-deploy-milvus). --- ### 5.2 Load Vectors -> **Working directory:** All `python vdbbench/...` commands in this section -> assume you are in `storage/vdb_benchmark/`. Console scripts (`uv run load-vdb`, -> etc.) work from any directory. +> **Working directory:** All `python vdbbench/...` commands in this section assume you are in `storage/vdb_benchmark/`. Console scripts (`uv run load-vdb`, etc.) work from any directory. #### Load using a YAML config @@ -581,9 +586,9 @@ Direct script configs live in `vdbbench/configs/` (relative to `storage/vdb_benc ```text vdbbench/configs/ -├── 10m_diskann.yaml (10M vectors, 10 shards, 1536 dim) +├── 10m_diskann.yaml (10M vectors, 10 shards, 1536 dim) ├── 10m_hnsw.yaml -├── 1m_diskann.yaml (1M vectors, 1 shard, 1536 dim) +├── 1m_diskann.yaml (1M vectors, 1 shard, 1536 dim) ├── 1m_diskann_512dim.yaml ├── 1m_hnsw.yaml └── 1m_aisaq_512dim.yaml @@ -593,8 +598,7 @@ vdbbench/configs/ ### 5.3 Compact -The load script performs compaction automatically when enabled in the config or -when `--compact` is passed. +The load script performs compaction automatically when enabled in the config or when `--compact` is passed. If the load command exits early, run compaction manually: @@ -655,8 +659,7 @@ uv run enhanced-bench \ --out-dir /tmp/vdbbench_results ``` -See [Section 9](#9-enhanced-benchmark-full-reference) for full parameter -reference and execution paths. +See [Section 9](#9-enhanced-benchmark-full-reference) for full parameter reference and execution paths. --- @@ -665,25 +668,32 @@ reference and execution paths. ### Available Commands ```bash -./mlpstorage vectordb --help -./mlpstorage vectordb datasize --help -./mlpstorage vectordb datagen --help -./mlpstorage vectordb run --help +./mlpstorage open vectordb --help +./mlpstorage open vectordb datasize --help +./mlpstorage open vectordb datagen --help +./mlpstorage open vectordb run --help +./mlpstorage closed vectordb run --help +./mlpstorage whatif vectordb run --help ``` ### Important Terminology VectorDB uses two similar-looking host flags with different meanings. -| Flag | Meaning | -|------|---------| +| Flag / positional | Meaning | +|-------------------|---------| +| `open`, `closed`, `whatif` | Top-level benchmark mode before `vectordb` | +| `file` / `object` | Positional storage mode selector for `datagen` and `run` | +| `--vdb-engine` | Vector database engine identity; currently `milvus` | +| `--vdb-index` | Result identity index family, for example `DISKANN`, `HNSW`, or `AISAQ` | +| `--index-type` | Milvus implementation index type for `datasize` and `datagen`; defaults to `--vdb-index` when omitted | | `--host` / `-s` | Milvus database endpoint host | | `--port` / `-p` | Milvus database endpoint port | | `--hosts` | Benchmark client hosts used by MPI | | `--npernode` | MPI ranks to start on each benchmark client host | | `--num-query-processes` | Local Python query workers inside each MPI rank | -| `--file` | POSIX/file storage mode selector for `mlpstorage` | -| `--open` | Acknowledge OPEN category execution | +| `--benchmark-mode` | VectorDB run mode: `timed`, `query_count`, or `sweep` | +| `--systemname` | System-under-test directory name under `results/` | | `--results-dir` | Root directory for benchmark output | **Do not confuse `--host` and `--hosts`.** @@ -696,16 +706,13 @@ VectorDB uses two similar-looking host flags with different meanings. Effective distributed query workers: ```text -effective_workers = - len(--hosts) * --npernode * --num-query-processes +effective_workers = len(--hosts) * --npernode * --num-query-processes ``` Example: ```text ---hosts node01 node02 ---npernode 2 ---num-query-processes 4 +--hosts node01 node02 --npernode 2 --num-query-processes 4 ``` starts: @@ -749,12 +756,9 @@ Custom configs can be added to the same directory. The vector dimension must be consistent between data loading and benchmarking. -If you override `--dimension` during `datagen`, the config YAML used for `run` -must specify the same dimension. Otherwise, Milvus will reject queries with a -vector dimension mismatch. +If you override `--dimension` during `datagen`, the config YAML used for `run` must specify the same dimension. Otherwise, Milvus will reject queries with a vector dimension mismatch. -The safest approach is to use the same `--config` for both `datagen` and `run`, -or create a dedicated config YAML for non-default dimensions. +The safest approach is to use the same `--config` for both `datagen` and `run`, or create a dedicated config YAML for non-default dimensions. --- @@ -764,15 +768,14 @@ or create a dedicated config YAML for non-default dimensions. For multi-node runs: -1. Run `./mlpstorage vectordb ...` from one launcher host. +1. Run `./mlpstorage open vectordb ...` from one launcher host. 2. The launcher host participates in the benchmark. 3. Passwordless SSH must work from the launcher to all hosts listed in `--hosts`. 4. The repository path must be identical on every benchmark client host. 5. The same `uv` environment must be installed on every benchmark client host. 6. `mpiexec` must be installed and available on every benchmark client host. 7. The `--results-dir` path must be visible at the same path from every host. -8. The Milvus endpoint given by `--host` and `--port` must be reachable from - every benchmark client host. +8. The Milvus endpoint given by `--host` and `--port` must be reachable from every benchmark client host. #### Install on every benchmark client host @@ -806,8 +809,13 @@ mpiexec -n 2 -hosts node01,node02 \ ### 7.2 Distributed Load -Distributed load uses MPI to start one or more VectorDB loader ranks across -benchmark client hosts. +Distributed load uses MPI to start one or more VectorDB loader ranks across benchmark client hosts. + +Before using `/shared/vdb_results`, initialize it once: + +```bash +./mlpstorage init MLCommons /shared/vdb_results +``` #### Rank behavior @@ -833,14 +841,14 @@ rank 0: #### Command ```bash -./mlpstorage vectordb datagen \ - --file \ - --open \ +./mlpstorage open vectordb datagen file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ @@ -853,20 +861,21 @@ rank 0: --batch-size 1000 \ --chunk-size 10000 \ --force \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` #### Example with two MPI ranks per host ```bash -./mlpstorage vectordb datagen \ - --file \ - --open \ +./mlpstorage open vectordb datagen file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 2 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ @@ -877,16 +886,16 @@ rank 0: --batch-size 1000 \ --chunk-size 10000 \ --force \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` -With `--hosts node01 node02` and `--npernode 2`, the distributed load starts -four MPI ranks. +With `--hosts node01 node02` and `--npernode 2`, the distributed load starts four MPI ranks. #### Output structure ```text -/shared/vdb_results//vectordb/load/ +/shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/datagen// ├── load_statistics.json ├── vdb_multi_node_summary.json ├── rank_0/ @@ -926,31 +935,32 @@ vectors_per_second = inserted_vectors / total_time_seconds ### 7.3 Distributed Simple Benchmark Distributed simple benchmark mode starts one `vdbbench` instance per MPI rank. -Each rank writes rank-local CSV, recall, and statistics files. The launcher then -aggregates the rank outputs. + +Each rank writes rank-local CSV, recall, and statistics files. The launcher then aggregates the rank outputs. #### Timed mode In timed mode, every MPI rank runs for the requested runtime. ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 2 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ - --mode timed \ + --benchmark-mode timed \ --runtime 120 \ --num-query-processes 2 \ --batch-size 10 \ --report-count 100 \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` @@ -962,44 +972,42 @@ This starts: #### Query-count mode -In query-count mode, `--queries` is interpreted as the global query count. The -MPI wrapper splits the query count across ranks. +In query-count mode, `--queries` is interpreted as the global query count. The MPI wrapper splits the query count across ranks. For example: ```text ---queries 100000 ---hosts node01 node02 ---npernode 2 +--queries 100000 --hosts node01 node02 --npernode 2 ``` starts four MPI ranks, and each rank receives approximately 25,000 queries. ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 2 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ - --mode query_count \ + --benchmark-mode query_count \ --queries 100000 \ --num-query-processes 2 \ --batch-size 10 \ --report-count 100 \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` #### Output structure ```text -/shared/vdb_results//vectordb/simple/ +/shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/run// ├── statistics.json ├── vdb_multi_node_summary.json ├── rank_0/ @@ -1066,49 +1074,49 @@ recall_by_query ### 7.4 Distributed Enhanced / Sweep Benchmark -Distributed enhanced benchmark mode starts one `enhanced-bench` instance per MPI -rank. Each rank writes enhanced-bench output under a rank-local output directory. -The launcher then groups and aggregates rank outputs by parameter set. +Distributed enhanced benchmark mode starts one `enhanced-bench` instance per MPI rank. Each rank writes enhanced-bench output under a rank-local output directory. The launcher then groups and aggregates rank outputs by parameter set. #### Command ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ - --mode sweep \ + --benchmark-mode sweep \ --queries 10000 \ --num-query-processes 4 \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` #### Example with four total MPI ranks ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 2 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ - --mode sweep \ + --benchmark-mode sweep \ --queries 20000 \ --num-query-processes 2 \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` @@ -1121,7 +1129,7 @@ With `--hosts node01 node02`, `--npernode 2`, and `--num-query-processes 2`: #### Output structure ```text -/shared/vdb_results//vectordb/enhanced/ +/shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/run// ├── enhanced_statistics.json ├── vdb_multi_node_summary.json ├── rank_0/ @@ -1174,32 +1182,26 @@ p99_latency_ms = max(rank p99_latency_ms) recall_mean = query-count-weighted mean, or exact when per-query recall is present ``` -For simple-bench, p95/p99 latency percentiles are exact because raw per-batch CSV -rows are available. For enhanced-bench, p95/p99 are conservative max-rank values -unless raw latency samples are also emitted by the enhanced output. +For simple-bench, p95/p99 latency percentiles are exact because raw per-batch CSV rows are available. For enhanced-bench, p95/p99 are conservative max-rank values unless raw latency samples are also emitted by the enhanced output. --- ### 7.5 Metrics Aggregation -Distributed VectorDB runs use rank-local output directories and a final -aggregation step. - -The aggregation script is: +Distributed VectorDB runs use rank-local output directories and a final aggregation step. The aggregation script is: ```bash uv run vdb-aggregate ``` -It is normally invoked automatically by `./mlpstorage vectordb`. It can also be -run manually. +It is normally invoked automatically by `./mlpstorage open vectordb`. It can also be run manually. #### Manual load aggregation ```bash uv run vdb-aggregate \ --phase load \ - --base-output-dir /shared/vdb_results//vectordb/load \ + --base-output-dir /shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/datagen/ \ --expected-ranks 2 ``` @@ -1208,7 +1210,7 @@ uv run vdb-aggregate \ ```bash uv run vdb-aggregate \ --phase simple \ - --base-output-dir /shared/vdb_results//vectordb/simple \ + --base-output-dir /shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/run/ \ --expected-ranks 2 ``` @@ -1217,7 +1219,7 @@ uv run vdb-aggregate \ ```bash uv run vdb-aggregate \ --phase enhanced \ - --base-output-dir /shared/vdb_results//vectordb/enhanced \ + --base-output-dir /shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/run/ \ --expected-ranks 2 ``` @@ -1225,12 +1227,9 @@ uv run vdb-aggregate \ ### 7.6 Disk I/O Deduplication -Disk I/O counters are node-local. If multiple MPI ranks run on the same host, -summing every rank's `/proc/diskstats` delta would double-count that host's disk -I/O. +Disk I/O counters are node-local. If multiple MPI ranks run on the same host, summing every rank's `/proc/diskstats` delta would double-count that host's disk I/O. -Distributed aggregation counts disk I/O only once per benchmark client host, -using the rank where: +Distributed aggregation counts disk I/O only once per benchmark client host, using the rank where: ```text local_rank == 0 @@ -1242,28 +1241,24 @@ The aggregated `disk_io` field records this policy. ### 7.7 Ground Truth and Recall -Recall is computed outside the timed query loop so it does not inflate latency -measurements. +Recall is computed outside the timed query loop so it does not inflate latency measurements. -The benchmark uses a FLAT ground-truth collection for exact nearest-neighbor -results. +The benchmark uses a FLAT ground-truth collection for exact nearest-neighbor results. Recommended ground-truth collection name: ```text -_flat_gt +_flat_gt ``` -Distributed wrappers should avoid multiple ranks racing to create/drop the same -FLAT ground-truth collection. The orchestration flow is: +Distributed wrappers should avoid multiple ranks racing to create/drop the same FLAT ground-truth collection. -```text -rank 0: - create or validate FLAT ground-truth collection +The orchestration flow is: -non-rank-0: - validate existing FLAT ground-truth collection - run with --no-create-flat +```text +rank 0: create or validate FLAT ground-truth collection +non-rank-0: validate existing FLAT ground-truth collection +run with --no-create-flat ``` Rank-local recall files include: @@ -1287,8 +1282,7 @@ per_query_recall recall_by_query ``` -The `per_query_recall` and `recall_by_query` fields are used for exact -multi-rank recall aggregation. +The `per_query_recall` and `recall_by_query` fields are used for exact multi-rank recall aggregation. --- @@ -1311,45 +1305,47 @@ Open MPI can be selected with: Example: ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl openmpi \ --mpi-bin mpirun \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ - --mode timed \ + --benchmark-mode timed \ --runtime 120 \ --num-query-processes 2 \ --batch-size 10 \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` Additional MPI arguments can be passed with `--mpi-params`: ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ - --mpi-params -env UCX_TLS tcp \ + --mpi-params="-env UCX_TLS tcp" \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_1m_1536dim_uniform_diskann \ - --mode query_count \ + --benchmark-mode query_count \ --queries 10000 \ --num-query-processes 2 \ --batch-size 10 \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` @@ -1360,50 +1356,55 @@ Additional MPI arguments can be passed with `--mpi-params`: ### Single-Node Example ```bash +# Initialize output root once. +./mlpstorage init MLCommons ~/vdb_results + # 1. Estimate storage. -./mlpstorage vectordb datasize \ - --file \ - --open \ +./mlpstorage open vectordb datasize \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --dimension 1536 \ - --num-vectors 1000000 \ - --index-type DISKANN + --num-vectors 1000000 # 2. Load vectors. -./mlpstorage vectordb datagen \ - --file \ - --open \ +./mlpstorage open vectordb datagen file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ --collection mlps_single_1m \ --force \ + --systemname vdb_single_system \ --results-dir ~/vdb_results # 3. Run simple benchmark. -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ --collection mlps_single_1m \ - --mode timed \ + --benchmark-mode timed \ --num-query-processes 2 \ --runtime 60 \ --batch-size 10 \ + --systemname vdb_single_system \ --results-dir ~/vdb_results # 4. Run enhanced benchmark. -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ --collection mlps_single_1m \ - --mode sweep \ + --benchmark-mode sweep \ --queries 10000 \ --num-query-processes 2 \ + --systemname vdb_single_system \ --results-dir ~/vdb_results # 5. View history. @@ -1416,15 +1417,18 @@ Additional MPI arguments can be passed with `--mpi-params`: # 1. Verify MPI. mpiexec -n 2 -hosts node01,node02 hostname -# 2. Load vectors across two benchmark client hosts. -./mlpstorage vectordb datagen \ - --file \ - --open \ +# 2. Initialize output root once. +./mlpstorage init MLCommons /shared/vdb_results + +# 3. Load vectors across two benchmark client hosts. +./mlpstorage open vectordb datagen file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ @@ -1433,43 +1437,46 @@ mpiexec -n 2 -hosts node01,node02 hostname --dimension 1536 \ --num-shards 4 \ --force \ + --systemname vdb_dist_system \ --results-dir /shared/vdb_results -# 3. Run distributed simple benchmark. -./mlpstorage vectordb run \ - --file \ - --open \ +# 4. Run distributed simple benchmark. +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_dist_1m \ - --mode timed \ + --benchmark-mode timed \ --runtime 120 \ --num-query-processes 2 \ --batch-size 10 \ + --systemname vdb_dist_system \ --results-dir /shared/vdb_results -# 4. Run distributed enhanced benchmark. -./mlpstorage vectordb run \ - --file \ - --open \ +# 5. Run distributed enhanced benchmark. +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_dist_1m \ - --mode sweep \ + --benchmark-mode sweep \ --queries 10000 \ --num-query-processes 2 \ + --systemname vdb_dist_system \ --results-dir /shared/vdb_results ``` @@ -1477,12 +1484,9 @@ mpiexec -n 2 -hosts node01,node02 hostname ## 9. Enhanced Benchmark Full Reference -> **Working directory:** All commands below assume you are in -> `storage/vdb_benchmark/`. +> **Working directory:** All commands below assume you are in `storage/vdb_benchmark/`. -`enhanced_bench.py` merges the operational features of `simple_bench.py` with -advanced features for parameter sweeps, warm/cold cache regimes, budget mode, -YAML config, and memory estimation. +`enhanced_bench.py` merges the operational features of `simple_bench.py` with advanced features for parameter sweeps, warm/cold cache regimes, budget mode, YAML config, and memory estimation. ### Two Execution Paths @@ -1495,8 +1499,7 @@ The script automatically selects the path based on the flags provided. ### Path A — Runtime / Query-Count Mode -This path mimics `simple_bench.py`. It runs workers for a fixed duration or query -count, writes per-process CSV files, and aggregates latency and recall stats. +This path mimics `simple_bench.py`. It runs workers for a fixed duration or query count, writes per-process CSV files, and aggregates latency and recall stats. Create the FLAT ground-truth collection (first run only): @@ -1604,7 +1607,7 @@ python vdbbench/enhanced_bench.py \ | `--search-ef` | `200` | Search parameter override | | `--num-query-vectors` | `1000` | Pre-generated query vectors for recall | | `--recall-k` | `--search-limit` | k for recall@k | -| `--gt-collection` | `_flat_gt` | FLAT GT collection name | +| `--gt-collection` | `_flat_gt` | FLAT GT collection name | | `--auto-create-flat` | `False` | Auto-create FLAT GT collection from source | | `--no-create-flat` | `False` | Validate and reuse existing FLAT GT collection | | `--vector-dim` | `1536` | Vector dimension | @@ -1631,9 +1634,9 @@ statistics.json #### Sweep path ```text -combined_bench_.json -combined_bench_.csv -combined_bench_.sweep.csv +combined_bench_.json +combined_bench_.csv +combined_bench_.sweep.csv ``` --- @@ -1642,11 +1645,9 @@ combined_bench_.sweep.csv ### Recall Measurement -Recall is computed outside the timed benchmark loop so it does not inflate -latency measurements. +Recall is computed outside the timed benchmark loop so it does not inflate latency measurements. -The benchmark uses a FLAT ground-truth collection for exact nearest-neighbor -results. +The benchmark uses a FLAT ground-truth collection for exact nearest-neighbor results. Simple benchmark output includes: @@ -1670,13 +1671,11 @@ per_query_recall recall_by_query ``` -The `per_query_recall` and `recall_by_query` fields are used for exact -multi-rank aggregation. +The `per_query_recall` and `recall_by_query` fields are used for exact multi-rank aggregation. ### Disk I/O Metrics -Disk I/O is measured by reading `/proc/diskstats` before and after each -benchmark run. +Disk I/O is measured by reading `/proc/diskstats` before and after each benchmark run. Fields include: @@ -1689,8 +1688,7 @@ read_iops write_iops ``` -In distributed mode, disk I/O is aggregated once per benchmark client host to -avoid double-counting multiple MPI ranks on the same host. +In distributed mode, disk I/O is aggregated once per benchmark client host to avoid double-counting multiple MPI ranks on the same host. --- @@ -1725,26 +1723,33 @@ MpiContext(rank=1, world_size=2, local_rank=0, hostname='node02') ### 3. `mlpstorage` dry run -Use `--what-if` to inspect the generated command without running it. +Initialize the shared results directory once: + +```bash +./mlpstorage init MLCommons /shared/vdb_results +``` + +Use top-level `whatif` plus `--dry-run` to inspect the generated command without running it: ```bash -./mlpstorage vectordb run \ - --file \ - --open \ - --what-if \ +./mlpstorage whatif vectordb run file \ + --dry-run \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_smoke \ - --mode query_count \ + --benchmark-mode query_count \ --queries 100 \ --num-query-processes 1 \ --batch-size 10 \ + --systemname vdb_smoke_system \ --results-dir /shared/vdb_results ``` @@ -1753,14 +1758,16 @@ Use `--what-if` to inspect the generated command without running it. This uses MPI on localhost and is useful before testing multiple nodes. ```bash -./mlpstorage vectordb datagen \ - --file \ - --open \ +./mlpstorage init MLCommons /tmp/vdb_results + +./mlpstorage open vectordb datagen file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts localhost \ --npernode 2 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ @@ -1771,28 +1778,31 @@ This uses MPI on localhost and is useful before testing multiple nodes. --batch-size 500 \ --chunk-size 1000 \ --force \ + --systemname vdb_smoke_system \ --results-dir /tmp/vdb_results ``` Then run a query-count benchmark: ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts localhost \ --npernode 2 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 127.0.0.1 \ --port 19530 \ --config default \ --collection mlps_smoke_10k \ - --mode query_count \ + --benchmark-mode query_count \ --queries 200 \ + --vector-dim 128 \ --num-query-processes 1 \ --batch-size 10 \ + --systemname vdb_smoke_system \ --results-dir /tmp/vdb_results ``` @@ -1804,29 +1814,37 @@ import json from pathlib import Path stats_files = sorted( - Path("/tmp/vdb_results").glob("**/vectordb/simple/statistics.json") + Path("/tmp/vdb_results").glob( + "**/vector_database/milvus/DISKANN/run/**/statistics.json" + ) ) assert stats_files, "No distributed statistics.json found" - stats = json.loads(stats_files[-1].read_text()) assert stats["total_queries"] == 200 assert stats["mpi"]["partial_failure"] is False - print(json.dumps(stats, indent=2)[:2000]) PY ``` ### 5. Multi-node load test +Initialize the shared results directory once: + +```bash +./mlpstorage init MLCommons /shared/vdb_results +``` + +Load data: + ```bash -./mlpstorage vectordb datagen \ - --file \ - --open \ +./mlpstorage open vectordb datagen file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ @@ -1837,6 +1855,7 @@ PY --batch-size 1000 \ --chunk-size 10000 \ --force \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` @@ -1848,14 +1867,14 @@ import json from pathlib import Path load_files = sorted( - Path("/shared/vdb_results").glob("**/vectordb/load/load_statistics.json") + Path("/shared/vdb_results").glob( + "**/vector_database/milvus/DISKANN/datagen/**/load_statistics.json" + ) ) assert load_files, "No load_statistics.json found" - stats = json.loads(load_files[-1].read_text()) assert stats["inserted_vectors"] == 1000000 assert stats["mpi"]["partial_failure"] is False - print(json.dumps(stats, indent=2)[:2000]) PY ``` @@ -1863,53 +1882,55 @@ PY ### 6. Multi-node simple benchmark test ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_multinode_1m \ - --mode timed \ + --benchmark-mode timed \ --runtime 120 \ --num-query-processes 2 \ --batch-size 10 \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` ### 7. Multi-node enhanced benchmark test ```bash -./mlpstorage vectordb run \ - --file \ - --open \ +./mlpstorage open vectordb run file \ --distributed \ --mpi-impl mpich \ --mpi-bin mpiexec \ --hosts node01 node02 \ --npernode 1 \ + --vdb-engine milvus \ + --vdb-index DISKANN \ --host 10.0.0.10 \ --port 19530 \ --config default \ --collection mlps_multinode_1m \ - --mode sweep \ + --benchmark-mode sweep \ --queries 10000 \ --num-query-processes 2 \ + --systemname vdb_multinode_system \ --results-dir /shared/vdb_results ``` Expected files: ```text -/shared/vdb_results//vectordb/load/load_statistics.json -/shared/vdb_results//vectordb/simple/statistics.json -/shared/vdb_results//vectordb/enhanced/enhanced_statistics.json -/shared/vdb_results//vectordb/*/vdb_multi_node_summary.json +/shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/datagen//load_statistics.json +/shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/run//statistics.json +/shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/run//enhanced_statistics.json +/shared/vdb_results/open/MLCommons/results/vdb_multinode_system/vector_database/milvus/DISKANN/run//vdb_multi_node_summary.json ``` --- @@ -1918,10 +1939,7 @@ Expected files: ### `vector dimension mismatch` -The dimension used for load and run does not match. - -Use the same config for both `datagen` and `run`, or update the config to match -the dimension passed to `datagen`. +The dimension used for load and run does not match. Use the same config for both `datagen` and `run`, or update the config to match the dimension passed to `datagen`. ### MPI launches only on one host @@ -1931,8 +1949,7 @@ Check: mpiexec -n 2 -hosts node01,node02 hostname ``` -If both lines show the same host, inspect the MPICH/Hydra host configuration and -SSH setup. +If both lines show the same host, inspect the MPICH/Hydra host configuration and SSH setup. ### Rank output is missing @@ -1954,8 +1971,9 @@ partial_failure ### Distributed aggregation cannot find files -Ensure `--results-dir` is visible at the same path from all benchmark client -hosts. For example, use a shared filesystem path such as: +Ensure `--results-dir` is visible at the same path from all benchmark client hosts. + +For example, use a shared filesystem path such as: ```text /shared/vdb_results @@ -1963,8 +1981,7 @@ hosts. For example, use a shared filesystem path such as: ### Recall is zero -Check that the FLAT ground-truth collection exists and contains the same vectors -as the ANN collection. +Check that the FLAT ground-truth collection exists and contains the same vectors as the ANN collection. Also check that rank-local `recall_stats.json` files contain non-empty: @@ -2006,11 +2023,11 @@ uv run vdb-aggregate --help ## 13. Contributing -Contributions are welcome. Pull requests that add or modify distributed -VectorDB behavior should include: +Contributions are welcome. Pull requests that add or modify distributed VectorDB behavior should include: * implementation changes * unit tests * single-host MPI smoke test results * multi-node test results when applicable * README updates + diff --git a/vdb_benchmark/vdbbench/benchmark/backends/milvus/README.md b/vdb_benchmark/vdbbench/benchmark/backends/milvus/README.md index 11ac7455..b7145269 100644 --- a/vdb_benchmark/vdbbench/benchmark/backends/milvus/README.md +++ b/vdb_benchmark/vdbbench/benchmark/backends/milvus/README.md @@ -49,8 +49,13 @@ that exceed RAM. | Build Parameter | Type | Default | Description | |----------------|------|---------|-------------| -| `MaxDegree` | int | 64 | Maximum out-degree of each graph node | -| `SearchListSize` | int | 200 | Candidate-list size during index build | +| `max_degree` | int | 64 | Maximum out-degree of each graph node | +| `search_list_size` | int | 200 | Candidate-list size during index build | + +> **Note:** knowhere reads snake_case DiskANN build parameters; the legacy +> CamelCase spellings (`MaxDegree`, `SearchListSize`) are still accepted in +> configs for backward compatibility and are normalized to snake_case before +> index creation (see issue #590). | Search Parameter | Type | Default | Description | |-----------------|------|---------|-------------| diff --git a/vdb_benchmark/vdbbench/benchmark/backends/milvus/__init__.py b/vdb_benchmark/vdbbench/benchmark/backends/milvus/__init__.py index da6b53e9..5b04cfc6 100644 --- a/vdb_benchmark/vdbbench/benchmark/backends/milvus/__init__.py +++ b/vdb_benchmark/vdbbench/benchmark/backends/milvus/__init__.py @@ -62,13 +62,13 @@ def backend_descriptor() -> BackendDescriptor: ), build_params=[ ParamDescriptor( - name="MaxDegree", + name="max_degree", description="Maximum out-degree of each graph node.", type="int", default=64, ), ParamDescriptor( - name="SearchListSize", + name="search_list_size", description="Candidate-list size during index build.", type="int", default=200, diff --git a/vdb_benchmark/vdbbench/benchmark/backends/milvus/backend.py b/vdb_benchmark/vdbbench/benchmark/backends/milvus/backend.py index 282754b9..eebe7eaf 100644 --- a/vdb_benchmark/vdbbench/benchmark/backends/milvus/backend.py +++ b/vdb_benchmark/vdbbench/benchmark/backends/milvus/backend.py @@ -83,9 +83,14 @@ def _build_index_params( "efConstruction": params.get("efConstruction", 200), } elif index_type == "DISKANN": + # knowhere reads snake_case DiskANN build params; CamelCase keys + # are silently ignored (issue #590). Accept legacy CamelCase from + # older configs but always emit snake_case to Milvus. ip["params"] = { - "MaxDegree": params.get("MaxDegree", 64), - "SearchListSize": params.get("SearchListSize", 200), + "max_degree": params.get( + "max_degree", params.get("MaxDegree", 64)), + "search_list_size": params.get( + "search_list_size", params.get("SearchListSize", 200)), } elif index_type == "AISAQ": ip["params"] = { diff --git a/vdb_benchmark/vdbbench/benchmark/configs/1m_diskann.yaml b/vdb_benchmark/vdbbench/benchmark/configs/1m_diskann.yaml index fbe3db27..af44c9f1 100644 --- a/vdb_benchmark/vdbbench/benchmark/configs/1m_diskann.yaml +++ b/vdb_benchmark/vdbbench/benchmark/configs/1m_diskann.yaml @@ -28,8 +28,8 @@ index: index_type: DISKANN metric_type: COSINE index_params: - MaxDegree: 64 - SearchListSize: 200 + max_degree: 64 + search_list_size: 200 num_shards: 1 search: diff --git a/vdb_benchmark/vdbbench/load_vdb.py b/vdb_benchmark/vdbbench/load_vdb.py index 1bc5212d..101d71de 100755 --- a/vdb_benchmark/vdbbench/load_vdb.py +++ b/vdb_benchmark/vdbbench/load_vdb.py @@ -44,8 +44,8 @@ def parse_args(): # Index parameters parser.add_argument("--index-type", type=str, default="DISKANN", help="Index type") parser.add_argument("--metric-type", type=str, default="COSINE", help="Metric type for index") - parser.add_argument("--max-degree", type=int, default=16, help="DiskANN MaxDegree parameter") - parser.add_argument("--search-list-size", type=int, default=200, help="DiskANN SearchListSize parameter") + parser.add_argument("--max-degree", type=int, default=16, help="DiskANN max_degree build parameter") + parser.add_argument("--search-list-size", type=int, default=200, help="DiskANN search_list_size build parameter") parser.add_argument("--M", type=int, default=16, help="HNSW M parameter") parser.add_argument("--ef-construction", type=int, default=200, help="HNSW efConstruction parameter") parser.add_argument("--inline-pq", type=int, default=16, help="AISAQ inline_pq parameter, performance(max_degree) vs scale(0) mode") @@ -329,9 +329,12 @@ def main(): "efConstruction": args.ef_construction } elif args.index_type == "DISKANN": + # knowhere's DiskANN config reads snake_case keys (max_degree, + # search_list_size); CamelCase keys are silently ignored and the + # index is built with server defaults (issue #590). index_params["params"] = { - "MaxDegree": args.max_degree, - "SearchListSize": args.search_list_size + "max_degree": args.max_degree, + "search_list_size": args.search_list_size } elif args.index_type == "AISAQ": index_params["params"] = { diff --git a/vdb_benchmark/vdbbench/mpi_wrapper.py b/vdb_benchmark/vdbbench/mpi_wrapper.py index d19b4d2c..b8a8f6f2 100644 --- a/vdb_benchmark/vdbbench/mpi_wrapper.py +++ b/vdb_benchmark/vdbbench/mpi_wrapper.py @@ -172,9 +172,11 @@ def _build_index_params(args: argparse.Namespace) -> dict[str, Any]: } elif index_type == "DISKANN": + # snake_case is required by knowhere's DiskANN config; CamelCase + # keys are silently ignored at build time (issue #590). index_params["params"] = { - "MaxDegree": args.max_degree, - "SearchListSize": args.search_list_size, + "max_degree": args.max_degree, + "search_list_size": args.search_list_size, } elif index_type == "AISAQ": From abac2c38a3c8c18fe6e484ce395f42c88f53e754 Mon Sep 17 00:00:00 2001 From: Curtis Anderson Date: Sat, 4 Jul 2026 16:16:33 -0700 Subject: [PATCH 2/2] chore: bump 3.0.29 -> 3.0.30; regenerate uv.lock Ride-along with the #590 DISKANN fix. Since 3.0.29 (silently rolled in by #648) the following have landed on main: #649, #650, #652, #654, #656, #657, #659, #665, and #602. Marks a natural version boundary before the DISKANN key-name fix ships. --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d18b109c..b4118e93 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "mlpstorage" -version = "3.0.29" +version = "3.0.30" description = "MLPerf Storage Benchmark Suite" readme = "README.md" license = {text = "Apache-2.0"} diff --git a/uv.lock b/uv.lock index c9cc66c8..e44dcf24 100644 --- a/uv.lock +++ b/uv.lock @@ -518,7 +518,7 @@ wheels = [ [[package]] name = "mlpstorage" -version = "3.0.29" +version = "3.0.30" source = { editable = "." } dependencies = [ { name = "dlio-benchmark", marker = "sys_platform == 'linux'" },