照片由 real-napster 在 Pixabay上
在我最近的一个项目中,我必须构建一个语义搜索系统,该系统可以高性能扩展并为报告搜索提供实时响应。我们在 AWS RDS 上使用 PostgreSQL 和 pgvector,并搭配 AWS Lambda 来实现这一目标。面临的挑战是允许用户使用自然语言查询而不是依赖死板的关键字进行搜索,同时确保响应时间在 1-2 秒甚至更短,并且只能利用 CPU 资源。
在这篇文章中,我将逐步介绍构建此搜索系统的步骤,从检索到重新排名,以及使用 OpenVINO 和智能批处理进行标记化进行的优化。
语义搜索概述:检索和重新排序
现代最先进的搜索系统通常包含两个主要步骤:检索和重新排名。
1) 检索: 第一步涉及根据用户查询检索相关文档的子集。这可以使用预先训练的嵌入模型来完成,例如 OpenAI 的小型和大型嵌入、Cohere 的嵌入模型或 Mixbread 的 mxbai 嵌入。检索的重点是通过测量文档与查询的相似性来缩小文档池的范围。
这是一个使用 Huggingface 的句子转换器库进行检索的简化示例,这是我最喜欢的库之一:
from sentence_transformers import SentenceTransformer import numpy as np # Load a pre-trained sentence transformer model model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2") # Sample query and documents (vectorize the query and the documents) query = "How do I fix a broken landing gear?" documents = ["Report 1 on landing gear failure", "Report 2 on engine problems"] # Get embeddings for query and documents query_embedding = model.encode(query) document_embeddings = model.encode(documents) # Calculate cosine similarity between query and documents similarities = np.dot(document_embeddings, query_embedding) # Retrieve top-k most relevant documents top_k = np.argsort(similarities)[-5:] print("Top 5 documents:", [documents[i] for i in top_k])
2)重新排名:检索到最相关的文档后,我们使用交叉编码器模型进一步提高这些文档的排名。此步骤会更准确地重新评估与查询相关的每个文档,重点关注更深入的上下文理解。
重新排名是有益的,因为它通过更精确地评分每个文档的相关性来增加额外的细化层。
这是使用 cross-encoder/ms-marco-TinyBERT-L-2-v2(一种轻量级交叉编码器)进行重新排名的代码示例:
from sentence_transformers import CrossEncoder # Load the cross-encoder model cross_encoder = CrossEncoder("cross-encoder/ms-marco-TinyBERT-L-2-v2") # Use the cross-encoder to rerank top-k retrieved documents query_document_pairs = [(query, doc) for doc in documents] scores = cross_encoder.predict(query_document_pairs) # Rank documents based on the new scores top_k_reranked = np.argsort(scores)[-5:] print("Top 5 reranked documents:", [documents[i] for i in top_k_reranked])
识别瓶颈:标记化和预测的成本
在开发过程中,我发现在使用句子转换器的默认设置处理 1,000 个报告时,标记化和预测阶段花费了相当长的时间。这造成了性能瓶颈,特别是因为我们的目标是实时响应。
下面我使用 SnakeViz 分析了我的代码以可视化性能:
如您所见,标记化和预测步骤异常缓慢,导致搜索结果的提供出现严重延迟。总的来说,平均需要 4-5 秒。这是因为标记化和预测步骤之间存在阻塞操作。如果我们还添加其他操作,例如数据库调用、过滤等,我们很容易就总共需要 8-9 秒。
使用 OpenVINO 优化性能
我面临的问题是:我们可以让它更快吗?答案是肯定的,通过利用 OpenVINO,一个针对 CPU 推理优化的后端。 OpenVINO 有助于加速英特尔硬件上的深度学习模型推理,我们在 AWS Lambda 上使用该硬件。
OpenVINO 优化的代码示例
以下是我如何将 OpenVINO 集成到搜索系统中以加快推理速度:
from sentence_transformers import SentenceTransformer import numpy as np # Load a pre-trained sentence transformer model model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2") # Sample query and documents (vectorize the query and the documents) query = "How do I fix a broken landing gear?" documents = ["Report 1 on landing gear failure", "Report 2 on engine problems"] # Get embeddings for query and documents query_embedding = model.encode(query) document_embeddings = model.encode(documents) # Calculate cosine similarity between query and documents similarities = np.dot(document_embeddings, query_embedding) # Retrieve top-k most relevant documents top_k = np.argsort(similarities)[-5:] print("Top 5 documents:", [documents[i] for i in top_k])
通过这种方法,我们可以获得 2-3 倍的加速,将原来的 4-5 秒减少到 1-2 秒。完整的工作代码位于 Github 上。
速度微调:批量大小和标记化
提高性能的另一个关键因素是优化标记化流程并调整批量大小和标记长度。通过增加批量大小(batch_size = 16)和减少令牌长度(max_length = 512),我们可以并行化令牌化并减少重复操作的开销。在我们的实验中,我们发现 16 到 64 之间的 batch_size 效果很好,任何更大的值都会降低性能。同样,我们将 max_length 设置为 128,如果报告的平均长度相对较短,则该值是可行的。通过这些更改,我们实现了 8 倍的整体加速,将重新排名时间缩短至 1 秒以下,即使在 CPU 上也是如此。
在实践中,这意味着尝试不同的批量大小和令牌长度,以找到数据速度和准确性之间的适当平衡。通过这样做,我们看到响应时间显着缩短,使得搜索系统即使有 1,000 份报告也可扩展。
结论
通过使用 OpenVINO 并优化标记化和批处理,我们能够构建一个高性能语义搜索系统,满足仅 CPU 设置的实时要求。事实上,我们的整体速度提升了 8 倍。使用句子转换器进行检索与使用交叉编码器模型进行重新排名相结合,创造了强大的、用户友好的搜索体验。
如果您正在构建响应时间和计算资源受到限制的类似系统,我强烈建议您探索 OpenVINO 和智能批处理以释放更好的性能。
希望您喜欢这篇文章。如果您觉得这篇文章有用,请给我一个赞,以便其他人也可以找到它,并与您的朋友分享。在 Linkedin 上关注我,了解我的最新工作。感谢您的阅读!
以上是使用 OpenVINO 和 Postgres 构建快速高效的语义搜索系统的详细内容。更多信息请关注PHP中文网其他相关文章!

