Closed3

GPUに対応したFAISSをソースコードからビルドする

bilzardbilzard

概要

近似近傍探索のライブラリFAISS[1]のGPUに対応したバージョンをソースからインストールする手順について備忘録として記す。

環境

  • OS: Ubuntu 22.04.3 LTS (Docker)
  • GPU: GeForce RTX 4090
  • CUDA: 12.1
  • base docker image: nvidia/cuda:11.8.0-devel-ubuntu22.04

公式インストール手順の躓きどころ

基本的には公式ドキュメント[2]の通りなのだが、いくつかすんなりといかないところがあったのでそれらを中心に記す。

MKLのインストール

MKLというのは数値計算のライブラリらしいが、いくつかの実装がある。
ここでは公式ドキュメントが推奨するIntelのoneMKL[3]をインストールした。
なお、インストール方法がいくつか提供されているが、自分の場合はAPTでインストールした。

ビルドオプション

自分の環境では以下のようにした。MKL_LIBRARIESにはMKLのライブラリのパスを指定するらしいが、具体的にどの*.soを指定するのかについて、検索した限り解決策が見つからなかった。ChatGPT-4の回答を元にlibmkl_rt.so.2のパスを指定したら動作したためこの設定を採用した(理にかなっているのかは不明)。

CUDA_ARCHITECTURESはNVIDIAが製造するGPU製品ごとにcapabilityという番号が付与されているので、CUDAの公式ドキュメントの表[4]をもとにその番号を指定する。自分の使用しているGeForce RTX 4090のcapabilityは8.9なので89を指定した。

    MKL_ROOT=/opt/intel/oneapi/mkl/latest/lib/intel64
    cmake -B build . \
        -DFAISS_ENABLE_GPU=ON \
        -DFAISS_ENABLE_PYTHON=ON \
        -DFAISS_ENABLE_RAFT=OFF \
        -DBUILD_TESTING=ON \
        -DBUILD_SHARED_LIBS=ON \
        -DFAISS_ENABLE_C_API=ON \
        -DCMAKE_BUILD_TYPE=Release \
        -DFAISS_OPT_LEVEL=avx2 \
        -DBLA_VENDOR=Intel10_64_dyn \
        -DMKL_LIBRARIES=$MKL_ROOT/libmkl_rt.so.2 \
        -DCUDAToolkit_ROOT=/usr/local/cuda-11.8 \
        -DCMAKE_CUDA_ARCHITECTURES="89" \
        -DPython_EXECUTABLE=/usr/bin/python3.10

最終的なインストール手順

執筆時点(2023.10.3)における自分の環境でのインストール手順は最終的に以下のようになった。

#!/bin/bash
#===================================================================================================
# 1. Install MKL
# ref: https://www.intel.com/content/www/us/en/developer/tools/oneapi/onemkl-download.html?operatingsystem=linux&distributions=aptpackagemanager
wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB |
    gpg --dearmor | tee /usr/share/keyrings/oneapi-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" |
    tee /etc/apt/sources.list.d/oneAPI.list
apt update && apt install -y intel-oneapi-mkl

# set environment variables
source /opt/intel/oneapi/setvars.sh intel64

# add init script to bashrc
printf "\n# initialize oneapi\nsource /opt/intel/oneapi/setvars.sh intel64\n" >>~/.bashrc

#===================================================================================================
# 2. Build FAISS from source
# ref: https://github.com/facebookresearch/faiss/blob/main/INSTALL.md#building-from-source

# install requirements to build python bindings
apt -y install swig

if [ ! -d faiss ]; then
    git clone https://github.com/facebookresearch/faiss
fi
cd faiss

# ref:
# - cuda capability: https://developer.nvidia.com/cuda-gpus#compute
#   GeForce RTX 4090 -> 8.9
if [ ! -d build ]; then
    MKL_ROOT=/opt/intel/oneapi/mkl/latest/lib/intel64
    cmake -B build . \
        -DFAISS_ENABLE_GPU=ON \
        -DFAISS_ENABLE_PYTHON=ON \
        -DFAISS_ENABLE_RAFT=OFF \
        -DBUILD_TESTING=ON \
        -DBUILD_SHARED_LIBS=ON \
        -DFAISS_ENABLE_C_API=ON \
        -DCMAKE_BUILD_TYPE=Release \
        -DFAISS_OPT_LEVEL=avx2 \
        -DBLA_VENDOR=Intel10_64_dyn \
        -DMKL_LIBRARIES=$MKL_ROOT/libmkl_rt.so.2 \
        -DCUDAToolkit_ROOT=/usr/local/cuda-11.8 \
        -DCMAKE_CUDA_ARCHITECTURES="89" \
        -DPython_EXECUTABLE=/usr/bin/python3.10

    # build faiss C++ library
    make -C build -j faiss

    # build the python bindings
    make -C build -j swigfaiss
fi
(cd build/faiss/python && python setup.py install)

# check if successfully installed
pip freeze | grep faiss

# build & run basic CPU example
make -C build demo_ivfpq_indexing
./build/demos/demo_ivfpq_indexing

# build & run basic GPU example
make -C build demo_ivfpq_indexing_gpu
./build/faiss/gpu/test/demo_ivfpq_indexing_gpu

# run realtime benchmark (CPU)
# wget ftp://ftp.irisa.fr/local/texmex/corpus/sift.tar.gz
# tar -xzvf sift.tar.gz
# mv sift sift1M
# make -C build demo_sift1M
# build/demos/demo_sift1M

参考資料

Appendix

python bindingをシステムにインストールする

上記手順ではfaissディレクトリを削除するとfaissライブラリを参照できなくなる。
ビルドした資材のみシステムにインストールし、他の中間生成物に依存しないようにするには以下のようにする。

# build wheel
(cd build/faiss/python && pip wheel . --no-deps)

# install *.so files to system
cp build/faiss/libfaiss.so /usr/local/lib/.
cp build/faiss/python/lib/faiss_python_callbacks.so /usr/local/lib/.

# install python bindings
(cd build/faiss/python && pip install faiss*.whl)
bilzardbilzard

python bindingのテスト

python上から利用できるかの確認は以下のようにする(コードはここから転載した)。

import faiss
import numpy as np

d = 64                           # dimension
nb = 1000000                     # database size
nq = 10000                       # nb of queries
np.random.seed(1234)             # make reproducible
xb = np.random.random((nb, d)).astype('float32')
xb[:, 0] += np.arange(nb) / 1000.
xq = np.random.random((nq, d)).astype('float32')
xq[:, 0] += np.arange(nq) / 1000.

gpu_resource = faiss.StandardGpuResources()
cpu_index = faiss.IndexFlatL2(d)
gpu_index = faiss.index_cpu_to_gpu(gpu_resource, 0, cpu_index)
gpu_index.add(xb)

k = 4                              # we want to see 4 nearest neighbors
D, I = gpu_index.search(xb, k)     # actual search
print(I)
[[     0    393    363     78]
 [     1    555    277    364]
 [     2    304    101     13]
 ...
 [999997 999636 999411 999877]
 [999998 999575 999987 999933]
 [999999 999916 999470 999911]]
このスクラップは2023/10/03にクローズされました