277 lines
7.6 KiB
Plaintext
277 lines
7.6 KiB
Plaintext
|
|
**********************************************************
|
|
** INSTALL file for Faiss (Fair AI Similarity Search). **
|
|
**********************************************************
|
|
|
|
|
|
The Faiss installation works in 3 steps, from easiest to most
|
|
involved:
|
|
|
|
1. compile the C++ core and examples
|
|
|
|
2. compile the Python interface
|
|
|
|
3. compile GPU part
|
|
|
|
Steps 2 and 3 depend on 1, but they are otherwise independent.
|
|
|
|
General compilation instructions
|
|
================================
|
|
|
|
Faiss has been tested only on x86_64 machines on Linux and Mac OS.
|
|
|
|
Faiss is compiled via a Makefile. The system-dependent configuration
|
|
of the Makefile is in an include file, makefile.inc. The variables in
|
|
makefile.inc must be set by hand.
|
|
|
|
Faiss requires a C++ compiler that understands:
|
|
- the Intel intrinsics for SSE instructions
|
|
- the GCC intrinsic for the popcount instruction
|
|
- basic OpenMP
|
|
|
|
There are a few models for makefile.inc in the example_makefiles/
|
|
subdirectory. Copy the relevant one for your system and adjust to your
|
|
needs. There are also indications for specific configurations in the
|
|
troubleshooting section of the wiki.
|
|
|
|
https://github.com/facebookresearch/faiss/wiki/Troubleshooting
|
|
|
|
Faiss comes as a .a archive, that can be linked with executables or
|
|
dynamic libraries (useful for the Python wrapper).
|
|
|
|
|
|
Step 1: Compiling the C++ Faiss
|
|
===============================
|
|
|
|
The CPU version of Faiss is written in C++03, so it should compile
|
|
even with relatively old C++ compilers.
|
|
|
|
BLAS/Lapack
|
|
-----------
|
|
|
|
The only variables that need to be configured for the C++ Faiss are
|
|
the BLAS/Lapack flags (a linear aglebra software package). It needs a
|
|
flag telling whether BLAS/Lapack uses 32 or 64 bit integers and the
|
|
linking flags. Faiss uses the Fortran 77 interface of BLAS/Lapack and
|
|
thus does not need an include path.
|
|
|
|
There are several BLAS implementations, depending on the OS and
|
|
machine. To have reasonable performance, the BLAS library should be
|
|
multithreaded. See the example makefile.inc's for hints and examples
|
|
on how to set the flags.
|
|
|
|
To check that the link flags are correct, and verify whether the
|
|
implementation uses 32 or 64 bit integers, you can
|
|
|
|
make tests/test_blas
|
|
|
|
and run
|
|
|
|
./tests/test_blas
|
|
|
|
Testing Faiss
|
|
-------------
|
|
|
|
Once the proper BLAS flags are set, the library should compile
|
|
smoothly by running
|
|
|
|
make
|
|
|
|
A basic usage example is in
|
|
|
|
tests/demo_ivfpq_indexing
|
|
|
|
it makes a small index, stores it and performs some searches. A normal
|
|
runtime is around 20s. With a fast machine and Intel MKL's BLAS it
|
|
runs in 2.5s.
|
|
|
|
A real-life benchmark
|
|
---------------------
|
|
|
|
A bit longer example runs and evaluates Faiss on the SIFT1M
|
|
dataset. To run it, please download the ANN_SIFT1M dataset from
|
|
|
|
http://corpus-texmex.irisa.fr/
|
|
|
|
and unzip it to the sudirectory sift1M.
|
|
|
|
Then compile and run
|
|
|
|
make tests/demo_sift1M
|
|
tests/demo_sift1M
|
|
|
|
This is a demonstration of the high-level auto-tuning API. You can try
|
|
setting a different index_key to find the indexing structure that
|
|
gives the best performance.
|
|
|
|
|
|
Step 2: Compiling the Python interface
|
|
======================================
|
|
|
|
The Python interface is compiled with
|
|
|
|
make py
|
|
|
|
If you want to compile it for another python version than the default
|
|
Python 2.7, in particular Python 3, the PYTHONCFLAGS must be adjusted in
|
|
makefile.inc, see the examples.
|
|
|
|
How it works
|
|
------------
|
|
|
|
The Python interface is provided via SWIG (Simple Wrapper and
|
|
Interface Generator) and an additional level of manual wrappers (in faiss.py).
|
|
|
|
SWIG generates two wrapper files: a Python file (swigfaiss.py) and a
|
|
C++ file that must be compiled to a dynamic library (_swigfaiss.so). These
|
|
files are included in the repository, so running swig is only required when
|
|
the C++ headers of Faiss are changed.
|
|
|
|
The C++ compilation to the dynamic library requires to set:
|
|
|
|
- SHAREDFLAGS: system-specific flags to generate a dynamic library
|
|
|
|
- PYTHONCFLAGS: include flags for Python
|
|
|
|
See the example makefile.inc's on how to set the flags.
|
|
|
|
|
|
Testing the Python wrapper
|
|
--------------------------
|
|
|
|
Often, a successful compile does not mean that the library works,
|
|
because missing symbols are detected only at runtime. You should be
|
|
able to load the Faiss dynamic library:
|
|
|
|
python -c "import faiss"
|
|
|
|
In case of failure, it reports the first missing symbol. To see all
|
|
missing symbols (on Linux), use
|
|
|
|
ldd -r _swigfaiss.so
|
|
|
|
Sometimes, problems (eg with BLAS libraries) appear only when actually
|
|
calling a BLAS function. A simple way to check this
|
|
|
|
python -c "import faiss, numpy
|
|
faiss.Kmeans(10, 20).train(numpy.random.rand(1000, 10).astype('float32'))"
|
|
|
|
|
|
Real-life test
|
|
--------------
|
|
|
|
The following script extends the demo_sift1M test to several types of
|
|
indexes:
|
|
|
|
export PYTHONPATH=. # needed because the script is in a subdirectory
|
|
mkdir tmp # some output will be written there
|
|
python python/demo_auto_tune.py
|
|
|
|
It will cycle through a few types of indexes and find optimal
|
|
operating points. You can play around with the types of indexes.
|
|
|
|
|
|
Step 3: Compiling the GPU implementation
|
|
========================================
|
|
|
|
There is a GPU-specific Makefile in the gpu/ directory. It depends on
|
|
the same ../makefile.inc for system-specific variables. You need
|
|
libfaiss.a from Step 1 for this to work.
|
|
|
|
The GPU version is a superset of the CPU version. In addition it
|
|
requires:
|
|
|
|
- a C++11 compliant compiler (and flags)
|
|
|
|
- the cuda compiler and related libraries (Cublas)
|
|
|
|
See the example makefile on how to set the flags.
|
|
|
|
The nvcc-specific flags to pass to the compiler, based on your desired
|
|
compute capability. Only compute capability 3.5+ is supported. For
|
|
example:
|
|
|
|
-gencode arch=compute_35,code="compute_35"
|
|
-gencode arch=compute_52,code="compute_52"
|
|
-gencode arch=compute_60,code="compute_60"
|
|
|
|
Most other flags are related to the C++11 compiler used by nvcc to
|
|
complile the actual C++ code. They are normally just transmitted by
|
|
nvcc, except some of them that are not recognized and that should be
|
|
escaped by prefixing them with -Xcompiler. Also link flags that are
|
|
prefixed with -Wl, should be passed with -Xlinker.
|
|
|
|
Then compile with
|
|
|
|
cd gpu; make
|
|
|
|
You may want to add '-j 10' to use 10 threads during compile.
|
|
|
|
Testing the GPU implementation
|
|
------------------------------
|
|
|
|
Compile the example with
|
|
|
|
cd gpu; make test/demo_ivfpq_indexing_gpu
|
|
|
|
This produce the GPU code equivalent to the CPU
|
|
demo_ivfpq_indexing. It also shows how to translate indexed from/to
|
|
the GPU.
|
|
|
|
Compiling the Python interface with GPU support
|
|
-----------------------------------------------
|
|
|
|
Given step 2, adding support of the GPU from Python is quite
|
|
straightforward. Run
|
|
|
|
cd gpu; make py
|
|
|
|
The import is the same for the GPU version and the CPU-only
|
|
version.
|
|
|
|
python -c "import faiss"
|
|
|
|
Faiss tries to load the GPU version first, and in case of failure,
|
|
loads the CPU-only version. To investigate more closely the cause of
|
|
a failure, you can run:
|
|
|
|
python -c "import _swigfaiss_gpu"
|
|
|
|
Python example with GPU support
|
|
-------------------------------
|
|
|
|
The auto-tuning example above also runs on the GPU. Edit
|
|
|
|
export PYTHONPATH=.
|
|
python/demo_auto_tune.py
|
|
|
|
to enable and run it.
|
|
|
|
Hot to use Faiss in your own projects
|
|
=====================================
|
|
|
|
C++
|
|
---
|
|
|
|
The makefile generates a static and a dynamic library
|
|
|
|
libfaiss.a
|
|
libfaiss.so (or libfaiss.dylib)
|
|
|
|
the executable should be linked to one of these. If you use
|
|
the static version (.a), add the LDFLAGS used in the Makefile.
|
|
|
|
Python
|
|
------
|
|
|
|
To import Faiss in your own Python project, you need the files
|
|
|
|
faiss.py
|
|
swigfaiss.py / swigfaiss_gpu.py
|
|
_swigfaiss.so / _swigfaiss_gpu.so
|
|
|
|
to be visible in the PYTHONPATH or in the current directory.
|
|
Then Faiss can be used in python with
|
|
|
|
import faiss
|