2. 快速入门

2.1. 软件包

2.1.1. 软件包信息

mcFaiss提供了 maca-mcFaiss-<VERSION>-linux-x86_64.tar.xz ,可以使用命令 tar -xJf 进行解压,解压后的二进制软件包信息说明参见下表。

表 2.1 mcFaiss发布的软件包

软件包类型

文件名示例

说明

deb发布包

mcfaiss-x.y.z.n+bu.v.w.m-x86_64.deb

mcFaiss发布包,适用于Ubuntu等使用deb包管理的系统。如果应用程序以动态库的方式依赖mcFaiss,则可以部署该二进制包作为依赖

deb开发包

mcfaiss-dev-x.y.z.n+bu.v.w.m-x86_64.deb

mcFaiss开发包,适用于Ubuntu等使用deb包管理的系统,用于开发应用程序使用,头文件和静态库由此包提供

rpm发布包

mcfaiss-x.y.z.n+bu.v.w.m-x86_64.rpm

mcFaiss发布包,适用于CentOS等使用rpm包管理的系统

rpm开发包

mcfaiss-devel-x.y.z.n+bu.v.w.m-x86_64.rpm

mcFaiss开发包,适用于CentOS等使用rpm包管理的系统

Python wheel包

faiss-x.y.z.n+bu.v.w.m-py3-none-manylinux_2_27_x86_64.whl

mcFaiss的Python二进制扩展包,适用于Python3.8及以上

备注

  • x.y.z.n表示对应包的软件发布版本,bu.v.w.m表示基于版本号为u.v.w.m的MXMACA进行编译的构建号。

  • x86_64表示CPU架构。

2.1.2. 软件包内容

安装mcFaiss的deb或rpm包会在 /opt/mxmap 路径下安装相关的二进制开发库和头文件。其中 mcfaiss 发布包会安装 .so 文件;mcfaiss-dev 开发包会安装头文件、静态库等。

/opt/mxmap 为起始路径,可以得到如下的文件内容:

├─include/
│   └─faiss/
│         ├─AutoTune.h
│         ├─Clustring.h
│         ├─......
│         └─index_io.h
├─lib/
│   ├─libfaiss.a
│   ├─libfaiss_avx2.a
│   ├─libfaiss_avx2.so
│   ├─libfaiss_gpu.a
│   └─libfaiss.so
└─share/
     └─faiss/
          ├─......
          └─faiss-va.b.c.patch
  • include/faiss/ 目录包含了Faiss所有的头文件

  • lib/libfaiss.alib/libfaiss_avx2.a 文件是静态链接库

  • lib/libfaiss.solib/libfaiss_avx2.so 文件是动态链接库

  • share/faiss/faiss-va.b.c.patch 文件是基于 a.b.c 版本的Faiss源码补丁

2.2. 安装部署

2.2.1. 操作系统及依赖

mcFaiss二进制发布包(deb或rpm)支持的操作系统及相关依赖,参见表 2.2

表 2.2 mcFaiss支持的操作系统及相关依赖

操作系统

相关依赖

说明

Ubuntu 18.04

依赖版本的MXMACA Runtime

  • MXMACA Runtime依赖的详细版本,参见《MXMAP发布说明》

  • 如果需要使用mcFaiss Python的扩展包,请使用Python 3.8及以上版本

libomp5

cu-bridge

Python3.8及以上

Ubuntu 20.04

同Ubuntu 18.04

Ubuntu 22.04

同Ubuntu 18.04

CentOS 8

依赖版本的MXMACA Runtime

  • MXMACA Runtime依赖的详细版本,参见《MXMAP发布说明》

  • 如果需要使用mcFaiss Python的扩展包,请使用Python 3.8及以上版本

libomp

cu-bridge

Python3.8及以上

请参考 cu-bridge使用指南安装并配置cu-bridge环境,建议安装到 /opt/maca/tools/ 目录下。

可以检查以下文件是否存在,并确认cu-bridge环境是否准备完毕:

/opt/maca/tools/cu-bridge/bin/cucc
/opt/maca/tools/cu-bridge/tools/cmake_maca