Linux终端中查看Python版本时遇到权限问题的解决方法当你在Linux终端中尝试查看Python的版本时,输入python...

本文解释了如何使用美丽的汤库来解析html。 它详细介绍了常见方法,例如find(),find_all(),select()和get_text(),以用于数据提取,处理不同的HTML结构和错误以及替代方案(SEL)

本文比较了Tensorflow和Pytorch的深度学习。 它详细介绍了所涉及的步骤:数据准备,模型构建,培训,评估和部署。 框架之间的关键差异,特别是关于计算刻度的

Python的statistics模块提供强大的数据统计分析功能,帮助我们快速理解数据整体特征,例如生物统计学和商业分析等领域。无需逐个查看数据点,只需查看均值或方差等统计量,即可发现原始数据中可能被忽略的趋势和特征,并更轻松、有效地比较大型数据集。 本教程将介绍如何计算平均值和衡量数据集的离散程度。除非另有说明,本模块中的所有函数都支持使用mean()函数计算平均值,而非简单的求和平均。 也可使用浮点数。 import random import statistics from fracti

本文讨论了诸如Numpy,Pandas,Matplotlib,Scikit-Learn,Tensorflow,Tensorflow,Django,Blask和请求等流行的Python库,并详细介绍了它们在科学计算,数据分析,可视化,机器学习,网络开发和H中的用途

本文指导Python开发人员构建命令行界面(CLIS)。 它使用Typer,Click和ArgParse等库详细介绍,强调输入/输出处理,并促进用户友好的设计模式,以提高CLI可用性。

在使用Python的pandas库时,如何在两个结构不同的DataFrame之间进行整列复制是一个常见的问题。假设我们有两个Dat...

文章讨论了虚拟环境在Python中的作用,重点是管理项目依赖性并避免冲突。它详细介绍了他们在改善项目管理和减少依赖问题方面的创建,激活和利益。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Dreamweaver Mac版
视觉化网页开发工具

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

SublimeText3汉化版
中文版,非常好用