Milvus 百萬向量搜索實驗(附數據,測試腳本,性能數據)

一、準備測試數據和腳本

本實驗所使用的原始數據集爲 SIFT1B ,關於該數據集的詳細信息請參考:http://corpus-texmex.irisa.fr/。在本次測試中,咱們提取了原始數據集中的 100 萬條數據。python

經實測,如下硬件配置可順利完成實驗:git

Component Minimum Config
OS Ubuntu LTS 18.04
CPU Intel Core i5-8250U
GPU Nvidia GeForce MX150, 2GB GDDR5
GPU Driver CUDA 10.1, Driver 418.74
Memory 8 GB DDR4
Storage NVMe SSD 256 GB

測試工具下載:sql

爲方便存放測試數據和腳本,請建立名爲 milvus_sift1m 的文件夾。利用前文提供的下載連接,將測試數據集下載到 milvus_sift1m 目錄下:docker

  • 測試數據集下載並解壓完成以後,你將會看到一個名爲 bvecs_data 的文件夾。該文件夾裏面存放了 10 個 npy 文件,每一個 npy 文件中存放了10 萬條 uint8 格式的向量數據。
  • 查詢向量集下載完成以後,你會看到一個 query.npy 的文件,該文件裏存放了 10,000 條實驗中須要查詢的向量。
  • 對照數據( groundtruth )包含一個名爲 ground_truth.txt 的文本文件,該文件裏存放的是查詢向量集中的每條向量的 top1000 類似向量的位置。
  • 測試腳本會包含一個 python 程序 milvus_bootcamp.py 和一個 shell 腳本 get_id.sh。

獲取完測試須要的數據和腳本後, milvus_sift1m 目錄下應該存放有如下內容:shell

  1. 100 萬測試數據: bvecs_data 文件夾
  2. 10,000 條查詢向量集: query.npy
  3. 10,000 條查詢向量集的 ground truth:ground_truth.txt
  4. 測試腳本:milvus_bootcamp.py 和 get_id.sh

注意bash

使用腳本 milvus_bootcamp.py 進行測試以前,請仔細閱讀該腳本的 README 。並根據實際狀況,對腳本中的相關變量值進行修改。 使用腳本 get_id.sh 測試以前須要爲它添加可執行權限,執行下述指令:工具

$ chmod +x get_id.sh

二、 配置 Milvus 參數

Milvus 能夠根據數據分佈和性能、準確性的要求靈活調整相關係統參數,以發揮產品的最佳性能。在此實驗中,採用以下表所示的參數配置,就能夠實現90%以上召回率。性能

配置文件: /home/$USER/milvus/conf/server_config.yaml測試

參數名稱 推薦值
index_building_threshold 64
cpu_cache_capacity 4
use_blas_threshold 801
nprobe 32

其他參數保持默認便可。配置文件參數修改完畢後,重啓 Milvus Docker 使配置生效。ui

$ docker restart <container id>

三、 數據導入