2.2.2. mcFaiss自动安装与卸载

  1. 自动安装命令:

    tar -xJf maca-mcFaiss-<VERSION>-linux-x86_64.tar.xz
    cd mcFaiss-<VERSION>
    bash mxmap-install.sh -f
    

    如果仅需要安装whl包、rpm包或deb包,则使用命令 bash mxmap-install.sh -i whl or rpm or deb,更多的用法请使用 bash mxmap-install.sh -h 来获得帮助。

  2. 自动卸载命令:

    cd mcFaiss-<VERSION>
    bash mxmap-install.sh -U
    

    如果仅需要卸载whl包、rpm包或deb包,则使用命令 bash mxmap-install.sh -u whl or rpm or deb,更多的用法请使用 bash mxmap-install.sh -h 来获得帮助。

2.2.3. mcFaiss手动安装

Ubuntu系统

假设mcFaiss的deb包已经保存在当前目录下,推荐使用 apt 安装:

$ sudo apt -y install ./mcfaiss-x.y.z.n+bu.v.w.m-x86_64.deb
$ sudo apt -y install ./mcfaiss-dev-x.y.z.n+bu.v.w.m-x86_64.deb

或者也可以使用 dpkg 命令进行安装:

$ sudo dpkg -i ./mcfaiss-x.y.z.n+bu.v.w.m-x86_64.deb
$ sudo dpkg -i ./mcfaiss-dev-x.y.z.n+bu.v.w.m-x86_64.deb

安装成功后,可以在 /opt/mxmap 目录下找到相应的文件,详细信息参见 2.1.2 软件包内容

CentOS系统

假设mcFaiss的rpm包已经保存在当前目录下:

$ sudo rpm -ivh ./mcfaiss-x.y.z.n+bu.v.w.m-x86_64.rpm
$ sudo rpm -ivh ./mcfaiss-devel-x.y.z.n+bu.v.w.m-x86_64.rpm

安装成功后,可以在 /opt/mxmap 目录下找到相应的文件,详细信息参见 2.1.2 软件包内容

Python二进制包

在支持的Linux系统中,可以使用pip进行安装。

$ python3.8 -m pip install ./faiss-x.y.z.n+bu.v.w.m-py3-none-manylinux_2_27_x86_64.whl

2.3. mcFaiss使用

mcFaiss提供C++和Python两种语言的接口,mcFaiss的C++/Python接口和Faiss提供的接口完全一致,用户可以参考 Faiss的C++接口文档进行开发。 目前,mcFaiss支持的Faiss版本为1.8.0。

2.3.1. 代码示例(C++)

使用C++进行Flat索引完成向量添加、搜索,代码示例如下:

#include <iostream>
#include <algorithm>
#include <memory>
#include <random>
#include <vector>

#include <faiss/IndexFlat.h>
#include <faiss/MetaIndexes.h>
#include <faiss/gpu/GpuIndexFlat.h>
#include <faiss/gpu/StandardGpuResources.h>

int main() {
    int d = 4; // dimension
    int nb = 100; // database size
    int nq = 10; // nb of queries
    int topk = 3; // nb of probes

    std::mt19937 rng;
    std::uniform_real_distribution<float> distribution(0.0, 1.0);

    std::vector<float> xb(d * nb);
    std::vector<float> xq(d * nq);
    std::vector<float> dis(d * nq * topk);
    std::vector<int64_t> rids(d * nq * topk);

    for (int i = 0; i < nb; i++) {
        for (int j = 0; j < d; j++) {
            xb[d * i + j] = distribution(rng);
        }
    }

    std::copy(xb.begin(), xb.begin() + d * nq, xq.begin());

    faiss::gpu::StandardGpuResources res;
    faiss::gpu::GpuIndexFlatConfig config;
    config.storeTransposed = false;
    faiss::gpu::GpuIndexFlatL2 index(&res, d, config);

    index.add(nb, xb.data());
    index.search(nq, xq.data(), topk, dis.data(), rids.data());

    for (int i = 0; i < nq; i++) {
        std::cout << "query " << i << ": ";
        for (int j = 0; j < topk; j++) {
            std::cout << rids[i * topk + j] << " ";
        }
        std::cout << std::endl;
    }
}

