Appearance
向量数据库的核心原理是把高维数据转换为多维向量,然后基于相似性度量快速检索与目标最相近的向量结果
关键三步
- 向量化
- 把非结构化数据转换成数值向量,保留语义或特征信息
- 索引构建
- 用HNSW图,产品量化PQ,位置敏感哈希LSH等结构预处理向量,加速后续搜索
- 近似搜索
- 允许一定误差,用ANN算法在速度和准确性之间取平衡,返回top-k相似结果,牺牲5%准度可以换来100倍速度提升
通俗理解
用快递站分拣包裹来比喻
- 把东西变成快递单号(向量化)
假设你有一堆包裹(图片、文本),每个包裹里装的东西都不一样,向量数据库会通过AI模型给每个包裹贴一个快递单号,比如一长串数字([0.3,-0.7,1.2,…]),这个单号能代表包裹的特征
- 给快递单号简历索引库(索引构建)
快递站要快速找到包裹,得按区域分拣
- HNSW图:像快递站分省、市、区三层货架,先定位到省、再缩小到市,最后找具体街道
- LSH哈希:把相似的快递单号扔到同一个框里,比如猫的图片全部放1号框,找的适合只看目标框
- PQ量化:把超长的快递单号拆成几段,用缩写代替,比如[0.3,0.7]缩写为A1,生内存还能加速
- 模糊找快递,不追求绝对准(近似搜索)
- 允许误差,可能找到95%像的,但是速度更快
- Top-K结果,直接给你5个最像的包裹,让你自己挑
对比传统数据库
- 传统数据库像查字典,必须精确拼写单词
- 向量数据库像描述找人,特征相似即可,允许误差
向量化怎么做
向量化靠的是Embedding模型,文本用text-embedding-ada-002,BGE,M3E这类模型
维度越高信息保留越完整,但是存储和计算成本就越高
中文BGE是768维,768维向量,单条就占3kb内存,1000w条就是30gb
索引结构详解
索引是向量数据库的核心,没有索引就只能暴力计算每条向量的距离
HNSW,分层可导航小世界图,像快递站分省市区一样,查询时从顶层开始眺,每层找最近的邻居往下走,最终定位到目标区域,构建时间长但查询极快,Milvus默认就用这个
IVF,Inverted File Index, 先用K-Means把向量聚成若干簇,查询时只在最近的几个簇内搜索,簇数量一般设置成数据量的平方根,比如100w数据分1000个簇
PQ,product quantization,把高维向量拆分成若干子向量,每段用聚类中心的编号代替原始值,128维向量拆成8段,每段用1字节编码,压缩比能到64倍
LSH,locality sensitive hashing, 设计一组哈希函数,让相似向量大概率落入一个桶,查询时只在一个桶里比较,适合海量数据的粗筛
性能指标
衡量向量索引性能主要看三个指标
- QPS:每秒查询数,Milvus在100w数据集上HNSW索引能跑到3000+QPS
- Recall@K,召回率,真正相似的结果有多少被检索出来,生产环境一般要求Recall@10 > 95%
- 延迟:单次查询耗时,毫秒级是基本要求,10ms内可以算优秀
调参主要要根据业务场景取舍,推荐系统可以牺牲点召回率换速度,搜索场景宁愿慢点也要召回准
一些其他问题
向量检索为什么不能用精确搜索,得用近似算法
- 精确搜索就是暴力计算每个向量的距离,时间复杂度是O(N*D),N是数据量,D是维度,1000w条768维向量,单词查询要算76亿次浮点运算,哪怕gpu也得跑个几百毫秒,近似算法通过索引结构把搜索范围做到千分之一或者万分之一,才能做到毫秒级响应,实际测试中,HNSW在Recall@10=95%的情况下速度比暴力搜快1000倍
HNSW和IVF怎么选
- 看内存够不够,HNSW把整个图结构加载到内存,100w 768维向量大概吃4-5gb的内存,IVF只存聚类中心和倒排索引,内存占用能省一半以上,如果内存比较足且对延迟要求高,选HNSW,数据量大内存吃紧就用IVF或者IVF_PQ组合
- Milvus里面还有个IVF_HNSW,先IVF分簇再在簇内构建HNSW,兼顾两者优势
向量数据库支持更新和删除吗,会有什么问题
- 支持,代价比传统数据库大,HNSW删除一个节点得断开它的所有边再重连邻居,频繁删除可能会导致图结构稀疏,查询效率下降
- IVF删除相对简单,倒排链表里标记一下就行,但是脏数据积累多了也得定期重建索引
- Milvus做法是软删除+后台Compaction,隔一段时间合并清理