随着LLM技术应用及落地,数据库需要提高向量分析以及AI支持能力,向量数据库及向量检索等能力“异军突起”,迎来业界持续不断关注。简单来说,向量检索技术以及向量数据库能为 LLM 提供外置的记忆单元,通过提供与问题及历史答案相关联的内容,协助 LLM 返回更准确的答案。
不仅仅是LLM,向量检索也早已在OLAP引擎中应用,用来提升非结构化数据的分析和检索能力。ByteHouse是火山引擎推出的云原生数据仓库,近期推出高性能向量检索能力,本篇将结合ByteHouse团队对向量数据库行业和技术的前沿观察,详细解读OLAP引擎如何建设高性能的向量检索能力,并最终通过开源软件VectorDBBench测试工具,在 cohere 1M 标准测试数据集上,recall 98 的情况下,QPS性能已可以超过专用向量数据库。
对于诸如图片、视频、音频等非结构化数据,传统数据库方式无法进行处理。目前,通用的技术是把非结构化数据通过一系列 embedding 模型将它变成向量化表示,然后将它们存储到数据库或者特定格式里。在搜索过程中,通过相同的一个模型把查询项转化成对应的向量,并进行一个近似度的匹配就可以实现对非结构化数据的查询。
在技术原理层面,向量检索主要是做一个 K Nearest Neighbors (K最近邻,简称 KNN) 计算,目标是在N个D维的向量的库中找最相似的k个结果。
在数据量较大场景,KNN 计算通常代价比较大,很难在较短时间内返回结果,此外,在很多场景,用户并不需要绝对精确的相似结果。因此,在真正在使用向量检索时,通常会使用相似最近邻搜索,即 ANN 的方式来替代 KNN,从 k 个绝对最近似结果变成 K 个近似最优结果,以牺牲一定准确度的前提,得到更短的响应时间。
由于大模型的训练数据有限,在针对一些最近的消息或者特定领域信息的查询来说,通常结果不准确。为了提升检索的准确性,一种比较常见的处理方式是将想搜索的信息的相关文档进行文本处理,并通过 embedding 模型将向量写入到向量数据库里后,把问题通过相同的 embedding 模型转化为向量进行近似度搜索,得到问题的相似知识作为 prompt,连同问题一起提交给大模型处理,最终得到更准确的答案。
向量检索算法基于其存储结构大致可分为四种。
目前实际场景中,使用较多的方法主要是后面的两种,即 Cluster-based 和 Graph-based。
首先,一个向量数据库需要具备向量类型数据和向量索引的存储与管理相关功能,包括增删改查等数据维护功能,另外,对于向量检索性能通常要求比较高。其次,向量检索通常需要与属性过滤等操作结合计算。最后,向量检索通常会与其他属性结合查询,比如以图搜图等场景,最终需要的,是相似的图片路径或文件。
构建向量数据库时,一种思路是以向量为中心,从底向上构建一个专用的向量数据库,这样的特点是,可以针对向量检索做特定的优化,能够保证较高的性能,缺点为缺乏复杂的数据管理和查询能力,通常需要结合其他数据库来使用。
另一种设计思路是基于现有的数据库和数据引擎增加向量检索相关扩展功能。优势是可以做到 all in one 的数据管理和查询支持,缺点为受现有架构的限制,很难做到较高的检索性能。
向量数据库目前还处于一个快速发展的阶段,目前看有两个趋势,一个是以专用向量数据库为基础,不断添加更多复杂的数据类型支持以及更多的数据管理机制,比如存算分离、一致性支持、实时导入等。此外,查询上也在不断添加前后置过滤等复杂查询策略的支持。
第二种构建思路是数据库加向量检索扩展,继续去支持更多的向量检索算法,并且不断按照向量检索的需求,添加特殊的过滤策略、简化对应的执行计划。
以上两种构建思路都在向一个统一的目标去汇合,即带有高性能向量检索,与完备数据管理和查询支持的数据库形态。这也是 ByteHouse 在设计向量检索相关功能时,主要考虑的一个目标。
ByteHouse是火山引擎研发的云原生数据仓库产品,在开源ClickHouse引擎之上做了技术架构重构,实现了云原生环境的部署和运维管理、存储计算分离、多租户管理等功能。在可扩展性、稳定性、可运维性、性能以及资源利用率方面都有巨大的提升。
此外,ByteHouse还支持了向量检索、全文检索、地理空间数据检索等功能。
ByteHouse 作为一款高性能向量数据库的底座的优势在于,其具备比较完备的 SQL 语法支持,高性能的计算引擎,以及比较完备的数据管理机制和丰富的数据表引擎,能够支持不同场景。
为了达到更高的向量检索性能,ByteHouse 基于向量为中心的设计思路,构建了一条高效的向量检索的执行路径,同时,引入了多种常用的向量检索算法,以满足不同场景的向量检索需求。
实际使用时,在建表时可以加一个 Index 的定义,包含索引名称、向量列、以及索引类型信息。
数据导入支持多种方式,比如基于 Kafka 的实时导入,insert file,python SDK 等。
基本查询是一个定式:select 需要的列信息,增加一个 order by + limit 的指令。查询支持与标量信息结合的混合查询,以及针对 distance 的 range 查询。
在添加高性能向量检索功能过程中,ByteHouse 主要克服以下三大难点:
根本原因:ByteHouse 中,当前最小的读取单元是一个 mark,即便通过 Vector Index 查询得到结果是有行号信息的,但是在真正读取的时候仍需要转成对应的 mark id 传给下层存储层读取。
优化:
1.把向量检索的计算进行了前置处理。
最初的设计中,向量检索计算时需要每个 data part 首先做 Vector Search 加上其他列信息的读取,然后再去做后面的 order by + limit 得到最终的结果。这种做法相当于每个data part 要取 top k,它的读取的行数是 part 数量乘以 mark_size 乘以 top k。这里做的优化是将 Vector Search 计算前置,上推到 data part 的读取之前,首先执行所有 data part 的 Vector Search,获取全局的 topK 个结果,再分配到各个 data part 去做 read。这样可以实现 IO 从百万减到千的级别的降低,实际使用中整体性能实现了两倍以上的提升。
2.存储层的过滤。
把 row level 的查询结果往下推到存储层读 mark 的位置进行一些过滤,减少了反序列化的开销。
3.在 filter by range 场景进行优化。
基于主键查找如按天查找或者按 label 查找等场景,只对首尾 mark 进行了一个读取和过滤,降低过滤语句的执行开销。
根本原因:相比于其他比较简单的索引,如 MinMax 等,向量索引构建时间更长,并且消耗资源更多。
优化:
原因:使用索引需要 Index 结构载入内存,载入到内存后才能进行一些检索加速。
优化:
加入Cache Preload 支持。在服务启动和数据写入以及后台数据 merge 的场景可以自动地把新的 index load 到内存。另外,自动的 GC 会把 Cache 中过期数据自动回收。
ByteHouse 团队基于业界最新的 VectorDBBench 测试工具进行测试,在 cohere 1M 标准测试数据集上,recall 98 的情况下,可以达到与专用向量数据库同等水平的性能。在 recall 95 以上的情况下,QPS 可以达到 2600 以上,p99 时延在 15ms 左右,具备业界领先优势。
评测对象:IVFPQFS+Refine(SQ8)和HNSW。
IVFPQFS+Refine(SQ8) 优点:
痛点:
很难在高精度的场景下替换HNSW