使用样例
本章节提供了一个简单的样例,帮助用户快速体验运用mxIndex进行检索的流程。
假定在Atlas 推理系列产品上,有业务需要使用到暴搜(Flat)算法,底库大小为100w,维度是512维,需要检索的向量是128个,topk是10,编写一个Demo调用Index接口大致步骤如下。
前提条件
- 已完成安装部署操作。
- 已经生成Flat和AICPU算子。
操作步骤
- 构造Demo,过程包括:
- Demo中引入暴搜(Flat)的头文件。
- 构造底库向量数据,这里用随机数生成代替。
- 归一化底库数据。
- 初始化Flat的Index。
- 调用接口添加底库。
- 调用接口进行检索。
demo.cpp代码如下:
#include <faiss/ascend/AscendIndexFlat.h> #include <sys/time.h> #include <random> // 获取当前时间 inline double GetMillisecs() { struct timeval tv = {0, 0}; gettimeofday(&tv, nullptr); return tv.tv_sec * 1e3 + tv.tv_usec * 1e-3; } // 使用随机数构造底库数据 void Generate(size_t ntotal, std::vector<float> &data, int seed = 5678) { std::default_random_engine e(seed); std::uniform_real_distribution<float> rCode(0.0f, 1.0f); data.resize(ntotal); for (size_t i = 0; i < ntotal; ++i) { data[i] = static_cast<float>(255 * rCode(e) - 128); } } // 底库数据归一化 void Norm(size_t total, std::vector<float> &data, int dim) { for (size_t i = 0; i < total; ++i) { float mod = 0; for (int j = 0; j < dim; ++j) { mod += data[i * dim + j] * data[i * dim + j]; } mod = sqrt(mod); for (int j = 0; j < dim; ++j) { data[i * dim + j] = data[i * dim + j] / mod; } } } int main() { int dim = 512; std::vector<int> device{0}; size_t ntotal = 1000000; int searchnum = 128; std::vector<float> features(dim * ntotal); int64_t resourceSize = static_cast<int64_t>(1024) * 1024 * 1024; int topK = 10; printf("Generating random numbers start!\r\n"); Generate(ntotal, features); Norm(ntotal, features, dim); try { // index初始化 faiss::ascend::AscendIndexFlatConfig conf(device, resourceSize); auto metricType = faiss::METRIC_INNER_PRODUCT; faiss::ascend::AscendIndexFlat index(dim, metricType, conf); index.reset(); // add底库 printf("add start!\r\n"); index.add(ntotal, features.data()); size_t tmpTotal = index.getBaseSize(0); if (tmpTotal != ntotal) { printf("------- Error -----------------\n"); return -1; } // search printf("search start!\r\n"); int loopTimes = 1; std::vector<float> dist(searchnum * topK, 0); std::vector<faiss::idx_t> label(searchnum * topK, 0); auto ts = GetMillisecs(); for (int i = 0; i < loopTimes; i++) { index.search(searchnum, features.data(), topK, dist.data(), label.data()); } auto te = GetMillisecs(); printf("search end!\r\n"); printf("flat, base:%lu, dim:%d, searchnum:%d, topk:%d, duration:%.3lf, QPS:%.4f\n", ntotal, dim, searchnum, topK, te - ts, 1000 * searchnum * loopTimes / (te - ts)); return 0; } catch(...) { printf("Exception caught! \r\n"); return -1; } }
- 编译demo.cpp
# 以安装路径“/home/work/FeatureRetrieval”为例 g++ --std=c++11 -fPIC -fPIE -fstack-protector-all -Wall -D_FORTIFY_SOURCE=2 -O3 -Wl,-z,relro,-z,now,-z,noexecstack -s -pie \ -o demo demo.cpp \ -I/home/work/FeatureRetrieval/mxIndex/include \ -I/usr/local/faiss/faiss1.7.4/include \ -I/usr/local/Ascend/driver/include \ -I/opt/OpenBLAS/include \ -L/home/work/FeatureRetrieval/mxIndex/host/lib \ -L/usr/local/faiss/faiss1.7.4/lib \ -L/usr/local/Ascend/driver/lib64 \ -L/usr/local/Ascend/driver/lib64/driver \ -L/opt/OpenBLAS/lib/include \ -L/usr/local/Ascend/ascend-toolkit/latest/lib64 \ -lfaiss -lascendfaiss -lopenblas -lc_sec -lascendcl -lascend_hal -lascendsearch -lock_hmm
- 运行Demo,显示search end!即表示Demo运行成功。
./demo ... search end!