从零构建向量数据库
本书主旨在于强化读者对向量数据库的认识,加深对于目前AI前置工程的步骤理解。
向量数据库基础
万物皆可向量化,通过固定指标、分化多个坐标参数来形容事物,从而确定事物之间的相似度、关系和距离。
余弦相似度——衡量两者在方向上的相似度(无关标量)
内积——可以用于确定向量在某些特征上面的绝对数值
欧式距离——确认两个向量之间的差异程度
应用案例:
- 以图搜图——图片转为向量形式,相似度计算,找到相似的图片
- 听歌识曲——歌曲向量化后,确认特征之间的相似度,快速定位匹配歌曲
- 客户服务——QA向量化后做相似度匹配,可以用RAG来加强
存储非结构化数据的存储系统;存储结构化数据的数据库系统。
数据库系统——存储系统的一种,聚焦于结构化数据,方便后续直接计算,可以通过索引和排序加速原始数据的访问速度。
当前数据库设计模式不适合向量的存储,多维的拆分行列会带来维数灾难,因为无法作为一个完整的数据单元存储,更适合按块存储的方式。
关系型数据库——字段定义预先设定,修改开销大;数据写入合法性校验开销。
非关系型数据库——动态新增行、列数据,不需提前设计表结构,简单校验,降低访问延迟。
向量数据和传统结构化数据的差异——四个:
- 维数差异——向量数据按块存储
- 字段内相关性差异——多维度数据集体组合计算衡量相似度,索引设计不同(聚类、图)
- 优化手段差异——固定数据格式的缓存机制加速
- 使用方法差异——语义理解的匹配和关键词精确匹配,基于语义。
大模型——学习和推理、自然语言理解、泛化
向量数据库极简史
20世纪80年代,利用多层神经网络模拟人类神经元的连接,深度——网络结构层数和每一层中神经元的数量及连接方式。
困难:
- 训练困难:计算资源有限,无法计算
- 梯度消失:反向传播算法中的梯度值可能随着传播到较深层的网络而逐渐变得极其微小,导致权重更新缓慢,显著影响模型收敛速度。
- 过拟合:大量参数导致过度拟合,在训练集上效果表现好,但是在测试集上泛化能力弱。
减少过度拟合——ReLU激活函数、dropout技术;top-5错误率用来衡量模型应对复杂任务的泛化能力。
人类需要处理非结构化数据的存储、索引和查询方式:
深度学习模型的输出:卷积神经网络CNN、循环神经网络RNN、大模型——将非结构化数据转换为高维向量,包含丰富语义信息,用专门数据库来有效存储、索引和查询。
相似度查询的需求——推荐系统、图像识别、文本查询。
AI应用落地:GPT、GLM大模型处理大量像两个数据,对大模型预训练和推理。
向量化技术:深度学习模型生成的向量化数据可以捕捉数据的深层特征,可以挖掘数据内在复杂关系
多模态数据处理:深度学习模型可以处理多类型的非结构数据,将其转化为统一的向量格式,存储、索引和查询多模态数据,支持跨模态的搜索和分析。
实时性要求:快速响应查询要求,基于深度学习模型的优化检索结构、降低访问延迟、满足实时性要求
AI原生数据库能力——降低开发者使用门槛
2017年,FAISS——高性能向量管理库,为大规模数据集上高效相似度查询提供解决方案:扁平索引(10w以下精确)、倒排扁平索引(聚类,亿行级别数据)、倒排乘积量化索引。
HNSWLib开源高性能近似最近邻查询库,基于HNSW图算法,内存占用换取高性能查询,支持千万行级。
代表向量数据库产品请详见P27页面
代表产品技术架构
插件式向量数据库:Redis内核框架扩展Vector Search功能,集成向量模块。实现了包括扁平、HNSW、IVF在内的多种索引数据结构。向量模块与JSON模块配合使用,输入输出参数采用JSON格式进行交互。
插件式向量数据库——Redis Vector Search。
单机向量数据库:Chroma专注于向量数据的存储、索引和查询功能,不提供传统数据库的复杂功能(主从数据复制、分布式处理、事务机制、复杂查询、聚合计算)
存算一体分布式向量数据库:Master集群和Worker集群,各节点单独负责本节点的数据向量处理,存储和计算资源耦合在同一节点,扩容效率较低。(腾讯云)
存算分离分布式向量数据库:Pinecone和Milvus,利用对象存储来持久化索引文件。索引集群负责提供计算能力;存储集群泽负责构建索引,同时利用对象存储持久化索引文件,方便后续的数据加载和扩容迁移。
向量数据库的核心能力
管理向量数据库的重要一点是:良好的数据组织结构
向量数据库分层:实例、库、文档、字段
- 实例:物理资源集合、连接地址、授权访问信息
- 库:逻辑上相关的集合组合、数据隔离、统一管理
- 集合:存储向量数据的逻辑载体、可靠性和可用性参数配置、索引类型定义
- 文档:多个字段的组合、数据存储的最底层完整单元、数据操作的基本单位
- 字段:标量字段——文本、数值、日期;向量字段——向量数据、索引类型(扁平、HNSW、IVF)
实际应用中:不同部门数据用不同实例隔开、不同业务系统用不同库隔开、不同模块用不同集合隔开、不同用户数据用不同的文档隔开。
索引:主键索引、向量索引、过滤器索引。
主键索引:快速查找特定文档的数据库索引类型,文档唯一标识符
向量索引:基于数学模型和算法,专门应对提高对高维向量数据的访问和查询效率。(扁平、HNSW、IVF,详见P40)
过滤器索引:基于标量字段构建的索引,根据字段条件表达式来过滤查询范围,以匹配相似向量文档。
索引重建——根据高维向量数据的规模变化,需要增加行数,则需要支持动态索引重建。
衡量向量数据库运行状况的三个指标:
- 访问延迟
- 实例吞吐量
- 召回率
动态Schema:根据业务动态增加或者减少字段,无需进行预设,而通过动态应用程序增加。
别名机制:主要用于线上向量数据库的切换使用。
向量化:提高方便用户使用的向量化接口,隐藏GPU的调试功能代码块。
混合查询:结合了标量和向量字段,配合自定义的标量字段查询和过滤器条件表达式来进行查询,从而提供高效的查询效率和准确率。
构建向量数据库
这一章主要分为三节,分别是:实现单机向量数据库、实现分布式向量数据库、优化向量数据库。
实现单机向量数据库
本节主要用伪代码展示详细的代码编写情况,
实现了向量数据管理:基于FAISS库,实现扁平索引的写入和查询功能;基于HNSWLib实现HNSW索引的写入和查询功能。
实现了混合数据管理:引入RocksDB标量存储组件,同时存储浮点数向量数据和标签过滤数据,在内存中基于映射和位图数据结构搭建支持混合查询的索引结构,实现过滤查询。
实现了系统恢复:实现预写日志模块的恢复手段,实现快照机制——依赖FAISS和HNSWLib的索引存储和加载能力,依赖过滤索引的存储和加载能力,确保系统能快速恢复。
实现分布式向量数据库
在单机向量数据库的基础上扩展了下述关键功能:
主从数据复制:使用轻量开源实现方案——NuRaft,借用Raft协议的数据复制和节点选举功能,实现主从节点的数据复制,并且提交日志信息到系统中。
元数据管理模块:引入MasterServer(基于ETCD的分布式存储能力)实现元数据管理模块,将元数据配置持久化到ETCD中。
代理模块:实现读写分离和强制主节点读取功能。
分片策略:解决单节点写入时的扩展问题,基于配置,根据请求是否包含分片键来进行转发。
优化向量数据库
性能优化:通过采用AVX-512指令集,在通信方面,基于gRPC的通信协议来优化ProxyServer和VdbServer之间的数据交换。
成本优化:通过混合部署ProxyServer、MasterServer、VdbServer来降低部署成本,并降低模块间通信的延迟。
易用性优化:基于SDK的访问,引入基于JWT的鉴权方案,独立数据库备份系统。