Faiss 用于高效相似性搜索和密集向量聚类, 常用于异常检测中的相似度评估, 库有 GPU 扩展版本, 但官方只支持 Linux. 本文讨论在 Windows 下编译 faiss-GPU 并安装到 Python.
虽然理论上我应该添加与 Windows+CUDA 相关的 Github Action, 然后合并到上游, 但是我暂时没有与之搏斗的念头.
准备工作
- 安装 Winget, 用于下载一些工具, 目前 Windows 应该是预装的, 但是如果你没, 可以访问getwinget或者微软官方文档
- VS 2019或2022, 截止当下(2025/09/23), Intel OneAPI 不支持 VS2026. 执行:
winget install Microsoft.VisualStudio.2022.BuildTools
, 或打开visual studio Installer
选择 vs2022 构建工具 - CMake,
winget install Kitware.CMake
- Ninja, 代替 MSBuild 编译会快很多, 执行:
winget install Ninja-build.Ninja
- swig, faiss 用来生成 Python 扩展, 执行:
winget install SWIG.SWIG
- BLAS, 根据官方建议, 如果在 Inter 平台, 选择 Intel OneAPI MKL, 其他则选择 OpenBLAS
- Intel OneAPI,
winget install Intel.OneAPI.BaseToolkit
, 文件很大(~2.8G), 安装后确保你能找到一个叫setvars.bat
的文件, 如果安装路径默认, 这个文件在C:\Program Files (x86)\Intel\oneAPI\setvars.bat
- OpenBLAS? 我没有试过, 我只是走通了上面的 MKL 流程
- Intel OneAPI,
- CUDA 12.x 访问
https://developer.nvidia.com/cuda-toolkit-archive
, 然后选一个. 我在12.4、12.9
都测试成功 - [可选] Python, 如果你不需要 Python 包可以没有
安装 gflags
faiss 依赖 gflags, 只需依次执行如下命令来安装
git clone https://github.com/gflags/gflags.git
cd gflags
cmake -B build-out . -G "Ninja" -DCMAKE_INSTALL_PREFIX=C:/opt/gflags # 目录会自动创建并注册
cmake --build build-out --config Release
cmake --install build-out
[可选] 配置 Python
找一个你认为合适的目录, 新建虚拟环境然后安装三个包, 随后激活虚拟环境并进入 Faiss 代码目录
python -m venv .venv
pip install setuptools packaging numpy
激活环境
首先在开始菜单找到x64 Native Tools Command Prompt for VS 2022
, 在其中执行 C:\Program Files (x86)\Intel\oneAPI\setvars.bat
, 结果类似于:
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.14.14
** Copyright (c) 2025 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools>"C:\Program Files (x86)\Intel\oneAPI\setvars.bat"
:: initializing oneAPI environment...
Initializing Visual Studio command-line environment...
Visual Studio version 17.14.14 environment configured.
"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\"
Visual Studio command-line environment initialized for: 'x64'
: advisor -- latest
: compiler -- latest
: dal -- latest
: debugger -- latest
: dev-utilities -- latest
: dnnl -- latest
: dpcpp-ct -- latest
: dpl -- latest
: ipp -- latest
: ippcp -- latest
: mkl -- latest
: ocloc -- latest
: pti -- latest
: tbb -- latest
: umf -- latest
: vtune -- latest
:: oneAPI environment initialized ::
我直接在 cmd 中执行C:\Program Files (x86)\Intel\oneAPI\setvars.bat
会告诉我找不到 VS 环境
克隆代码
我对上游代码做了些修改, 在上游修补之前, 你可以克隆我的分支
git clone https://github.com/myuanz/faiss.git
cd faiss
之后默认都在 Faiss 代码目录执行.
配置
# 如果需要 Python 扩展, 执行
cmake . -B build -DFAISS_ENABLE_PYTHON=ON -G "Ninja" -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DFAISS_ENABLE_GPU=ON
# 如果不需要 Python 扩展, 执行
cmake . -B build -DFAISS_ENABLE_PYTHON=OFF -G "Ninja" -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DFAISS_ENABLE_GPU=ON
如果提示 SWIG 找不到, 则你需要在 PowerShell 里执行:
' -DSWIG_EXECUTABLE=' + (Get-Item (where.exe swig | Select-Object -First 1) -Force).Target
一份可能的输出是:
-DSWIG_EXECUTABLE=C:\Users\pc\AppData\Local\Microsoft\WinGet\Packages\SWIG.SWIG_Microsoft.Winget.Source_8wekyb3d8bbwe\swigwin-4.3.1\swig.exe
把这句粘贴到之前 cmake 命令的后面
构建 C++ 部分
cmake --build build -j
cmake --install build --prefix install
我也将这个导出的install
放到了 releases
构建 Python 部分
cd build/faiss/python
python setup.py install
修改 loader.py
我不确定为什么, 我需要修改 loader.py 里的
- from .swigfaiss import *
+ from swigfaiss import *
才能正常导入
检查结果正确性
我在仓库里额外提供了一个 try_import_faiss_python.py
, 安装 faiss-python 之后修改 loader, 然后执行这个文件可以看到一些 GPU 信息和性能比对. 由于运行时还需要一些 dll, 该文件在开头也添加了一些路径:
import os, sys, ctypes
for p in (
r'./build/faiss/python',
r'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.9\bin',
r'C:\Program Files (x86)\Intel\oneAPI\compiler\2025.2\bin',
r'C:\Program Files (x86)\Intel\oneAPI\mkl\2025.2\bin'
):
p = os.path.abspath(p)
os.add_dll_directory(p)
sys.path.append(p)
#
# The below code is generated by LLM:
# GPU self-check
ngpu = faiss.get_num_gpus()
print(f"[INFO] Num GPUs detected by FAISS: {ngpu}")
if ngpu == 0:
raise RuntimeError("Can't find GPU")
# %%
# Parameters (adjust as needed; Flat complexity ~ nb*nq*d)
d = 64
nb = 200_000
nq = 40_000 # Increase batch size to avoid launch/scheduling overhead dominating
k = 10
seed = 123
rs = np.random.RandomState(seed)
xb = rs.randn(nb, d).astype('float32')
xq = rs.randn(nq, d).astype('float32')
xb = rs.randn(nb, d).astype('float32')
# Make the vectors have a "small structure" for sanity check
xb[:100, :] += 3
xq = (rs.randn(nq, d)).astype('float32')
xq[:5, :] += 3
# ---- CPU baseline ----
cpu = faiss.IndexFlatL2(d)
t0 = time.perf_counter()
cpu.add(xb)
t1 = time.perf_counter()
Dcpu, Icpu = cpu.search(xq, k)
t2 = time.perf_counter()
print(f"[CPU] add {1e3*(t1-t0):.1f} ms search {1e3*(t2-t1):.1f} ms")
... # 下略
执行代码会首先看到 CPU 满载, 然后 GPU 满载. 这份代码只是跑通了, 姿势不太好看, 以后有机会研究一下怎么发 whl 吧.