【向量数据库】相似向量检索Faiss数据库的安装及余弦相似度计算(C++)
目录
- 简介
- 安装方法
- 安装OpenBLAS
- 安装lapack
- 编译Faiss
- 代码示例
- 余弦相似度计算
- 输出ID号而非索引的改进版
简介
Faiss 是一个强大的向量相似度搜索库,具有以下优点:
-
高效的搜索性能:Faiss 在处理大规模向量数据时表现出色。它利用了高度优化的索引结构和近似搜索算法,可以快速地执行最近邻搜索和相似度匹配,具有很低的查询延迟。
-
高度可扩展:Faiss 提供了多种索引结构和算法的选择,包括 k-d树、IVF(Inverted File System)和 PQ(Product Quantization)等。这些索引结构能够轻松应对大规模的向量数据集,并支持高效的并行计算和分布式处理。
-
高精度的近似搜索:Faiss 通过采用近似搜索技术,在保证搜索速度的同时,尽量接近精确搜索的结果。这使得 Faiss 在许多实际应用中能够有效地处理高维度的向量数据,如图像、文本和推荐系统等。
-
多语言支持:Faiss 提供了多种编程语言的接口,如 Python、Java 和 Go 等,使得它能够方便地集成到各种应用和平台中。
然而,Faiss 也有一些局限性和缺点:
-
内存消耗:Faiss 在处理大规模向量数据时可能需要大量的内存。特别是在使用一些高级索引结构和算法时,内存消耗可能会很高。
-
学习曲线陡峭:对于初次接触 Faiss 的开发者来说,学习曲线可能会比较陡峭。理解并配置 Faiss 的索引结构、算法和参数可能需要一定的时间和经验。
综上所述,Faiss 是一个强大而高效的向量相似度搜索库,适用于大规模的向量数据集和高维度的向量数据。它提供了高速的近似搜索和优化的索引结构,有助于构建复杂的检索系统和应用。然而,在使用 Faiss 时需要注意内存消耗和学习曲线的挑战。
安装方法
安装OpenBLAS
OpenBLAS 是一个开源的数值线性代数库,用于高性能科学计算和数据处理。它提供了基于多核处理器和向量指令集的并行化实现,以加速矩阵运算和其他数值计算操作。
git clone https://github.com/xianyi/OpenBLAS.git
gfortran 是 GNU Compiler Collection(简称 GCC)的一部分,它是 GNU 项目开发的免费开源的编译器套件。gfortran 是 GCC 提供的 Fortran 编译器,用于编译和执行 Fortran 程序。
使用gfortran进行编译:
sudo apt install gfortran
cd OpenBLAS
make FC=gfortran
make install
ln -s /opt/OpenBLAS/lib/libopenblas.so /usr/lib/libopenblas.so
LD_LIBRARY_PATH=/opt/OpenBLAS/lib
export LD_LIBRARY_PATH
在这个特定的命令中,FC=gfortran将设置FC变量的值为"gfortran",指示构建过程使用gfortran作为Fortran编译器。
安装lapack
LAPACK(Linear Algebra Package)是一个用于数值线性代数计算的库,它提供了一系列高性能的算法和子程序,用于解决线性方程组、特征值问题、奇异值分解和相关的数值计算任务。
wget http://www.netlib.org/lapack/lapack-3.4.2.tgz
tar -zxf lapack-3.4.2.tgz
cd lapack-3.4.2
cp ./INSTALL/make.inc.gfortran ./
mv make.inc.gfortran make.inc
vi Makefile # 修改如下
[#lib: lapacklib tmglib
lib: blaslib variants lapacklig tmglib]
make
cd lapacke
make
cp include/*.h /usr/include
cd ..
cp *.a /usr/lib
编译Faiss
git clone https://github.com/facebookresearch/faiss.git
cd faiss
#这个命令是使用 CMake 构建一个项目,并将构建产物放置在名为 “build” 的目录中。
cmake -B build . -DFAISS_ENABLE_GPU=OFF -DFAISS_ENABLE_PYTHON=OFF
#这个命令是使用 make 构建名为 “faiss” 的目标,并且指定构建目录为 “build”。
make -C build -j faiss
#这个命令是使用 make 进行构建,并将构建产物安装到系统中。同样在build目录下构建
make -C build install
代码示例
余弦相似度计算
给定一个向量,在已有的两个向量中,找到余弦相似度最优的一个向量:
#include <iostream>
#include <cmath>
#include <faiss/IndexFlat.h>
#include <faiss/index_io.h>
#include <faiss/utils/distances.h>
int main() {// 创建索引对象faiss::IndexFlatIP index(2); // 使用L2距离度量,2维向量// 添加向量数据float xb[4] = {1.0, 1.0, 0.0, 0.5}; // 2个2维向量//存储向量个数:int n=2;// 为了使用内积求出余弦相似度,要对每个向量进行归一化操作size_t d = 2; // 向量维度float norm[d]={0,0};// 计算向量的 L2 范数,是已经过开方的// 函数有四个参数:// x:指向输入向量数组的指针,所有向量在内存中是连续存储的。即向量数组的布局是 [x₀₀, x₀₁, ..., xₙ₋₁(d-1)]。// norms:指向输出结果数组的指针,用于存储计算出的 L2 范数。结果数组的布局和输入向量相同,即 [norm₀, norm₁, ..., normₙ₋₁]。// d:向量的维度,即每个向量的元素数目。// n:向量的数量(或者说是向量数组的长度)。faiss::fvec_norms_L2(norm, xb,d,n); // 将每个向量归一化为单位向量,同时添加到索引中#pragma omp parallel{#pragma omp forfor (int i = 0; i < n; i++) {// 每个向量的起始地址float* vector = &xb[i * d]; // 将向量归一化为单位向量for (size_t j = 0; j < d; j++) {vector[j] /= norm[i];}// 每次将1个向量添加到索引中#pragma omp critical{index.add(1, vector);}}//进行同步#pragma omp barrier}// 保存索引到文件faiss::write_index(&index, "index.faissindex");// 从文件加载索引faiss::Index* loaded_index = faiss::read_index("index.faissindex");// 执行搜索float xq[2] = {1.0, 0.0}; // 查询向量int k = 1; // 返回最接近的2个邻居faiss::idx_t* I = new faiss::idx_t[k]; // 邻居索引float* D = new float[k]; // 邻居距离// search 方法的主要参数如下:
// n:表示要搜索的查询向量的数量,即查询向量的个数。
// x:一个指向浮点数的指针,表示查询向量的数据。x 的大小应该为 n 乘以向量的维度。
// k:表示要返回的相似邻居的数量。
// distances:一个指向浮点数的指针,用于存储查询向量与相似邻居之间的距离。distances 的大小应该为 n 乘以 k。
// labels:一个指向整数的指针,用于存储相似邻居的索引(标签)。labels 的大小应该为 n 乘以 k。loaded_index->search(1, xq, k, D, I);// 打印结果std::cout << "查询结果:" << std::endl;std::cout << "邻居索引: " << I[0] << ", 距离: " << D[0] << std::endl;//返回原始向量:// 获取索引为 i 的向量// 向量的维度std::vector<float> vectors(index.d);index.reconstruct(I[0], vectors.data());// 使用循环遍历并打印该向量每个元素for (const auto& element : vectors) {std::cout << element << " ";}std::cout << std::endl;// 释放内存delete loaded_index;delete[] I;delete[] D;return 0;
}
对应cmakelist:
cmake_minimum_required(VERSION 3.5)
project(fangdou)
FIND_PACKAGE( OpenMP REQUIRED)
if(OPENMP_FOUND)
message("OPENMP FOUND")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()# 添加 Faiss 库的路径
set(FAISS_INCLUDE_DIR /usr/local/include/faiss)
set(FAISS_LIBRARY_DIR /usr/local/lib)include_directories(
${FAISS_INCLUDE_DIR}
)SET(OpenCV_DIR /usr/local/lib/cmake/opencv4/)
FIND_PACKAGE(OpenCV REQUIRED)file(GLOB_RECURSE cpp_srcs ${CMAKE_SOURCE_DIR}/src/*.cpp ${CMAKE_SOURCE_DIR}/src/*.cc ${CMAKE_SOURCE_DIR}/src/*.h)link_directories(
/usr/lib/x86_64-linux-gnu/
${FAISS_LIBRARY_DIR}
)add_executable(${PROJECT_NAME} ${cpp_srcs})target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS} faiss openblas)
输出ID号而非索引的改进版
#include <iostream>
#include <cmath>
#include <faiss/IndexFlat.h>
#include <faiss/index_io.h>
#include <faiss/utils/distances.h>
#include <faiss/IndexIDMap.h>
int main() {// 创建一个IndexFlatIP内积索引对象作为内部索引faiss::IndexFlatIP inner_index(2);// 创建一个IndexIDMap对象,将内部索引设置为IndexFlatIPfaiss::IndexIDMap index(&inner_index);// 添加向量数据float xb[4] = {1.0, 1.0, 0.0, 0.5}; // 2个2维向量//idsfaiss::idx_t ids[] = {1001, 1002};//存储向量个数:int n=2;// 为了使用内积求出余弦相似度,要对每个向量进行归一化操作size_t d = 2; // 向量维度float norm[d]={0,0};// 计算向量的 L2 范数,是已经过开方的// 函数有四个参数:// x:指向输入向量数组的指针,所有向量在内存中是连续存储的。即向量数组的布局是 [x₀₀, x₀₁, ..., xₙ₋₁(d-1)]。// norms:指向输出结果数组的指针,用于存储计算出的 L2 范数。结果数组的布局和输入向量相同,即 [norm₀, norm₁, ..., normₙ₋₁]。// d:向量的维度,即每个向量的元素数目。// n:向量的数量(或者说是向量数组的长度)。faiss::fvec_norms_L2(norm, xb,d,n); // 将每个向量归一化为单位向量,同时添加到索引中#pragma omp parallel{#pragma omp forfor (int i = 0; i < n; i++) {// 每个向量的起始地址float* vector = &xb[i * d]; // 将向量归一化为单位向量for (size_t j = 0; j < d; j++) {vector[j] /= norm[i];}// 每次将1个向量添加到索引中#pragma omp critical{index.add_with_ids(1, vector,&ids[i]);}}//进行同步#pragma omp barrier}// 保存索引到文件faiss::write_index(&index, "index.faissindex");// 从文件加载索引faiss::Index* loaded_index = faiss::read_index("index.faissindex");// 执行搜索float xq[2] = {1.0, 0.0}; // 查询向量int k = 1; // 返回最接近的2个邻居faiss::idx_t* I = new faiss::idx_t[k]; // 邻居索引float* D = new float[k]; // 邻居距离// search 方法的主要参数如下:
// n:表示要搜索的查询向量的数量,即查询向量的个数。
// x:一个指向浮点数的指针,表示查询向量的数据。x 的大小应该为 n 乘以向量的维度。
// k:表示要返回的相似邻居的数量。
// distances:一个指向浮点数的指针,用于存储查询向量与相似邻居之间的距离。distances 的大小应该为 n 乘以 k。
// labels:一个指向整数的指针,用于存储相似邻居的索引(标签)。labels 的大小应该为 n 乘以 k。loaded_index->search(1, xq, k, D, I);// 打印结果std::cout << "查询结果:" << std::endl;std::cout << "邻居索引: " << I[0] << ", 距离: " << D[0] << std::endl;//此时不再支持返回原向量。// 释放内存delete loaded_index;delete[] I;delete[] D;return 0;
}
相关文章:
【向量数据库】相似向量检索Faiss数据库的安装及余弦相似度计算(C++)
目录 简介安装方法安装OpenBLAS安装lapack编译Faiss 代码示例余弦相似度计算输出ID号而非索引的改进版 简介 Faiss 是一个强大的向量相似度搜索库,具有以下优点: 高效的搜索性能:Faiss 在处理大规模向量数据时表现出色。它利用了高度优化的索…...
教育培训小程序的设计与功能解析
随着互联网的发展,线上教育逐渐成为一种趋势,越来越多的人开始选择在线学习。而搭建一个适合自己的线上教育小程序,可以为教育机构或个人提供更好的教学和学习体验。在本文中,我们将介绍如何通过一个第三方制作平台来搭建在线教育…...
【ES】illegal_argument_exception“,“reason“:“Result window is too large
查询ES数据返回错误: {"root_cause":[{"type":"illegal_argument_exception","reason":"Result window is too large, from size must be less than or equal to: [10000] but was [999999]. See the scroll api for…...
SpringBoot实现登录拦截
如果我们不进行登录拦截的话,即使我们跳过登录页面直接去访问任意一个页面也能访问成功,那么登录功能就没有意义,同时也会存在安全问题,因为有些操作是要用户登录后才能执行的,如果用户没有登录,该接口就获…...
浅谈泛在电力物联网、能源互联网与虚拟电厂
导读:从能源互联网推进受阻,到泛在电力物联网名噪一时,到虚拟电厂再次走向火爆,能源领域亟需更进一步的数智化发展。如今,随着新型电力系统建设推进,虚拟电厂有望迎来快速发展。除了国网和南网公司下属的电…...
深度学习框架安装与配置指南:PyTorch和TensorFlow详细教程
如何安装和配置深度学习框架PyTorch和TensorFlow 为什么选择PyTorch和TensorFlow?PyTorchTensorFlow安装PyTorch 步骤1:安装Python步骤2:使用pip安装PyTorch 安装TensorFlow 步骤1:安装Python步骤2:使用pip安装TensorF…...
vue中属性执行顺序
vue中属性的执行顺序 在Vue 2中,组件的生命周期和数据绑定的执行顺序如下: data:首先,组件会调用 data 函数,该函数返回一个对象,该对象的属性和方法会被分配给组件的 $data。init:接下来&…...
【代码随想录】Day 50 动态规划11 (买卖股票Ⅲ、Ⅳ)
买卖股票Ⅲ https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/ 无语了。。。 写的很好就是怎么都过不了。。。 还是就用代码随想录的写法吧。。。 class Solution { public:int maxProfit(vector<int>& prices) {int n prices.size();vector&…...
PHP反序列化漏洞
一、序列化,反序列化 序列化:将php对象压缩并按照一定格式转换成字符串过程反序列化:从字符串转换回php对象的过程目的:为了方便php对象的传输和存储 seriallize() 传入参数为php对象,序列化成字符串 unseriali…...
容器编排学习(一)k8s集群管理
一 Kubernetes 1 概述 就在Docker容器技术被炒得热火朝天之时,大家发现,如果想要将Docker应用于具体的业务实现,是存在困难的一一编排、管理和调度等各个方面,都不容易。于是,人们迫切需要一套管理系统࿰…...
js去除字符串空格的几种方式
方法1:(最常用)全部去除掉空格 var str abc d e f g ; function trim(str) { var reg /[\t\r\f\n\s]*/g; if (typeof str string) { var trimStr str.replace(reg,); } console.lo…...
Spring 自带工具——URI 工具UriComponentsBuilder
UriComponentsBuilder 是 Spring Framework 提供的一个实用工具类,用于构建 URI(Uniform Resource Identifier)。URI 是用于标识和定位资源的字符串,例如 URL(Uniform Resource Locator)就是一种特殊的 URI…...
优化案例5:视图目标列改写优化
优化案例5:视图目标列改写优化 1. 问题描述2. 分析过程2.1 目标SQL2.2 解决思路1)效率低的执行计划2)视图过滤性3)查看已有索引定义 2.3 视图改写2.4 增添复合索引 3. 优化总结 DM技术交流QQ群:940124259 1. 问题描述…...
Origin绘制彩色光谱图
成果图 1、双击线条打开如下窗口 2、选择“图案”-》颜色-》按点-》映射-》Wavelength 3、选择颜色映射 4、单击填充-》选择加载调色板-》Rainbow-》确定 5、单击级别,设置成从370到780,右侧增量选择2(越小,颜色渐变越细腻&am…...
项目复盘:从实践中学习
引言 在我们的工作生涯中,每一个项目都是一次学习的机会。项目复盘是对已完成项目的全面评估,旨在理解我们做得好的地方,以及需要改进的地方。这篇文章将分享我们如何进行项目复盘,以及我们从中学到了什么。 项目背景 在我们开…...
机器学习和数据挖掘02-Gaussian Naive Bayes
概念 贝叶斯定理: 贝叶斯定理是概率中的基本定理,描述了如何根据更多证据或信息更新假设的概率。在分类的上下文中,它用于计算给定特征集的类别的后验概率。 特征独立性假设: 高斯朴素贝叶斯中的“朴素”假设是,给定…...
【面试题精讲】Java Stream排序的实现方式
首发博客地址 系列文章地址 如何使用Java Stream进行排序 在Java中,使用Stream进行排序可以通过sorted()方法来实现。sorted()方法用于对Stream中的元素进行排序操作。具体实现如下: 对基本类型元素的排序: 使用sorted()方法对Stream进行排序…...
浅谈Spring
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。 一、什么是IOC? IoC Inversion of Control 翻译成中⽂是“控制反转”的意思,也就是说 Spring 是⼀个“控制反转”的容器。 1.1控制反转推导 这个控制反转怎…...
Java 复习笔记 - 面向对象进阶篇
文章目录 一,Static(一)Static的概述(二)静态变量(三)静态方法(四)工具类(五)static的注意事项 二,继承(一)继…...
微信小程序中识别html标签的方法
rich-text组件 在微信小程序中有一个组件rich-text可以识别文本节点或是元素节点 具体入下: //需要识别的数据放在data中,然后放在nodes属性中即可 <rich-text nodes"{{data}}"></rich-text>详情可以参考官方文档:https://developers.weixin.qq.com/mi…...
02_常见网络层协议的头结构
1.ARP报文的报文结构 ARP首部的5个字段的含义: 硬件类型:值为1表示以太网MAC地址。 协议类型:表示要映射的协议地址类型,0x0800 表示映射为IP地址。 硬件地址长度:在以太网ARP的请求和应答中都是6,表示M…...
ChatGLM学习
GLM paper:https://arxiv.org/pdf/2103.10360.pdfchatglm 130B:https://arxiv.org/pdf/2210.02414.pdf 前置知识补充 双流自注意力 Two-stream self-attention mechanism(双流自注意机制)是一种用于自然语言处理任务的注意力机制…...
Flink之Watermark
1.乱序问题 流处理从事件产生,到流经source,再到operator,中间是有一个过程和时间的,虽然大部分情况下,流到operator的数据都是按照事件产生的时间顺序来的,但是也不排除由于网络、分布式等原因࿰…...
二轮平衡小车3:PID速度环
使用芯片:STM32 F103 C8T6 今日继续我的二路平衡小车开发之路,今日编写的是二轮平衡小车的PID速度环,我准备了纸飞机串口助手软件来辅助测试调节PID。 本文主要贴代码,之前的文章都有原理,代码中相应初始化驱动部分也…...
C语言之练习题
欢迎来到我的世界 希望这篇文章对你有所帮助,有不足的地方还请指正,大家一起学习交流 ! 目录 前言编程题第一题:珠玑妙算第二题:寻找奇数第三题:寻找峰值第四题:数对 总结 前言 这是暑假题目的收尾文章&am…...
没钱,没人,没经验?传统制造型企业如何用无代码实现转型
2023年,国家市场监督管理总局发布了三项重要标准,包括《工业互联网平台选型要求》、《工业互联网平台微服务参考框架》和《工业互联网平台开放应用编程接口功能要求》。这些标准的发布对于完善工业互联网平台标准体系,提升多样化工业互联网平…...
CentOS ARM 部署 kubernetes v1.24.6
1.背景 之前安装的kubernetes版本为v1.19.0 树莓派使用(CentOS7.9 armv71 Kubernetes1.19.0), 由于版本过低,一些HPA相关的功能支持不是特别好,因此需要将版本升级,本次会将版本升级为v1.24.6. 2. 如何upgrade 2.1. 优雅升级 kubeadm自带…...
LeetCode 725. Split Linked List in Parts【链表】中等
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
云计算中的负载均衡技术,确保资源的平衡分配
文章目录 1. 硬件负载均衡器2. 软件负载均衡器3. DNS负载均衡4. 内容分发网络(CDN) 🎈个人主页:程序员 小侯 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏 ✨收录专栏:云计算 ✨文章内…...
探索 SOCKS5 代理在跨境电商中的网络安全应用
随着全球化的发展,跨境电商成为了商业界的一颗新星,为企业提供了无限的发展机遇。然而,随之而来的是网络安全的挑战,特别是在处理国际网络流量时。在这篇文章中,我们将探讨如何利用 SOCKS5 代理和代理 IP 技术来加强跨…...
医院如何做网站策划?/免费人脉推广软件
CPython c语言开发的 使用最广的解释器IPython 基于cpython之上的一个交互式计时器 交互方式增强 功能和cpython一样PyPy 目标是执行效率 采用JIT技术 对python代码进行动态编译,提高执行效率JPython 运行在Java上的解释器 直接把python代码编译成Java字节码执行Iro…...
wordpress主题报错/网站代发外链
PHP 安全三板斧:过滤、验证和转义之过滤篇 & Laravel底层SQL注入规避由 学院君 创建于4年前, 最后更新于 1年前版本号 #328413 views19 likes0 collects我们在开发应用时,一般有个约定:不要信任任何来自不受自己控制的数据源中的数据。例…...
企业网站做电脑营销/文章推广平台
问题 当物体正常展示后,设置为实体展示,却无法显示出立体的效果来,按照给出的MeshLambertMaterial材料设置的例子反复尝试都不成功 实例 var cubeGeometry new THREE.BoxGeometry(15, 15, 15); var meshMaterial new THREE.MeshLamebertM…...
住房和城乡建设厅网站青海省/今日军事新闻头条
typedef int ElemType; typedef struct Node { ElemType data; struct Node *prev; struct Node *next; }RingLink;以上是定义结构体。 以下是双向循环链表的实现 void RingLinkInit(RingLink *head) //初始化 { if (head NULL) exit(0); head->next head->prev …...
dede网站建设的个人总结/搜索引擎排名大全
nana 安全牛 漏洞管理依然是大多数安全计划的重要组成部分,全球绝大多数公司企业都认同这一点。 在安全公司Tripwire最近的一份网络健康状态调查中,80%的受访者称自家企业有漏洞扫描计划。约60%的受访者每天或每周进行一次扫描,40%的受访者…...
icp备案证书号查询/沈阳网站制作优化推广
Spring实现定时任务方法 标签: springquartztask 2017-03-11 02:02 190人阅读 评论(0) 收藏 举报 分类: spring(3) 作者同类文章Xtask quartz 版权声明:本文为博主原创文章࿰…...