
1.倒排索引倒排索引Inverted Index就是一张词→文档编号的查找表。假设你手里三张纸1我 爱 北京2北京 好 大3我 爱 吃 烤鸭问题哪张纸上写了“北京”正排索引把三张纸从头看到尾一张张找。倒排索引相当于提前做一个小抄北京[1, 2]烤鸭[3]爱[1, 3]根据北京对应文档编号直接答出1号和2号。总结1.提前做小抄建索引要花时间但之后每次查都很快。2.小抄里不存原文只存编号。所以查到编号后还得回去把那几张纸拿出来看这叫“回表”。3.比的是步数笨办法要翻一万张小抄只要看一眼。2.KNNKNNK-Nearest Neighbors就是K个相邻邻居。K就是取几条的意思如K5意思是取最近的5条数据。还是那三张纸的例子换成这三句1 号想买台便宜点的笔记本2 号北京烤鸭真好吃3 号有没有性价比高的电脑推荐现在你搜「便宜电脑」。用倒排索引翻小抄查「电脑」只会命中 3 号1 号写的是「笔记本」而小抄里没有「电脑」这个词所以搜不到。明明是一个意思却漏了。这就是关键词搜索最大的毛病字不一样就找不到。KNN 换了另一套办法它不比较文字而是比较句子之间的意思够不够近。做法分两步1.先给每句话算出一串数字相当于在图上给每句话画一个“点”意思越接近点就挨得越近。2.搜索时先把你问的这句话也画成一个点然后看周围哪几个点离得最近把它们挑出来。这样1 号和 3 号因为意思像位置是挨着的都能被挑出来。总结1.倒排比字KNN 比意思。2.KNN 要先算数字每句话都变成一串数叫向量这一步很贵所以一般提前算好存起来。3.两个一起用最香先用 KNN 捞一批“意思像的”再用倒排索引保证“对的别漏”——这就是大家说的混合检索。3.ANNANNApproximate Nearest Neighbor近似最相邻。它不保证找的绝对准只保证找的足够准同时快很多。ANN 怎么偷懒一句话先缩小范围只在“可能最近的那一小片”里找。打个比方你要找全城离你最近的 5 家火锅店精确 KNN 把全城几千家店全部跑一遍量完再排序。结果绝对准但你得跑断腿。ANN 先看地图大致范围判断你的位置大概在哪个片区然后只在这几个片区里挑。可能漏掉隔壁片区一家没招牌的店但 5 家里有 4.9 家是对的而且你快了几百倍。这就是全部思想接受 1% 的漏换 100 倍的快。文本 → 模型算成一串数字embedding→ 用 ANN 建好“地图”存进向量库HNSW 图 / IVF 簇→ 用户 query 也算成一串数字→ 拿这串数字在地图上找最近的 K 条 → 返回结果ANN是一类方法的总称具体实现方法HNSW把点连成一张关系网还分出“快速通道层”。先坐电梯到高层、粗略定位到大致区域再一层层往下走到最底层精挑常用于Elasticsearch、Milvus、Qdrant、pgvector 的默认选择IVF先把全库点分成若干簇像分成若干小区搜索时只查离你最近的那几个簇Faiss 常用PQ把 768 个数压缩成 96 个字节像把大照片压成缩略图省内存、算得快代价是精度略降是内存不够时的救命方案4.PQ乘积量化把一整条精确向量抄成几个档位编号用查表代替浮点乘法。用精度换内存和速度。为什么要它1 亿条 128 维 float32 50 GB装不下。压到 4 字节/条后是 400 MB装得下才算得快。比方档位代替精确值不写「身高 179.3 cm、体重 68.4 kg」写「身高高、体重中」。损失精度但判断「这两个人像不像」完全够用。比方PQ一个人一条向量一个字段一段子向量档位表码本256 个聚类中心填好的档位1 个编号 1 字节建库三步切分把 D 维向量切成 M 段每段 D/M 维。例128 维切成 8段 × 16维训练对每一段单独跑 k-means聚成256 个中心。每段各有一套独立码本段 1 的 256 个中心和段 2 的 256 个中心毫无关系。256 是为了让编号刚好塞进 1 字节uint8编码每段去自己的码本里找最近的中心记下编号0~255。M 段 → M 个编号 → M 字节关键区别码本是训练出来的离线一次编号是编码算出来的每条向量一次。手算一遍为了手算把 256 个中心缩成 4 个。真实档位由 k-means 从样本学出。原始向量[1.0, 1.2, 5.0, 4.8, 9.1, 8.9]切 3 段每段 2 维。 档位(0,0)、(1,1)、(5,5)、(9,9)等等256个段原始最近档位编号1(1.0, 1.2)(1, 1)12(5.0, 4.8)(5, 5)23(9.1, 8.9)(9, 9)3存储结果[1, 2, 3]—— 3 个字节原来 6 个 float 24 字节为什么 6 个数变 3 个数因为每 2 个数组成一段一段整体换成一个编号2 合 1。为什么这里只压缩 8 倍压缩比 每段维数 × 4这里每段 2 维 → 2×4 8 倍。工程里每段 1632 维所以是 64128 倍。小注4 个档位其实 2 bit 就够说「3 字节」是为了对齐「1 编号 1 字节」的工程口径。解码近似还原查表拼回(1,1, 5,5, 9,9)≈ 原始向量只差一点点。记忆点编码 查最近的档位解码 用档位拼回去。查询三步把查询向量 q 切成同样的 M段算距离表对每个子段 q_m预先算出它到该段 256 个中心的距离得到 M × 256 个值。 存的是距离平方因为后面要相加用库向量的编号查表累加Distance(Q→V0) D0[124] D1[56] D2[132] D3[222]两个关键数字压缩比 每段维数 × 4 每段 32 维 → 128 倍组合数 256^M 名字里的「乘积」有损所以要 rerank量化误差 → 名次噪声 → 粗排捞 100 条 → 用原始向量重算 Top-10判断结果直接给用户看必做 rerank只做召回给下游可以省。