導入數據以前,首先確保 bvecs_data 文件夾與測試腳本 milvus_bootcamp.py 都放在 milvus_sift1m 目錄下,而後確認 Milvus 已經正常啓動。( Milvus 安裝及啓動方法參見:Milvus 快速上手

進入 milvus_sift1m 目錄,運行以下腳本:

$ python3 milvus_bootcamp.py --table=ann_1m_sq8 --index=ivfsq8 -t

腳本會建立一張名爲 ann_1m_sq8 的表,它採用的索引類型爲 ivfsq8 ,並導入數據:

1m_import

上述過程完成以後,運行以下腳本以查看 Milvus 中存在的的表,以及表中的向量條數:

$ python3 milvus_bootcamp.py --show
$ python3 milvus_bootcamp.py --table=ann_1m_sq8 --rows

數據導入完成後,會在 milvus_sift1m 目錄下產生一個名爲 ann_1m_sq8_idmap.txt 的文件,該文件中存放的是 Milvus 爲每一條向量分配的向量編號( ids )以及該向量的具體位置。

爲了確保導入 Milvus 的數據已經所有建好索引,請進入 /home/$USER/milvus/db 目錄,在終端輸入以下命令:

$ sqlite3 meta.sqlite

進入交互式命令行以後,輸入以下命令,檢查向量數據表當前的狀態:

sqlite> select * from TableFiles where table_id='ann_1m_sq8';
30|ann_1m_sq8|3|1565599487052367000|3|102400000|1565599495009366|1565599487052372|1190712
31|ann_1m_sq8|3|1565599495107862000|3|102400000|1565599502559292|1565599495107863|1190712
32|ann_1m_sq8|3|1565599502656466000|3|102400000|1565599510079453|1565599502656467|1190712
33|ann_1m_sq8|3|1565599510129972000|3|51200000|1565599513555987|1565599510129973|1190712
34|ann_1m_sq8|3|1565599513650120000|3|102400000|1565599521067974|1565599513650121|1190712
35|ann_1m_sq8|3|1565599521132604000|3|51200000|1565599524843984|1565599521132605|1190712

Milvus 會將一個向量數據表分紅若干數據分片進行存儲,所以查詢命令會返回多條記錄。其中第三列數字表明數據表採用的索引類型,數字 3 表明採用的是 ivfsq8 索引。第五列數字表明索引構建的狀況,當這列數字爲 3 時,表明相應的數據表分片上的索引已構建完畢。若是某個分片上的索引尚未構建完成,能夠手動爲這個數據分片創建索引。進入 milvus_sift1m 目錄,運行以下腳本:

$ python3 milvus_bootcamp.py --table=ann_1m_sq8 --build

手動創建索引後,再次進入 sqlite 交互界面,確認全部數據分片都已經建好索引。若是想了解其餘列數據表明的含義,請進入 /home/$USER/milvus/db 目錄,在 sqlite 交互界面輸入以下命令進行查看。

sqlite>.schema

四、準確性測試

SIFT1B 提供了10,000 條向量的查詢向量集,而且對於每條查詢向量都給出了該向量在不一樣規模數據集上的 top1000 ground truth。所以,能夠方便地對 Milvus 查詢結果的準確率進行計算。準確率計算公式爲:

準確率= ( Milvus 查詢結果與 Groundtruth 一致的向量個數 ) / ( query_records 的向量個數 * top_k )

(1)執行準確性測試腳本

從 10,000 條查詢向量中隨機取出 10 條向量,而後測試 Milvus 針對這 10 條向量的 top20 結果的準確率。進入 milvus_sift1m 目錄,運行以下腳本:

$ python3 milvus_bootcamp.py --table=ann_1m_sq8 -q 10 -k 20 -s

(2)驗證準確性測試結果

上述腳本運行完成後,將會生成一個名爲 accuracy_results 的文件夾,在該文件夾下面會有一個名爲 10_20_result.csv 的文件,文件裏的內容以下圖所示:

1m_accu_10_20

  • nq: 表明的是第幾個查詢向量
  • topk: 表明的是查詢該向量的前 k 個類似的向量
  • total_time: 表明整個查詢花費的總時間,單位:秒
  • avg_time: 表明每一條向量的平均查詢時間,單位:秒
  • recall: 表明 milvus 的查詢結果與 ground truth 對比後的準確率

Milvus 查詢準確率與搜索子空間( nprobe 參數)有很大關係。本次測試中 nprobe 設置爲32,Milvus 查詢準確率能夠達到 90% 以上。能夠經過增大 nprobe 值來實現更高的準確率但同時也會下降 Milvus 的查詢性能。

所以,須要結合實際數據分佈和業務SLA,調整搜索子空間大小以達到性能和準確性的平衡。

五、性能測試

爲評估 Milvus 的查詢性能,進入 milvus_sift1m 目錄,運行以下腳本:

$ python3 milvus_bootcamp.py --table=ann_1m_sq8 -s

運行結束後,將會生成一個名爲 performance_results 的文件夾,在該文件夾下會有一個名爲 xxx_results.csv 的文件,'xxx' 表明執行命令的時間。文件內容以下圖所示(未徹底展現):

1m_per_10_20

  • nq: 表明要查詢的向量數
  • topk: 表明的是查詢某個向量的前 k 個類似的向量
  • total_time: 表明的是查詢 nq個向量的前 k 個類似向量一共花費的時間,單位:秒
  • avg_time: 表明的是查詢一個向量的 topk 個類似向量的平均時間,單位:秒

注意

  1. milvus_bootcamp.py 中設置的待測試的 nq 爲:一、50、100、150、200、250、300、350、400、450、500、550、600、650、700、750、800。對於每個 nq,milvus_bootcamp.py 設置的 topk 爲:一、20、50、100、300、500、800、1000。
  2. Milvus 啓動後,進行第一次向量檢索時,須要花部分時間加載數據到內存。
  3. 若是兩次測試間隔一段時間,Intel CPU可能降頻至基礎頻率。性能測試時儘可能連續運行測試案例。第一個測試案例能夠運行兩次,取第二次的運行時間。
相關文章
相關標籤/搜索