如果需要在曦云系列GPU上编译并运行上述示例,需要使用mxcc进行编译。

$ mxcc example.cpp -o example -I${MACA_PATH}/include \
    -I${MACA_PATH}/tools/cu-bridge/include \
    -I${MACA_PATH}/include \
    -I${MACA_PATH}/include/mcblas \
    -I${MACA_PATH}/include/common \
    -I${MACA_PATH}/include/mcr \
    -I/opt/mxmap/include \
    -L/opt/mxmap/lib \
    -lfaiss -lruntime_cu

编译成功后,运行 example 程序,可以得到如下的输出:

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/mxmap/lib ./example
query 0: 0 11 99
query 1: 1 50 78
query 2: 2 92 86
query 3: 3 93 63
query 4: 4 83 24
query 5: 5 60 17
query 6: 6 37 68
query 7: 7 36 14
query 8: 8 40 64
query 9: 9 83 24

注意事项

如果您的工程需要通过CMake的find_package使用mcFaiss,需要注意以下两点:

  • 由于 mcfaiss-dev 安装包将文件安装到 /opt/mxmap 目录下,所以需要设置 CMAKE_PREFIX_PATH,如下:

    set(CMAKE_PREFIX_PATH /opt/mxmap)
    find_package(faiss CONFIG REQUIRED)
    
  • 使用静态链接mcFaiss时,需要从源码编译安装0.3.x版本的OpenBLAS,编译命令参考如下:

    curl -fL https://gitee.com/mirrors/OpenBLAS/repository/archive/v0.3.27.tar.gz | tar xz
    cd OpenBLAS*
    cmake -S . -B build -D CMAKE_BUILD_TYPE=Release -D NO_AVX512=1 -D NOFORTRAN=1 -D USE_OPENMP=1 -D USE_THREAD=0
    cmake --build build -j
    sudo make -C build/ install
    

2.3.2. 代码示例(Python)

使用Python进行Flat索引完成向量添加、搜索,代码示例如下:

import faiss
import numpy as np

d = 4 # dimension
nb = 100 # database size
nq = 10 # nb of queries
topk = 3 # nb of probes

xb = np.random.random((nb, d)).astype('float32')
xq = xb[:nq]

index = faiss.IndexFlatL2(d)

index.add(xb)
dis, rids = index.search(xq, topk)

for i in range(nq):
    print('query {}: {}'.format(i, rids[i]))

安装mcFaiss Python扩展包后,使用Python来运行上述脚本,可以得到如下的输出:

$ python3.8 example.py
query 0: [ 0 74 24]
query 1: [ 1 20 58]
query 2: [ 2 90 33]
query 3: [ 3 81 40]
query 4: [ 4 47 28]
query 5: [ 5 66 85]
query 6: [ 6 45 67]
query 7: [ 7 14 49]
query 8: [ 8 62 31]
query 9: [ 9 17 69]

2.4. 常见问题

2.4.1. OpenBLAS引起coredump

如果在CPU核数较多的环境中使用Faiss,可能会出现如下错误:

OpenBLAS warning: precompiled NUM_THREADS exceeded, adding auxiliary array for thread metadata.

OpenBLAS: Program is Terminated. Because you tried to allocate too many memory regions. This library was built to support a maximum of 50 threads - either rebuild OpenBLAS with a larger NUM_THREADS value or set the environment variable OPENBLAS_NUM_THREADS to a sufficiently small number. This error typically occurs when the software that relies on OpenBLAS calls BLAS functions from many threads in parallel, or when your computer has more cpu cores than what OpenBLAS was configured to handle.

如提示信息所示,运行时所启动的线程数量超过了OpenBLAS的最大值。可以通过设置环境变量限制使用的线程数量,比如,使用以下命令将线程数量限制到50:

OMP_NUM_THREADS=50 OPENBLAS_NUM_THREADS=50 ./TestGpuIndexIVFFlat

2.4.2. 环境变量设置

如果应用程序使用的GPU设备的数量少于实际数量,为了获得最佳性能,建议通过 MACA_VISIBLE_DEVICES 环境变量指定实际使用的GPU ID。