如何提升OpenAI语义搜索速度?大规模嵌入数据优化方案咨询
百万级嵌入向量相似度搜索提速方案
FAISS完全适配你的场景,它是Meta专门为大规模向量相似度搜索开发的工具,能把你当前线性遍历的O(n)复杂度降到近似O(log n),轻松支撑百万级数据的快速检索。
核心优化步骤:从JSON到FAISS索引
1. 构建FAISS索引(只需执行一次)
首先把JSON里的嵌入向量转换成numpy数组,然后构建FAISS索引并保存到本地,避免每次启动都重新处理数据:
import numpy as np import faiss import json # 读取JSON数据 with open("data_a_b_j.json", "r") as f: embedding_data = json.load(f) # 提取嵌入向量并转为numpy数组(float32是FAISS要求的格式) embeddings = np.array([item["embedding"] for item in embedding_data], dtype=np.float32) # 预归一化向量:余弦相似度 = 归一化向量的内积,这样可以用FAISS的内积索引替代余弦计算 faiss.normalize_L2(embeddings) # 构建精确内积索引(对应余弦相似度) index = faiss.IndexFlatIP(embeddings.shape[1]) # 添加向量到索引 index.add(embeddings) # 保存索引到文件,后续直接加载即可 faiss.write_index(index, "embeddings.index")
2. 快速相似度搜索(每次查询执行)
后续查询时直接加载索引,对查询向量归一化后执行搜索:
import numpy as np import faiss # 加载预构建的索引 index = faiss.read_index("embeddings.index") # 假设你已经得到查询向量embedding_query(来自OpenAI的嵌入结果) embedding_query = np.array(embedding_query, dtype=np.float32).reshape(1, -1) faiss.normalize_L2(embedding_query) # 搜索top-5最相似的向量(k可以根据需求调整) k = 5 distances, indices = index.search(embedding_query, k) # 结果解释:distances是相似度(内积值,即余弦相似度),indices是对应原数据的下标 print("Top相似向量下标:", indices[0]) print("对应相似度:", distances[0])
额外优化建议
- 替换JSON存储:JSON读取百万级数据效率极低,建议换成Parquet、Feather等列式存储格式,或者用PostgreSQL+pgvector这类支持向量搜索的数据库,数据加载速度会大幅提升。
- 选择近似索引(可选):如果百万级数据下精确搜索仍嫌慢,可以用IVF类索引(比如
faiss.IndexIVFFlat),通过聚类减少搜索范围,牺牲少量精度换取更高速度:# 示例:构建IVF1024索引(聚类数1024) quantizer = faiss.IndexFlatIP(embeddings.shape[1]) index = faiss.IndexIVFFlat(quantizer, embeddings.shape[1], 1024, faiss.METRIC_INNER_PRODUCT) index.train(embeddings) # 先训练聚类中心 index.add(embeddings) - 硬件加速:如果有GPU,直接使用FAISS的GPU版本,速度能提升10-100倍,只需把索引转移到GPU即可:
res = faiss.StandardGpuResources() gpu_index = faiss.index_cpu_to_gpu(res, 0, index)
对比原方案的优势
你当前的线性遍历方案,在10万条数据时大概需要几百毫秒,百万级则要几秒甚至更久;而FAISS的精确搜索在百万级数据下,单条查询耗时通常在1毫秒以内,近似搜索可以做到微秒级。
内容的提问来源于stack exchange,提问作者Sree Sankar
相关产品推荐
相关产品推荐

