使用Google通用句编码器时如何提升6万行文本余弦相似度计算效率
相似句子查找效率优化方案
1 算法优化:替换暴力匹配为向量检索方案
原来的双重循环是O(n²)时间复杂度,6万条数据对应36亿次运算,天然就不可能快。针对高维句向量的相似检索场景,直接用成熟的向量检索工具即可,精度损失可忽略的前提下速度提升上千倍:
- 优先选Meta开源的
FAISS库,对稠密向量的余弦相似度检索做了深度优化,支持CPU/GPU加速,6万条数据用精确检索模式也能在几分钟内跑完。
示例代码如下:
import faiss import numpy as np # 首先对所有句向量做L2归一化,归一化后内积计算结果等价于余弦相似度 normalized_emb = sentence_embeddings.numpy() faiss.normalize_L2(normalized_emb) # 构建精确内积索引,6万数据量不需要用近似索引,精度100% dim = normalized_emb.shape[1] index = faiss.IndexFlatIP(dim) index.add(normalized_emb) # 批量查询每个向量的Top10相似结果 k = 10 sim_scores, sim_indices = index.search(normalized_emb, k) # 筛选符合阈值的结果,跳过自身,还可以只保留idx < idx2的对避免重复存储 for idx in range(len(sentences)): for score, target_idx in zip(sim_scores[idx][1:], sim_indices[idx][1:]): if score >= 0.8: # 自行存储结果即可 pass
2 纯Python精确匹配优化
如果必须做100%精确的全量两两计算,也不要用Python原生双重循环,换成numpy向量化运算,底层为C实现,比纯Python循环快上百倍:
import numpy as np normalized_emb = sentence_embeddings.numpy() # 归一化后直接矩阵乘法算出全量相似度矩阵 normalized_emb = normalized_emb / np.linalg.norm(normalized_emb, axis=1, keepdims=True) sim_matrix = np.dot(normalized_emb, normalized_emb.T) # 筛选出相似度≥0.8且不是自身的句子对 mask = (sim_matrix >= 0.8) & (np.eye(len(sentences)) == 0) src_indices, tgt_indices = np.where(mask) # 得到的src_indices和tgt_indices就是符合要求的句子对下标
注意该方案需要约14G内存存储6万*6万的相似度矩阵,内存不足可以拆分批次计算。
3 其他编程语言解决方案
如果追求更高性能,可选用以下方案:
- Rust:通过
faiss-rs绑定调用FAISS接口,性能比Python调用高30%左右,内存占用更低,适合生产环境部署。 - C++:直接调用FAISS原生接口,性能最优,适合超大规模数据的长期检索任务。
内容的提问来源于stack exchange,提问作者Aadhiraj Nayar
相关产品推荐
相关产品推荐

